changeset 14242:637675470c58 gui

Added OctaveDEs konsole sources.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Sun, 22 Jan 2012 14:18:05 +0100
parents a9992bc3c3f7
children b871a65c5681
files gui/OctaveDE_Qt-README gui/all.pro gui/konsole/Application.cpp gui/konsole/Application.h gui/konsole/BlockArray.cpp gui/konsole/BlockArray.h gui/konsole/BookmarkHandler.cpp gui/konsole/BookmarkHandler.h gui/konsole/CMakeLists.txt gui/konsole/Character.h gui/konsole/CharacterColor.h gui/konsole/ColorScheme.cpp gui/konsole/ColorScheme.h gui/konsole/ColorSchemeEditor.cpp gui/konsole/ColorSchemeEditor.h gui/konsole/CopyInputDialog.cpp gui/konsole/CopyInputDialog.h gui/konsole/EditProfileDialog.cpp gui/konsole/EditProfileDialog.h gui/konsole/Emulation.cpp gui/konsole/Emulation.h gui/konsole/Filter.cpp gui/konsole/Filter.h gui/konsole/History.cpp gui/konsole/History.h gui/konsole/HistorySizeDialog.cpp gui/konsole/HistorySizeDialog.h gui/konsole/IncrementalSearchBar.cpp gui/konsole/IncrementalSearchBar.h gui/konsole/KeyBindingEditor.cpp gui/konsole/KeyBindingEditor.h gui/konsole/KeyboardTranslator.cpp gui/konsole/KeyboardTranslator.h gui/konsole/LineFont.h gui/konsole/MainWindow.cpp gui/konsole/MainWindow.h gui/konsole/Makefile gui/konsole/ManageProfilesDialog.cpp gui/konsole/ManageProfilesDialog.h gui/konsole/Part.cpp gui/konsole/Part.h gui/konsole/ProcessInfo.cpp gui/konsole/ProcessInfo.h gui/konsole/Profile.cpp gui/konsole/Profile.h gui/konsole/ProfileList.cpp gui/konsole/ProfileList.h gui/konsole/ProfileListWidget.cpp gui/konsole/ProfileListWidget.h gui/konsole/Pty.cpp gui/konsole/Pty.h gui/konsole/RemoteConnectionDialog.cpp gui/konsole/RemoteConnectionDialog.h gui/konsole/RenameTabsDialog.cpp gui/konsole/RenameTabsDialog.h gui/konsole/Screen.cpp gui/konsole/Screen.h gui/konsole/ScreenWindow.cpp gui/konsole/ScreenWindow.h gui/konsole/Session.cpp gui/konsole/Session.h gui/konsole/SessionController.cpp gui/konsole/SessionController.h gui/konsole/SessionManager.cpp gui/konsole/SessionManager.h gui/konsole/ShellCommand.cpp gui/konsole/ShellCommand.h gui/konsole/TabTitleFormatAction.cpp gui/konsole/TabTitleFormatAction.h gui/konsole/TerminalCharacterDecoder.cpp gui/konsole/TerminalCharacterDecoder.h gui/konsole/TerminalDisplay.cpp gui/konsole/TerminalDisplay.h gui/konsole/ViewContainer.cpp gui/konsole/ViewContainer.h gui/konsole/ViewManager.cpp gui/konsole/ViewManager.h gui/konsole/ViewProperties.cpp gui/konsole/ViewProperties.h gui/konsole/ViewSplitter.cpp gui/konsole/ViewSplitter.h gui/konsole/Vt102Emulation.cpp gui/konsole/Vt102Emulation.h gui/konsole/WarningBox.cpp gui/konsole/WarningBox.h gui/konsole/XKB.cpp gui/konsole/ZModemDialog.cpp gui/konsole/ZModemDialog.h gui/konsole/fontembedder.cpp gui/konsole/kdecore_export.h gui/konsole/konsole_export.h gui/konsole/konsole_wcwidth.cpp gui/konsole/konsole_wcwidth.h gui/konsole/kprocess.cpp gui/konsole/kprocess.h gui/konsole/kprocess_p.h gui/konsole/kpty.cpp gui/konsole/kpty.h gui/konsole/kpty_export.h gui/konsole/kpty_p.h gui/konsole/kptydevice.cpp gui/konsole/kptydevice.h gui/konsole/kptyprocess.cpp gui/konsole/kptyprocess.h gui/konsole/main.cpp gui/konsole/qtermwidget.cpp gui/konsole/qtermwidget.h gui/qtermwidget/AUTHORS gui/qtermwidget/COPYING gui/qtermwidget/CVS/Entries gui/qtermwidget/CVS/Repository gui/qtermwidget/CVS/Root gui/qtermwidget/Changelog gui/qtermwidget/INSTALL gui/qtermwidget/README gui/qtermwidget/TODO gui/qtermwidget/lib/BlockArray.cpp gui/qtermwidget/lib/BlockArray.h gui/qtermwidget/lib/CVS/Entries gui/qtermwidget/lib/CVS/Repository gui/qtermwidget/lib/CVS/Root gui/qtermwidget/lib/Character.h gui/qtermwidget/lib/CharacterColor.h gui/qtermwidget/lib/ColorTables.h gui/qtermwidget/lib/DefaultTranslatorText.h gui/qtermwidget/lib/Emulation.cpp gui/qtermwidget/lib/Emulation.h gui/qtermwidget/lib/ExtendedDefaultTranslator.h gui/qtermwidget/lib/Filter.cpp gui/qtermwidget/lib/Filter.h gui/qtermwidget/lib/History.cpp gui/qtermwidget/lib/History.h gui/qtermwidget/lib/KeyboardTranslator.cpp gui/qtermwidget/lib/KeyboardTranslator.h gui/qtermwidget/lib/LineFont.h gui/qtermwidget/lib/LineFont.src gui/qtermwidget/lib/Pty.cpp gui/qtermwidget/lib/Pty.h gui/qtermwidget/lib/README gui/qtermwidget/lib/Screen.cpp gui/qtermwidget/lib/Screen.h gui/qtermwidget/lib/ScreenWindow.cpp gui/qtermwidget/lib/ScreenWindow.h gui/qtermwidget/lib/Session.cpp gui/qtermwidget/lib/Session.h gui/qtermwidget/lib/ShellCommand.cpp gui/qtermwidget/lib/ShellCommand.h gui/qtermwidget/lib/TerminalCharacterDecoder.cpp gui/qtermwidget/lib/TerminalCharacterDecoder.h gui/qtermwidget/lib/TerminalDisplay.cpp gui/qtermwidget/lib/TerminalDisplay.h gui/qtermwidget/lib/Vt102Emulation.cpp gui/qtermwidget/lib/Vt102Emulation.h gui/qtermwidget/lib/default.keytab gui/qtermwidget/lib/k3process.cpp gui/qtermwidget/lib/k3process.h gui/qtermwidget/lib/k3processcontroller.cpp gui/qtermwidget/lib/k3processcontroller.h gui/qtermwidget/lib/kb-layouts/CVS/Entries gui/qtermwidget/lib/kb-layouts/CVS/Repository gui/qtermwidget/lib/kb-layouts/CVS/Root gui/qtermwidget/lib/kb-layouts/default.keytab gui/qtermwidget/lib/kb-layouts/linux.keytab gui/qtermwidget/lib/kb-layouts/vt420pc.keytab gui/qtermwidget/lib/konsole_wcwidth.cpp gui/qtermwidget/lib/konsole_wcwidth.h gui/qtermwidget/lib/kpty.cpp gui/qtermwidget/lib/kpty.h gui/qtermwidget/lib/kpty_p.h gui/qtermwidget/lib/lib.pro gui/qtermwidget/lib/qtermwidget.cpp gui/qtermwidget/lib/qtermwidget.h gui/qtermwidget/qtermwidget.pro gui/qtermwidget/src/CVS/Entries gui/qtermwidget/src/CVS/Repository gui/qtermwidget/src/CVS/Root gui/qtermwidget/src/README gui/qtermwidget/src/main.cpp gui/qtermwidget/src/src.pro
diffstat 179 files changed, 39943 insertions(+), 22061 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/OctaveDE_Qt-README	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,36 @@
+This is a first step toward migrating octavede from GTK+ with the VTE terminal emulator widget to a QT-based solutions. There was a previous developer who had taken the KDE Konsole application and remove all KDE dependencies and created a QT-only widget on top of a subset of the Konsole sources. It was called qtermwidget (http://qtermwidget.sourceforge.net).  I would like to make a set of patches for Konsole so that Konsole can be separated into a QT-only part and a KDE app on top of it and proposed it to the Konsole maintainers to make this process easier for all future versions of Konsole.
+
+Here are a few notes about the current sources
+
+Directories
+================================================================================
+konsole - contains all the modifies source code for Konsole, plus some sources from KDElibs
+kb-layouts - taken from the qtermwidget project to handle different keyboards
+src - modified from the qtermwidget project to create a terminal running octave. This program runs
+      octave_main() in the same thread as the UI so that the UI can interact with octave through
+      the same octave_server class that was used for the GTK+/VTE version of octavede.
+
+BUILD
+================================================================================
+I didn't want to try and figure out how to compile QT stuff (with all the weird MOC stuff)
+using autotools, so I used a .pro file for compiling the src directory and a CMakeLists.txt
+file for compiling the konsole library.
+
+Steps:
+1) cd konsole
+2) ccmake .
+3) c c g (for configure, configure, generate)
+4) make
+5) cd ../src
+6) qmake
+7) make
+
+You will definitely need to modify src.pro to point to your octave installation. I was pointing to my own recent build, but I don't think at this point that anything depends
+on a specific version of octave.
+
+Please let me know if you have any problems.
+
+jpswensen at gmail.com
+
+
+
--- a/gui/all.pro	Sat Jan 21 11:26:36 2012 +0100
+++ b/gui/all.pro	Sun Jan 22 14:18:05 2012 +0100
@@ -16,5 +16,4 @@
 
 TEMPLATE = subdirs
 
-SUBDIRS += octave-gui\
-	qtermwidget
+SUBDIRS += octave-gui
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Application.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,462 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "Application.h"
+
+// std
+#include <iostream>
+
+#include "kdebug.h"
+
+// Qt
+#include <QHashIterator>
+#include <QFileInfo>
+#include <QDir>
+
+// KDE
+#include <KAction>
+#include <KCmdLineArgs>
+#include <KDebug>
+#include <KWindowSystem>
+
+// Konsole
+#include "ColorScheme.h"
+#include "ProfileList.h"
+#include "SessionManager.h"
+#include "KeyboardTranslator.h"
+#include "MainWindow.h"
+#include "Session.h"
+#include "TerminalDisplay.h"
+#include "ViewManager.h"
+
+using namespace Konsole;
+
+Application::Application() : KUniqueApplication()
+{
+    init();
+}
+
+void Application::init()
+{
+    _sessionList = 0;
+    _backgroundInstance = 0;
+
+    // check for compositing functionality
+    TerminalDisplay::setTransparencyEnabled( KWindowSystem::compositingActive() );
+#if defined(Q_WS_MAC) && QT_VERSION >= 0x040600
+    // this ensures that Ctrl and Meta are not swapped, so CTRL-C and friends
+    // will work correctly in the terminal
+    setAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
+#endif
+}
+
+Application* Application::self()
+{
+    return (Application*)KApp;
+}
+
+MainWindow* Application::newMainWindow()
+{
+    MainWindow* window = new MainWindow();
+    window->setSessionList( new ProfileList(true,window) );
+
+    connect( window , SIGNAL(newSessionRequest(Profile::Ptr,const QString&,ViewManager*)), 
+                      this , SLOT(createSession(Profile::Ptr,const QString&,ViewManager*)));
+    connect( window , SIGNAL(newSSHSessionRequest(Profile::Ptr,const KUrl&,ViewManager*)),
+                      this , SLOT(createSSHSession(Profile::Ptr,const KUrl&,ViewManager*)));
+    connect( window , SIGNAL(newWindowRequest(Profile::Ptr,const QString&)),
+                      this , SLOT(createWindow(Profile::Ptr,const QString&)) );
+    connect( window->viewManager() , SIGNAL(viewDetached(Session*)) , this , SLOT(detachView(Session*)) );
+
+    return window;
+}
+
+void Application::listAvailableProfiles()
+{
+    QList<QString> paths = SessionManager::instance()->availableProfilePaths();
+    QListIterator<QString> iter(paths);
+
+    while ( iter.hasNext() )
+    {
+        QFileInfo info(iter.next());
+        std::cout << info.baseName().toLocal8Bit().data() << std::endl;
+    }
+    quit();
+}
+
+int Application::newInstance()
+{
+    KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+    static bool firstInstance = true;
+
+    // handle session management
+    if ((args->count() != 0) || !firstInstance || !isSessionRestored())
+    {
+        // check for arguments to print help or other information to the terminal,
+        // quit if such an argument was found
+        if ( processHelpArgs(args) )
+            return 0;
+
+        // create a new window or use an existing one
+        MainWindow* window = processWindowArgs(args);
+
+        // select profile to use
+        processProfileSelectArgs(args,window);
+
+        // process various command-line options which cause a property of the
+        // default profile to be changed
+        processProfileChangeArgs(args,window);
+
+        if ( !args->isSet("tabs-from-file") ) {
+            // create new session
+            Session* session = createSession(window->defaultProfile(),
+                                             QString(),
+                                             window->viewManager());
+            if ( !args->isSet("close") ) {
+                session->setAutoClose(false);
+            }
+        }
+        else {
+            // create new session(s) as described in file
+            processTabsFromFileArgs(args, window);
+        }
+
+        // if the background-mode argument is supplied, start the background session
+        // ( or bring to the front if it already exists )
+        if ( args->isSet("background-mode") )
+            startBackgroundMode(window);
+        else
+        {
+            // Qt constrains top-level windows which have not been manually resized
+            // (via QWidget::resize()) to a maximum of 2/3rds of the screen size.
+            //
+            // This means that the terminal display might not get the width/height
+            // it asks for.  To work around this, the widget must be manually resized
+            // to its sizeHint().
+            //
+            // This problem only affects the first time the application is run.  After
+            // that KMainWindow will have manually resized the window to its saved size
+            // at this point (so the Qt::WA_Resized attribute will be set)
+            if (!window->testAttribute(Qt::WA_Resized))
+                window->resize(window->sizeHint());
+
+            window->show();
+        }
+    }
+
+    firstInstance = false;
+    args->clear();
+    return 0;
+}
+
+/* Documentation for tab file:
+ * ;; is the token separator
+ * # at the beginning of line results in line being ignored
+ * tokens are title:, command:, profile: (not used currently)
+ * Note that the title is static and the tab will close when the 
+ * command is complete (do not use --noclose).  You can start new tabs.
+ * Examples:
+title: This is the title;; command: ssh jupiter
+title: Top this!;; command: top
+#title: This is commented out;; command: ssh jupiter
+command: ssh  earth
+*/
+void Application::processTabsFromFileArgs(KCmdLineArgs* args, MainWindow* window)
+{
+    // Open tab configuration file
+    const QString tabsFileName(args->getOption("tabs-from-file"));
+    QFile tabsFile(tabsFileName);
+    if(!tabsFile.open(QFile::ReadOnly)) {
+        kWarning() << "ERROR: Cannot open tabs file "
+                   << tabsFileName.toLocal8Bit().data();
+        quit();
+    }
+    
+    unsigned int sessions = 0;
+    while (!tabsFile.atEnd()) {
+        QString lineString(tabsFile.readLine());
+        if ((lineString.isEmpty()) || (lineString[0] == '#'))
+            continue;
+
+        QHash<QString, QString> lineTokens;
+        QStringList lineParts = lineString.split(";;", QString::SkipEmptyParts);
+
+        for (int i = 0; i < lineParts.size(); ++i) {
+            QString key = lineParts.at(i).section(':', 0, 0).trimmed().toLower();
+            QString value = lineParts.at(i).section(':', 1, 1).trimmed();
+            lineTokens[key] = value;
+
+        }
+        // command: is the only token required
+        if (lineTokens.contains("command")) {
+            createTabFromArgs(args, window, lineTokens);
+            sessions++;
+        } else {
+            kWarning() << "Tab file line must have the 'command:' entry.";
+        }
+    }
+    tabsFile.close();
+
+    if (sessions < 1) {
+        kWarning() << "No valid lines found in "
+                   << tabsFileName.toLocal8Bit().data();
+       quit();
+    }
+}
+
+void Application::createTabFromArgs(KCmdLineArgs* args, MainWindow* window, const QHash<QString, QString>& tokens)
+{
+    QString title = tokens["title"];
+    QString command = tokens["command"];
+    QString profile = tokens["profile"]; // currently not used
+
+    // TODO: A lot of duplicate code below
+
+    // Get the default profile
+    Profile::Ptr defaultProfile = window->defaultProfile();
+    if (!defaultProfile) {
+        defaultProfile = SessionManager::instance()->defaultProfile();
+    }
+
+    // Create profile setting, with command and workdir
+    Profile::Ptr newProfile = Profile::Ptr(new Profile(defaultProfile));
+    newProfile->setHidden(true);
+    newProfile->setProperty(Profile::Command,   command);
+    newProfile->setProperty(Profile::Arguments, command.split(' '));
+    if(args->isSet("workdir")) {
+        newProfile->setProperty(Profile::Directory,args->getOption("workdir"));
+    }
+    if(!newProfile->isEmpty()) {
+        window->setDefaultProfile(newProfile); 
+    }    
+                    
+    // Create the new session
+    Session* session = createSession(window->defaultProfile(), QString(), window->viewManager());
+    session->setTabTitleFormat(Session::LocalTabTitle, title);
+    session->setTabTitleFormat(Session::RemoteTabTitle, title);
+    session->setTitle(Session::DisplayedTitleRole, title);   // Ensure that new title is displayed
+    if ( !args->isSet("close") ) {
+        session->setAutoClose(false);
+    }
+    if (!window->testAttribute(Qt::WA_Resized)) {
+        window->resize(window->sizeHint());
+    }
+                    
+    // Reset the profile to default. Otherwise, the next manually
+    // created tab would have the command above!
+    newProfile = Profile::Ptr(new Profile(defaultProfile));
+    newProfile->setHidden(true);
+    window->setDefaultProfile(newProfile); 
+                
+}
+
+MainWindow* Application::processWindowArgs(KCmdLineArgs* args)
+{
+    MainWindow* window = 0;
+    if ( args->isSet("new-tab") )
+    {
+        QListIterator<QWidget*> iter(topLevelWidgets());
+        iter.toBack();
+        while ( iter.hasPrevious() )
+        {
+            window = qobject_cast<MainWindow*>(iter.previous());
+            if ( window != 0 )
+                break;
+        } 
+    }
+    
+    if ( window == 0 )
+    {
+        window = newMainWindow();
+    }
+    return window;
+}
+
+void Application::processProfileSelectArgs(KCmdLineArgs* args,MainWindow* window)
+{
+    if ( args->isSet("profile") )
+    {
+        Profile::Ptr profile = SessionManager::instance()->loadProfile(args->getOption("profile"));
+        if (!profile)
+            profile = SessionManager::instance()->defaultProfile();
+
+         window->setDefaultProfile(profile);
+    }
+}
+
+bool Application::processHelpArgs(KCmdLineArgs* args)
+{
+    if ( args->isSet("list-profiles") )
+    {
+        listAvailableProfiles();
+        return true;
+    }
+    return false;
+}
+void Application::processProfileChangeArgs(KCmdLineArgs* args,MainWindow* window) 
+{
+    Profile::Ptr defaultProfile = window->defaultProfile();
+    if (!defaultProfile)
+        defaultProfile = SessionManager::instance()->defaultProfile();
+    Profile::Ptr newProfile = Profile::Ptr(new Profile(defaultProfile));
+    newProfile->setHidden(true);
+    // run a custom command
+    if ( args->isSet("e") ) 
+    {
+        QStringList arguments;
+        arguments << args->getOption("e");
+        for ( int i = 0 ; i < args->count() ; i++ )
+           arguments << args->arg(i); 
+
+        QString exec = args->getOption("e");
+        if (exec.startsWith(QLatin1String("./")))
+          exec = QDir::currentPath() + exec.mid(1);
+        newProfile->setProperty(Profile::Command,exec);
+        newProfile->setProperty(Profile::Arguments,arguments);
+    }
+
+    // change the initial working directory
+    if( args->isSet("workdir") )
+    {
+        newProfile->setProperty(Profile::Directory,args->getOption("workdir"));
+    }
+
+    // temporary changes to profile options specified on the command line
+    foreach( const QString &value , args->getOptionList("p") ) 
+    {
+        ProfileCommandParser parser;
+        
+        QHashIterator<Profile::Property,QVariant> iter(parser.parse(value));
+        while ( iter.hasNext() )
+        {
+            iter.next();
+            newProfile->setProperty(iter.key(),iter.value());
+        }        
+    }
+
+    if (!newProfile->isEmpty())
+    {
+        window->setDefaultProfile(newProfile); 
+    }    
+}
+
+void Application::startBackgroundMode(MainWindow* window)
+{
+        if ( _backgroundInstance )
+        {
+            return;
+        }
+
+        KAction* action = new KAction(window);
+        KShortcut shortcut = action->shortcut();
+        action->setObjectName( QLatin1String("Konsole Background Mode" ));
+        //TODO - Customizable key sequence for this
+        action->setGlobalShortcut( KShortcut(QKeySequence(Qt::Key_F12)) );
+
+        _backgroundInstance = window;
+        
+        connect( action , SIGNAL(triggered()) , this , SLOT(toggleBackgroundInstance()) );
+}
+
+void Application::toggleBackgroundInstance()
+{
+    Q_ASSERT( _backgroundInstance );
+
+    if ( !_backgroundInstance->isVisible() )
+    {
+        _backgroundInstance->show();
+        // ensure that the active terminal display has the focus.
+        // without this, an odd problem occurred where the focus widgetwould change
+        // each time the background instance was shown 
+        _backgroundInstance->viewManager()->activeView()->setFocus();
+    }
+    else 
+    {
+        _backgroundInstance->hide();
+    }
+}
+
+Application::~Application()
+{
+    SessionManager::instance()->closeAll();
+    SessionManager::instance()->saveState();
+}
+
+void Application::detachView(Session* session)
+{
+    MainWindow* window = newMainWindow();
+    window->viewManager()->createView(session);
+    window->show();
+}
+
+void Application::createWindow(Profile::Ptr profile , const QString& directory)
+{
+    MainWindow* window = newMainWindow();
+    window->setDefaultProfile(profile);
+    createSession(profile,directory,window->viewManager());
+    window->show();
+}
+
+Session* Application::createSession(Profile::Ptr profile, const QString& directory , ViewManager* view)
+{
+    if (!profile)
+        profile = SessionManager::instance()->defaultProfile();
+
+    Session* session = SessionManager::instance()->createSession(profile);
+
+    if (!directory.isEmpty() && profile->property<bool>(Profile::StartInCurrentSessionDir))
+        session->setInitialWorkingDirectory(directory);
+
+    // create view before starting the session process so that the session doesn't suffer
+    // a change in terminal size right after the session starts.  some applications such as GNU Screen
+    // and Midnight Commander don't like this happening
+    view->createView(session);
+    session->run();
+
+    return session;
+}
+
+Session* Application::createSSHSession(Profile::Ptr profile, const KUrl& url, ViewManager* view)
+{
+    if (!profile)
+        profile = SessionManager::instance()->defaultProfile();
+
+    Session* session = SessionManager::instance()->createSession(profile);
+
+    session->sendText("ssh ");
+
+    if ( url.port() > -1 )
+        session->sendText("-p " + QString::number(url.port()) + ' ' );
+    if ( url.hasUser() )
+        session->sendText(url.user() + '@');
+    if ( url.hasHost() )
+        session->sendText(url.host() + '\r');
+
+    // create view before starting the session process so that the session doesn't suffer
+    // a change in terminal size right after the session starts.  some applications such as GNU Screen
+    // and Midnight Commander don't like this happening
+    view->createView(session);
+    session->run();
+
+    return session;
+}
+
+#include "Application.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Application.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,98 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+// KDE 
+#include <KUniqueApplication>
+
+// Konsole
+#include "Profile.h"
+
+class KCmdLineArgs;
+
+namespace Konsole
+{
+class ProfileList;
+class ViewManager;
+class MainWindow;
+class Session;
+
+/**
+ * The Konsole Application.
+ *
+ * The application consists of one or more main windows and a set of factories to create 
+ * new sessions and views.
+ *
+ * To create a new main window with a default terminal session, call the newInstance() method.
+ * Empty main windows can be created using newMainWindow().
+ *
+ * The factory used to create new terminal sessions can be retrieved using the sessionManager() accessor.
+ */
+class Application : public KUniqueApplication
+{
+Q_OBJECT
+
+public:
+    /** Constructs a new Konsole application. */
+    Application();
+    
+    virtual ~Application();
+
+    /** Creates a new main window and opens a default terminal session */
+    virtual int newInstance();
+
+    /** 
+     * Creates a new, empty main window and connects to its newSessionRequest()
+     * and newWindowRequest() signals to trigger creation of new sessions or
+     * windows when then they are emitted.  
+     */
+    MainWindow* newMainWindow();
+
+    /** Returns the Application instance */
+    static Application* self();
+
+private slots:
+    Session* createSession(Profile::Ptr profile, const QString& directory , ViewManager* view);
+    Session* createSSHSession(Profile::Ptr profile, const KUrl& url, ViewManager* view);
+    void createWindow(Profile::Ptr profile , const QString& directory);
+    void detachView(Session* session);
+
+    void toggleBackgroundInstance();
+
+private:
+    void init();
+    void listAvailableProfiles();
+    void startBackgroundMode(MainWindow* window);
+    bool processHelpArgs(KCmdLineArgs* args);
+    MainWindow* processWindowArgs(KCmdLineArgs* args);
+    void processProfileSelectArgs(KCmdLineArgs* args,MainWindow* window);
+    void processProfileChangeArgs(KCmdLineArgs* args,MainWindow* window);
+    void processTabsFromFileArgs(KCmdLineArgs* args, MainWindow* window);
+    void createTabFromArgs(KCmdLineArgs* args, MainWindow* window, const QHash<QString, QString>&);
+
+    KCmdLineArgs*   _arguments;
+    ProfileList*    _sessionList;
+    
+    MainWindow* _backgroundInstance;
+};
+
+}
+#endif //APPLICATION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/BlockArray.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,340 @@
+/*
+    This file is part of Konsole, an X terminal.
+    Copyright 2000 by Stephan Kulow <coolo@kde.org>
+
+    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 "BlockArray.h"
+
+// System
+#include <assert.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <stdio.h>
+
+// KDE
+//#include <kde_file.h>
+//#include <kdebug.h>
+
+#define KDE_fseek ::fseek
+#define KDE_lseek ::lseek
+
+
+using namespace Konsole;
+
+static int blocksize = 0;
+
+BlockArray::BlockArray()
+    : size(0),
+      current(size_t(-1)),
+      index(size_t(-1)),
+      lastmap(0),
+      lastmap_index(size_t(-1)),
+      lastblock(0), ion(-1),
+      length(0)
+{
+    // lastmap_index = index = current = size_t(-1);
+    if (blocksize == 0)
+        blocksize = ((sizeof(Block) / getpagesize()) + 1) * getpagesize();
+
+}
+
+BlockArray::~BlockArray()
+{
+    setHistorySize(0);
+    assert(!lastblock);
+}
+
+size_t BlockArray::append(Block *block)
+{
+    if (!size)
+        return size_t(-1);
+
+    ++current;
+    if (current >= size) current = 0;
+
+    int rc;
+    rc = KDE_lseek(ion, current * blocksize, SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setHistorySize(0); return size_t(-1); }
+    rc = write(ion, block, blocksize); if (rc < 0) { perror("HistoryBuffer::add.write"); setHistorySize(0); return size_t(-1); }
+
+    length++;
+    if (length > size) length = size;
+
+    ++index;
+
+    delete block;
+    return current;
+}
+
+size_t BlockArray::newBlock()
+{
+    if (!size)
+        return size_t(-1);
+    append(lastblock);
+
+    lastblock = new Block();
+    return index + 1;
+}
+
+Block *BlockArray::lastBlock() const
+{
+    return lastblock;
+}
+
+bool BlockArray::has(size_t i) const
+{
+    if (i == index + 1)
+        return true;
+
+    if (i > index)
+        return false;
+    if (index - i >= length)
+        return false;
+    return true;
+}
+
+const Block* BlockArray::at(size_t i)
+{
+    if (i == index + 1)
+        return lastblock;
+
+    if (i == lastmap_index)
+        return lastmap;
+
+    if (i > index) {
+        //kDebug(1211) << "BlockArray::at() i > index\n";
+        return 0;
+    }
+    
+//     if (index - i >= length) {
+//         kDebug(1211) << "BlockArray::at() index - i >= length\n";
+//         return 0;
+//     }
+
+    size_t j = i; // (current - (index - i) + (index/size+1)*size) % size ;
+
+    assert(j < size);
+    unmap();
+
+    Block *block = (Block*)mmap(0, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize);
+
+    if (block == (Block*)-1) { perror("mmap"); return 0; }
+
+    lastmap = block;
+    lastmap_index = i;
+
+    return block;
+}
+
+void BlockArray::unmap()
+{
+    if (lastmap) {
+        int res = munmap((char*)lastmap, blocksize);
+        if (res < 0) perror("munmap");
+    }
+    lastmap = 0;
+    lastmap_index = size_t(-1);
+}
+
+bool BlockArray::setSize(size_t newsize)
+{
+    return setHistorySize(newsize * 1024 / blocksize);
+}
+
+bool BlockArray::setHistorySize(size_t newsize)
+{
+//    kDebug(1211) << "setHistorySize " << size << " " << newsize;
+
+    if (size == newsize)
+        return false;
+
+    unmap();
+
+    if (!newsize) {
+        delete lastblock;
+        lastblock = 0;
+        if (ion >= 0) close(ion);
+        ion = -1;
+        current = size_t(-1);
+        return true;
+    }
+
+    if (!size) {
+        FILE* tmp = tmpfile();
+        if (!tmp) {
+            perror("konsole: cannot open temp file.\n");
+        } else {
+            ion = dup(fileno(tmp));
+            if (ion<0) {
+                perror("konsole: cannot dup temp file.\n");
+                fclose(tmp);
+            }
+        }
+        if (ion < 0)
+            return false;
+
+        assert(!lastblock);
+
+        lastblock = new Block();
+        size = newsize;
+        return false;
+    }
+
+    if (newsize > size) {
+        increaseBuffer();
+        size = newsize;
+        return false;
+    } else {
+        decreaseBuffer(newsize);
+        if (ftruncate(ion, length*blocksize) == -1)
+            perror("ftruncate");
+        size = newsize;
+
+        return true;
+    }
+}
+
+void moveBlock(FILE *fion, int cursor, int newpos, char *buffer2)
+{
+    int res = KDE_fseek(fion, cursor * blocksize, SEEK_SET);
+    if (res)
+        perror("fseek");
+    res = fread(buffer2, blocksize, 1, fion);
+    if (res != 1)
+        perror("fread");
+
+    res = KDE_fseek(fion, newpos * blocksize, SEEK_SET);
+    if (res)
+        perror("fseek");
+    res = fwrite(buffer2, blocksize, 1, fion);
+    if (res != 1)
+        perror("fwrite");
+    //    printf("moving block %d to %d\n", cursor, newpos);
+}
+
+void BlockArray::decreaseBuffer(size_t newsize)
+{
+    if (index < newsize) // still fits in whole
+        return;
+
+    int offset = (current - (newsize - 1) + size) % size;
+
+    if (!offset)
+        return;
+
+    // The Block constructor could do somthing in future...
+    char *buffer1 = new char[blocksize];
+
+    FILE *fion = fdopen(dup(ion), "w+b");
+    if (!fion) {
+        delete [] buffer1;
+        perror("fdopen/dup");
+        return;
+    }
+
+    int firstblock;
+    if (current <= newsize) {
+        firstblock = current + 1;
+    } else {
+        firstblock = 0;
+    }
+
+    size_t oldpos;
+    for (size_t i = 0, cursor=firstblock; i < newsize; i++) {
+        oldpos = (size + cursor + offset) % size;
+        moveBlock(fion, oldpos, cursor, buffer1);
+        if (oldpos < newsize) {
+            cursor = oldpos;
+        } else
+            cursor++;
+    }
+
+    current = newsize - 1;
+    length = newsize;
+
+    delete [] buffer1;
+
+    fclose(fion);
+
+}
+
+void BlockArray::increaseBuffer()
+{
+    if (index < size) // not even wrapped once
+        return;
+
+    int offset = (current + size + 1) % size;
+    if (!offset) // no moving needed
+        return;
+
+    // The Block constructor could do somthing in future...
+    char *buffer1 = new char[blocksize];
+    char *buffer2 = new char[blocksize];
+
+    int runs = 1;
+    int bpr = size; // blocks per run
+
+    if (size % offset == 0) {
+        bpr = size / offset;
+        runs = offset;
+    }
+
+    FILE *fion = fdopen(dup(ion), "w+b");
+    if (!fion) {
+        perror("fdopen/dup");
+    delete [] buffer1;
+    delete [] buffer2;
+        return;
+    }
+
+    int res;
+    for (int i = 0; i < runs; i++)
+    {
+        // free one block in chain
+        int firstblock = (offset + i) % size;
+        res = KDE_fseek(fion, firstblock * blocksize, SEEK_SET);
+        if (res)
+            perror("fseek");
+        res = fread(buffer1, blocksize, 1, fion);
+        if (res != 1)
+            perror("fread");
+        int newpos = 0;
+        for (int j = 1, cursor=firstblock; j < bpr; j++)
+        {
+            cursor = (cursor + offset) % size;
+            newpos = (cursor - offset + size) % size;
+            moveBlock(fion, cursor, newpos, buffer2);
+        }
+        res = KDE_fseek(fion, i * blocksize, SEEK_SET);
+        if (res)
+            perror("fseek");
+        res = fwrite(buffer1, blocksize, 1, fion);
+        if (res != 1)
+            perror("fwrite");
+    }
+    current = size - 1;
+    length = size;
+
+    delete [] buffer1;
+    delete [] buffer2;
+
+    fclose(fion);
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/BlockArray.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,123 @@
+/*
+    This file is part of Konsole, an X terminal.
+    Copyright 2000 by Stephan Kulow <coolo@kde.org>
+
+    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.
+*/
+
+#ifndef BLOCKARRAY_H
+#define BLOCKARRAY_H
+
+#include <unistd.h>
+
+//#error Do not use in KDE 2.1
+
+#define BlockSize (1 << 12)
+#define ENTRIES   ((BlockSize - sizeof(size_t) ) / sizeof(unsigned char))
+
+namespace Konsole
+{
+
+struct Block {
+    Block() { size = 0; }
+    unsigned char data[ENTRIES];
+    size_t size;
+};
+
+// ///////////////////////////////////////////////////////
+
+class BlockArray {
+public:
+    /**
+    * Creates a history file for holding
+    * maximal size blocks. If more blocks
+    * are requested, then it drops earlier
+    * added ones.
+    */
+    BlockArray();
+
+    /// destructor
+    ~BlockArray();
+
+    /**
+    * adds the Block at the end of history.
+    * This may drop other blocks.
+    *
+    * The ownership on the block is transferred.
+    * An unique index number is returned for accessing
+    * it later (if not yet dropped then)
+    *
+    * Note, that the block may be dropped completely
+    * if history is turned off.
+    */
+    size_t append(Block *block);
+
+    /**
+    * gets the block at the index. Function may return
+    * 0 if the block isn't available any more.
+    *
+    * The returned block is strictly readonly as only
+    * maped in memory - and will be invalid on the next
+    * operation on this class.
+    */
+    const Block *at(size_t index);
+
+    /**
+    * reorders blocks as needed. If newsize is null,
+    * the history is emptied completely. The indices
+    * returned on append won't change their semantic,
+    * but they may not be valid after this call.
+    */
+    bool setHistorySize(size_t newsize);
+
+    size_t newBlock();
+
+    Block *lastBlock() const;
+
+    /**
+    * Convenient function to set the size in KBytes
+    * instead of blocks
+    */
+    bool setSize(size_t newsize);
+
+    size_t len() const { return length; }
+
+    bool has(size_t index) const;
+
+    size_t getCurrent() const { return current; }
+
+private:
+    void unmap();
+    void increaseBuffer();
+    void decreaseBuffer(size_t newsize);
+
+    size_t size;
+    // current always shows to the last inserted block
+    size_t current;
+    size_t index;
+
+    Block *lastmap;
+    size_t lastmap_index;
+    Block *lastblock;
+
+    int ion;
+    size_t length;
+
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/BookmarkHandler.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,178 @@
+/*  This file was part of the KDE libraries
+    
+    Copyright 2002 Carsten Pfeiffer <pfeiffer@kde.org>
+    Copyright 2007-2008 Robert Knight <robertknight@gmail.com> 
+
+    library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation, version 2
+    or ( at your option ), any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+// Born as kdelibs/kio/kfile/kfilebookmarkhandler.characterpp
+
+// Own
+#include "BookmarkHandler.h"
+
+// Qt
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+
+// KDE
+#include <kshell.h>
+
+#include <KBookmarkMenu>
+#include <KDebug>
+#include <KMenu>
+#include <KStandardDirs>
+
+// Konsole
+#include "ViewProperties.h"
+
+using namespace Konsole;
+
+BookmarkHandler::BookmarkHandler( KActionCollection* collection, 
+                                  KMenu* menu, 
+                                  bool toplevel , 
+                                  QObject* parent )
+    : QObject( parent ),
+      KBookmarkOwner(),
+      m_toplevel(toplevel),
+      m_activeView(0)
+{
+    setObjectName( QLatin1String( "BookmarkHandler" ) );
+
+    m_menu = menu;
+
+    QString new_bm_file = KStandardDirs::locateLocal( "data", "konsole/bookmarks.xml" );
+
+    m_file = KStandardDirs::locate( "data", "konsole/bookmarks.xml" );
+    if ( m_file.isEmpty() )
+        m_file = KStandardDirs::locateLocal( "data", "konsole/bookmarks.xml" );
+
+    KBookmarkManager *manager = KBookmarkManager::managerForFile( m_file, "konsole" );
+
+    manager->setUpdate( true );
+
+    if (toplevel) {
+        m_bookmarkMenu = new KBookmarkMenu( manager, this, m_menu,
+                                            collection );
+    } else {
+        m_bookmarkMenu = new KBookmarkMenu( manager, this, m_menu,
+                                            NULL);
+    }
+}
+
+BookmarkHandler::~BookmarkHandler()
+{
+    delete m_bookmarkMenu;
+}
+
+void BookmarkHandler::openBookmark( const KBookmark & bm, Qt::MouseButtons, Qt::KeyboardModifiers )
+{
+    emit openUrl( bm.url() );
+}
+void BookmarkHandler::openFolderinTabs( const KBookmarkGroup& group )
+{
+    emit openUrls(group.groupUrlList());
+}
+bool BookmarkHandler::enableOption(BookmarkOption option ) const
+{
+    if(option == ShowAddBookmark || option == ShowEditBookmark)
+        return m_toplevel;
+    else
+        return KBookmarkOwner::enableOption(option);
+}
+
+QString BookmarkHandler::currentUrl() const
+{
+    return urlForView(m_activeView);
+}
+
+QString BookmarkHandler::urlForView(ViewProperties* view) const
+{
+    if ( view )
+    {
+        return view->url().prettyUrl();
+    }
+    else
+    {
+        return QString(); 
+    }
+}
+
+QString BookmarkHandler::currentTitle() const
+{
+    return titleForView(m_activeView);
+}
+
+QString BookmarkHandler::titleForView(ViewProperties* view) const
+{
+    const KUrl &u = view ? view->url() : KUrl(); 
+    if (u.isLocalFile())
+    {
+       QString path = u.path();
+       path = KShell::tildeExpand(path);
+
+       path = QFileInfo(path).baseName();
+
+       return path;
+    }
+    else if ( u.hasHost() )
+    {
+        if ( u.hasUser() )
+            return i18nc("@item:inmenu The user's name and host they are connected to via ssh", "%1 on %2",u.user(),u.host());
+        else
+            return i18nc("@item:inmenu The host the user is connected to via ssh", "%1",u.host());
+    }
+    return u.prettyUrl();
+}
+
+bool BookmarkHandler::supportsTabs() const
+{
+    return true;
+}
+
+QList<QPair<QString,QString> > BookmarkHandler::currentBookmarkList() const
+{
+    QList<QPair<QString,QString> > list;
+
+    QListIterator<ViewProperties*> iter( m_views );
+    
+    while ( iter.hasNext() )
+    {
+        ViewProperties* next = iter.next();
+        list << QPair<QString,QString>(titleForView(next) , urlForView(next));
+    }
+
+    return list;
+}
+
+void BookmarkHandler::setViews(const QList<ViewProperties*>& views) 
+{
+    m_views = views;
+}
+QList<ViewProperties*> BookmarkHandler::views() const
+{
+    return m_views;
+}
+void BookmarkHandler::setActiveView( ViewProperties* view )
+{
+    m_activeView = view;
+}
+ViewProperties* BookmarkHandler::activeView() const
+{
+    return m_activeView;
+}
+
+#include "BookmarkHandler.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/BookmarkHandler.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,133 @@
+/* This file was part of the KDE libraries
+    
+    Copyright 2002 Carsten Pfeiffer <pfeiffer@kde.org>
+    Copyright 2007-2008 Robert Knight <robertknight@gmail.com>
+
+    library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation, version 2 
+    or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+// Born as kdelibs/kio/kfile/kfilebookmarkhandler.h
+
+#ifndef KONSOLEBOOKMARKHANDLER_H
+#define KONSOLEBOOKMARKHANDLER_H
+
+// Qt
+#include <QtGui/QMenu>
+
+// KDE
+#include <KBookmarkManager>
+
+// Konsole
+#include "konsole_export.h"
+
+class KMenu;
+class KBookmarkMenu;
+class KBookmarkManager;
+class KActionCollection;
+
+namespace Konsole
+{
+
+class ViewProperties;
+
+/**
+ * This class handles the communication between the bookmark menu and the active session,
+ * providing a suggested title and URL when the user clicks the "Add Bookmark" item in
+ * the bookmarks menu.
+ *
+ * The bookmark handler is associated with a session controller, which is used to 
+ * determine the working URL of the current session.  When the user changes the active
+ * view, the bookmark handler's controller should be changed using setController()
+ *
+ * When the user selects a bookmark, the openUrl() signal is emitted.
+ */
+class KONSOLEPRIVATE_EXPORT BookmarkHandler : public QObject, public KBookmarkOwner
+{
+    Q_OBJECT
+
+public:
+
+    /**
+     * Constructs a new bookmark handler for Konsole bookmarks.
+     *
+     * @param collection The collection which the boomark menu's actions should be added to
+     * @param menu The menu which the bookmark actions should be added to
+     * @param toplevel TODO: Document me
+     * @param parent TODO: Document me
+     */
+    BookmarkHandler( KActionCollection* collection , KMenu* menu, bool toplevel , QObject* parent );
+    ~BookmarkHandler();
+
+    QMenu * popupMenu();
+
+    virtual QString currentUrl() const;
+    virtual QString currentTitle() const;
+    virtual bool enableOption(BookmarkOption option) const;
+    virtual bool supportsTabs() const;
+    virtual QList<QPair<QString,QString> > currentBookmarkList() const;
+    virtual void openFolderinTabs(const KBookmarkGroup& group);
+
+    /** 
+     * Returns the menu which this bookmark handler inserts its actions into.
+     */
+    KMenu *menu() const { return m_menu; }
+
+    QList<ViewProperties*> views() const;
+    ViewProperties* activeView() const;
+
+public slots:
+    /**
+     *
+     */
+    void setViews( const QList<ViewProperties*>& views );
+
+    void setActiveView( ViewProperties* view );
+
+signals:
+    /**
+     * Emitted when the user selects a bookmark from the bookmark menu.
+     *
+     * @param url The url of the bookmark which was selected by the user.
+     */
+    void openUrl( const KUrl& url ); 
+
+    /**
+     * Emitted when the user selects 'Open Folder in Tabs' 
+     * from the bookmark menu.
+     *
+     * @param urls The urls of the bookmarks in the folder whoose
+     * 'Open Folder in Tabs' action was triggered
+     */
+    void openUrls( const QList<KUrl>& urls );
+
+private Q_SLOTS:
+    void openBookmark( const KBookmark & bm, Qt::MouseButtons, Qt::KeyboardModifiers );
+
+private:
+    QString titleForView( ViewProperties* view ) const;
+    QString urlForView( ViewProperties* view ) const;
+
+    KMenu* m_menu;
+    KBookmarkMenu* m_bookmarkMenu;
+    QString m_file;
+    bool m_toplevel;
+    ViewProperties* m_activeView;
+    QList<ViewProperties*> m_views;
+};
+
+}
+
+#endif // KONSOLEBOOKMARKHANDLER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/CMakeLists.txt	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,92 @@
+project(qtermwidget)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui REQUIRED)
+
+include_directories( ${QT_INCLUDES} )
+
+set(kpty_LIB_SRCS
+   kpty.cpp
+   kptydevice.cpp
+   kprocess.cpp
+   kptyprocess.cpp
+)
+
+SET( kpty_MOC_HDR
+	./kptydevice.h
+	./kprocess.h
+)
+
+set(qtermwidget_LIB_SRCS
+  Pty.cpp
+  Session.cpp
+  TerminalDisplay.cpp
+  ScreenWindow.cpp
+  Filter.cpp
+  Vt102Emulation.cpp
+  Emulation.cpp
+  Screen.cpp
+  TerminalCharacterDecoder.cpp
+  History.cpp
+  BlockArray.cpp
+  ShellCommand.cpp
+  ProcessInfo.cpp
+  KeyboardTranslator.cpp
+  konsole_wcwidth.cpp
+  qtermwidget.cpp
+)
+
+set(qtermwidget_MOC_HDR
+  ./Pty.h
+  ./Session.h
+  ./TerminalDisplay.h
+  ./ScreenWindow.h
+  ./Filter.h
+  ./Vt102Emulation.h
+  ./Emulation.h
+  ./qtermwidget.h
+)
+
+# Generate the KPty moc files
+QT4_GENERATE_MOC(kptydevice.h kptydevice.moc)
+SET_SOURCE_FILES_PROPERTIES(kptydevice.cpp PROPERTIES OBJECT_DEPENDS kptydevice.moc)
+QT4_GENERATE_MOC(kprocess.h kprocess.moc)
+SET_SOURCE_FILES_PROPERTIES(kprocess.cpp PROPERTIES OBJECT_DEPENDS kprocess.moc)
+QT4_GENERATE_MOC(kptyprocess.h kptyprocess.moc)
+SET_SOURCE_FILES_PROPERTIES(kptyprocess.cpp PROPERTIES OBJECT_DEPENDS kptyprocess.moc)
+
+# Generate the qtermwidget moc file
+QT4_GENERATE_MOC(Pty.h Pty.moc)
+SET_SOURCE_FILES_PROPERTIES(Pty.cpp PROPERTIES OBJECT_DEPENDS Pty.moc)
+QT4_GENERATE_MOC(Session.h Session.moc)
+SET_SOURCE_FILES_PROPERTIES(Session.cpp PROPERTIES OBJECT_DEPENDS Session.moc)
+QT4_GENERATE_MOC(TerminalDisplay.h TerminalDisplay.moc)
+SET_SOURCE_FILES_PROPERTIES(TerminalDisplay.cpp PROPERTIES OBJECT_DEPENDS TerminalDisplay.moc)
+QT4_GENERATE_MOC(ScreenWindow.h ScreenWindow.moc)
+SET_SOURCE_FILES_PROPERTIES(ScreenWindow.cpp PROPERTIES OBJECT_DEPENDS ScreenWindow.moc)
+QT4_GENERATE_MOC(Filter.h Filter.moc)
+SET_SOURCE_FILES_PROPERTIES(Filter.cpp PROPERTIES OBJECT_DEPENDS Filter.moc)
+QT4_GENERATE_MOC(Vt102Emulation.h Vt102Emulation.moc)
+SET_SOURCE_FILES_PROPERTIES(Vt102Emulation.cpp PROPERTIES OBJECT_DEPENDS Vt102Emulation.moc)
+QT4_GENERATE_MOC(Emulation.h Emulation.moc)
+SET_SOURCE_FILES_PROPERTIES(Emulation.cpp PROPERTIES OBJECT_DEPENDS Emulation.moc)
+QT4_GENERATE_MOC(qtermwidget.h qtermwidget.moc)
+SET_SOURCE_FILES_PROPERTIES(qtermwidget.cpp PROPERTIES OBJECT_DEPENDS qtermwidget.moc)
+
+#QT4_GENERATE_MOC(.h .moc)
+#SET_SOURCE_FILES_PROPERTIES(.cpp PROPERTIES OBJECT_DEPENDS .moc)
+
+
+add_library(qtermwidget ${LIBRARY_TYPE} ${kpty_LIB_SRCS} ${qtermwidget_LIB_SRCS})
+
+target_link_libraries(qtermwidget ${UTIL_LIBRARY} ${UTEMPTER_LIBRARY})
+target_link_libraries(qtermwidget LINK_INTERFACE_LIBRARIES ${QT_QTCORE_LIBRARY} )
+
+set_target_properties(qtermwidget PROPERTIES
+   VERSION ${GENERIC_LIB_VERSION}
+   SOVERSION ${GENERIC_LIB_SOVERSION}
+)
+
+
+########### next target ###############
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Character.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,224 @@
+/*
+    This file is part of Konsole, KDE's terminal.
+    
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef CHARACTER_H
+#define CHARACTER_H
+
+// Qt
+#include <QtCore/QHash>
+
+// Local
+#include "CharacterColor.h"
+
+namespace Konsole
+{
+
+typedef unsigned char LineProperty;
+
+static const int LINE_DEFAULT        = 0;
+static const int LINE_WRAPPED          = (1 << 0);
+static const int LINE_DOUBLEWIDTH      = (1 << 1);
+static const int LINE_DOUBLEHEIGHT    = (1 << 2);
+
+#define DEFAULT_RENDITION  0
+#define RE_BOLD            (1 << 0)
+#define RE_BLINK           (1 << 1)
+#define RE_UNDERLINE       (1 << 2)
+#define RE_REVERSE         (1 << 3) // Screen only
+#define RE_INTENSIVE       (1 << 3) // Widget only
+#define RE_CURSOR          (1 << 4)
+#define RE_EXTENDED_CHAR   (1 << 5)
+
+/**
+ * A single character in the terminal which consists of a unicode character
+ * value, foreground and background colors and a set of rendition attributes
+ * which specify how it should be drawn.
+ */
+class Character
+{
+public:
+  /** 
+   * Constructs a new character.
+   *
+   * @param _c The unicode character value of this character.
+   * @param _f The foreground color used to draw the character.
+   * @param _b The color used to draw the character's background.
+   * @param _r A set of rendition flags which specify how this character is to be drawn.
+   */
+  inline Character(quint16 _c = ' ',
+            CharacterColor  _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
+            CharacterColor  _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
+            quint8  _r = DEFAULT_RENDITION)
+       : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {}
+
+  union
+  {
+    /** The unicode character value for this character. */
+    quint16 character;
+    /** 
+     * Experimental addition which allows a single Character instance to contain more than
+     * one unicode character.
+     *
+     * charSequence is a hash code which can be used to look up the unicode
+     * character sequence in the ExtendedCharTable used to create the sequence.
+     */
+    quint16 charSequence; 
+  };
+
+  /** A combination of RENDITION flags which specify options for drawing the character. */
+  quint8  rendition;
+
+  /** The foreground color used to draw this character. */
+  CharacterColor  foregroundColor; 
+  /** The color used to draw this character's background. */
+  CharacterColor  backgroundColor;
+
+  /** 
+   * Returns true if this character has a transparent background when
+   * it is drawn with the specified @p palette.
+   */
+  bool   isTransparent(const ColorEntry* palette) const;
+  /**
+   * Returns true if this character should always be drawn in bold when
+   * it is drawn with the specified @p palette, independent of whether
+   * or not the character has the RE_BOLD rendition flag. 
+   */
+  ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
+  
+  /** 
+   * returns true if the format (color, rendition flag) of the compared characters is equal
+   */
+  bool equalsFormat(const Character &other) const;
+
+  /** 
+   * Compares two characters and returns true if they have the same unicode character value,
+   * rendition and colors.
+   */
+  friend bool operator == (const Character& a, const Character& b);
+  /**
+   * Compares two characters and returns true if they have different unicode character values,
+   * renditions or colors.
+   */
+  friend bool operator != (const Character& a, const Character& b);
+};
+
+inline bool operator == (const Character& a, const Character& b)
+{ 
+  return a.character == b.character && 
+         a.rendition == b.rendition && 
+         a.foregroundColor == b.foregroundColor && 
+         a.backgroundColor == b.backgroundColor;
+}
+
+inline bool operator != (const Character& a, const Character& b)
+{
+  return    a.character != b.character || 
+            a.rendition != b.rendition || 
+            a.foregroundColor != b.foregroundColor || 
+            a.backgroundColor != b.backgroundColor;
+}
+
+inline bool Character::isTransparent(const ColorEntry* base) const
+{
+  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::equalsFormat(const Character& other) const
+{
+  return 
+    backgroundColor==other.backgroundColor &&
+    foregroundColor==other.foregroundColor &&
+    rendition==other.rendition;
+}	
+
+inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
+{
+    if (backgroundColor._colorSpace == COLOR_SPACE_DEFAULT)
+        return base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
+    else if (backgroundColor._colorSpace == COLOR_SPACE_SYSTEM)
+        return base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
+    else
+        return ColorEntry::UseCurrentFormat;
+}
+
+extern unsigned short vt100_graphics[32];
+
+
+/**
+ * A table which stores sequences of unicode characters, referenced
+ * by hash keys.  The hash key itself is the same size as a unicode
+ * character ( ushort ) so that it can occupy the same space in
+ * a structure.
+ */
+class ExtendedCharTable
+{
+public:
+    /** Constructs a new character table. */
+    ExtendedCharTable();
+    ~ExtendedCharTable();
+
+    /**
+     * Adds a sequences of unicode characters to the table and returns
+     * a hash code which can be used later to look up the sequence
+     * using lookupExtendedChar()
+     *
+     * If the same sequence already exists in the table, the hash
+     * of the existing sequence will be returned.
+     *
+     * @param unicodePoints An array of unicode character points
+     * @param length Length of @p unicodePoints
+     */
+    ushort createExtendedChar(ushort* unicodePoints , ushort length);
+    /**
+     * Looks up and returns a pointer to a sequence of unicode characters
+     * which was added to the table using createExtendedChar().
+     *
+     * @param hash The hash key returned by createExtendedChar()
+     * @param length This variable is set to the length of the 
+     * character sequence.
+     *
+     * @return A unicode character sequence of size @p length.
+     */
+    ushort* lookupExtendedChar(ushort hash , ushort& length) const;
+
+    /** The global ExtendedCharTable instance. */
+    static ExtendedCharTable instance;
+private:
+    // calculates the hash key of a sequence of unicode points of size 'length'
+    ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
+    // tests whether the entry in the table specified by 'hash' matches the 
+    // character sequence 'unicodePoints' of size 'length'
+    bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
+    // internal, maps hash keys to character sequence buffers.  The first ushort
+    // in each value is the length of the buffer, followed by the ushorts in the buffer
+    // themselves.
+    QHash<ushort,ushort*> extendedCharTable;
+};
+
+}
+Q_DECLARE_TYPEINFO(Konsole::Character, Q_MOVABLE_TYPE);
+
+#endif // CHARACTER_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/CharacterColor.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,299 @@
+/*
+    This file is part of Konsole, KDE's terminal.
+    
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef CHARACTERCOLOR_H
+#define CHARACTERCOLOR_H
+
+// Qt
+#include <QtGui/QColor>
+
+//#include <kdemacros.h>
+#define KDE_NO_EXPORT
+
+namespace Konsole
+{
+
+/** 
+ * An entry in a terminal display's color palette. 
+ *
+ * A color palette is an array of 16 ColorEntry instances which map
+ * system color indexes (from 0 to 15) into actual colors.
+ *
+ * Each entry can be set as bold, in which case any text
+ * drawn using the color should be drawn in bold.  
+ *
+ * Each entry can also be transparent, in which case the terminal
+ * display should avoid drawing the background for any characters
+ * using the entry as a background.
+ */
+class ColorEntry
+{
+public:
+  /** Specifies the weight to use when drawing text with this color. */
+  enum FontWeight 
+  {
+    /** Always draw text in this color with a bold weight. */
+    Bold,
+    /** Always draw text in this color with a normal weight. */
+    Normal,
+    /** 
+     * Use the current font weight set by the terminal application.  
+     * This is the default behavior.
+     */
+    UseCurrentFormat
+  };
+
+  /** 
+   * Constructs a new color palette entry.
+   *
+   * @param c The color value for this entry.
+   * @param tr Specifies that the color should be transparent when used as a background color.
+   * @param weight Specifies the font weight to use when drawing text with this color. 
+   */
+  ColorEntry(QColor c, bool tr, FontWeight weight = UseCurrentFormat) 
+          : color(c), transparent(tr), fontWeight(weight) {}
+
+  /**
+   * Constructs a new color palette entry with an undefined color, and
+   * with the transparent and bold flags set to false.
+   */ 
+  ColorEntry() : transparent(false), fontWeight(UseCurrentFormat) {} 
+ 
+  /**
+   * Sets the color, transparency and boldness of this color to those of @p rhs.
+   */ 
+  void operator=(const ColorEntry& rhs) 
+  { 
+       color = rhs.color; 
+       transparent = rhs.transparent; 
+       fontWeight = rhs.fontWeight; 
+  }
+
+  /** The color value of this entry for display. */
+  QColor color;
+
+  /** 
+   * If true character backgrounds using this color should be transparent. 
+   * This is not applicable when the color is used to render text.
+   */
+  bool   transparent;
+  /**
+   * Specifies the font weight to use when drawing text with this color. 
+   * This is not applicable when the color is used to draw a character's background.
+   */
+  FontWeight fontWeight;        
+};
+
+
+// Attributed Character Representations ///////////////////////////////
+
+// Colors
+
+#define BASE_COLORS   (2+8)
+#define INTENSITIES   2
+#define TABLE_COLORS  (INTENSITIES*BASE_COLORS)
+
+#define DEFAULT_FORE_COLOR 0
+#define DEFAULT_BACK_COLOR 1
+
+//a standard set of colors using black text on a white background.
+//defined in TerminalDisplay.cpp
+
+extern const ColorEntry base_color_table[TABLE_COLORS] KDE_NO_EXPORT;
+
+/* CharacterColor is a union of the various color spaces.
+
+   Assignment is as follows:
+
+   Type  - Space        - Values
+
+   0     - Undefined   - u:  0,      v:0        w:0
+   1     - Default     - u:  0..1    v:intense  w:0
+   2     - System      - u:  0..7    v:intense  w:0
+   3     - Index(256)  - u: 16..255  v:0        w:0
+   4     - RGB         - u:  0..255  v:0..256   w:0..256
+
+   Default colour space has two separate colours, namely
+   default foreground and default background colour.
+*/
+
+#define COLOR_SPACE_UNDEFINED   0
+#define COLOR_SPACE_DEFAULT     1
+#define COLOR_SPACE_SYSTEM      2
+#define COLOR_SPACE_256         3
+#define COLOR_SPACE_RGB         4
+
+/**
+ * Describes the color of a single character in the terminal.
+ */
+class CharacterColor
+{
+    friend class Character;
+
+public:
+  /** Constructs a new CharacterColor whoose color and color space are undefined. */
+  CharacterColor() 
+      : _colorSpace(COLOR_SPACE_UNDEFINED), 
+        _u(0), 
+        _v(0), 
+        _w(0) 
+  {}
+
+  /** 
+   * Constructs a new CharacterColor using the specified @p colorSpace and with 
+   * color value @p co
+   *
+   * The meaning of @p co depends on the @p colorSpace used.
+   *
+   * TODO : Document how @p co relates to @p colorSpace
+   *
+   * TODO : Add documentation about available color spaces.
+   */
+  CharacterColor(quint8 colorSpace, int co) 
+      : _colorSpace(colorSpace), 
+        _u(0), 
+        _v(0), 
+        _w(0)
+  {
+    switch (colorSpace)
+    {
+        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:
+            _colorSpace = COLOR_SPACE_UNDEFINED;
+    }
+  }
+
+  /** 
+   * Returns true if this character color entry is valid.
+   */
+  bool isValid() 
+  {
+        return _colorSpace != COLOR_SPACE_UNDEFINED;
+  }
+    
+  /** 
+   * Toggles the value of this color between a normal system color and the corresponding intensive
+   * system color.
+   * 
+   * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM
+   * color spaces.
+   */
+  void toggleIntensive();
+
+  /** 
+   * Returns the color within the specified color @p palette
+   *
+   * The @p palette is only used if this color is one of the 16 system colors, otherwise
+   * it is ignored.
+   */
+  QColor color(const ColorEntry* palette) const;
+ 
+  /** 
+   * Compares two colors and returns true if they represent the same color value and
+   * use the same color space.
+   */
+  friend bool operator == (const CharacterColor& a, const CharacterColor& b);
+  /**
+   * Compares two colors and returns true if they represent different color values
+   * or use different color spaces.
+   */
+  friend bool operator != (const CharacterColor& a, const CharacterColor& b);
+
+private:
+  quint8 _colorSpace;
+
+  // bytes storing the character color 
+  quint8 _u; 
+  quint8 _v; 
+  quint8 _w; 
+};
+
+inline bool operator == (const CharacterColor& a, const CharacterColor& b)
+{ 
+    return     a._colorSpace == b._colorSpace &&
+            a._u == b._u &&
+            a._v == b._v &&
+            a._w == b._w;
+}
+inline bool operator != (const CharacterColor& a, const CharacterColor& b)
+{
+    return !operator==(a,b);
+}
+
+inline const QColor color256(quint8 u, const ColorEntry* base)
+{
+  //   0.. 16: system colors
+  if (u <   8) return base[u+2            ].color; u -= 8;
+  if (u <   8) return base[u+2+BASE_COLORS].color; u -= 8;
+
+  //  16..231: 6x6x6 rgb color cube
+  if (u < 216) return QColor(((u/36)%6) ? (40*((u/36)%6)+55) : 0,
+                             ((u/ 6)%6) ? (40*((u/ 6)%6)+55) : 0,
+                             ((u/ 1)%6) ? (40*((u/ 1)%6)+55) : 0); u -= 216;
+  
+  // 232..255: gray, leaving out black and white
+  int gray = u*10+8; return QColor(gray,gray,gray);
+}
+
+inline QColor CharacterColor::color(const ColorEntry* base) const
+{
+  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);
+    case COLOR_SPACE_UNDEFINED: return QColor();
+  }
+
+  Q_ASSERT(false); // invalid color space
+
+  return QColor();
+}
+
+inline void CharacterColor::toggleIntensive()
+{
+  if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT)
+  {
+    _v = !_v;
+  }
+}
+
+
+}
+
+#endif // CHARACTERCOLOR_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ColorScheme.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,706 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ColorScheme.h"
+
+// Qt
+#include <QtGui/QBrush>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+
+// KDE
+#include <KColorScheme>
+#include <KConfig>
+#include <KLocale>
+#include <KDebug>
+#include <KConfigGroup>
+#include <KStandardDirs>
+
+using namespace Konsole;
+
+const ColorEntry ColorScheme::defaultTable[TABLE_COLORS] =
+ // The following are almost IBM standard color codes, with some slight
+ // gamma correction for the dim colors to compensate for bright X screens.
+ // It contains the 8 ansiterm/xterm colors in 2 intensities.
+{
+    ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
+QColor(0xFF,0xFF,0xFF), 1), // Dfore, Dback
+    ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
+QColor(0xB2,0x18,0x18), 0), // Black, Red
+    ColorEntry( QColor(0x18,0xB2,0x18), 0), ColorEntry(
+QColor(0xB2,0x68,0x18), 0), // Green, Yellow
+    ColorEntry( QColor(0x18,0x18,0xB2), 0), ColorEntry(
+QColor(0xB2,0x18,0xB2), 0), // Blue, Magenta
+    ColorEntry( QColor(0x18,0xB2,0xB2), 0), ColorEntry(
+QColor(0xB2,0xB2,0xB2), 0), // Cyan, White
+    // intensive
+    ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
+QColor(0xFF,0xFF,0xFF), 1),
+    ColorEntry( QColor(0x68,0x68,0x68), 0), ColorEntry(
+QColor(0xFF,0x54,0x54), 0),
+    ColorEntry( QColor(0x54,0xFF,0x54), 0), ColorEntry(
+QColor(0xFF,0xFF,0x54), 0),
+    ColorEntry( QColor(0x54,0x54,0xFF), 0), ColorEntry(
+QColor(0xFF,0x54,0xFF), 0),
+    ColorEntry( QColor(0x54,0xFF,0xFF), 0), ColorEntry(
+QColor(0xFF,0xFF,0xFF), 0)
+};
+
+const char* const ColorScheme::colorNames[TABLE_COLORS] =
+{
+  "Foreground",
+  "Background",
+  "Color0",
+  "Color1",
+  "Color2",
+  "Color3",
+  "Color4",
+  "Color5",
+  "Color6",
+  "Color7",
+  "ForegroundIntense",
+  "BackgroundIntense",
+  "Color0Intense",
+  "Color1Intense",
+  "Color2Intense",
+  "Color3Intense",
+  "Color4Intense",
+  "Color5Intense",
+  "Color6Intense",
+  "Color7Intense"
+};
+const char* const ColorScheme::translatedColorNames[TABLE_COLORS] =
+{
+    I18N_NOOP("Foreground"),
+    I18N_NOOP("Background"),
+    I18N_NOOP("Color 1"),
+    I18N_NOOP("Color 2"),
+    I18N_NOOP("Color 3"),
+    I18N_NOOP("Color 4"),
+    I18N_NOOP("Color 5"),
+    I18N_NOOP("Color 6"),
+    I18N_NOOP("Color 7"),
+    I18N_NOOP("Color 8"),
+    I18N_NOOP("Foreground (Intense)"),
+    I18N_NOOP("Background (Intense)"),
+    I18N_NOOP("Color 1 (Intense)"),
+    I18N_NOOP("Color 2 (Intense)"),
+    I18N_NOOP("Color 3 (Intense)"),
+    I18N_NOOP("Color 4 (Intense)"),
+    I18N_NOOP("Color 5 (Intense)"),
+    I18N_NOOP("Color 6 (Intense)"),
+    I18N_NOOP("Color 7 (Intense)"),
+    I18N_NOOP("Color 8 (Intense)")
+};
+
+ColorScheme::ColorScheme()
+{
+    _table = 0;
+    _randomTable = 0;
+    _opacity = 1.0;
+}
+ColorScheme::ColorScheme(const ColorScheme& other)
+      : _opacity(other._opacity)
+       ,_table(0)
+       ,_randomTable(0)
+{
+    setName(other.name());
+    setDescription(other.description());
+
+    if ( other._table != 0 )
+    {
+        for ( int i = 0 ; i < TABLE_COLORS ; i++ )
+            setColorTableEntry(i,other._table[i]);
+    }
+
+    if ( other._randomTable != 0 )
+    {
+        for ( int i = 0 ; i < TABLE_COLORS ; i++ )
+        {
+            const RandomizationRange& range = other._randomTable[i];
+            setRandomizationRange(i,range.hue,range.saturation,range.value);
+        }
+    }
+}
+ColorScheme::~ColorScheme()
+{
+    delete[] _table;
+    delete[] _randomTable;
+}
+
+void ColorScheme::setDescription(const QString& description) { _description = description; }
+QString ColorScheme::description() const { return _description; }
+
+void ColorScheme::setName(const QString& name) { _name = name; }
+QString ColorScheme::name() const { return _name; }
+
+void ColorScheme::setColorTableEntry(int index , const ColorEntry& entry)
+{
+    Q_ASSERT( index >= 0 && index < TABLE_COLORS );
+
+    if ( !_table ) 
+    {
+        _table = new ColorEntry[TABLE_COLORS];
+
+        for (int i=0;i<TABLE_COLORS;i++)
+            _table[i] = defaultTable[i];
+    }
+    
+    _table[index] = entry; 
+}
+ColorEntry ColorScheme::colorEntry(int index , uint randomSeed) const
+{
+    Q_ASSERT( index >= 0 && index < TABLE_COLORS );
+
+    if ( randomSeed != 0 )
+        qsrand(randomSeed);
+
+    ColorEntry entry = colorTable()[index];
+
+    if ( randomSeed != 0 && 
+        _randomTable != 0 && 
+        !_randomTable[index].isNull() )
+    {
+        const RandomizationRange& range = _randomTable[index];
+      
+
+        int hueDifference = range.hue ? (qrand() % range.hue) - range.hue/2 : 0;
+        int saturationDifference = range.saturation ? (qrand() % range.saturation) - range.saturation/2 : 0;
+        int  valueDifference = range.value ? (qrand() % range.value) - range.value/2 : 0;
+
+        QColor& color = entry.color;
+      
+        int newHue = qAbs( (color.hue() + hueDifference) % MAX_HUE );
+        int newValue = qMin( qAbs(color.value() + valueDifference) , 255 );
+        int newSaturation = qMin( qAbs(color.saturation() + saturationDifference) , 255 );
+
+        color.setHsv(newHue,newSaturation,newValue);
+    }
+
+    return entry;
+}
+void ColorScheme::getColorTable(ColorEntry* table , uint randomSeed) const
+{
+    for ( int i = 0 ; i < TABLE_COLORS ; i++ )
+        table[i] = colorEntry(i,randomSeed);
+}
+bool ColorScheme::randomizedBackgroundColor() const
+{
+    return _randomTable == 0 ? false : !_randomTable[1].isNull();
+}
+void ColorScheme::setRandomizedBackgroundColor(bool randomize)
+{
+    // the hue of the background colour is allowed to be randomly 
+    // adjusted as much as possible.
+    //
+    // the value and saturation are left alone to maintain read-ability
+    if ( randomize )
+    {
+        setRandomizationRange( 1 /* background color index */ , MAX_HUE , 255 , 0 ); 
+    }
+    else
+    {
+        if ( _randomTable )
+            setRandomizationRange( 1 /* background color index */ , 0 , 0 , 0 );
+    }
+}
+
+void ColorScheme::setRandomizationRange( int index , quint16 hue , quint8 saturation ,
+                                         quint8 value )
+{
+    Q_ASSERT( hue <= MAX_HUE );
+    Q_ASSERT( index >= 0 && index < TABLE_COLORS );
+
+    if ( _randomTable == 0 )
+        _randomTable = new RandomizationRange[TABLE_COLORS];
+
+    _randomTable[index].hue = hue;
+    _randomTable[index].value = value;
+    _randomTable[index].saturation = saturation;
+}
+
+const ColorEntry* ColorScheme::colorTable() const
+{
+    if ( _table )
+        return _table;
+    else
+        return defaultTable;
+}
+QColor ColorScheme::foregroundColor() const
+{
+    return colorTable()[0].color;
+}
+QColor ColorScheme::backgroundColor() const
+{
+    return colorTable()[1].color;
+}
+bool ColorScheme::hasDarkBackground() const
+{
+    // value can range from 0 - 255, with larger values indicating higher brightness.
+    // so 127 is in the middle, anything less is deemed 'dark'
+    return backgroundColor().value() < 127;
+}
+void ColorScheme::setOpacity(qreal opacity) { _opacity = opacity; }
+qreal ColorScheme::opacity() const { return _opacity; }
+
+void ColorScheme::read(KConfig& config)
+{
+    KConfigGroup configGroup = config.group("General");
+
+    QString description = configGroup.readEntry("Description", I18N_NOOP("Un-named Color Scheme"));
+
+    _description = i18n(description.toUtf8());
+    _opacity = configGroup.readEntry("Opacity",qreal(1.0));
+
+    for (int i=0 ; i < TABLE_COLORS ; i++)
+    {
+        readColorEntry(config,i);
+    }
+}
+void ColorScheme::write(KConfig& config) const
+{
+    KConfigGroup configGroup = config.group("General");
+
+    configGroup.writeEntry("Description",_description);
+    configGroup.writeEntry("Opacity",_opacity);
+    
+    for (int i=0 ; i < TABLE_COLORS ; i++)
+    {
+        RandomizationRange random = _randomTable != 0 ? _randomTable[i] : RandomizationRange();
+        writeColorEntry(config,colorNameForIndex(i),colorTable()[i],random);
+    }
+}
+
+QString ColorScheme::colorNameForIndex(int index) 
+{
+    Q_ASSERT( index >= 0 && index < TABLE_COLORS );
+
+    return QString(colorNames[index]);
+}
+QString ColorScheme::translatedColorNameForIndex(int index) 
+{
+    Q_ASSERT( index >= 0 && index < TABLE_COLORS );
+
+    return i18n(translatedColorNames[index]);
+}
+void ColorScheme::readColorEntry(KConfig& config , int index)
+{
+    KConfigGroup configGroup(&config,colorNameForIndex(index));
+    
+    ColorEntry entry;
+
+    entry.color = configGroup.readEntry("Color",QColor());
+    entry.transparent = configGroup.readEntry("Transparent",false);
+
+    // Deprecated key from KDE 4.0 which set 'Bold' to true to force
+    // a color to be bold or false to use the current format
+    //
+    // TODO - Add a new tri-state key which allows for bold, normal or
+    // current format
+    if (configGroup.hasKey("Bold"))
+        entry.fontWeight = configGroup.readEntry("Bold",false) ? ColorEntry::Bold :
+                                                                 ColorEntry::UseCurrentFormat;
+
+    quint16 hue = configGroup.readEntry("MaxRandomHue",0);
+    quint8 value = configGroup.readEntry("MaxRandomValue",0);
+    quint8 saturation = configGroup.readEntry("MaxRandomSaturation",0);
+
+    setColorTableEntry( index , entry );
+
+    if ( hue != 0 || value != 0 || saturation != 0 )
+       setRandomizationRange( index , hue , saturation , value ); 
+}
+void ColorScheme::writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry , const RandomizationRange& random) const
+{
+    KConfigGroup configGroup(&config,colorName);
+
+    configGroup.writeEntry("Color",entry.color);
+    configGroup.writeEntry("Transparency",(bool)entry.transparent);
+    if (entry.fontWeight != ColorEntry::UseCurrentFormat)
+    {
+        configGroup.writeEntry("Bold",entry.fontWeight == ColorEntry::Bold);
+    }
+
+    // record randomization if this color has randomization or 
+    // if one of the keys already exists 
+    if ( !random.isNull() || configGroup.hasKey("MaxRandomHue") )
+    {
+        configGroup.writeEntry("MaxRandomHue",(int)random.hue);
+        configGroup.writeEntry("MaxRandomValue",(int)random.value);
+        configGroup.writeEntry("MaxRandomSaturation",(int)random.saturation);
+    }
+}
+
+
+// 
+// Work In Progress - A color scheme for use on KDE setups for users
+// with visual disabilities which means that they may have trouble
+// reading text with the supplied color schemes.
+//
+// This color scheme uses only the 'safe' colors defined by the
+// KColorScheme class.  
+//
+// A complication this introduces is that each color provided by 
+// KColorScheme is defined as a 'background' or 'foreground' color.
+// Only foreground colors are allowed to be used to render text and 
+// only background colors are allowed to be used for backgrounds.
+//
+// The ColorEntry and TerminalDisplay classes do not currently
+// support this restriction.  
+//
+// Requirements:
+//  - A color scheme which uses only colors from the KColorScheme class
+//  - Ability to restrict which colors the TerminalDisplay widget 
+//    uses as foreground and background color
+//  - Make use of KGlobalSettings::allowDefaultBackgroundImages() as
+//    a hint to determine whether this accessible color scheme should 
+//    be used by default.
+//
+//
+// -- Robert Knight <robertknight@gmail.com> 21/07/2007
+//
+AccessibleColorScheme::AccessibleColorScheme()
+    : ColorScheme()
+{
+    // basic attributes
+    setName("accessible");
+    setDescription(i18n("Accessible Color Scheme"));
+
+    // setup colors
+    const int ColorRoleCount = 8;
+
+    const KColorScheme colorScheme(QPalette::Active);
+
+    QBrush colors[ColorRoleCount] =
+    {
+        colorScheme.foreground( colorScheme.NormalText ),
+        colorScheme.background( colorScheme.NormalBackground ),
+
+        colorScheme.foreground( colorScheme.InactiveText ),
+        colorScheme.foreground( colorScheme.ActiveText ),
+        colorScheme.foreground( colorScheme.LinkText ),
+        colorScheme.foreground( colorScheme.VisitedText ),
+        colorScheme.foreground( colorScheme.NegativeText ),
+        colorScheme.foreground( colorScheme.NeutralText )
+    };
+
+    for ( int i = 0 ; i < TABLE_COLORS ; i++ ) 
+    {
+        ColorEntry entry;
+        entry.color = colors[ i % ColorRoleCount ].color();
+
+        setColorTableEntry( i , entry ); 
+    }   
+}
+
+KDE3ColorSchemeReader::KDE3ColorSchemeReader( QIODevice* device ) :
+    _device(device)
+{
+}
+ColorScheme* KDE3ColorSchemeReader::read() 
+{
+    Q_ASSERT( _device->openMode() == QIODevice::ReadOnly ||
+              _device->openMode() == QIODevice::ReadWrite  );
+
+    ColorScheme* scheme = new ColorScheme();
+
+    QRegExp comment("#.*$");
+    while ( !_device->atEnd() )
+    {
+        QString line(_device->readLine());
+        line.remove(comment);
+        line = line.simplified();
+
+        if ( line.isEmpty() )
+            continue;
+
+        if ( line.startsWith(QLatin1String("color")) )
+        {
+            if (!readColorLine(line,scheme))
+                kWarning() << "Failed to read KDE 3 color scheme line" << line;
+        }
+        else if ( line.startsWith(QLatin1String("title")) )
+        {
+            if (!readTitleLine(line,scheme))
+                kWarning() << "Failed to read KDE 3 color scheme title line" << line;
+        }
+        else
+        {
+            kWarning() << "KDE 3 color scheme contains an unsupported feature, '" <<
+                line << "'";
+        } 
+    }
+
+    return scheme;
+}
+bool KDE3ColorSchemeReader::readColorLine(const QString& line,ColorScheme* scheme)
+{
+    QStringList list = line.split(QChar(' '));
+
+    if (list.count() != 7)
+        return false;
+    if (list.first() != "color")
+        return false;
+    
+    int index = list[1].toInt();
+    int red = list[2].toInt();
+    int green = list[3].toInt();
+    int blue = list[4].toInt();
+    int transparent = list[5].toInt();
+    int bold = list[6].toInt();
+
+    const int MAX_COLOR_VALUE = 255;
+
+    if(     (index < 0 || index >= TABLE_COLORS )
+        ||  (red < 0 || red > MAX_COLOR_VALUE )
+        ||  (blue < 0 || blue > MAX_COLOR_VALUE )
+        ||  (green < 0 || green > MAX_COLOR_VALUE )
+        ||  (transparent != 0 && transparent != 1 )
+        ||  (bold != 0 && bold != 1)    )
+        return false;
+
+    ColorEntry entry;
+    entry.color = QColor(red,green,blue);
+    entry.transparent = ( transparent != 0 );
+    entry.fontWeight = ( bold != 0 ) ? ColorEntry::Bold : ColorEntry::UseCurrentFormat;
+
+    scheme->setColorTableEntry(index,entry);
+    return true;
+}
+bool KDE3ColorSchemeReader::readTitleLine(const QString& line,ColorScheme* scheme)
+{
+    if( !line.startsWith(QLatin1String("title")) )
+        return false;
+
+    int spacePos = line.indexOf(' ');
+    if( spacePos == -1 )
+        return false;
+
+    QString description = line.mid(spacePos+1);
+
+    scheme->setDescription(i18n(description.toUtf8()));
+    return true;
+}
+ColorSchemeManager::ColorSchemeManager()
+    : _haveLoadedAll(false)
+{
+}
+ColorSchemeManager::~ColorSchemeManager()
+{
+    QHashIterator<QString,const ColorScheme*> iter(_colorSchemes);
+    while (iter.hasNext())
+    {
+        iter.next();
+        delete iter.value();
+    }
+}
+void ColorSchemeManager::loadAllColorSchemes()
+{
+    int success = 0;
+    int failed = 0;
+
+    QList<QString> nativeColorSchemes = listColorSchemes();
+    
+    QListIterator<QString> nativeIter(nativeColorSchemes);
+    while ( nativeIter.hasNext() )
+    {
+        if ( loadColorScheme( nativeIter.next() ) )
+            success++;
+        else
+            failed++;
+    }
+
+    QList<QString> kde3ColorSchemes = listKDE3ColorSchemes();
+    QListIterator<QString> kde3Iter(kde3ColorSchemes);
+    while ( kde3Iter.hasNext() )
+    {
+        if ( loadKDE3ColorScheme( kde3Iter.next() ) )
+            success++;
+        else
+            failed++;
+    }
+
+    if ( failed > 0 )
+        kWarning() << "failed to load " << failed << " color schemes.";
+
+    _haveLoadedAll = true;
+}
+QList<const ColorScheme*> ColorSchemeManager::allColorSchemes()
+{
+    if ( !_haveLoadedAll )
+    {
+        loadAllColorSchemes();
+    }
+
+    return _colorSchemes.values();
+}
+bool ColorSchemeManager::loadKDE3ColorScheme(const QString& filePath)
+{
+    QFile file(filePath);
+    if (!filePath.endsWith(QLatin1String(".schema")) || !file.open(QIODevice::ReadOnly))
+        return false;
+
+    KDE3ColorSchemeReader reader(&file);
+    ColorScheme* scheme = reader.read();
+    scheme->setName(QFileInfo(file).baseName());
+    file.close();
+
+    if (scheme->name().isEmpty())
+    {
+        kWarning() << "color scheme name is not valid.";
+        delete scheme;
+        return false;
+    }
+    
+    QFileInfo info(filePath);
+
+    if ( !_colorSchemes.contains(info.baseName()) )
+        _colorSchemes.insert(scheme->name(),scheme);
+    else
+    {
+        kWarning() << "color scheme with name" << scheme->name() << "has already been" <<
+            "found, ignoring.";
+        delete scheme;
+    }
+
+    return true;
+}
+void ColorSchemeManager::addColorScheme(ColorScheme* scheme) 
+{
+    _colorSchemes.insert(scheme->name(),scheme);
+
+    // save changes to disk
+    QString path = KGlobal::dirs()->saveLocation("data","konsole/") + scheme->name() + ".colorscheme";
+    KConfig config(path , KConfig::NoGlobals);
+
+    scheme->write(config);
+}
+bool ColorSchemeManager::loadColorScheme(const QString& filePath)
+{
+    if ( !filePath.endsWith(QLatin1String(".colorscheme")) || !QFile::exists(filePath) )
+        return false;
+
+    QFileInfo info(filePath);
+    
+    KConfig config(filePath , KConfig::NoGlobals);
+    ColorScheme* scheme = new ColorScheme();
+    scheme->setName(info.baseName());
+    scheme->read(config);
+
+    if (scheme->name().isEmpty()) 
+    {
+        kWarning() << "Color scheme in" << filePath << "does not have a valid name and was not loaded.";
+        delete scheme;
+        return false;
+    }    
+
+    if ( !_colorSchemes.contains(info.baseName()) )
+    {
+        _colorSchemes.insert(scheme->name(),scheme);
+    }
+    else
+    {
+        kWarning() << "color scheme with name" << scheme->name() << "has already been" <<
+            "found, ignoring.";
+        
+        delete scheme;
+    }
+
+    return true; 
+}
+QList<QString> ColorSchemeManager::listKDE3ColorSchemes()
+{
+    return KGlobal::dirs()->findAllResources("data",
+                                             "konsole/*.schema",
+                                              KStandardDirs::NoDuplicates);
+    
+}
+QList<QString> ColorSchemeManager::listColorSchemes()
+{
+    return KGlobal::dirs()->findAllResources("data",
+                                             "konsole/*.colorscheme",
+                                             KStandardDirs::NoDuplicates);
+}
+const ColorScheme ColorSchemeManager::_defaultColorScheme;
+const ColorScheme* ColorSchemeManager::defaultColorScheme() const
+{
+    return &_defaultColorScheme;
+}
+bool ColorSchemeManager::deleteColorScheme(const QString& name)
+{
+    Q_ASSERT( _colorSchemes.contains(name) );
+
+    // lookup the path and delete 
+    QString path = findColorSchemePath(name);
+    if ( QFile::remove(path) )
+    {
+        _colorSchemes.remove(name);
+        return true;
+    }
+    else
+    {
+        kWarning() << "Failed to remove color scheme -" << path;
+        return false;
+    }
+}
+QString ColorSchemeManager::findColorSchemePath(const QString& name) const
+{
+    QString path = KStandardDirs::locate("data","konsole/"+name+".colorscheme");
+
+    if ( !path.isEmpty() )
+       return path; 
+
+    path = KStandardDirs::locate("data","konsole/"+name+".schema");
+
+    return path;
+}
+const ColorScheme* ColorSchemeManager::findColorScheme(const QString& name) 
+{
+    if ( name.isEmpty() )
+        return defaultColorScheme();
+
+    if ( _colorSchemes.contains(name) )
+        return _colorSchemes[name];
+    else
+    {
+        // look for this color scheme
+        QString path = findColorSchemePath(name); 
+        if ( !path.isEmpty() && loadColorScheme(path) )
+        {
+            return findColorScheme(name); 
+        } 
+        else 
+        {
+            if (!path.isEmpty() && loadKDE3ColorScheme(path))
+                return findColorScheme(name);
+        }
+
+        kWarning() << "Could not find color scheme - " << name;
+
+        return 0; 
+    }
+}
+K_GLOBAL_STATIC( ColorSchemeManager , theColorSchemeManager )
+ColorSchemeManager* ColorSchemeManager::instance()
+{
+    return theColorSchemeManager;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ColorScheme.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,334 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef COLORSCHEME_H
+#define COLORSCHEME_H
+
+// Qt
+#include <QtCore/QHash>
+#include <QtCore/QList>
+#include <QtCore/QMetaType>
+#include <QtCore/QIODevice>
+#include <QtCore/QSet>
+
+// Konsole
+#include "CharacterColor.h"
+
+class QIODevice;
+class KConfig;
+
+namespace Konsole
+{
+
+/**
+ * Represents a color scheme for a terminal display.  
+ *
+ * The color scheme includes the palette of colors used to draw the text and character backgrounds
+ * in the display and the opacity level of the display background. 
+ */
+class ColorScheme
+{
+public:
+    /** 
+     * Constructs a new color scheme which is initialised to the default color set 
+     * for Konsole.
+     */
+    ColorScheme();
+    ColorScheme(const ColorScheme& other);
+    ~ColorScheme();
+
+    /** Sets the descriptive name of the color scheme. */
+    void setDescription(const QString& description);
+    /** Returns the descriptive name of the color scheme. */
+    QString description() const;
+
+    /** Sets the name of the color scheme */
+    void setName(const QString& name);
+    /** Returns the name of the color scheme */
+    QString name() const;
+
+    /** Reads the color scheme from the specified configuration source */
+    void read(KConfig& config);
+    /** Writes the color scheme to the specified configuration source */
+    void write(KConfig& config) const;
+
+    /** Sets a single entry within the color palette. */
+    void setColorTableEntry(int index , const ColorEntry& entry);
+
+    /** 
+     * Copies the color entries which form the palette for this color scheme
+     * into @p table.  @p table should be an array with TABLE_COLORS entries.
+     *
+     * @param table Array into which the color entries for this color scheme
+     * are copied.
+     * @param randomSeed Color schemes may allow certain colors in their
+     * palette to be randomized.  The seed is used to pick the random color.
+     */
+    void getColorTable(ColorEntry* table, uint randomSeed = 0) const;
+   
+    /**
+     * Retrieves a single color entry from the table.
+     *
+     * See getColorTable()
+     */
+    ColorEntry colorEntry(int index , uint randomSeed = 0) const;
+
+    /** 
+     * Convenience method.  Returns the 
+     * foreground color for this scheme, 
+     * this is the primary color used to draw the 
+     * text in this scheme.
+     */
+    QColor foregroundColor() const;
+    /**
+     * Convenience method.  Returns the background color for 
+     * this scheme, this is the primary color used to 
+     * draw the terminal background in this scheme.
+     */
+    QColor backgroundColor() const;
+
+    /** 
+     * Returns true if this color scheme has a dark background.
+     * The background color is said to be dark if it has a value of less than 127
+     * in the HSV color space.
+     */
+    bool hasDarkBackground() const;
+
+    /** 
+     * Sets the opacity level of the display background. @p opacity ranges
+     * between 0 (completely transparent background) and 1 (completely
+     * opaque background).
+     *
+     * Defaults to 1.
+     *
+     * TODO: More documentation
+     */
+    void setOpacity(qreal opacity);
+    /** 
+     * Returns the opacity level for this color scheme, see setOpacity()
+     * TODO: More documentation
+     */
+    qreal opacity() const;
+
+    /** 
+     * Enables randomization of the background color.  This will cause
+     * the palette returned by getColorTable() and colorEntry() to
+     * be adjusted depending on the value of the random seed argument
+     * to them.
+     */ 
+    void setRandomizedBackgroundColor(bool randomize);
+
+    /** Returns true if the background color is randomized. */
+    bool randomizedBackgroundColor() const;
+
+    static QString colorNameForIndex(int index);
+    static QString translatedColorNameForIndex(int index);
+
+private:
+    // specifies how much a particular color can be randomized by
+    class RandomizationRange
+    {
+    public:
+        RandomizationRange() : hue(0) , saturation(0) , value(0) {}
+
+        bool isNull() const 
+        {
+            return ( hue == 0 && saturation == 0 && value == 0 );
+        }
+
+        quint16 hue;
+        quint8  saturation;
+        quint8  value;
+    };
+
+    // returns the active color table.  if none has been set specifically,
+    // this is the default color table.
+    const ColorEntry* colorTable() const;
+
+    // reads a single colour entry from a KConfig source
+    // and sets the palette entry at 'index' to the entry read.
+    void readColorEntry(KConfig& config , int index); 
+    // writes a single colour entry to a KConfig source
+    void writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry,const RandomizationRange& range) const;
+
+    // sets the amount of randomization allowed for a particular color 
+    // in the palette.  creates the randomization table if 
+    // it does not already exist
+    void setRandomizationRange( int index , quint16 hue , quint8 saturation , quint8 value );
+
+    QString _description;
+    QString _name;
+    qreal _opacity;
+    ColorEntry* _table; // pointer to custom color table or 0 if the default
+                        // color scheme is being used
+
+
+    static const quint16 MAX_HUE = 340;
+
+    RandomizationRange* _randomTable;   // pointer to randomization table or 0
+                                        // if no colors in the color scheme support
+                                        // randomization
+
+    static const char* const colorNames[TABLE_COLORS];
+    static const char* const translatedColorNames[TABLE_COLORS];
+
+    static const ColorEntry defaultTable[]; // table of default color entries
+};
+
+/** 
+ * A color scheme which uses colors from the standard KDE color palette.
+ *
+ * This is designed primarily for the benefit of users who are using specially
+ * designed colors.
+ *
+ * TODO Implement and make it the default on systems with specialized KDE
+ * color schemes.
+ */
+class AccessibleColorScheme : public ColorScheme
+{
+public:
+    AccessibleColorScheme();
+};
+
+/**
+ * Reads a color scheme stored in the .schema format used in the KDE 3 incarnation
+ * of Konsole
+ *
+ * Only the basic essentials ( title and color palette entries ) are currently
+ * supported.  Additional options such as background image and background
+ * blend colors are ignored.
+ */
+class KDE3ColorSchemeReader
+{
+public:
+    /** 
+     * Constructs a new reader which reads from the specified device. 
+     * The device should be open in read-only mode. 
+     */
+    KDE3ColorSchemeReader( QIODevice* device );
+
+    /** 
+     * Reads and parses the contents of the .schema file from the input
+     * device and returns the ColorScheme defined within it.
+     *
+     * Returns a null pointer if an error occurs whilst parsing
+     * the contents of the file.
+     */
+    ColorScheme* read();
+
+private:
+    // reads a line from the file specifying a colour palette entry
+    // format is: color [index] [red] [green] [blue] [transparent] [bold]
+    bool readColorLine(const QString& line , ColorScheme* scheme);
+    bool readTitleLine(const QString& line , ColorScheme* scheme);
+
+    QIODevice* _device;
+};
+
+/**
+ * Manages the color schemes available for use by terminal displays.
+ * See ColorScheme
+ */
+class ColorSchemeManager
+{
+public:
+
+    /**
+     * Constructs a new ColorSchemeManager and loads the list
+     * of available color schemes.
+     *
+     * The color schemes themselves are not loaded until they are first
+     * requested via a call to findColorScheme()
+     */
+    ColorSchemeManager();
+    /**
+     * Destroys the ColorSchemeManager and saves any modified color schemes to disk.
+     */
+    ~ColorSchemeManager();
+
+    /**
+     * Returns the default color scheme for Konsole
+     */
+    const ColorScheme* defaultColorScheme() const;
+ 
+    /**
+     * Returns the color scheme with the given name or 0 if no
+     * scheme with that name exists.  If @p name is empty, the
+     * default color scheme is returned.
+     *
+     * The first time that a color scheme with a particular name is
+     * requested, the configuration information is loaded from disk.
+     */
+    const ColorScheme* findColorScheme(const QString& name);
+
+    /**
+     * Adds a new color scheme to the manager.  If @p scheme has the same name as
+     * an existing color scheme, it replaces the existing scheme.
+     *
+     * TODO - Ensure the old color scheme gets deleted
+     */
+    void addColorScheme(ColorScheme* scheme);
+
+    /**
+     * Deletes a color scheme.  Returns true on successful deletion or false otherwise. 
+     */
+    bool deleteColorScheme(const QString& name);
+
+    /** 
+     * Returns a list of the all the available color schemes. 
+     * This may be slow when first called because all of the color
+     * scheme resources on disk must be located, read and parsed.
+     *
+     * Subsequent calls will be inexpensive. 
+     */
+    QList<const ColorScheme*> allColorSchemes();    
+
+    /** Returns the global color scheme manager instance. */
+    static ColorSchemeManager* instance();
+
+private:
+    // loads a color scheme from a KDE 4+ .colorscheme file
+    bool loadColorScheme(const QString& path);
+    // loads a color scheme from a KDE 3 .schema file
+    bool loadKDE3ColorScheme(const QString& path);
+    // returns a list of paths of color schemes in the KDE 4+ .colorscheme file format
+    QList<QString> listColorSchemes();
+    // returns a list of paths of color schemes in the .schema file format
+    // used in KDE 3
+    QList<QString> listKDE3ColorSchemes();
+    // loads all of the color schemes
+    void loadAllColorSchemes();
+    // finds the path of a color scheme
+    QString findColorSchemePath(const QString& name) const;
+
+    QHash<QString,const ColorScheme*> _colorSchemes;
+    QSet<ColorScheme*> _modifiedSchemes;
+
+    bool _haveLoadedAll;
+
+    static const ColorScheme _defaultColorScheme;
+};
+
+}
+
+Q_DECLARE_METATYPE(const Konsole::ColorScheme*)
+
+#endif //COLORSCHEME_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ColorSchemeEditor.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,198 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ColorSchemeEditor.h"
+
+// Qt
+#include <QtGui/QBrush>
+#include <QtGui/QFontMetrics>
+#include <QtGui/QHeaderView>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QItemEditorCreator>
+
+// KDE
+#include <KColorDialog>
+#include <KDebug>
+#include <KWindowSystem>
+
+// Konsole
+#include "ui_ColorSchemeEditor.h"
+#include "CharacterColor.h"
+
+using namespace Konsole;
+
+#if 0
+class ColorEditorCreator : public QItemEditorCreatorBase
+{
+    virtual QWidget* createWidget(QWidget* parent) const
+    {
+        return new KColorButton(parent);
+    }
+
+    virtual QByteArray valuePropertyName() const
+    {
+        return QByteArray("color");
+    }
+};
+#endif
+
+ColorSchemeEditor::ColorSchemeEditor(QWidget* parent)
+    : QWidget(parent)
+    , _colors(0)
+{
+    _ui = new Ui::ColorSchemeEditor();
+    _ui->setupUi(this);
+
+    // description edit
+    _ui->descriptionEdit->setClearButtonShown(true);
+    connect( _ui->descriptionEdit , SIGNAL(textChanged(const QString&)) , this , 
+            SLOT(setDescription(const QString&)) );
+
+    // transparency slider
+    QFontMetrics metrics(font());
+    _ui->transparencyPercentLabel->setMinimumWidth( metrics.width("100%") );
+
+    connect( _ui->transparencySlider , SIGNAL(valueChanged(int)) , this , SLOT(setTransparencyPercentLabel(int)) );
+
+    // randomized background
+    connect( _ui->randomizedBackgroundCheck , SIGNAL(toggled(bool)) , this , 
+             SLOT(setRandomizedBackgroundColor(bool)) );
+
+    // color table
+    _ui->colorTable->setColumnCount(2);
+    _ui->colorTable->setRowCount(TABLE_COLORS);
+
+    QStringList labels;
+    labels << i18nc("@label:listbox Column header text for color names", "Name") << i18nc("@label:listbox Column header text for the actual colors", "Color");
+    _ui->colorTable->setHorizontalHeaderLabels(labels);
+
+    _ui->colorTable->horizontalHeader()->setStretchLastSection(true);
+
+    QTableWidgetItem* item = new QTableWidgetItem("Test");
+    _ui->colorTable->setItem(0,0,item);
+
+    _ui->colorTable->verticalHeader()->hide();
+
+    connect( _ui->colorTable , SIGNAL(itemClicked(QTableWidgetItem*)) , this , 
+            SLOT(editColorItem(QTableWidgetItem*)) );
+
+    // warning label when transparency is not available
+    if ( KWindowSystem::compositingActive() )
+    {
+        _ui->transparencyWarningWidget->setVisible(false);
+    }
+    else
+    {
+        _ui->transparencyWarningWidget->setText(i18nc("@info:status",
+            "The background transparency setting will not"
+            " be used because your desktop does not appear to support"
+            " transparent windows."));
+    }
+}
+void ColorSchemeEditor::setRandomizedBackgroundColor( bool randomize )
+{
+    _colors->setRandomizedBackgroundColor(randomize);
+}
+ColorSchemeEditor::~ColorSchemeEditor()
+{
+    delete _colors;
+    delete _ui;
+}
+void ColorSchemeEditor::editColorItem( QTableWidgetItem* item )
+{
+    // ignore if this is not a color column
+    if ( item->column() != 1 ) 
+        return;
+
+    QColor color = item->background().color();
+    int result = KColorDialog::getColor( color );
+    if ( result == KColorDialog::Accepted ) {
+        item->setBackground( color );
+
+        ColorEntry entry( _colors->colorEntry(item->row()) );
+        entry.color = color;
+        _colors->setColorTableEntry( item->row(), entry ); 
+    
+        emit colorsChanged( _colors );
+
+    }
+}
+void ColorSchemeEditor::setDescription(const QString& text)
+{
+    if ( _colors )
+        _colors->setDescription(text);
+
+    if ( _ui->descriptionEdit->text() != text )
+        _ui->descriptionEdit->setText(text);
+}
+void ColorSchemeEditor::setTransparencyPercentLabel(int percent)
+{
+    _ui->transparencyPercentLabel->setText( QString("%1%").arg(percent) );
+    
+    qreal opacity = ( 100.0 - percent ) / 100.0;
+    _colors->setOpacity(opacity);
+}
+void ColorSchemeEditor::setup(const ColorScheme* scheme)
+{
+    if ( _colors )
+        delete _colors;
+
+    _colors = new ColorScheme(*scheme);
+
+    // setup description edit
+    _ui->descriptionEdit->setText(_colors->description());
+
+    // setup color table
+    setupColorTable(_colors);
+
+    // setup transparency slider
+    const int transparencyPercent = qRound( (1-_colors->opacity())*100 );
+    
+    _ui->transparencySlider->setValue(transparencyPercent);
+    setTransparencyPercentLabel(transparencyPercent);
+
+    // randomized background color checkbox
+    _ui->randomizedBackgroundCheck->setChecked( scheme->randomizedBackgroundColor() );
+}
+void ColorSchemeEditor::setupColorTable(const ColorScheme* colors)
+{
+    ColorEntry table[TABLE_COLORS];
+    colors->getColorTable(table);
+
+    for ( int row = 0 ; row < TABLE_COLORS ; row++ )
+    {
+        QTableWidgetItem* nameItem = new QTableWidgetItem( ColorScheme::translatedColorNameForIndex(row) );
+        QTableWidgetItem* colorItem = new QTableWidgetItem();
+        colorItem->setBackground( table[row].color );
+        colorItem->setFlags( colorItem->flags() & ~Qt::ItemIsEditable & ~Qt::ItemIsSelectable );
+
+        _ui->colorTable->setItem(row,0,nameItem);
+        _ui->colorTable->setItem(row,1,colorItem);
+    }
+
+    // ensure that color names are as fully visible as possible
+    _ui->colorTable->resizeColumnToContents(0);
+}
+ColorScheme* ColorSchemeEditor::colorScheme() const
+{
+    return _colors;
+}
+
+#include "ColorSchemeEditor.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ColorSchemeEditor.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,89 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef COLORSCHEMEEDITOR_H
+#define COLORSCHEMEEDITOR_H
+
+// Qt
+#include <QtGui/QWidget>
+
+// Konsole
+#include "ColorScheme.h"
+
+class QTableWidgetItem;
+
+namespace Ui
+{
+    class ColorSchemeEditor;
+}
+
+namespace Konsole
+{
+
+class ColorScheme;
+
+/**
+ * A dialog for editing color schemes.
+ *
+ * After creation, the dialog can be initialised with the settings
+ * of a color scheme using the setup() method.
+ *
+ * The dialog creates a copy of the supplied color scheme to which
+ * any changes made are applied.  The modified color scheme
+ * can be retrieved using the colorScheme() method.  
+ *
+ * When changes are made the colorsChanged() signal is emitted.
+ */
+class ColorSchemeEditor : public QWidget
+{
+Q_OBJECT
+
+public:
+   /** Constructs a new color scheme editor with the specified parent. */
+   ColorSchemeEditor(QWidget* parent = 0);
+   virtual ~ColorSchemeEditor();
+
+   /** Initialises the dialog with the properties of the specified color scheme. */
+   void setup(const ColorScheme* scheme);
+   /** Returns the modified color scheme. */
+   ColorScheme* colorScheme() const;
+
+signals:
+   /** Emitted when the colors in the color scheme change. */
+   void colorsChanged(ColorScheme* scheme);
+
+public slots:
+    /** Sets the text displayed in the description edit field. */
+   void setDescription(const QString& description);
+
+private slots:
+   void setTransparencyPercentLabel(int percent);
+   void setRandomizedBackgroundColor(bool randomized); 
+   void editColorItem(QTableWidgetItem* item);
+
+private:
+   void setupColorTable(const ColorScheme* table);
+
+   Ui::ColorSchemeEditor* _ui;
+   ColorScheme* _colors;    
+};
+
+}
+
+#endif // COLORSCHEMEEDITOR_H 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/CopyInputDialog.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,200 @@
+/*
+    Copyright 2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "CopyInputDialog.h"
+
+// Qt
+#include <QtGui/QSortFilterProxyModel>
+#include <QtGui/QHeaderView>
+
+// Konsole
+#include "ui_CopyInputDialog.h"
+
+using namespace Konsole;
+
+CopyInputDialog::CopyInputDialog(QWidget* parent)
+: KDialog(parent)
+{
+    setCaption(i18n("Copy Input"));
+    setButtons( KDialog::Ok | KDialog::Cancel );
+
+    _ui = new Ui::CopyInputDialog();
+    _ui->setupUi(mainWidget());
+
+    connect(_ui->selectAllButton,SIGNAL(clicked()),this,SLOT(selectAll()));
+    connect(_ui->deselectAllButton,SIGNAL(clicked()),this,SLOT(deselectAll()));
+
+    _ui->filterEdit->setClearButtonShown(true);
+    _ui->filterEdit->setFocus();
+
+    _model = new CheckableSessionModel(parent);
+    _model->setCheckColumn(1);
+    _model->setSessions(SessionManager::instance()->sessions());
+
+    QSortFilterProxyModel* filterProxyModel = new QSortFilterProxyModel(this);
+    filterProxyModel->setDynamicSortFilter(true);
+    filterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+    filterProxyModel->setSourceModel(_model);
+    filterProxyModel->setFilterKeyColumn(-1);
+
+    connect(_ui->filterEdit,SIGNAL(textChanged(QString)),filterProxyModel,
+    SLOT(setFilterFixedString(QString)));
+
+    _ui->sessionList->setModel(filterProxyModel);
+    _ui->sessionList->setColumnHidden(0,true); // Hide number column
+    _ui->sessionList->header()->hide();
+}
+
+CopyInputDialog::~CopyInputDialog()
+{
+    delete _ui;
+}
+
+void CopyInputDialog::setChosenSessions(const QSet<Session*>& sessions)
+{
+    QSet<Session*> checked = sessions;
+    if (_masterSession)
+        checked.insert(_masterSession);
+
+    _model->setCheckedSessions(checked);        
+}
+QSet<Session*> CopyInputDialog::chosenSessions() const
+{
+    return _model->checkedSessions();
+}
+void CopyInputDialog::setMasterSession(Session* session) 
+{
+    if (_masterSession)
+        _model->setCheckable(_masterSession,true);
+
+    _model->setCheckable(session,false);
+    QSet<Session*> checked = _model->checkedSessions();
+    checked.insert(session);
+    _model->setCheckedSessions(checked);
+
+    _masterSession = session;
+}
+void CopyInputDialog::setSelectionChecked(bool checked)
+{
+    QAbstractItemModel* model = _ui->sessionList->model();
+    int rows = model->rowCount();
+
+    QModelIndexList selected = _ui->sessionList->selectionModel()->selectedIndexes();
+
+    if (selected.count() > 1)
+    {
+        foreach(const QModelIndex &index,selected)
+            setRowChecked(index.row(),checked);
+    }
+    else 
+    {
+        for (int i=0;i<rows;i++)
+            setRowChecked(i,checked);
+    }
+}
+void CopyInputDialog::setRowChecked(int row, bool checked)
+{
+    QAbstractItemModel* model = _ui->sessionList->model();
+    QModelIndex index = model->index(row,_model->checkColumn());
+    if (checked)
+        model->setData(index,(int)Qt::Checked,Qt::CheckStateRole);
+    else
+        model->setData(index,(int)Qt::Unchecked,Qt::CheckStateRole);
+}
+CheckableSessionModel::CheckableSessionModel(QObject* parent)
+: SessionListModel(parent)
+, _checkColumn(0)
+{
+}
+void CheckableSessionModel::setCheckColumn(int column)
+{
+    _checkColumn = column;
+    reset();
+}
+Qt::ItemFlags CheckableSessionModel::flags(const QModelIndex& index) const
+{
+    Session* session = (Session*)index.internalPointer();
+    
+    if (_fixedSessions.contains(session))
+        return SessionListModel::flags(index) & ~Qt::ItemIsEnabled;
+    else
+        return SessionListModel::flags(index) | Qt::ItemIsUserCheckable;
+}
+QVariant CheckableSessionModel::data(const QModelIndex& index, int role) const
+{
+    if (role == Qt::CheckStateRole && index.column() == _checkColumn)
+    {
+        Session* session = (Session*)index.internalPointer();
+
+        if (_checkedSessions.contains(session))
+            return QVariant::fromValue((int)Qt::Checked);
+        else
+            return QVariant::fromValue((int)Qt::Unchecked);
+    } 
+    else
+        return SessionListModel::data(index,role);
+}
+bool CheckableSessionModel::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+    if (role == Qt::CheckStateRole && index.column() == _checkColumn)
+    {
+        Session* session = (Session*)index.internalPointer();
+
+        if (_fixedSessions.contains(session))
+            return false;
+
+        if (value.value<int>() == Qt::Checked)
+            _checkedSessions.insert(session);
+        else
+            _checkedSessions.remove(session);
+
+        emit dataChanged(index,index);
+        return true;
+    }
+    else
+        return SessionListModel::setData(index,value,role);
+}
+void CheckableSessionModel::setCheckedSessions(const QSet<Session*> sessions)
+{
+    _checkedSessions = sessions;
+    reset();
+}
+QSet<Session*> CheckableSessionModel::checkedSessions() const
+{
+    return _checkedSessions;
+}
+void CheckableSessionModel::setCheckable(Session* session, bool checkable)
+{
+    if (!checkable)
+        _fixedSessions.insert(session);
+    else
+        _fixedSessions.remove(session);
+
+    reset();
+}
+void CheckableSessionModel::sessionRemoved(Session* session)
+{
+    _checkedSessions.remove(session);
+    _fixedSessions.remove(session);
+}
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/CopyInputDialog.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,129 @@
+/*
+    Copyright 2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef COPYINPUTDIALOG
+#define COPYINPUTDIALOG
+
+// Qt
+#include <QPointer>
+
+// KDE
+#include <KDialog>
+
+// Konsole
+#include "SessionManager.h"
+#include "Session.h"
+
+namespace Ui
+{
+    class CopyInputDialog;
+}
+
+namespace Konsole
+{
+class CheckableSessionModel;
+
+/**
+ * Dialog which allows the user to mark a list of sessions to copy
+ * the input from the current session to.  The current session is 
+ * set using setMasterSession().  After the dialog has been executed,
+ * the set of chosen sessions can be retrieved using chosenSessions()
+ */
+class CopyInputDialog : public KDialog
+{
+Q_OBJECT
+
+public:
+    CopyInputDialog(QWidget* parent = 0);
+    ~CopyInputDialog();
+    /** 
+     * Sets the 'source' session whoose input will be copied to 
+     * other sessions.  This session is displayed grayed out in the list
+     * and cannot be unchecked.
+     */
+    void setMasterSession(Session* master);
+    /** See setMasterSession() */
+    Session* masterSession() const;
+
+    /** Sets the sessions in the list which are checked. */
+    void setChosenSessions(const QSet<Session*>& sessions);
+    /** Set setChosenSessions() */
+    QSet<Session*> chosenSessions() const;
+
+private slots:
+    void selectAll() { setSelectionChecked(true); };
+    void deselectAll() { setSelectionChecked(false); };
+
+private:
+    // Checks or unchecks selected sessions.  If there are no
+    // selected items then all sessions are checked or unchecked
+    void setSelectionChecked(bool checked);
+    void setRowChecked(int row, bool checked);
+
+    Ui::CopyInputDialog* _ui;
+    CheckableSessionModel* _model;
+    QPointer<Session> _masterSession;
+};
+
+/** 
+ * A list of sessions with a checkbox next to each one which allows the 
+ * user to select a subset of the available sessions to perform
+ * some action on them.
+ */
+class CheckableSessionModel : public SessionListModel
+{
+Q_OBJECT 
+
+public:
+    CheckableSessionModel(QObject* parent); 
+
+    void setCheckColumn(int column);
+    int checkColumn() const;
+
+    /** 
+     * Sets whether a session can be checked or un-checked. 
+     * Non-checkable items have the Qt::ItemIsEnabled flag unset. 
+     */
+    void setCheckable(Session* session, bool checkable);
+
+    /** Sets the list of sessions which are currently checked. */
+    void setCheckedSessions(const QSet<Session*> sessions);
+    /** Returns the set of checked sessions. */
+    QSet<Session*> checkedSessions() const;
+
+    // reimplemented from QAbstractItemModel
+    virtual Qt::ItemFlags flags(const QModelIndex& index) const;
+    virtual QVariant data(const QModelIndex& index, int role) const;
+    virtual bool setData(const QModelIndex& index, const QVariant& value, int role);
+
+protected:
+    virtual void sessionRemoved(Session*);
+
+private:
+    QSet<Session*> _checkedSessions;
+    QSet<Session*> _fixedSessions;
+    int _checkColumn;
+};
+inline int CheckableSessionModel::checkColumn() const
+{ return _checkColumn; }
+
+}
+
+#endif // COPYINPUTDIALOG
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/EditProfileDialog.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,1289 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "EditProfileDialog.h"
+
+// Qt
+#include <QtGui/QKeyEvent>
+#include <QtGui/QBrush>
+#include <QtGui/QPainter>
+#include <QtGui/QStandardItem>
+#include <QtCore/QTextCodec>
+#include <QtGui/QLinearGradient>
+#include <QtGui/QRadialGradient>
+
+#include <QtCore/QTimer>
+#include <QtCore/QTimeLine>
+
+// KDE
+#include <kcodecaction.h>
+#include <KDebug>
+#include <KFontDialog>
+#include <KIcon>
+#include <KIconDialog>
+#include <KFileDialog>
+#include <KUrlCompletion>
+#include <KWindowSystem>
+#include <KTextEdit>
+
+#include <cmath>
+
+// Konsole
+#include "ColorScheme.h"
+#include "ColorSchemeEditor.h"
+#include "ui_EditProfileDialog.h"
+#include "KeyBindingEditor.h"
+#include "KeyboardTranslator.h"
+#include "SessionManager.h"
+#include "ShellCommand.h"
+#include "TabTitleFormatAction.h"
+
+using namespace Konsole;
+
+EditProfileDialog::EditProfileDialog(QWidget* parent)
+    : KDialog(parent)
+    , _colorSchemeAnimationTimeLine(0)
+    , _delayedPreviewTimer(new QTimer(this))
+{
+    setCaption(i18n("Edit Profile"));
+    setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
+
+    connect( this , SIGNAL(applyClicked()) , this , SLOT(save()) );
+    connect( _delayedPreviewTimer , SIGNAL(timeout()) , this , SLOT(delayedPreviewActivate()) );
+    _ui = new Ui::EditProfileDialog();
+    _ui->setupUi(mainWidget());
+
+    // - Renable in a later KDE 4.x release when this feature works again
+    _ui->enableResizeWindowButton->setVisible(false);
+    
+    // there are various setupXYZPage() methods to load the items
+    // for each page and update their states to match the profile
+    // being edited.
+    //
+    // these are only called when needed ( ie. when the user clicks
+    // the tab to move to that page ).
+    //
+    // the _pageNeedsUpdate vector keeps track of the pages that have
+    // not been updated since the last profile change and will need
+    // to be refreshed when the user switches to them
+    _pageNeedsUpdate.resize( _ui->tabWidget->count() );
+    connect( _ui->tabWidget , SIGNAL(currentChanged(int)) , this , 
+            SLOT(preparePage(int)) );
+
+    _tempProfile = new Profile;
+    _tempProfile->setHidden(true);
+}
+EditProfileDialog::~EditProfileDialog()
+{
+    delete _ui;
+}
+void EditProfileDialog::save()
+{
+    if ( _tempProfile->isEmpty() )
+        return;
+
+    SessionManager::instance()->changeProfile(_profile,_tempProfile->setProperties());
+
+    // ensure that these settings are not undone by a call
+    // to unpreview()
+    QHashIterator<Profile::Property,QVariant> iter(_tempProfile->setProperties());
+    while ( iter.hasNext() )
+    {
+        iter.next();
+        _previewedProperties.remove(iter.key());
+    }
+}
+void EditProfileDialog::reject()
+{
+    unpreviewAll();
+    KDialog::reject();
+}
+void EditProfileDialog::accept()
+{
+    save();
+    unpreviewAll();
+    KDialog::accept(); 
+}
+QString EditProfileDialog::groupProfileNames(const ProfileGroup::Ptr group, int maxLength)
+{
+    QString caption;
+    int count = group->profiles().count();
+    for (int i=0;i < count;i++)
+    {
+        caption += group->profiles()[i]->name();
+        if (i < (count-1)) 
+        {
+            caption += ',';
+            // limit caption length to prevent very long window titles
+            if (maxLength > 0 && caption.length() > maxLength)
+            {
+                caption += "...";
+                break;
+            }
+        }
+    }
+    return caption;
+}
+void EditProfileDialog::updateCaption(const Profile::Ptr profile)
+{
+    const int MAX_GROUP_CAPTION_LENGTH = 25;
+    ProfileGroup::Ptr group = profile->asGroup(); 
+    if (group && group->profiles().count() > 1)
+    {
+        QString caption = groupProfileNames(group,MAX_GROUP_CAPTION_LENGTH); 
+         setCaption( i18np("Editing profile: %2","Editing %1 profiles: %2",group->profiles().count(), caption) );
+    }
+    else
+        setCaption( i18n("Edit Profile \"%1\"",profile->name()) );
+}
+void EditProfileDialog::setProfile(Profile::Ptr profile)
+{
+    _profile = profile;
+
+    Q_ASSERT( profile );
+
+    // update caption
+    updateCaption(profile);
+
+    // mark each page of the dialog as out of date
+    // and force an update of the currently visible page
+    //
+    // the other pages will be updated as necessary
+    _pageNeedsUpdate.fill(true);
+    preparePage( _ui->tabWidget->currentIndex() );
+
+    if ( _tempProfile )
+    {
+        _tempProfile = new Profile;
+    }
+}
+const Profile::Ptr EditProfileDialog::lookupProfile() const
+{
+    return _profile; 
+}
+void EditProfileDialog::preparePage(int page)
+{
+    const Profile::Ptr info = lookupProfile();
+
+    Q_ASSERT( _pageNeedsUpdate.count() > page );
+    Q_ASSERT( info );
+
+    QWidget* pageWidget = _ui->tabWidget->widget(page);
+    
+    if ( _pageNeedsUpdate[page] )
+    {
+       if ( pageWidget == _ui->generalTab )
+            setupGeneralPage(info);
+       else if ( pageWidget == _ui->tabsTab )
+            setupTabsPage(info);
+       else if ( pageWidget == _ui->appearanceTab )
+            setupAppearancePage(info);
+       else if ( pageWidget == _ui->scrollingTab )
+            setupScrollingPage(info);
+       else if ( pageWidget == _ui->keyboardTab )
+            setupKeyboardPage(info);
+       else if ( pageWidget == _ui->advancedTab )
+            setupAdvancedPage(info);
+       else
+           Q_ASSERT(false);
+
+        _pageNeedsUpdate[page] = false;
+    }
+
+    // start page entry animation for color schemes
+    if ( pageWidget == _ui->appearanceTab )
+            _colorSchemeAnimationTimeLine->start();
+}
+void EditProfileDialog::selectProfileName()
+{
+    _ui->profileNameEdit->selectAll();
+    _ui->profileNameEdit->setFocus();
+}
+void EditProfileDialog::setupGeneralPage(const Profile::Ptr info)
+{
+    // basic profile options
+    {
+        ProfileGroup::Ptr group = info->asGroup(); 
+        if (!group || group->profiles().count() < 2)
+        {
+            _ui->profileNameEdit->setClearButtonShown(true);
+            _ui->profileNameEdit->setText( info->name() );
+        }
+        else 
+        {
+            _ui->profileNameEdit->setText( groupProfileNames(group,-1) );
+            _ui->profileNameLabel->setEnabled(false);
+            _ui->profileNameEdit->setEnabled(false);
+        }
+    }
+
+    ShellCommand command( info->command() , info->arguments() );
+    _ui->commandEdit->setText( command.fullCommand() );
+
+    KUrlCompletion* exeCompletion = new KUrlCompletion(KUrlCompletion::ExeCompletion);
+    exeCompletion->setParent(this);
+    exeCompletion->setDir(QString());
+    _ui->commandEdit->setCompletionObject( exeCompletion );
+    _ui->initialDirEdit->setText( info->defaultWorkingDirectory() );
+
+    KUrlCompletion* dirCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion);
+    dirCompletion->setParent(this);
+    _ui->initialDirEdit->setCompletionObject( dirCompletion );
+    _ui->initialDirEdit->setClearButtonShown(true);
+    _ui->dirSelectButton->setIcon( KIcon("folder-open") );
+    _ui->iconSelectButton->setIcon( KIcon(info->icon()) );
+    _ui->startInSameDirButton->setChecked(info->property<bool>(Profile::StartInCurrentSessionDir));
+
+    // window options
+    _ui->showMenuBarButton->setChecked( info->property<bool>(Profile::ShowMenuBar) );
+    _ui->saveGeometryOnExitButton->setChecked( info->property<bool>(Profile::SaveGeometryOnExit) );
+
+    // signals and slots
+    connect( _ui->dirSelectButton , SIGNAL(clicked()) , this , SLOT(selectInitialDir()) );
+    connect( _ui->iconSelectButton , SIGNAL(clicked()) , this , SLOT(selectIcon()) );
+    connect( _ui->startInSameDirButton , SIGNAL(toggled(bool)) , this , 
+            SLOT(startInSameDir(bool)));
+    connect( _ui->profileNameEdit , SIGNAL(textChanged(const QString&)) , this ,
+            SLOT(profileNameChanged(const QString&)) );
+    connect( _ui->initialDirEdit , SIGNAL(textChanged(const QString&)) , this , 
+            SLOT(initialDirChanged(const QString&)) );
+    connect(_ui->commandEdit , SIGNAL(textChanged(const QString&)) , this ,
+            SLOT(commandChanged(const QString&)) ); 
+    
+    connect(_ui->showMenuBarButton , SIGNAL(toggled(bool)) , this , 
+            SLOT(showMenuBar(bool)) );
+    connect(_ui->saveGeometryOnExitButton , SIGNAL(toggled(bool)) , this ,
+            SLOT(saveGeometryOnExit(bool)) );
+
+    connect(_ui->environmentEditButton , SIGNAL(clicked()) , this , 
+            SLOT(showEnvironmentEditor()) );
+}
+void EditProfileDialog::showEnvironmentEditor()
+{
+    const Profile::Ptr info = lookupProfile();
+
+    KDialog* dialog = new KDialog(this);
+    KTextEdit* edit = new KTextEdit(dialog);
+
+    QStringList currentEnvironment = info->property<QStringList>(Profile::Environment);
+
+    edit->setPlainText( currentEnvironment.join("\n") );
+    dialog->setPlainCaption(i18n("Edit Environment"));
+    dialog->setMainWidget(edit);
+
+    if ( dialog->exec() == QDialog::Accepted )
+    {
+        QStringList newEnvironment = edit->toPlainText().split('\n');
+        _tempProfile->setProperty(Profile::Environment,newEnvironment);
+    }
+
+    dialog->deleteLater();
+}
+void EditProfileDialog::setupTabsPage(const Profile::Ptr info)
+{
+    // tab title format
+    _ui->tabTitleEdit->setClearButtonShown(true);
+    _ui->remoteTabTitleEdit->setClearButtonShown(true);
+    _ui->tabTitleEdit->setText( info->property<QString>(Profile::LocalTabTitleFormat) );
+    _ui->remoteTabTitleEdit->setText( 
+            info->property<QString>(Profile::RemoteTabTitleFormat));
+
+    // tab options
+    int tabMode = info->property<int>(Profile::TabBarMode);
+    int tabPosition = info->property<int>(Profile::TabBarPosition);
+
+    // note: Items should be in the same order as the 
+    // Profile::TabBarModeEnum enum
+    _ui->tabBarVisibilityCombo->addItems( QStringList() << i18n("Always Hide Tab Bar")
+                                                        << i18n("Show Tab Bar When Needed") 
+                                                        << i18n("Always Show Tab Bar") );
+    _ui->tabBarVisibilityCombo->setCurrentIndex(tabMode);
+
+    // note: Items should be in the same order as the
+    // Profile::TabBarPositionEnum enum
+    _ui->tabBarPositionCombo->addItems( QStringList() << i18n("Below Terminal Displays")
+                                                      << i18n("Above Terminal Displays") );
+
+    _ui->tabBarPositionCombo->setCurrentIndex(tabPosition);
+    _ui->newTabButton->setChecked(info->property<bool>(Profile::ShowNewAndCloseTabButtons));
+
+    // signals and slots
+    connect( _ui->tabBarVisibilityCombo , SIGNAL(activated(int)) , this , 
+             SLOT(tabBarVisibilityChanged(int)) );
+    connect( _ui->tabBarPositionCombo , SIGNAL(activated(int)) , this ,
+             SLOT(tabBarPositionChanged(int)) );
+    connect( _ui->newTabButton , SIGNAL(toggled(bool)) , this ,
+             SLOT(showNewTabButton(bool)) );
+
+    connect(_ui->tabTitleEdit , SIGNAL(textChanged(const QString&)) , this ,
+            SLOT(tabTitleFormatChanged(const QString&)) );
+    connect(_ui->remoteTabTitleEdit , SIGNAL(textChanged(const QString&)) , this ,
+            SLOT(remoteTabTitleFormatChanged(const QString&)));
+
+    // menus for local and remote tab title dynamic elements
+    TabTitleFormatAction* localTabTitleAction = new TabTitleFormatAction(this);
+    localTabTitleAction->setContext(Session::LocalTabTitle);
+    _ui->tabTitleEditButton->setMenu(localTabTitleAction->menu());
+    connect( localTabTitleAction , SIGNAL(dynamicElementSelected(const QString&)) , 
+            this , SLOT(insertTabTitleText(const QString&)) );
+
+    TabTitleFormatAction* remoteTabTitleAction = new TabTitleFormatAction(this);
+    remoteTabTitleAction->setContext(Session::RemoteTabTitle);
+    _ui->remoteTabTitleEditButton->setMenu(remoteTabTitleAction->menu());
+    connect( remoteTabTitleAction , SIGNAL(dynamicElementSelected(const QString&)) ,
+           this , SLOT(insertRemoteTabTitleText(const QString&)) ); 
+}
+void EditProfileDialog::showNewTabButton(bool show)
+{ _tempProfile->setProperty(Profile::ShowNewAndCloseTabButtons,show); }
+void EditProfileDialog::tabBarVisibilityChanged(int newValue)
+{
+    _tempProfile->setProperty( Profile::TabBarMode , newValue );
+}
+void EditProfileDialog::tabBarPositionChanged(int newValue)
+{
+    _tempProfile->setProperty( Profile::TabBarPosition , newValue );
+}
+void EditProfileDialog::insertTabTitleText(const QString& text)
+{
+    _ui->tabTitleEdit->insert(text);
+}
+void EditProfileDialog::insertRemoteTabTitleText(const QString& text)
+{
+    _ui->remoteTabTitleEdit->insert(text);
+}
+void EditProfileDialog::showMenuBar(bool show)
+{
+    _tempProfile->setProperty(Profile::ShowMenuBar,show);
+}
+void EditProfileDialog::saveGeometryOnExit(bool save)
+{
+    _tempProfile->setProperty(Profile::SaveGeometryOnExit,save);
+}
+void EditProfileDialog::tabTitleFormatChanged(const QString& format)
+{
+    _tempProfile->setProperty(Profile::LocalTabTitleFormat,format);
+}
+void EditProfileDialog::remoteTabTitleFormatChanged(const QString& format)
+{
+    _tempProfile->setProperty(Profile::RemoteTabTitleFormat,format);
+}
+
+void EditProfileDialog::selectIcon()
+{
+    const QString& icon = KIconDialog::getIcon(KIconLoader::Desktop, KIconLoader::Application,
+                                               false, 0, false, this);
+    if (!icon.isEmpty())
+    {
+        _ui->iconSelectButton->setIcon( KIcon(icon) );
+        _tempProfile->setProperty(Profile::Icon,icon);
+    }
+}
+void EditProfileDialog::profileNameChanged(const QString& text)
+{
+    _tempProfile->setProperty(Profile::Name,text);
+    updateCaption(_tempProfile);
+}
+void EditProfileDialog::startInSameDir(bool sameDir)
+{
+    _tempProfile->setProperty(Profile::StartInCurrentSessionDir,sameDir);
+}
+void EditProfileDialog::initialDirChanged(const QString& dir)
+{
+    _tempProfile->setProperty(Profile::Directory,dir);
+}
+void EditProfileDialog::commandChanged(const QString& command)
+{
+    ShellCommand shellCommand(command);
+
+    _tempProfile->setProperty(Profile::Command,shellCommand.command());
+    _tempProfile->setProperty(Profile::Arguments,shellCommand.arguments());
+}
+void EditProfileDialog::selectInitialDir()
+{
+    const KUrl url = KFileDialog::getExistingDirectoryUrl(_ui->initialDirEdit->text(),
+                                                          this,
+                                                          i18n("Select Initial Directory"));
+
+    if ( !url.isEmpty() )
+        _ui->initialDirEdit->setText(url.path());
+}
+void EditProfileDialog::setupAppearancePage(const Profile::Ptr info)
+{
+    ColorSchemeViewDelegate* delegate = new ColorSchemeViewDelegate(this);
+    _ui->colorSchemeList->setItemDelegate(delegate);
+    
+    _colorSchemeAnimationTimeLine = new QTimeLine( 500 , this );
+    delegate->setEntryTimeLine(_colorSchemeAnimationTimeLine);
+    
+    connect( _colorSchemeAnimationTimeLine , SIGNAL(valueChanged(qreal)) , this ,
+             SLOT(colorSchemeAnimationUpdate()) );
+   
+    _ui->transparencyWarningWidget->setVisible(false);
+    _ui->transparencyWarningWidget->setText(i18n("This color scheme uses a transparent background"
+                                                 " which does not appear to be supported on your"
+                                                 " desktop"));
+    _ui->editColorSchemeButton->setEnabled(false);
+    _ui->removeColorSchemeButton->setEnabled(false);
+
+    // setup color list
+    updateColorSchemeList(true);
+    
+    _ui->colorSchemeList->setMouseTracking(true);
+    _ui->colorSchemeList->installEventFilter(this);
+    _ui->colorSchemeList->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
+
+    connect( _ui->colorSchemeList->selectionModel() , 
+            SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)) 
+            , this , SLOT(colorSchemeSelected()) );
+    connect( _ui->colorSchemeList , SIGNAL(entered(const QModelIndex&)) , this , 
+            SLOT(previewColorScheme(const QModelIndex&)) );
+    
+    updateColorSchemeButtons();
+
+    connect( _ui->editColorSchemeButton , SIGNAL(clicked()) , this , 
+            SLOT(editColorScheme()) );
+    connect( _ui->removeColorSchemeButton , SIGNAL(clicked()) , this ,
+            SLOT(removeColorScheme()) );
+    connect( _ui->newColorSchemeButton , SIGNAL(clicked()) , this , 
+            SLOT(newColorScheme()) );
+
+    // setup font preview
+    bool antialias = info->property<bool>(Profile::AntiAliasFonts);
+
+    QFont font = info->font();
+    font.setStyleStrategy(antialias ? QFont::PreferAntialias : QFont::NoAntialias);
+
+    _ui->fontPreviewLabel->installEventFilter(this);
+    _ui->fontPreviewLabel->setFont(font);
+    setFontSliderRange(font);
+    setFontSliderValue(font);
+
+    connect( _ui->fontSizeSlider , SIGNAL(valueChanged(int)) , this ,
+             SLOT(setFontSize(int)) );
+    connect( _ui->editFontButton , SIGNAL(clicked()) , this ,
+             SLOT(showFontDialog()) );
+
+    // setup font smoothing 
+    _ui->antialiasTextButton->setChecked(antialias);
+    connect( _ui->antialiasTextButton , SIGNAL(toggled(bool)) , this , 
+             SLOT(setAntialiasText(bool)) );
+
+    bool boldIntense = info->property<bool>(Profile::BoldIntense);
+    _ui->boldIntenseButton->setChecked(boldIntense);
+    connect( _ui->boldIntenseButton , SIGNAL(toggled(bool)) , this ,
+             SLOT(setBoldIntense(bool)));
+}
+void EditProfileDialog::setAntialiasText(bool enable)
+{
+    _tempProfile->setProperty(Profile::AntiAliasFonts,enable);
+
+    QFont font = _ui->fontPreviewLabel->font();
+    font.setStyleStrategy(enable ? QFont::PreferAntialias : QFont::NoAntialias);
+
+    // update preview to reflect text smoothing state
+    fontSelected(font);
+}
+void EditProfileDialog::setBoldIntense(bool enable)
+{
+    _tempProfile->setProperty(Profile::BoldIntense,enable);
+    preview(Profile::BoldIntense,enable);
+}
+void EditProfileDialog::colorSchemeAnimationUpdate()
+{
+    QAbstractItemModel* model = _ui->colorSchemeList->model();
+
+    for ( int i = model->rowCount() ; i >= 0 ; i-- )
+        _ui->colorSchemeList->update( model->index(i,0) );
+}
+void EditProfileDialog::updateColorSchemeList(bool selectCurrentScheme)
+{
+    if (!_ui->colorSchemeList->model())
+        _ui->colorSchemeList->setModel(new QStandardItemModel(this));
+
+    const QString& name = lookupProfile()->colorScheme();
+    const ColorScheme* currentScheme = ColorSchemeManager::instance()->findColorScheme(name);
+
+    QStandardItemModel* model = qobject_cast<QStandardItemModel*>(_ui->colorSchemeList->model());
+
+    Q_ASSERT(model);
+    
+    model->clear();
+
+    QList<const ColorScheme*> schemeList = ColorSchemeManager::instance()->allColorSchemes();
+    QListIterator<const ColorScheme*> schemeIter(schemeList);
+
+    QStandardItem* selectedItem = 0;
+
+    while (schemeIter.hasNext())
+    {
+        const ColorScheme* colors = schemeIter.next();
+        QStandardItem* item = new QStandardItem(colors->description());
+        item->setData( QVariant::fromValue(colors) ,  Qt::UserRole + 1);
+        item->setFlags( item->flags() );
+       
+        if ( currentScheme == colors ) 
+            selectedItem = item;  
+
+        model->appendRow(item);
+    }
+
+    model->sort(0);
+
+    if ( selectCurrentScheme && selectedItem )
+    {
+        _ui->colorSchemeList->updateGeometry();
+        _ui->colorSchemeList->selectionModel()->setCurrentIndex( selectedItem->index() , 
+                                                                 QItemSelectionModel::Select );
+
+        // update transparency warning label
+        updateTransparencyWarning();
+    }
+}
+void EditProfileDialog::updateKeyBindingsList(bool selectCurrentTranslator)
+{
+    if (!_ui->keyBindingList->model())
+        _ui->keyBindingList->setModel(new QStandardItemModel(this));
+
+    KeyboardTranslatorManager* keyManager = KeyboardTranslatorManager::instance();
+
+    const QString& name = lookupProfile()
+                                    ->property<QString>(Profile::KeyBindings);
+
+    const KeyboardTranslator* currentTranslator = keyManager->findTranslator(name);
+    
+    QStandardItemModel* model = qobject_cast<QStandardItemModel*>(_ui->keyBindingList->model());
+
+    Q_ASSERT(model);
+
+    model->clear();
+
+    QStandardItem* selectedItem = 0;
+
+    QList<QString> translatorNames = keyManager->allTranslators();
+    QListIterator<QString> iter(translatorNames);
+    while (iter.hasNext())
+    {
+        const QString& name = iter.next();
+
+        const KeyboardTranslator* translator = keyManager->findTranslator(name);
+
+        QStandardItem* item = new QStandardItem(translator->description());
+        item->setData(QVariant::fromValue(translator),Qt::UserRole+1);
+        item->setIcon( KIcon("preferences-desktop-keyboard") );
+
+        if ( translator == currentTranslator )
+            selectedItem = item;
+
+        model->appendRow(item);
+    }
+
+    model->sort(0);
+    
+    if ( selectCurrentTranslator && selectedItem )
+    {
+        _ui->keyBindingList->selectionModel()->setCurrentIndex( selectedItem->index() , 
+                                                                  QItemSelectionModel::Select );
+    }
+}
+bool EditProfileDialog::eventFilter( QObject* watched , QEvent* event )
+{
+    if ( watched == _ui->colorSchemeList && event->type() == QEvent::Leave )
+    {
+        if ( _tempProfile->isPropertySet(Profile::ColorScheme) )
+            preview(Profile::ColorScheme,_tempProfile->colorScheme());
+        else
+            unpreview(Profile::ColorScheme);
+    }
+    if ( watched == _ui->fontPreviewLabel && event->type() == QEvent::FontChange )
+    {
+        const QFont& labelFont = _ui->fontPreviewLabel->font();
+        qreal size = labelFont.pointSizeF();
+        QString fontSize  = KGlobal::locale()->formatNumber(size, size == floor(size) ? 0 : 1);
+        _ui->fontPreviewLabel->setText(i18n("%1, size %2", labelFont.family(), fontSize));
+    }
+
+    return KDialog::eventFilter(watched,event);
+}
+void EditProfileDialog::unpreviewAll()
+{
+    _delayedPreviewTimer->stop();
+    _delayedPreviewProperties.clear();
+
+    QHash<Profile::Property,QVariant> map;
+    QHashIterator<int,QVariant> iter(_previewedProperties);
+    while ( iter.hasNext() )
+    {
+        iter.next();
+        map.insert((Profile::Property)iter.key(),iter.value());
+    }
+
+    // undo any preview changes
+    if ( !map.isEmpty() )
+        SessionManager::instance()->changeProfile(_profile,map,false);
+}
+void EditProfileDialog::unpreview(int property)
+{
+    _delayedPreviewProperties.remove(property);
+    
+    if (!_previewedProperties.contains(property))
+        return;
+    
+    QHash<Profile::Property,QVariant> map;
+    map.insert((Profile::Property)property,_previewedProperties[property]);
+    SessionManager::instance()->changeProfile(_profile,map,false); 
+
+    _previewedProperties.remove(property);
+}
+void EditProfileDialog::delayedPreview(int property , const QVariant& value)
+{
+    _delayedPreviewProperties.insert(property,value); 
+
+    _delayedPreviewTimer->stop();
+    _delayedPreviewTimer->start(300);
+}
+void EditProfileDialog::delayedPreviewActivate()
+{
+    Q_ASSERT( qobject_cast<QTimer*>(sender()) );
+
+    QMutableHashIterator<int,QVariant> iter(_delayedPreviewProperties);
+    if ( iter.hasNext() ) 
+    {
+        iter.next();
+        preview(iter.key(),iter.value());
+    }
+}
+void EditProfileDialog::preview(int property , const QVariant& value)
+{
+    QHash<Profile::Property,QVariant> map;
+    map.insert((Profile::Property)property,value);
+
+    _delayedPreviewProperties.remove(property);
+
+    const Profile::Ptr original = lookupProfile();
+
+    // skip previews for profile groups if the profiles in the group
+    // have conflicting original values for the property
+    //
+    // TODO - Save the original values for each profile and use to unpreview properties
+    ProfileGroup::Ptr group = original->asGroup();
+    if (group && group->profiles().count() > 1 &&
+        original->property<QVariant>((Profile::Property)property).isNull())
+        return;
+
+    if (!_previewedProperties.contains(property))   
+    {
+        _previewedProperties.insert(property , original->property<QVariant>((Profile::Property)property) );
+    }
+
+    // temporary change to color scheme
+    SessionManager::instance()->changeProfile( _profile , map , false);
+}
+void EditProfileDialog::previewColorScheme(const QModelIndex& index)
+{
+    const QString& name = index.data(Qt::UserRole+1).value<const ColorScheme*>()->name();
+
+    delayedPreview( Profile::ColorScheme , name );
+}
+void EditProfileDialog::removeColorScheme()
+{
+    QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes();
+
+    if ( !selected.isEmpty() )
+    {
+        const QString& name = selected.first().data(Qt::UserRole+1).value<const ColorScheme*>()->name();
+        
+        if (ColorSchemeManager::instance()->deleteColorScheme(name))    
+            _ui->colorSchemeList->model()->removeRow(selected.first().row());
+    }
+}
+void EditProfileDialog::showColorSchemeEditor(bool isNewScheme)
+{    
+    QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes();
+
+    QAbstractItemModel* model = _ui->colorSchemeList->model();
+    const ColorScheme* colors = 0;
+    if ( !selected.isEmpty() )
+        colors = model->data(selected.first(),Qt::UserRole+1).value<const ColorScheme*>();
+    else
+        colors = ColorSchemeManager::instance()->defaultColorScheme();
+
+    Q_ASSERT(colors);
+
+    KDialog* dialog = new KDialog(this);
+
+    if ( isNewScheme )
+        dialog->setCaption(i18n("New Color Scheme"));
+    else
+        dialog->setCaption(i18n("Edit Color Scheme"));
+
+    ColorSchemeEditor* editor = new ColorSchemeEditor;
+    dialog->setMainWidget(editor);
+    editor->setup(colors);
+
+    if ( isNewScheme )
+        editor->setDescription(i18n("New Color Scheme"));
+        
+    if ( dialog->exec() == QDialog::Accepted )
+    {
+        ColorScheme* newScheme = new ColorScheme(*editor->colorScheme());
+
+        // if this is a new color scheme, pick a name based on the description
+        if ( isNewScheme )
+            newScheme->setName(newScheme->description());
+
+        ColorSchemeManager::instance()->addColorScheme( newScheme );
+        
+        updateColorSchemeList(true);
+
+        preview(Profile::ColorScheme,newScheme->name());
+    }
+}
+void EditProfileDialog::newColorScheme()
+{
+    showColorSchemeEditor(true);    
+}
+void EditProfileDialog::editColorScheme()
+{
+    showColorSchemeEditor(false);
+}
+void EditProfileDialog::colorSchemeSelected()
+{
+    QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes();
+
+    if ( !selected.isEmpty() )
+    {
+        QAbstractItemModel* model = _ui->colorSchemeList->model();
+        const ColorScheme* colors = model->data(selected.first(),Qt::UserRole+1).value<const ColorScheme*>();
+
+        //kDebug() << "Setting temp profile color to" << colors->name();
+        
+        previewColorScheme(selected.first());
+        _tempProfile->setProperty(Profile::ColorScheme,colors->name());
+
+        updateTransparencyWarning();
+    }
+
+    updateColorSchemeButtons();
+}
+void EditProfileDialog::updateColorSchemeButtons()
+{
+    enableIfNonEmptySelection(_ui->editColorSchemeButton,_ui->colorSchemeList->selectionModel());
+    enableIfNonEmptySelection(_ui->removeColorSchemeButton,_ui->colorSchemeList->selectionModel());
+}
+void EditProfileDialog::updateKeyBindingsButtons()
+{    
+    enableIfNonEmptySelection(_ui->editKeyBindingsButton,_ui->keyBindingList->selectionModel());
+    enableIfNonEmptySelection(_ui->removeKeyBindingsButton,_ui->keyBindingList->selectionModel());
+}
+void EditProfileDialog::enableIfNonEmptySelection(QWidget* widget,QItemSelectionModel* selectionModel)
+{
+    widget->setEnabled(selectionModel->hasSelection());
+}
+void EditProfileDialog::updateTransparencyWarning() 
+{
+    // zero or one indexes can be selected
+    foreach( const QModelIndex& index , _ui->colorSchemeList->selectionModel()->selectedIndexes() ) 
+    {
+        bool hasTransparency = index.data(Qt::UserRole+1).value<const ColorScheme*>()->opacity() < 1.0;
+        _ui->transparencyWarningWidget->setHidden(KWindowSystem::compositingActive() || !hasTransparency);
+    }
+}
+void EditProfileDialog::setupKeyboardPage(const Profile::Ptr /* info */)
+{
+    // setup translator list
+    updateKeyBindingsList(true); 
+
+    connect( _ui->keyBindingList->selectionModel() , 
+                SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
+                SLOT(keyBindingSelected()) );
+    connect( _ui->newKeyBindingsButton , SIGNAL(clicked()) , this ,
+            SLOT(newKeyBinding()) );
+
+    updateKeyBindingsButtons();
+
+    connect( _ui->editKeyBindingsButton , SIGNAL(clicked()) , this , 
+          SLOT(editKeyBinding()) );  
+    connect( _ui->removeKeyBindingsButton , SIGNAL(clicked()) , this ,
+            SLOT(removeKeyBinding()) );
+}
+void EditProfileDialog::keyBindingSelected()
+{
+    QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes();
+
+    if ( !selected.isEmpty() )
+    {
+        QAbstractItemModel* model = _ui->keyBindingList->model();
+        const KeyboardTranslator* translator = model->data(selected.first(),Qt::UserRole+1)
+                                                .value<const KeyboardTranslator*>();
+        _tempProfile->setProperty(Profile::KeyBindings,translator->name());
+    }
+
+    updateKeyBindingsButtons();
+}
+void EditProfileDialog::removeKeyBinding()
+{
+    QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes();
+
+    if ( !selected.isEmpty() )
+    {
+        const QString& name = selected.first().data(Qt::UserRole+1).value<const KeyboardTranslator*>()->name();
+        if (KeyboardTranslatorManager::instance()->deleteTranslator(name))
+            _ui->keyBindingList->model()->removeRow(selected.first().row());   
+    }
+}
+void EditProfileDialog::showKeyBindingEditor(bool isNewTranslator)
+{
+    QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes();
+    QAbstractItemModel* model = _ui->keyBindingList->model();
+
+    const KeyboardTranslator* translator = 0;
+    if ( !selected.isEmpty() )
+        translator = model->data(selected.first(),Qt::UserRole+1).value<const KeyboardTranslator*>();
+    else
+        translator = KeyboardTranslatorManager::instance()->defaultTranslator();
+
+    Q_ASSERT(translator);
+
+    KDialog* dialog = new KDialog(this);
+
+    if ( isNewTranslator )
+        dialog->setCaption(i18n("New Key Binding List"));
+    else
+        dialog->setCaption(i18n("Edit Key Binding List"));
+
+    KeyBindingEditor* editor = new KeyBindingEditor;
+    dialog->setMainWidget(editor);
+    
+    if ( translator )
+        editor->setup(translator);
+
+    if ( isNewTranslator )
+        editor->setDescription(i18n("New Key Binding List"));
+
+    if ( dialog->exec() == QDialog::Accepted )
+    {
+        KeyboardTranslator* newTranslator = new KeyboardTranslator(*editor->translator());
+
+        if ( isNewTranslator )
+            newTranslator->setName(newTranslator->description());
+
+        KeyboardTranslatorManager::instance()->addTranslator( newTranslator );
+
+        updateKeyBindingsList();
+        
+        const QString& currentTranslator = lookupProfile()
+                                        ->property<QString>(Profile::KeyBindings);
+
+        if ( newTranslator->name() == currentTranslator )
+        {
+            _tempProfile->setProperty(Profile::KeyBindings,newTranslator->name());
+        }
+    }
+}
+void EditProfileDialog::newKeyBinding()
+{
+    showKeyBindingEditor(true);
+}
+void EditProfileDialog::editKeyBinding()
+{
+    showKeyBindingEditor(false);
+}
+void EditProfileDialog::setupCombo( ComboOption* options , const Profile::Ptr profile )
+{
+    while ( options->button != 0 )
+    {
+        options->button->setChecked(profile->property<bool>((Profile::Property)options->property));
+        connect( options->button , SIGNAL(toggled(bool)) , this , options->slot );
+
+        ++options;
+    }
+}
+void EditProfileDialog::setupRadio( RadioOption* possible , int actual )
+{
+    while (possible->button != 0)
+    {
+        if ( possible->property == actual )
+            possible->button->setChecked(true);
+        else
+            possible->button->setChecked(false);
+   
+        connect( possible->button , SIGNAL(clicked()) , this , possible->slot );
+
+        ++possible;
+    }
+}
+
+void EditProfileDialog::setupScrollingPage(const Profile::Ptr profile)
+{
+    // setup scrollbar radio
+    int scrollBarPosition = profile->property<int>(Profile::ScrollBarPosition);
+   
+    RadioOption positions[] = { {_ui->scrollBarHiddenButton,Profile::ScrollBarHidden,SLOT(hideScrollBar())},
+                                {_ui->scrollBarLeftButton,Profile::ScrollBarLeft,SLOT(showScrollBarLeft())},
+                                {_ui->scrollBarRightButton,Profile::ScrollBarRight,SLOT(showScrollBarRight())},
+                                {0,0,0} 
+                              }; 
+
+    setupRadio( positions , scrollBarPosition );
+   
+    // setup scrollback type radio
+    int scrollBackType = profile->property<int>(Profile::HistoryMode);
+    
+    RadioOption types[] = { {_ui->disableScrollbackButton,Profile::DisableHistory,SLOT(noScrollBack())},
+                            {_ui->fixedScrollbackButton,Profile::FixedSizeHistory,SLOT(fixedScrollBack())},
+                            {_ui->unlimitedScrollbackButton,Profile::UnlimitedHistory,SLOT(unlimitedScrollBack())},
+                            {0,0,0} };
+    setupRadio( types , scrollBackType ); 
+    
+    // setup scrollback line count spinner
+    _ui->scrollBackLinesSpinner->setValue( profile->property<int>(Profile::HistorySize) );
+
+    // signals and slots
+    connect( _ui->scrollBackLinesSpinner , SIGNAL(valueChanged(int)) , this , 
+            SLOT(scrollBackLinesChanged(int)) );
+}
+
+void EditProfileDialog::scrollBackLinesChanged(int lineCount)
+{
+    _tempProfile->setProperty(Profile::HistorySize , lineCount);
+}
+void EditProfileDialog::noScrollBack()
+{
+    _tempProfile->setProperty(Profile::HistoryMode , Profile::DisableHistory);
+}
+void EditProfileDialog::fixedScrollBack()
+{
+    _tempProfile->setProperty(Profile::HistoryMode , Profile::FixedSizeHistory);
+}
+void EditProfileDialog::unlimitedScrollBack()
+{
+    _tempProfile->setProperty(Profile::HistoryMode , Profile::UnlimitedHistory );
+}
+void EditProfileDialog::hideScrollBar()
+{
+    _tempProfile->setProperty(Profile::ScrollBarPosition , Profile::ScrollBarHidden );
+}
+void EditProfileDialog::showScrollBarLeft()
+{
+    _tempProfile->setProperty(Profile::ScrollBarPosition , Profile::ScrollBarLeft );
+}
+void EditProfileDialog::showScrollBarRight()
+{
+    _tempProfile->setProperty(Profile::ScrollBarPosition , Profile::ScrollBarRight );
+}
+void EditProfileDialog::setupAdvancedPage(const Profile::Ptr profile)
+{
+    ComboOption  options[] = { { _ui->enableBlinkingTextButton , Profile::BlinkingTextEnabled , 
+                                 SLOT(toggleBlinkingText(bool)) },
+                               { _ui->enableFlowControlButton , Profile::FlowControlEnabled ,
+                                 SLOT(toggleFlowControl(bool)) },
+                               { _ui->enableResizeWindowButton , Profile::AllowProgramsToResizeWindow ,
+                                 SLOT(toggleResizeWindow(bool)) },
+                               { _ui->enableBlinkingCursorButton , Profile::BlinkingCursorEnabled ,
+                                 SLOT(toggleBlinkingCursor(bool)) },
+                               { _ui->tripleClickMode , Profile::TripleClickMode ,
+                                 SLOT(toggleTripleClickMode(bool)) },
+                               { _ui->enableBidiRenderingButton , Profile::BidiRenderingEnabled ,
+                                 SLOT(togglebidiRendering(bool)) },
+                               { 0 , 0 , 0 }
+                             };
+    setupCombo( options , profile );
+
+    // interaction options
+    _ui->wordCharacterEdit->setText( profile->property<QString>(Profile::WordCharacters) );
+
+    connect( _ui->wordCharacterEdit , SIGNAL(textChanged(const QString&)) , this , 
+            SLOT(wordCharactersChanged(const QString&)) );
+
+    // cursor options
+    if ( profile->property<bool>(Profile::UseCustomCursorColor) )
+        _ui->customCursorColorButton->setChecked(true);
+    else
+        _ui->autoCursorColorButton->setChecked(true);
+
+    _ui->customColorSelectButton->setColor( profile->property<QColor>(Profile::CustomCursorColor) );
+
+    connect( _ui->customCursorColorButton , SIGNAL(clicked()) , this , SLOT(customCursorColor()) );
+    connect( _ui->autoCursorColorButton , SIGNAL(clicked()) , this , SLOT(autoCursorColor()) );
+    connect( _ui->customColorSelectButton , SIGNAL(changed(const QColor&)) , 
+            SLOT(customCursorColorChanged(const QColor&)) );
+
+    int shape = profile->property<int>(Profile::CursorShape);
+    _ui->cursorShapeCombo->setCurrentIndex(shape);
+
+    connect( _ui->cursorShapeCombo , SIGNAL(activated(int)) , this , SLOT(setCursorShape(int)) ); 
+
+    // encoding options
+    QAction* codecAction = new KCodecAction(this);
+    _ui->selectEncodingButton->setMenu( codecAction->menu() );
+    connect( codecAction , SIGNAL(triggered(QTextCodec*)) , this , SLOT(setDefaultCodec(QTextCodec*)) );
+
+    _ui->characterEncodingLabel->setText( profile->property<QString>(Profile::DefaultEncoding) );
+
+}
+void EditProfileDialog::setDefaultCodec(QTextCodec* codec)
+{
+    QString name = QString(codec->name());
+
+    _tempProfile->setProperty(Profile::DefaultEncoding,name);
+    _ui->characterEncodingLabel->setText(codec->name());
+}
+void EditProfileDialog::customCursorColorChanged(const QColor& color)
+{
+    _tempProfile->setProperty(Profile::CustomCursorColor,color);
+
+    // ensure that custom cursor colors are enabled
+    _ui->customCursorColorButton->click();
+}
+void EditProfileDialog::wordCharactersChanged(const QString& text)
+{
+    _tempProfile->setProperty(Profile::WordCharacters,text);
+}
+void EditProfileDialog::autoCursorColor()
+{
+    _tempProfile->setProperty(Profile::UseCustomCursorColor,false);
+}
+void EditProfileDialog::customCursorColor()
+{
+    _tempProfile->setProperty(Profile::UseCustomCursorColor,true);
+}
+void EditProfileDialog::setCursorShape(int index)
+{
+    _tempProfile->setProperty(Profile::CursorShape,index);
+}
+void EditProfileDialog::togglebidiRendering(bool enable)
+{
+    _tempProfile->setProperty(Profile::BidiRenderingEnabled,enable);
+}
+void EditProfileDialog::toggleBlinkingCursor(bool enable)
+{
+    _tempProfile->setProperty(Profile::BlinkingCursorEnabled,enable);
+}
+void EditProfileDialog::toggleTripleClickMode(bool enable)
+{
+    _tempProfile->setProperty(Profile::TripleClickMode,enable);
+}
+void EditProfileDialog::toggleBlinkingText(bool enable)
+{
+    _tempProfile->setProperty(Profile::BlinkingTextEnabled,enable);
+}
+void EditProfileDialog::toggleFlowControl(bool enable)
+{
+    _tempProfile->setProperty(Profile::FlowControlEnabled,enable);
+}
+void EditProfileDialog::toggleResizeWindow(bool enable)
+{
+    _tempProfile->setProperty(Profile::AllowProgramsToResizeWindow,enable);
+}
+void EditProfileDialog::fontSelected(const QFont& font)
+{
+    QFont previewFont = font;
+
+   setFontSliderRange(font);
+   setFontSliderValue(font);
+
+   _ui->fontPreviewLabel->setFont(previewFont);
+   
+   _tempProfile->setProperty(Profile::Font,font);
+
+   preview(Profile::Font,font);
+}
+void EditProfileDialog::showFontDialog()
+{
+    QFont currentFont = _ui->fontPreviewLabel->font();
+   
+    KFontDialog* dialog = new KFontDialog(this, KFontChooser::FixedFontsOnly);
+    dialog->setFont(currentFont, true);
+
+    connect( dialog , SIGNAL(fontSelected(const QFont&)) , this , SLOT(fontSelected(const QFont&)) );
+
+    if (dialog->exec() == QDialog::Rejected)
+        fontSelected(currentFont);
+}
+void EditProfileDialog::setFontSize(int pointSize)
+{
+    QFont newFont = _ui->fontPreviewLabel->font();
+    newFont.setPointSizeF(pointSize / 10.0);
+    _ui->fontPreviewLabel->setFont(newFont);
+
+    _tempProfile->setProperty(Profile::Font,newFont);
+
+    preview(Profile::Font,newFont);
+}
+
+void EditProfileDialog::setFontSliderRange(const QFont& font)
+{
+    QSlider* slider = _ui->fontSizeSlider;
+    // Minimum on the slider is 4, 
+    // Maximum is the greater of 2 times the current size and 14
+    slider->setRange( qMin(4 * 10, qRound(font.pointSizeF() * 10)),
+                      qMax(14 * 10, 2 * qRound(font.pointSize() * 10)) );
+
+}
+
+void EditProfileDialog::setFontSliderValue(const QFont& font)
+{
+   _ui->fontSizeSlider->setValue(qRound(font.pointSize() * 10));
+}
+
+ColorSchemeViewDelegate::ColorSchemeViewDelegate(QObject* parent)
+ : QAbstractItemDelegate(parent)
+{
+
+}
+
+void ColorSchemeViewDelegate::setEntryTimeLine(QTimeLine* timeLine)
+{
+    _entryTimeLine = timeLine;
+}
+
+void ColorSchemeViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
+                       const QModelIndex& index) const
+{
+    // entry animation
+    //
+    // note that the translation occurs for each item drawn, but the 
+    // painter is not reset between painting items.  this means that when
+    // the items are painted in order ( as occurs when the list is first
+    // shown ), there is a visually pleasing staggering of items as they
+    // enter.
+    if ( _entryTimeLine != 0 )
+    {
+        qreal value = 1.0-_entryTimeLine->currentValue();
+        painter->translate(  value * 
+                             option.rect.width() , 0 );
+
+        painter->setOpacity( _entryTimeLine->currentValue() );
+    }
+
+    const ColorScheme* scheme = index.data(Qt::UserRole + 1).value<const ColorScheme*>();
+
+    Q_ASSERT(scheme);
+
+    bool transparencyAvailable = KWindowSystem::compositingActive();
+
+    painter->setRenderHint( QPainter::Antialiasing );
+
+    // draw background
+    painter->setPen( QPen(scheme->foregroundColor() , 1) );
+
+    // radial gradient for background
+    // from a lightened version of the scheme's background color in the center to
+    // a darker version at the outer edge
+    QColor color = scheme->backgroundColor();
+    QRectF backgroundRect = QRectF(option.rect).adjusted(1.5,1.5,-1.5,-1.5);
+  
+    QRadialGradient backgroundGradient(backgroundRect.center() , backgroundRect.width() / 2);
+    backgroundGradient.setColorAt( 0 , color.lighter(105) );
+    backgroundGradient.setColorAt( 1 , color.darker(115) );
+   
+    const int backgroundRectXRoundness = 4;
+    const int backgroundRectYRoundness = 30;
+
+    QPainterPath backgroundRectPath(backgroundRect.topLeft());
+    backgroundRectPath.addRoundRect( backgroundRect , backgroundRectXRoundness , backgroundRectYRoundness );
+
+    if ( transparencyAvailable )
+    {
+        painter->save();
+        color.setAlphaF(scheme->opacity());
+        painter->setCompositionMode( QPainter::CompositionMode_Source );
+        painter->setBrush(backgroundGradient);
+
+        painter->drawPath(backgroundRectPath);
+        painter->restore();
+    }
+    else
+    {
+        painter->setBrush(backgroundGradient);
+        painter->drawPath(backgroundRectPath);
+    }
+
+    // draw stripe at the side using scheme's foreground color
+    painter->setPen( QPen(Qt::NoPen) );
+    QPainterPath path( option.rect.topLeft() );
+    path.lineTo( option.rect.width() / 10.0 , option.rect.top() );
+    path.lineTo( option.rect.bottomLeft() );
+    path.lineTo( option.rect.topLeft() );
+    painter->setBrush( scheme->foregroundColor() );
+    painter->drawPath(path.intersected(backgroundRectPath));
+
+    // draw highlight 
+    // with a linear gradient going from translucent white to transparent
+    QLinearGradient gradient( option.rect.topLeft() , option.rect.bottomLeft() );
+    gradient.setColorAt( 0 , QColor(255,255,255,90) );
+    gradient.setColorAt( 1 , Qt::transparent );
+    painter->setBrush(gradient);
+    painter->drawRoundRect( backgroundRect , 4 , 30 );
+
+    //const bool isChecked = index.data(Qt::CheckStateRole) == Qt::Checked;
+    const bool isSelected = option.state & QStyle::State_Selected;
+
+    // draw border on selected items
+    if ( isSelected ) //|| isChecked )
+    {
+        static const int selectedBorderWidth = 6;
+
+
+        painter->setBrush( QBrush(Qt::NoBrush) );
+        QPen pen;
+        
+        QColor highlightColor = option.palette.highlight().color();
+
+        if ( isSelected )
+            highlightColor.setAlphaF(1.0);
+        else
+            highlightColor.setAlphaF(0.7);
+
+        pen.setBrush(highlightColor);
+        pen.setWidth(selectedBorderWidth);
+        pen.setJoinStyle(Qt::MiterJoin);
+        
+        painter->setPen(pen);
+
+
+        painter->drawRect( option.rect.adjusted(selectedBorderWidth/2,
+                                                selectedBorderWidth/2,
+                                                -selectedBorderWidth/2,
+                                                -selectedBorderWidth/2) );
+    }
+
+    // draw color scheme name using scheme's foreground color
+    QPen pen(scheme->foregroundColor());
+    painter->setPen(pen);
+
+    painter->drawText( option.rect , Qt::AlignCenter , 
+                        index.data(Qt::DisplayRole).value<QString>() );
+
+}
+
+QSize ColorSchemeViewDelegate::sizeHint( const QStyleOptionViewItem& option,
+                       const QModelIndex& /*index*/) const
+{
+    const int width = 200;
+    qreal colorWidth = (qreal)width / TABLE_COLORS;
+    int margin = 5;
+    qreal heightForWidth = ( colorWidth * 2 ) + option.fontMetrics.height() + margin;
+
+    // temporary
+    return QSize(width,(int)heightForWidth);
+}
+
+#include "EditProfileDialog.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/EditProfileDialog.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,277 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef EDITPROFILEDIALOG_H
+#define EDITPROFILEDIALOG_H
+
+// Qt
+#include <QtGui/QAbstractItemDelegate>
+#include <QtCore/QPair>
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QPointer>
+
+// KDE
+#include <KDialog>
+
+// Local
+#include "Profile.h"
+
+class QAbstractButton;
+class QItemSelectionModel;
+class QTextCodec;
+class QTimeLine;
+
+namespace Ui
+{
+    class EditProfileDialog;
+}
+
+namespace Konsole
+{
+
+class Profile;
+
+/**
+ * A dialog which allows the user to edit a profile.
+ * After the dialog is created, it can be initialised with the settings
+ * for a profile using setProfile().  When the user makes changes to the 
+ * dialog and accepts the changes, the dialog will update the
+ * profile in the SessionManager by calling the SessionManager's 
+ * changeProfile() method.
+ *
+ * Some changes made in the dialog are preview-only changes which cause
+ * the SessionManager's changeProfile() method to be called with
+ * the persistant argument set to false.  These changes are then
+ * un-done when the dialog is closed.
+ */
+class KONSOLEPRIVATE_EXPORT EditProfileDialog : public KDialog
+{
+Q_OBJECT
+
+public:
+    /** Constructs a new dialog with the specified parent. */
+    EditProfileDialog(QWidget* parent = 0);
+    virtual ~EditProfileDialog();
+
+    /**
+     * Initialises the dialog with the settings for the specified session
+     * type.
+     *
+     * When the dialog closes, the profile will be updated in the SessionManager
+     * with the altered settings.
+     *
+     * @param profile The profile to be edited
+     */
+    void setProfile(Profile::Ptr profile);
+
+    /** 
+     * Selects the text in the profile name edit area. 
+     * When the dialog is being used to create a new profile,
+     * this can be used to draw the user's attention to the profile name
+     * and make it easy for them to change it.
+     */
+    void selectProfileName();
+
+public slots:
+    // reimplemented
+    virtual void accept();
+    // reimplemented 
+    virtual void reject();
+
+protected:
+    virtual bool eventFilter(QObject* watched , QEvent* event);
+
+private slots:
+    // sets up the specified tab page if necessary
+    void preparePage(int);
+
+    // saves changes to profile
+    void save();
+
+    // general page
+    void selectInitialDir();
+    void selectIcon();
+
+    void profileNameChanged(const QString& text);
+    void initialDirChanged(const QString& text);
+    void startInSameDir(bool);
+    void commandChanged(const QString& text);
+    void tabTitleFormatChanged(const QString& text);
+    void remoteTabTitleFormatChanged(const QString& text);
+
+    void insertTabTitleText(const QString& text);
+    void insertRemoteTabTitleText(const QString& text);
+
+    void showMenuBar(bool);
+    void saveGeometryOnExit(bool);
+    void showEnvironmentEditor();
+    void tabBarVisibilityChanged(int);
+    void tabBarPositionChanged(int);
+    void showNewTabButton(bool);
+
+    // appearance page
+    void setFontSize(int pointSize);
+    void setFontSliderRange(const QFont&);
+    void setFontSliderValue(const QFont&);
+    void setAntialiasText(bool enable);
+    void setBoldIntense(bool enable);
+    void showFontDialog();
+    void newColorScheme();
+    void editColorScheme();
+    void removeColorScheme();
+    void colorSchemeSelected();
+    void previewColorScheme(const QModelIndex& index);
+    void fontSelected(const QFont&);
+
+    void colorSchemeAnimationUpdate();
+
+    // scrolling page
+    void noScrollBack();
+    void fixedScrollBack();
+    void unlimitedScrollBack();
+   
+    void scrollBackLinesChanged(int);
+
+    void hideScrollBar();
+    void showScrollBarLeft();
+    void showScrollBarRight();
+
+    // keyboard page
+    void editKeyBinding();
+    void newKeyBinding();
+    void keyBindingSelected();
+    void removeKeyBinding();
+
+    // advanced page
+    void toggleBlinkingText(bool);
+    void toggleFlowControl(bool);
+    void toggleResizeWindow(bool);
+    void togglebidiRendering(bool);
+    void toggleBlinkingCursor(bool);
+    void toggleTripleClickMode(bool);
+
+    void setCursorShape(int);
+    void autoCursorColor();
+    void customCursorColor();
+    void customCursorColorChanged(const QColor&);
+    void wordCharactersChanged(const QString&);
+    void setDefaultCodec(QTextCodec*);
+
+    // apply the first previewed changes stored up by delayedPreview()
+    void delayedPreviewActivate();
+
+private:
+    // initialize various pages of the dialog
+    void setupGeneralPage(const Profile::Ptr info);
+    void setupTabsPage(const Profile::Ptr info);
+    void setupAppearancePage(const Profile::Ptr info);
+    void setupKeyboardPage(const Profile::Ptr info);
+    void setupScrollingPage(const Profile::Ptr info);
+    void setupAdvancedPage(const Profile::Ptr info);
+
+    void updateColorSchemeList(bool selectCurrentScheme = false);
+    void updateColorSchemeButtons();
+    void updateKeyBindingsList(bool selectCurrentTranslator = false);
+    void updateKeyBindingsButtons();
+
+    void showColorSchemeEditor(bool newScheme);
+    void showKeyBindingEditor(bool newTranslator);
+
+    void changeCheckedItem( QAbstractItemModel* mode,  const QModelIndex& to );
+
+    void preview(int property , const QVariant& value);
+    void delayedPreview(int property , const QVariant& value);
+    void unpreview(int property);
+    void unpreviewAll();
+    void enableIfNonEmptySelection(QWidget* widget,QItemSelectionModel* selectionModel);
+
+    void updateCaption(const Profile::Ptr profile);
+    void updateTransparencyWarning();
+
+    static QString groupProfileNames(const ProfileGroup::Ptr group, int maxLength = -1);
+
+    struct RadioOption
+    {
+       QAbstractButton* button;
+       int property;
+       const char* slot; 
+    };
+    void setupRadio(RadioOption* possible,int actual);
+    struct ComboOption
+    {
+       QAbstractButton* button;
+       int property;
+       const char* slot;
+    };
+    void setupCombo(ComboOption* options , const Profile::Ptr profile);
+
+    const Profile::Ptr lookupProfile() const;
+
+    Ui::EditProfileDialog* _ui;
+    Profile::Ptr _tempProfile;
+    Profile::Ptr _profile;
+
+    // keeps track of pages which need to be updated to match the current
+    // profile.  all elements in this vector are set to true when the 
+    // profile is changed and individual elements are set to false 
+    // after an update by a call to ensurePageLoaded()
+    QVector<bool> _pageNeedsUpdate;
+    QHash<int,QVariant> _previewedProperties;
+    
+    QTimeLine* _colorSchemeAnimationTimeLine;
+
+    QHash<int,QVariant> _delayedPreviewProperties;
+    QTimer* _delayedPreviewTimer;
+};
+
+/**
+ * A delegate which can display and edit color schemes in a view.
+ */
+class ColorSchemeViewDelegate : public QAbstractItemDelegate
+{
+Q_OBJECT
+
+public:
+    ColorSchemeViewDelegate(QObject* parent = 0);
+
+    // reimplemented
+    virtual void paint(QPainter* painter, const QStyleOptionViewItem& option,
+                       const QModelIndex& index) const;
+    virtual QSize sizeHint( const QStyleOptionViewItem& option,
+                       const QModelIndex& index) const;
+
+    /** 
+     * Sets the timeline used to control the entry animation
+     * for this delegate.
+     *
+     * During a call to paint(), the value of the timeLine is used to
+     * determine how to render the item ( with 0 being the beginning 
+     * of the animation and 1.0 being the end )
+     */
+    void setEntryTimeLine( QTimeLine* timeLine );
+
+private:
+    QPointer<QTimeLine> _entryTimeLine;
+
+};
+
+}
+
+#endif // EDITPROFILEDIALOG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Emulation.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,460 @@
+/*
+    Copyright 2007-2008 Robert Knight <robertknight@gmail.com> 
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+    Copyright 1996 by Matthias Ettrich <ettrich@kde.org>
+
+    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 "Emulation.h"
+
+// System
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+// Qt
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
+#include <QtCore/QHash>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QRegExp>
+#include <QtCore/QTextStream>
+#include <QtCore/QThread>
+
+#include <QtCore/QTime>
+
+// KDE
+//#include <kdebug.h>
+
+// Konsole
+#include "KeyboardTranslator.h"
+#include "Screen.h"
+#include "TerminalCharacterDecoder.h"
+#include "ScreenWindow.h"
+
+using namespace Konsole;
+
+Emulation::Emulation() :
+  _currentScreen(0),
+  _codec(0),
+  _decoder(0),
+  _keyTranslator(0),
+  _usesMouse(false)
+{
+  // create screens with a default size
+  _screen[0] = new Screen(40,80);
+  _screen[1] = new Screen(40,80);
+  _currentScreen = _screen[0];
+
+  QObject::connect(&_bulkTimer1, SIGNAL(timeout()), this, SLOT(showBulk()) );
+  QObject::connect(&_bulkTimer2, SIGNAL(timeout()), this, SLOT(showBulk()) );
+   
+  // listen for mouse status changes
+  connect( this , SIGNAL(programUsesMouseChanged(bool)) , 
+           SLOT(usesMouseChanged(bool)) );
+}
+
+bool Emulation::programUsesMouse() const
+{
+    return _usesMouse;
+}
+
+void Emulation::usesMouseChanged(bool usesMouse)
+{
+    _usesMouse = usesMouse;
+}
+
+ScreenWindow* Emulation::createWindow()
+{
+    ScreenWindow* window = new ScreenWindow();
+    window->setScreen(_currentScreen);
+    _windows << window;
+
+    connect(window , SIGNAL(selectionChanged()),
+            this , SLOT(bufferedUpdate()));
+
+    connect(this , SIGNAL(outputChanged()),
+            window , SLOT(notifyOutputChanged()) );
+    return window;
+}
+
+Emulation::~Emulation()
+{
+  QListIterator<ScreenWindow*> windowIter(_windows);
+
+  while (windowIter.hasNext())
+  {
+    delete windowIter.next();
+  }
+
+  delete _screen[0];
+  delete _screen[1];
+  delete _decoder;
+}
+
+void Emulation::setScreen(int n)
+{
+  Screen *old = _currentScreen;
+  _currentScreen = _screen[n & 1];
+  if (_currentScreen != old) 
+  {
+     // tell all windows onto this emulation to switch to the newly active screen
+     foreach(ScreenWindow* window,_windows)
+         window->setScreen(_currentScreen);
+  }
+}
+
+void Emulation::clearHistory()
+{
+    _screen[0]->setScroll( _screen[0]->getScroll() , false );
+}
+void Emulation::setHistory(const HistoryType& t)
+{
+  _screen[0]->setScroll(t);
+
+  showBulk();
+}
+
+const HistoryType& Emulation::history() const
+{
+  return _screen[0]->getScroll();
+}
+
+void Emulation::setCodec(const QTextCodec * qtc)
+{
+  if (qtc)
+      _codec = qtc;
+  else
+     setCodec(LocaleCodec);
+
+  delete _decoder;
+  _decoder = _codec->makeDecoder();
+
+  emit useUtf8Request(utf8());
+}
+
+void Emulation::setCodec(EmulationCodec codec)
+{
+    if ( codec == Utf8Codec )
+        setCodec( QTextCodec::codecForName("utf8") );
+    else if ( codec == LocaleCodec )
+        setCodec( QTextCodec::codecForLocale() );
+}
+
+void Emulation::setKeyBindings(const QString& name)
+{
+  _keyTranslator = KeyboardTranslatorManager::instance()->findTranslator(name);
+  if (!_keyTranslator)
+  {
+      _keyTranslator = KeyboardTranslatorManager::instance()->defaultTranslator();
+  }
+}
+
+QString Emulation::keyBindings() const
+{
+  return _keyTranslator->name();
+}
+
+void Emulation::receiveChar(int c)
+// process application unicode input to terminal
+// this is a trivial scanner
+{
+  c &= 0xff;
+  switch (c)
+  {
+    case '\b'      : _currentScreen->backspace();                 break;
+    case '\t'      : _currentScreen->tab();                       break;
+    case '\n'      : _currentScreen->newLine();                   break;
+    case '\r'      : _currentScreen->toStartOfLine();             break;
+    case 0x07      : emit stateSet(NOTIFYBELL);
+                     break;
+    default        : _currentScreen->displayCharacter(c);         break;
+  };
+}
+
+void Emulation::sendKeyEvent( QKeyEvent* ev )
+{
+  emit stateSet(NOTIFYNORMAL);
+  
+  if (!ev->text().isEmpty())
+  { // A block of text
+    // Note that the text is proper unicode.
+    // We should do a conversion here
+    emit sendData(ev->text().toUtf8(),ev->text().length());
+  }
+}
+
+void Emulation::sendString(const char*,int)
+{
+    // default implementation does nothing
+}
+
+void Emulation::sendMouseEvent(int /*buttons*/, int /*column*/, int /*row*/, int /*eventType*/)
+{
+    // default implementation does nothing
+}
+
+/*
+   We are doing code conversion from locale to unicode first.
+TODO: Character composition from the old code.  See #96536
+*/
+
+void Emulation::receiveData(const char* text, int length)
+{
+    emit stateSet(NOTIFYACTIVITY);
+
+    bufferedUpdate();
+        
+    QString unicodeText = _decoder->toUnicode(text,length);
+
+    //send characters to terminal emulator
+    for (int i=0;i<unicodeText.length();i++)
+        receiveChar(unicodeText[i].unicode());
+
+    //look for z-modem indicator
+    //-- someone who understands more about z-modems that I do may be able to move
+    //this check into the above for loop?
+    for (int i=0;i<length;i++)
+    {
+        if (text[i] == '\030')
+        {
+            if ((length-i-1 > 3) && (strncmp(text+i+1, "B00", 3) == 0))
+                emit zmodemDetected();
+        }
+    }
+}
+
+//OLDER VERSION
+//This version of onRcvBlock was commented out because
+//    a)  It decoded incoming characters one-by-one, which is slow in the current version of Qt (4.2 tech preview)
+//    b)  It messed up decoding of non-ASCII characters, with the result that (for example) chinese characters
+//        were not printed properly.
+//
+//There is something about stopping the _decoder if "we get a control code halfway a multi-byte sequence" (see below)
+//which hasn't been ported into the newer function (above).  Hopefully someone who understands this better
+//can find an alternative way of handling the check.  
+
+
+/*void Emulation::onRcvBlock(const char *s, int len)
+{
+  emit notifySessionState(NOTIFYACTIVITY);
+  
+  bufferedUpdate();
+  for (int i = 0; i < len; i++)
+  {
+
+    QString result = _decoder->toUnicode(&s[i],1);
+    int reslen = result.length();
+
+    // If we get a control code halfway a multi-byte sequence
+    // we flush the _decoder and continue with the control code.
+    if ((s[i] < 32) && (s[i] > 0))
+    {
+       // Flush _decoder
+       while(!result.length())
+          result = _decoder->toUnicode(&s[i],1);
+       reslen = 1;
+       result.resize(reslen);
+       result[0] = QChar(s[i]);
+    }
+
+    for (int j = 0; j < reslen; j++)
+    {
+      if (result[j].characterategory() == QChar::Mark_NonSpacing)
+         _currentScreen->compose(result.mid(j,1));
+      else
+         onRcvChar(result[j].unicode());
+    }
+    if (s[i] == '\030')
+    {
+      if ((len-i-1 > 3) && (strncmp(s+i+1, "B00", 3) == 0))
+          emit zmodemDetected();
+    }
+  }
+}*/
+
+void Emulation::writeToStream( TerminalCharacterDecoder* _decoder , 
+                               int startLine ,
+                               int endLine) 
+{
+  _currentScreen->writeLinesToStream(_decoder,startLine,endLine);
+}
+
+int Emulation::lineCount() const
+{
+    // sum number of lines currently on _screen plus number of lines in history
+    return _currentScreen->getLines() + _currentScreen->getHistLines();
+}
+
+#define BULK_TIMEOUT1 10
+#define BULK_TIMEOUT2 40
+
+void Emulation::showBulk()
+{
+    _bulkTimer1.stop();
+    _bulkTimer2.stop();
+
+    emit outputChanged();
+
+    _currentScreen->resetScrolledLines();
+    _currentScreen->resetDroppedLines();
+}
+
+void Emulation::bufferedUpdate()
+{
+   _bulkTimer1.setSingleShot(true);
+   _bulkTimer1.start(BULK_TIMEOUT1);
+   if (!_bulkTimer2.isActive())
+   {
+      _bulkTimer2.setSingleShot(true);
+      _bulkTimer2.start(BULK_TIMEOUT2);
+   }
+}
+
+char Emulation::eraseChar() const
+{
+  return '\b';
+}
+
+void Emulation::setImageSize(int lines, int columns)
+{
+  if ((lines < 1) || (columns < 1)) 
+    return;
+
+  QSize screenSize[2] = { QSize(_screen[0]->getColumns(),
+                                _screen[0]->getLines()),
+                          QSize(_screen[1]->getColumns(),
+                                _screen[1]->getLines()) };
+  QSize newSize(columns,lines);
+
+  if (newSize == screenSize[0] && newSize == screenSize[1])
+    return;    
+
+  _screen[0]->resizeImage(lines,columns);
+  _screen[1]->resizeImage(lines,columns);
+
+  emit imageSizeChanged(lines,columns);
+
+  bufferedUpdate();
+}
+
+QSize Emulation::imageSize() const
+{
+  return QSize(_currentScreen->getColumns(), _currentScreen->getLines());
+}
+
+ushort ExtendedCharTable::extendedCharHash(ushort* unicodePoints , ushort length) const
+{
+    ushort hash = 0;
+    for ( ushort i = 0 ; i < length ; i++ )
+    {
+        hash = 31*hash + unicodePoints[i];
+    }
+    return hash;
+}
+bool ExtendedCharTable::extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const
+{
+    ushort* entry = extendedCharTable[hash];
+
+    // compare given length with stored sequence length ( given as the first ushort in the 
+    // stored buffer ) 
+    if ( entry == 0 || entry[0] != length ) 
+       return false;
+    // if the lengths match, each character must be checked.  the stored buffer starts at
+    // entry[1]
+    for ( int i = 0 ; i < length ; i++ )
+    {
+        if ( entry[i+1] != unicodePoints[i] )
+           return false; 
+    } 
+    return true;
+}
+ushort ExtendedCharTable::createExtendedChar(ushort* unicodePoints , ushort length)
+{
+    // look for this sequence of points in the table
+    ushort hash = extendedCharHash(unicodePoints,length);
+
+    // check existing entry for match
+    while ( extendedCharTable.contains(hash) )
+    {
+        if ( extendedCharMatch(hash,unicodePoints,length) )
+        {
+            // this sequence already has an entry in the table, 
+            // return its hash
+            return hash;
+        }
+        else
+        {
+            // if hash is already used by another, different sequence of unicode character
+            // points then try next hash
+            hash++;
+        }
+    }    
+
+    
+     // add the new sequence to the table and
+     // return that index
+    ushort* buffer = new ushort[length+1];
+    buffer[0] = length;
+    for ( int i = 0 ; i < length ; i++ )
+       buffer[i+1] = unicodePoints[i]; 
+    
+    extendedCharTable.insert(hash,buffer);
+
+    return hash;
+}
+
+ushort* ExtendedCharTable::lookupExtendedChar(ushort hash , ushort& length) const
+{
+    // lookup index in table and if found, set the length
+    // argument and return a pointer to the character sequence
+
+    ushort* buffer = extendedCharTable[hash];
+    if ( buffer )
+    {
+        length = buffer[0];
+        return buffer+1;
+    }
+    else
+    {
+        length = 0;
+        return 0;
+    }
+}
+
+ExtendedCharTable::ExtendedCharTable()
+{
+}
+ExtendedCharTable::~ExtendedCharTable()
+{
+    // free all allocated character buffers
+    QHashIterator<ushort,ushort*> iter(extendedCharTable);
+    while ( iter.hasNext() )
+    {
+        iter.next();
+        delete[] iter.value();
+    }
+}
+
+// global instance
+ExtendedCharTable ExtendedCharTable::instance;
+
+
+#include "Emulation.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Emulation.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,470 @@
+/*
+    This file is part of Konsole, an X terminal.
+    
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef EMULATION_H
+#define EMULATION_H
+
+// System
+#include <stdio.h>
+
+// Qt 
+#include <QtGui/QKeyEvent>
+//#include <QPointer>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+#include <QtCore/QTimer>
+
+// Konsole
+#include "konsole_export.h"
+
+namespace Konsole
+{
+
+class KeyboardTranslator;
+class HistoryType;
+class Screen;
+class ScreenWindow;
+class TerminalCharacterDecoder;
+
+/** 
+ * This enum describes the available states which 
+ * the terminal emulation may be set to.
+ *
+ * These are the values used by Emulation::stateChanged() 
+ */
+enum 
+{ 
+    /** The emulation is currently receiving user input. */
+    NOTIFYNORMAL=0, 
+    /** 
+     * The terminal program has triggered a bell event
+     * to get the user's attention.
+     */
+    NOTIFYBELL=1, 
+    /** 
+     * The emulation is currently receiving data from its 
+     * terminal input.
+     */
+    NOTIFYACTIVITY=2,
+
+    // unused here? 
+    NOTIFYSILENCE=3 
+};
+
+/**
+ * Base class for terminal emulation back-ends.
+ *
+ * The back-end is responsible for decoding an incoming character stream and 
+ * producing an output image of characters.
+ *
+ * When input from the terminal is received, the receiveData() slot should be called with
+ * the data which has arrived.  The emulation will process the data and update the 
+ * screen image accordingly.  The codec used to decode the incoming character stream
+ * into the unicode characters used internally can be specified using setCodec() 
+ *
+ * The size of the screen image can be specified by calling setImageSize() with the 
+ * desired number of lines and columns.  When new lines are added, old content
+ * is moved into a history store, which can be set by calling setHistory(). 
+ *
+ * The screen image can be accessed by creating a ScreenWindow onto this emulation 
+ * by calling createWindow().  Screen windows provide access to a section of the 
+ * output.  Each screen window covers the same number of lines and columns as the 
+ * image size returned by imageSize().  The screen window can be moved up and down
+ * and provides transparent access to both the current on-screen image and the 
+ * previous output.  The screen windows emit an outputChanged signal
+ * when the section of the image they are looking at changes.
+ * Graphical views can then render the contents of a screen window, listening for notifications
+ * of output changes from the screen window which they are associated with and updating 
+ * accordingly. 
+ *
+ * The emulation also is also responsible for converting input from the connected views such
+ * as keypresses and mouse activity into a character string which can be sent
+ * to the terminal program.  Key presses can be processed by calling the sendKeyEvent() slot,
+ * while mouse events can be processed using the sendMouseEvent() slot.  When the character
+ * stream has been produced, the emulation will emit a sendData() signal with a pointer
+ * to the character buffer.  This data should be fed to the standard input of the terminal
+ * process.  The translation of key presses into an output character stream is performed
+ * using a lookup in a set of key bindings which map key sequences to output
+ * character sequences.  The name of the key bindings set used can be specified using
+ * setKeyBindings()
+ *
+ * The emulation maintains certain state information which changes depending on the 
+ * input received.  The emulation can be reset back to its starting state by calling 
+ * reset().  
+ *
+ * The emulation also maintains an activity state, which specifies whether
+ * terminal is currently active ( when data is received ), normal
+ * ( when the terminal is idle or receiving user input ) or trying
+ * to alert the user ( also known as a "Bell" event ).  The stateSet() signal
+ * is emitted whenever the activity state is set.  This can be used to determine
+ * how long the emulation has been active/idle for and also respond to
+ * a 'bell' event in different ways.
+ */
+class KONSOLEPRIVATE_EXPORT Emulation : public QObject
+{ 
+Q_OBJECT
+
+public:
+ 
+   /** Constructs a new terminal emulation */ 
+   Emulation();
+  ~Emulation();
+
+  /**
+   * Creates a new window onto the output from this emulation.  The contents
+   * of the window are then rendered by views which are set to use this window using the
+   * TerminalDisplay::setScreenWindow() method.
+   */
+  ScreenWindow* createWindow();
+
+  /** Returns the size of the screen image which the emulation produces */
+  QSize imageSize() const;
+
+  /**
+   * Returns the total number of lines, including those stored in the history.
+   */ 
+  int lineCount() const;
+
+  /** 
+   * Sets the history store used by this emulation.  When new lines
+   * are added to the output, older lines at the top of the screen are transferred to a history
+   * store.   
+   *
+   * The number of lines which are kept and the storage location depend on the 
+   * type of store.
+   */
+  void setHistory(const HistoryType&);
+  /** Returns the history store used by this emulation.  See setHistory() */
+  const HistoryType& history() const;
+  /** Clears the history scroll. */
+  void clearHistory();
+
+  /** 
+   * Copies the output history from @p startLine to @p endLine 
+   * into @p stream, using @p decoder to convert the terminal
+   * characters into text. 
+   *
+   * @param decoder A decoder which converts lines of terminal characters with 
+   * appearance attributes into output text.  PlainTextDecoder is the most commonly
+   * used decoder.
+   * @param startLine Index of first line to copy
+   * @param endLine Index of last line to copy
+   */
+  virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine);
+  
+  /** Returns the codec used to decode incoming characters.  See setCodec() */
+  const QTextCodec* codec() const { return _codec; }
+  /** Sets the codec used to decode incoming characters.  */
+  void setCodec(const QTextCodec*);
+
+  /** 
+   * Convenience method.  
+   * Returns true if the current codec used to decode incoming
+   * characters is UTF-8
+   */
+  bool utf8() const
+  { Q_ASSERT(_codec); return _codec->mibEnum() == 106; }
+  
+
+  /** TODO Document me */
+  virtual char eraseChar() const;
+
+  /** 
+   * Sets the key bindings used to key events
+   * ( received through sendKeyEvent() ) into character
+   * streams to send to the terminal.
+   */
+  void setKeyBindings(const QString& name);
+  /** 
+   * Returns the name of the emulation's current key bindings.
+   * See setKeyBindings()
+   */
+  QString keyBindings() const;
+
+  /** 
+   * Copies the current image into the history and clears the screen.
+   */
+  virtual void clearEntireScreen() =0;
+
+  /** Resets the state of the terminal. */
+  virtual void reset() =0;
+
+  /** 
+   * Returns true if the active terminal program wants
+   * mouse input events.
+   *
+   * The programUsesMouseChanged() signal is emitted when this
+   * changes.
+   */
+  bool programUsesMouse() const;
+
+public slots: 
+
+  /** Change the size of the emulation's image */
+  virtual void setImageSize(int lines, int columns);
+  
+  /** 
+   * Interprets a sequence of characters and sends the result to the terminal.
+   * This is equivalent to calling sendKeyEvent() for each character in @p text in succession.
+   */
+  virtual void sendText(const QString& text) = 0;
+
+  /** 
+   * Interprets a key press event and emits the sendData() signal with
+   * the resulting character stream. 
+   */
+  virtual void sendKeyEvent(QKeyEvent*);
+ 
+  /** 
+   * Converts information about a mouse event into an xterm-compatible escape
+   * sequence and emits the character sequence via sendData()
+   */
+  virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
+  
+  /**
+   * Sends a string of characters to the foreground terminal process. 
+   *
+   * @param string The characters to send.  
+   * @param length Length of @p string or if set to a negative value, @p string will
+   * be treated as a null-terminated string and its length will be determined automatically.
+   */
+  virtual void sendString(const char* string, int length = -1) = 0;
+
+  /** 
+   * Processes an incoming stream of characters.  receiveData() decodes the incoming
+   * character buffer using the current codec(), and then calls receiveChar() for
+   * each unicode character in the resulting buffer.  
+   *
+   * receiveData() also starts a timer which causes the outputChanged() signal
+   * to be emitted when it expires.  The timer allows multiple updates in quick
+   * succession to be buffered into a single outputChanged() signal emission.
+   *
+   * @param buffer A string of characters received from the terminal program.
+   * @param len The length of @p buffer
+   */
+  void receiveData(const char* buffer,int len);
+
+signals:
+
+  /** 
+   * Emitted when a buffer of data is ready to send to the 
+   * standard input of the terminal.
+   *
+   * @param data The buffer of data ready to be sent
+   * @param len The length of @p data in bytes
+   */
+  void sendData(const char* data,int len);
+
+  /** 
+   * Requests that sending of input to the emulation
+   * from the terminal process be suspended or resumed.
+   *
+   * @param suspend If true, requests that sending of 
+   * input from the terminal process' stdout be 
+   * suspended.  Otherwise requests that sending of
+   * input be resumed. 
+   */
+  void lockPtyRequest(bool suspend);
+
+  /**
+   * Requests that the pty used by the terminal process
+   * be set to UTF 8 mode.  
+   *
+   * TODO: More documentation
+   */
+  void useUtf8Request(bool);
+
+  /**
+   * Emitted when the activity state of the emulation is set.
+   *
+   * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY
+   * or NOTIFYBELL
+   */
+  void stateSet(int state);
+
+  /** TODO Document me */
+  void zmodemDetected();
+
+
+  /**
+   * Requests that the color of the text used
+   * to represent the tabs associated with this
+   * emulation be changed.  This is a Konsole-specific
+   * extension from pre-KDE 4 times.
+   *
+   * TODO: Document how the parameter works.
+   */
+  void changeTabTextColorRequest(int color);
+
+  /** 
+   * This is emitted when the program running in the shell indicates whether or
+   * not it is interested in mouse events.
+   *
+   * @param usesMouse This will be true if the program wants to be informed about
+   * mouse events or false otherwise.
+   */
+  void programUsesMouseChanged(bool usesMouse);
+
+  /** 
+   * Emitted when the contents of the screen image change.
+   * The emulation buffers the updates from successive image changes,
+   * and only emits outputChanged() at sensible intervals when
+   * there is a lot of terminal activity.
+   *
+   * Normally there is no need for objects other than the screen windows
+   * created with createWindow() to listen for this signal.
+   *
+   * ScreenWindow objects created using createWindow() will emit their
+   * own outputChanged() signal in response to this signal. 
+   */
+  void outputChanged();
+
+  /**
+   * Emitted when the program running in the terminal wishes to update the 
+   * session's title.  This also allows terminal programs to customize other
+   * aspects of the terminal emulation display. 
+   *
+   * This signal is emitted when the escape sequence "\033]ARG;VALUE\007"
+   * is received in the input string, where ARG is a number specifying what
+   * should change and VALUE is a string specifying the new value.
+   *
+   * TODO:  The name of this method is not very accurate since this method
+   * is used to perform a whole range of tasks besides just setting
+   * the user-title of the session.    
+   *
+   * @param title Specifies what to change.
+   * <ul>
+   * <li>0 - Set window icon text and session title to @p newTitle</li>
+   * <li>1 - Set window icon text to @p newTitle</li>
+   * <li>2 - Set session title to @p newTitle</li>
+   * <li>11 - Set the session's default background color to @p newTitle,
+   *         where @p newTitle can be an HTML-style string ("#RRGGBB") or a named
+   *         color (eg 'red', 'blue').  
+   *         See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more
+   *         details.
+   * </li>
+   * <li>31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)</li>
+   * <li>32 - Sets the icon associated with the session.  @p newTitle is the name 
+   *    of the icon to use, which can be the name of any icon in the current KDE icon
+   *    theme (eg: 'konsole', 'kate', 'folder_home')</li>
+   * </ul>
+   * @param newTitle Specifies the new title 
+   */
+
+  void titleChanged(int title,const QString& newTitle);
+
+  /**
+   * Emitted when the program running in the terminal changes the
+   * screen size.
+   */
+  void imageSizeChanged(int lineCount , int columnCount);
+
+  /** 
+   * Emitted when the terminal program requests to change various properties
+   * of the terminal display.  
+   *
+   * A profile change command occurs when a special escape sequence, followed
+   * by a string containing a series of name and value pairs is received.
+   * This string can be parsed using a ProfileCommandParser instance.
+   *
+   * @param text A string expected to contain a series of key and value pairs in
+   * the form:  name=value;name2=value2 ...
+   */
+  void profileChangeCommandReceived(const QString& text);
+
+  /** 
+   * Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed.
+   * @param suspendKeyPressed True if Ctrl+S was pressed to suspend output or Ctrl+Q to
+   * resume output.
+   */
+  void flowControlKeyPressed(bool suspendKeyPressed);
+
+protected:
+  virtual void setMode(int mode) = 0;
+  virtual void resetMode(int mode) = 0;
+   
+  /** 
+   * Processes an incoming character.  See receiveData()
+   * @p ch A unicode character code. 
+   */
+  virtual void receiveChar(int ch);
+
+  /** 
+   * Sets the active screen.  The terminal has two screens, primary and alternate.
+   * The primary screen is used by default.  When certain interactive programs such
+   * as Vim are run, they trigger a switch to the alternate screen.
+   *
+   * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen
+   */
+  void setScreen(int index); 
+
+  enum EmulationCodec
+  {
+      LocaleCodec = 0,
+      Utf8Codec   = 1
+  };
+  void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8
+
+
+  QList<ScreenWindow*> _windows;
+  
+  Screen* _currentScreen;  // pointer to the screen which is currently active, 
+                            // this is one of the elements in the screen[] array
+
+  Screen* _screen[2];      // 0 = primary screen ( used by most programs, including the shell
+                            //                      scrollbars are enabled in this mode )
+                            // 1 = alternate      ( used by vi , emacs etc.
+                            //                      scrollbars are not enabled in this mode )
+                            
+  
+  //decodes an incoming C-style character stream into a unicode QString using 
+  //the current text codec.  (this allows for rendering of non-ASCII characters in text files etc.)
+  const QTextCodec* _codec;
+  QTextDecoder* _decoder;
+  const KeyboardTranslator* _keyTranslator; // the keyboard layout
+
+protected slots:
+  /** 
+   * Schedules an update of attached views.
+   * Repeated calls to bufferedUpdate() in close succession will result in only a single update,
+   * much like the Qt buffered update of widgets. 
+   */
+  void bufferedUpdate();
+
+private slots: 
+
+  // triggered by timer, causes the emulation to send an updated screen image to each
+  // view
+  void showBulk(); 
+
+  void usesMouseChanged(bool usesMouse);
+
+private:
+  bool _usesMouse;
+  QTimer _bulkTimer1;
+  QTimer _bulkTimer2;
+  
+};
+
+}
+
+#endif // ifndef EMULATION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Filter.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,541 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "Filter.h"
+
+// System
+#include <iostream>
+
+// Qt
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
+#include <QtCore/QString>
+#include <QtCore/QTextStream>
+#include <QtCore/QSharedData>
+#include <QtCore/QFile>
+
+// KDE
+//#include <KLocale>
+//#include <KRun>
+
+// Konsole
+#include "TerminalCharacterDecoder.h"
+#include "konsole_wcwidth.h"
+#include "konsole_export.h"
+
+using namespace Konsole;
+
+FilterChain::~FilterChain()
+{
+    QMutableListIterator<Filter*> iter(*this);
+    
+    while ( iter.hasNext() )
+    {
+        Filter* filter = iter.next();
+        iter.remove();
+        delete filter;
+    }
+}
+
+void FilterChain::addFilter(Filter* filter)
+{
+    append(filter);
+}
+void FilterChain::removeFilter(Filter* filter)
+{
+    removeAll(filter);
+}
+bool FilterChain::containsFilter(Filter* filter)
+{
+    return contains(filter);
+}
+void FilterChain::reset()
+{
+    QListIterator<Filter*> iter(*this);
+    while (iter.hasNext())
+        iter.next()->reset();
+}
+void FilterChain::setBuffer(const QString* buffer , const QList<int>* linePositions)
+{
+    QListIterator<Filter*> iter(*this);
+    while (iter.hasNext())
+        iter.next()->setBuffer(buffer,linePositions);
+}
+void FilterChain::process()
+{
+    QListIterator<Filter*> iter(*this);
+    while (iter.hasNext())
+        iter.next()->process();
+}
+void FilterChain::clear()
+{
+    QList<Filter*>::clear();
+}
+Filter::HotSpot* FilterChain::hotSpotAt(int line , int column) const
+{
+    QListIterator<Filter*> iter(*this);
+    while (iter.hasNext())
+    {
+        Filter* filter = iter.next();
+        Filter::HotSpot* spot = filter->hotSpotAt(line,column);
+        if ( spot != 0 )
+        {
+            return spot;
+        }
+    }
+
+    return 0;
+}
+
+QList<Filter::HotSpot*> FilterChain::hotSpots() const
+{
+    QList<Filter::HotSpot*> list;
+    QListIterator<Filter*> iter(*this);
+    while (iter.hasNext())
+    {
+        Filter* filter = iter.next();
+        list << filter->hotSpots();
+    }
+    return list;
+}
+//QList<Filter::HotSpot*> FilterChain::hotSpotsAtLine(int line) const;
+
+TerminalImageFilterChain::TerminalImageFilterChain()
+: _buffer(0)
+, _linePositions(0)
+{
+}
+
+TerminalImageFilterChain::~TerminalImageFilterChain()
+{
+    delete _buffer;
+    delete _linePositions;
+}
+
+void TerminalImageFilterChain::setImage(const Character* const image , int lines , int columns, const QVector<LineProperty>& lineProperties)
+{
+    if (empty())
+        return;
+
+    // reset all filters and hotspots
+    reset();
+
+    PlainTextDecoder decoder;
+    decoder.setTrailingWhitespace(false);
+    
+    // setup new shared buffers for the filters to process on
+    QString* newBuffer = new QString();
+    QList<int>* newLinePositions = new QList<int>();
+    setBuffer( newBuffer , newLinePositions );
+
+    // free the old buffers
+    delete _buffer;
+    delete _linePositions;
+
+    _buffer = newBuffer;
+    _linePositions = newLinePositions;
+
+    QTextStream lineStream(_buffer);
+    decoder.begin(&lineStream);
+
+    for (int i=0 ; i < lines ; i++)
+    {
+        _linePositions->append(_buffer->length());
+        decoder.decodeLine(image + i*columns,columns,LINE_DEFAULT);
+
+        // pretend that each line ends with a newline character.
+        // this prevents a link that occurs at the end of one line
+        // being treated as part of a link that occurs at the start of the next line
+        //
+        // the downside is that links which are spread over more than one line are not
+        // highlighted.  
+        //
+        // TODO - Use the "line wrapped" attribute associated with lines in a
+        // terminal image to avoid adding this imaginary character for wrapped
+        // lines
+        if ( !(lineProperties.value(i,LINE_DEFAULT) & LINE_WRAPPED) )
+            lineStream << QChar('\n');
+    }
+    decoder.end();
+}
+
+Filter::Filter() :
+_linePositions(0),
+_buffer(0)
+{
+}
+
+Filter::~Filter()
+{
+    QListIterator<HotSpot*> iter(_hotspotList);
+    while (iter.hasNext())
+    {
+        delete iter.next();
+    }
+}
+void Filter::reset()
+{
+    _hotspots.clear();
+    _hotspotList.clear();
+}
+
+void Filter::setBuffer(const QString* buffer , const QList<int>* linePositions)
+{
+    _buffer = buffer;
+    _linePositions = linePositions;
+}
+
+void Filter::getLineColumn(int position , int& startLine , int& startColumn)
+{
+    Q_ASSERT( _linePositions );
+    Q_ASSERT( _buffer );
+
+
+    for (int i = 0 ; i < _linePositions->count() ; i++)
+    {
+        int nextLine = 0;
+
+        if ( i == _linePositions->count()-1 )
+            nextLine = _buffer->length() + 1;
+        else
+            nextLine = _linePositions->value(i+1);
+
+        if ( _linePositions->value(i) <= position && position < nextLine ) 
+        {
+            startLine = i;
+            startColumn = string_width(buffer()->mid(_linePositions->value(i),position - _linePositions->value(i)));
+            return;
+        }
+    }
+}
+    
+
+/*void Filter::addLine(const QString& text)
+{
+    _linePositions << _buffer.length();
+    _buffer.append(text);
+}*/
+
+const QString* Filter::buffer()
+{
+    return _buffer;
+}
+Filter::HotSpot::~HotSpot()
+{
+}
+void Filter::addHotSpot(HotSpot* spot)
+{
+    _hotspotList << spot;
+
+    for (int line = spot->startLine() ; line <= spot->endLine() ; line++)
+    {
+        _hotspots.insert(line,spot);
+    }    
+}
+QList<Filter::HotSpot*> Filter::hotSpots() const
+{
+    return _hotspotList;
+}
+QList<Filter::HotSpot*> Filter::hotSpotsAtLine(int line) const
+{
+    return _hotspots.values(line);
+}
+
+Filter::HotSpot* Filter::hotSpotAt(int line , int column) const
+{
+    QListIterator<HotSpot*> spotIter(_hotspots.values(line));
+
+    while (spotIter.hasNext())
+    {
+        HotSpot* spot = spotIter.next();
+        
+        if ( spot->startLine() == line && spot->startColumn() > column )
+            continue;
+        if ( spot->endLine() == line && spot->endColumn() < column )
+            continue;
+       
+        return spot;
+    }
+
+    return 0;
+}
+
+Filter::HotSpot::HotSpot(int startLine , int startColumn , int endLine , int endColumn)
+    : _startLine(startLine)
+    , _startColumn(startColumn)
+    , _endLine(endLine)
+    , _endColumn(endColumn)
+    , _type(NotSpecified)
+{
+}
+QString Filter::HotSpot::tooltip() const
+{
+    return QString();
+}
+QList<QAction*> Filter::HotSpot::actions()
+{
+    return QList<QAction*>();
+}
+int Filter::HotSpot::startLine() const
+{
+    return _startLine;
+}
+int Filter::HotSpot::endLine() const
+{
+    return _endLine;
+}
+int Filter::HotSpot::startColumn() const
+{
+    return _startColumn;
+}
+int Filter::HotSpot::endColumn() const
+{
+    return _endColumn;
+}
+Filter::HotSpot::Type Filter::HotSpot::type() const
+{
+    return _type;
+}
+void Filter::HotSpot::setType(Type type)
+{
+    _type = type;
+}
+
+RegExpFilter::RegExpFilter()
+{
+}
+
+RegExpFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
+    : Filter::HotSpot(startLine,startColumn,endLine,endColumn)
+{
+    setType(Marker);
+}
+
+void RegExpFilter::HotSpot::activate(QObject*)
+{
+}
+
+void RegExpFilter::HotSpot::setCapturedTexts(const QStringList& texts)
+{
+    _capturedTexts = texts;
+}
+QStringList RegExpFilter::HotSpot::capturedTexts() const
+{
+    return _capturedTexts;
+}
+
+void RegExpFilter::setRegExp(const QRegExp& regExp) 
+{
+    _searchText = regExp;
+}
+QRegExp RegExpFilter::regExp() const
+{
+    return _searchText;
+}
+/*void RegExpFilter::reset(int)
+{
+    _buffer = QString();
+}*/
+void RegExpFilter::process()
+{
+    int pos = 0;
+    const QString* text = buffer();
+
+    Q_ASSERT( text );
+
+    // ignore any regular expressions which match an empty string.
+    // otherwise the while loop below will run indefinitely
+    static const QString emptyString("");
+    if ( _searchText.exactMatch(emptyString) )
+        return;
+
+    while(pos >= 0)
+    {
+        pos = _searchText.indexIn(*text,pos);
+
+        if ( pos >= 0 )
+        {
+            int startLine = 0;
+            int endLine = 0;
+            int startColumn = 0;
+            int endColumn = 0;
+
+            getLineColumn(pos,startLine,startColumn);
+            getLineColumn(pos + _searchText.matchedLength(),endLine,endColumn);
+
+            RegExpFilter::HotSpot* spot = newHotSpot(startLine,startColumn,
+                                           endLine,endColumn);
+            spot->setCapturedTexts(_searchText.capturedTexts());
+
+            addHotSpot( spot );  
+            pos += _searchText.matchedLength();
+
+            // if matchedLength == 0, the program will get stuck in an infinite loop
+            if ( _searchText.matchedLength() == 0 )
+                pos = -1;
+        }
+    }    
+}
+
+RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn,
+                                                int endLine,int endColumn)
+{
+    return new RegExpFilter::HotSpot(startLine,startColumn,
+                                                  endLine,endColumn);
+}
+RegExpFilter::HotSpot* UrlFilter::newHotSpot(int startLine,int startColumn,int endLine,
+                                                    int endColumn)
+{
+    return new UrlFilter::HotSpot(startLine,startColumn,
+                                               endLine,endColumn);
+}
+UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
+: RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn)
+, _urlObject(new FilterObject(this))
+{
+    setType(Link);
+}
+QString UrlFilter::HotSpot::tooltip() const
+{
+    QString url = capturedTexts().first();
+
+    const UrlType kind = urlType();
+
+    if ( kind == StandardUrl )
+        return QString(); 
+    else if ( kind == Email )
+        return QString(); 
+    else
+        return QString();
+}
+UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
+{
+    QString url = capturedTexts().first();
+    
+    if ( FullUrlRegExp.exactMatch(url) )
+        return StandardUrl;
+    else if ( EmailAddressRegExp.exactMatch(url) )
+        return Email;
+    else
+        return Unknown;
+}
+
+void UrlFilter::HotSpot::activate(QObject* object)
+{
+    QString url = capturedTexts().first();
+
+    const UrlType kind = urlType();
+
+    const QString& actionName = object ? object->objectName() : QString();
+
+    if ( actionName == "copy-action" )
+    {
+        QApplication::clipboard()->setText(url);
+        return;
+    }
+
+    if ( !object || actionName == "open-action" )
+    {
+        if ( kind == StandardUrl )
+        {
+            // if the URL path does not include the protocol ( eg. "www.kde.org" ) then
+            // prepend http:// ( eg. "www.kde.org" --> "http://www.kde.org" )
+            if (!url.contains("://"))
+            {
+                url.prepend("http://");
+            }
+        } 
+        else if ( kind == Email )
+        {
+            url.prepend("mailto:");
+        }
+    
+        //new KRun(url,QApplication::activeWindow());
+    }
+}
+
+// Note:  Altering these regular expressions can have a major effect on the performance of the filters 
+// used for finding URLs in the text, especially if they are very general and could match very long
+// pieces of text.
+// Please be careful when altering them.
+
+//regexp matches:
+// full url:  
+// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, comma and dot
+const QRegExp UrlFilter::FullUrlRegExp("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]");
+// email address:
+// [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
+const QRegExp UrlFilter::EmailAddressRegExp("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b");
+
+// matches full url or email address
+const QRegExp UrlFilter::CompleteUrlRegExp('('+FullUrlRegExp.pattern()+'|'+
+                                            EmailAddressRegExp.pattern()+')');
+
+UrlFilter::UrlFilter()
+{
+    setRegExp( CompleteUrlRegExp );
+}
+UrlFilter::HotSpot::~HotSpot()
+{
+    delete _urlObject;
+}
+void FilterObject::activated()
+{
+    _filter->activate(sender());
+}
+QList<QAction*> UrlFilter::HotSpot::actions()
+{
+    QList<QAction*> list;
+
+    const UrlType kind = urlType();
+
+    QAction* openAction = new QAction(_urlObject);
+    QAction* copyAction = new QAction(_urlObject);;
+
+    Q_ASSERT( kind == StandardUrl || kind == Email );
+
+    if ( kind == StandardUrl )
+    {
+        openAction->setText(i18n("Open Link"));
+        copyAction->setText(i18n("Copy Link Address"));
+    }
+    else if ( kind == Email )
+    {
+        openAction->setText(i18n("Send Email To..."));
+        copyAction->setText(i18n("Copy Email Address"));
+    }
+
+    // object names are set here so that the hotspot performs the
+    // correct action when activated() is called with the triggered
+    // action passed as a parameter.
+    openAction->setObjectName( QLatin1String("open-action" ));
+    copyAction->setObjectName( QLatin1String("copy-action" ));
+
+    QObject::connect( openAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
+    QObject::connect( copyAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
+
+    list << openAction;
+    list << copyAction;
+
+    return list; 
+}
+
+#include "Filter.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Filter.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,382 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef FILTER_H
+#define FILTER_H
+
+// Qt
+#include <QtGui/QAction>
+#include <QtCore/QList>
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QHash>
+#include <QtCore/QRegExp>
+
+// Local
+#include "Character.h"
+
+namespace Konsole
+{
+
+/**
+ * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
+ * and marks the areas which match the filter's patterns as 'hotspots'.
+ *
+ * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
+ * and an action.  When the user performs some activity such as a mouse-click in a hotspot area ( the exact
+ * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
+ * activate() method should be called.  Depending on the type of hotspot this will trigger a suitable response.
+ *
+ * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
+ * Hotspots may have more than one action, in which case the list of actions can be obtained using the 
+ * actions() method.
+ *
+ * Different subclasses of filter will return different types of hotspot.
+ * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
+ * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest
+ * and add them to the filter's list of hotspots using addHotSpot()
+ */
+class Filter
+{
+public:
+    /**
+    * Represents an area of text which matched the pattern a particular filter has been looking for.
+    *
+    * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
+    * and an action.  When the user performs some activity such as a mouse-click in a hotspot area ( the exact
+    * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
+    * activate() method should be called.  Depending on the type of hotspot this will trigger a suitable response.
+    *
+    * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
+    * Hotspots may have more than one action, in which case the list of actions can be obtained using the 
+    * actions() method.  These actions may then be displayed in a popup menu or toolbar for example. 
+    */
+    class HotSpot
+    {
+    public:
+       /** 
+        * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
+        * in a block of text.
+        */
+       HotSpot(int startLine , int startColumn , int endLine , int endColumn);
+       virtual ~HotSpot();
+
+       enum Type
+       {
+            // the type of the hotspot is not specified
+            NotSpecified,
+            // this hotspot represents a clickable link
+            Link,
+            // this hotspot represents a marker
+            Marker
+       }; 
+
+       /** Returns the line when the hotspot area starts */
+       int startLine() const;
+       /** Returns the line where the hotspot area ends */
+       int endLine() const;
+       /** Returns the column on startLine() where the hotspot area starts */
+       int startColumn() const;
+       /** Returns the column on endLine() where the hotspot area ends */
+       int endColumn() const;
+       /** 
+        * Returns the type of the hotspot.  This is usually used as a hint for views on how to represent
+        * the hotspot graphically.  eg.  Link hotspots are typically underlined when the user mouses over them
+        */
+       Type type() const;
+       /** 
+        * Causes the an action associated with a hotspot to be triggered. 
+        *
+        * @param object The object which caused the hotspot to be triggered.  This is
+        * typically null ( in which case the default action should be performed ) or
+        * one of the objects from the actions() list.  In which case the associated
+        * action should be performed. 
+        */
+       virtual void activate(QObject* object = 0) = 0; 
+       /** 
+        * Returns a list of actions associated with the hotspot which can be used in a 
+        * menu or toolbar 
+        */
+       virtual QList<QAction*> actions();
+
+       /** 
+        * Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or
+        * an empty string if there is no tooltip associated with this hotspot.
+        *
+        * The default implementation returns an empty string. 
+        */
+       virtual QString tooltip() const;
+
+    protected:
+       /** Sets the type of a hotspot.  This should only be set once */
+       void setType(Type type);
+
+    private:
+       int    _startLine;
+       int    _startColumn;
+       int    _endLine;
+       int    _endColumn;
+       Type _type;
+    
+    };
+
+    /** Constructs a new filter. */
+    Filter();
+    virtual ~Filter();
+
+    /** Causes the filter to process the block of text currently in its internal buffer */
+    virtual void process() = 0;
+
+    /** 
+     * Empties the filters internal buffer and resets the line count back to 0.
+     * All hotspots are deleted. 
+     */
+    void reset();
+
+    /** Adds a new line of text to the filter and increments the line count */
+    //void addLine(const QString& string);
+
+    /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */
+    HotSpot* hotSpotAt(int line , int column) const;
+
+    /** Returns the list of hotspots identified by the filter */
+    QList<HotSpot*> hotSpots() const;
+
+    /** Returns the list of hotspots identified by the filter which occur on a given line */
+    QList<HotSpot*> hotSpotsAtLine(int line) const;
+
+    /** 
+     * TODO: Document me
+     */
+    void setBuffer(const QString* buffer , const QList<int>* linePositions);
+
+protected:
+    /** Adds a new hotspot to the list */
+    void addHotSpot(HotSpot*);
+    /** Returns the internal buffer */
+    const QString* buffer();
+    /** Converts a character position within buffer() to a line and column */
+    void getLineColumn(int position , int& startLine , int& startColumn);
+
+private:
+    QMultiHash<int,HotSpot*> _hotspots;
+    QList<HotSpot*> _hotspotList;
+    
+    const QList<int>* _linePositions;
+    const QString* _buffer;
+};
+
+/** 
+ * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot 
+ * instance for them.
+ *
+ * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression
+ * are found. 
+ */
+class RegExpFilter : public Filter
+{
+public:
+    /** 
+     * Type of hotspot created by RegExpFilter.  The capturedTexts() method can be used to find the text
+     * matched by the filter's regular expression.
+     */
+    class HotSpot : public Filter::HotSpot
+    {
+    public:
+        HotSpot(int startLine, int startColumn, int endLine , int endColumn);
+        virtual void activate(QObject* object = 0);
+
+        /** Sets the captured texts associated with this hotspot */
+        void setCapturedTexts(const QStringList& texts);
+        /** Returns the texts found by the filter when matching the filter's regular expression */
+        QStringList capturedTexts() const;
+    private:
+        QStringList _capturedTexts;
+    };
+
+    /** Constructs a new regular expression filter */
+    RegExpFilter();
+
+    /** 
+     * Sets the regular expression which the filter searches for in blocks of text. 
+     *
+     * Regular expressions which match the empty string are treated as not matching
+     * anything. 
+     */
+    void setRegExp(const QRegExp& text);
+    /** Returns the regular expression which the filter searches for in blocks of text */
+    QRegExp regExp() const;
+
+    /** 
+     * Reimplemented to search the filter's text buffer for text matching regExp() 
+     *
+     * If regexp matches the empty string, then process() will return immediately
+     * without finding results. 
+     */
+    virtual void process();
+
+protected:
+    /** 
+     * Called when a match for the regular expression is encountered.  Subclasses should reimplement this
+     * to return custom hotspot types
+     */
+    virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn,
+                                    int endLine,int endColumn);
+
+private:
+    QRegExp _searchText;
+};
+
+class FilterObject;
+
+/** A filter which matches URLs in blocks of text */
+class UrlFilter : public RegExpFilter 
+{
+public:
+    /** 
+     * Hotspot type created by UrlFilter instances.  The activate() method opens a web browser 
+     * at the given URL when called.
+     */
+    class HotSpot : public RegExpFilter::HotSpot 
+    {
+    public:
+        HotSpot(int startLine,int startColumn,int endLine,int endColumn);
+        virtual ~HotSpot();
+
+        virtual QList<QAction*> actions();
+
+        /** 
+         * Open a web browser at the current URL.  The url itself can be determined using
+         * the capturedTexts() method.
+         */
+        virtual void activate(QObject* object = 0);
+
+        virtual QString tooltip() const;
+    private:
+        enum UrlType
+        {
+            StandardUrl,
+            Email,
+            Unknown
+        };
+        UrlType urlType() const;
+
+        FilterObject* _urlObject;
+    };
+
+    UrlFilter();
+
+protected:
+    virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int);
+
+private:
+    
+    static const QRegExp FullUrlRegExp;
+    static const QRegExp EmailAddressRegExp;
+
+    // combined OR of FullUrlRegExp and EmailAddressRegExp
+    static const QRegExp CompleteUrlRegExp; 
+};
+
+class FilterObject : public QObject
+{
+Q_OBJECT
+public:
+    FilterObject(Filter::HotSpot* filter) : _filter(filter) {}
+private slots:
+    void activated();
+private:
+    Filter::HotSpot* _filter;
+};
+
+/** 
+ * A chain which allows a group of filters to be processed as one. 
+ * The chain owns the filters added to it and deletes them when the chain itself is destroyed.
+ *
+ * Use addFilter() to add a new filter to the chain.  
+ * When new text to be filtered arrives, use addLine() to add each additional
+ * line of text which needs to be processed and then after adding the last line, use
+ * process() to cause each filter in the chain to process the text.
+ *
+ * After processing a block of text, the reset() method can be used to set the filter chain's
+ * internal cursor back to the first line.
+ *
+ * The hotSpotAt() method will return the first hotspot which covers a given position.
+ *
+ * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
+ * a given line respectively.
+ */
+class FilterChain : protected QList<Filter*>
+{
+public:
+    virtual ~FilterChain();
+
+    /** Adds a new filter to the chain.  The chain will delete this filter when it is destroyed */
+    void addFilter(Filter* filter);
+    /** Removes a filter from the chain.  The chain will no longer delete the filter when destroyed */
+    void removeFilter(Filter* filter);
+    /** Returns true if the chain contains @p filter */
+    bool containsFilter(Filter* filter);
+    /** Removes all filters from the chain */
+    void clear();
+
+    /** Resets each filter in the chain */
+    void reset();
+    /**
+     * Processes each filter in the chain 
+     */
+    void process();
+
+    /** Sets the buffer for each filter in the chain to process. */
+    void setBuffer(const QString* buffer , const QList<int>* linePositions); 
+
+    /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
+    Filter::HotSpot* hotSpotAt(int line , int column) const;
+    /** Returns a list of all the hotspots in all the chain's filters */
+    QList<Filter::HotSpot*> hotSpots() const;
+    /** Returns a list of all hotspots at the given line in all the chain's filters */
+    QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
+
+};
+
+/** A filter chain which processes character images from terminal displays */
+class TerminalImageFilterChain : public FilterChain
+{
+public:
+    TerminalImageFilterChain();
+    virtual ~TerminalImageFilterChain();
+
+    /**
+     * Set the current terminal image to @p image.
+     *
+     * @param image The terminal image
+     * @param lines The number of lines in the terminal image
+     * @param columns The number of columns in the terminal image
+     * @param lineProperties The line properties to set for image
+     */
+    void setImage(const Character* const image , int lines , int columns,
+                  const QVector<LineProperty>& lineProperties);  
+
+private:
+    QString* _buffer;
+    QList<int>* _linePositions;
+};
+
+}
+#endif //FILTER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/History.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,987 @@
+/*
+    This file is part of Konsole, an X terminal.
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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 "History.h"
+
+// System
+#include <iostream>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+
+// KDE
+//#include <kde_file.h>
+//#include <kdebug.h>
+
+// Reasonable line size
+#define LINE_SIZE    1024
+
+using namespace Konsole;
+
+/*
+   An arbitrary long scroll.
+
+   One can modify the scroll only by adding either cells
+   or newlines, but access it randomly.
+
+   The model is that of an arbitrary wide typewriter scroll
+   in that the scroll is a serie of lines and each line is
+   a serie of cells with no overwriting permitted.
+
+   The implementation provides arbitrary length and numbers
+   of cells and line/column indexed read access to the scroll
+   at constant costs.
+
+KDE4: Can we use QTemporaryFile here, instead of KTempFile?
+
+FIXME: some complain about the history buffer comsuming the
+       memory of their machines. This problem is critical
+       since the history does not behave gracefully in cases
+       where the memory is used up completely.
+
+       I put in a workaround that should handle it problem
+       now gracefully. I'm not satisfied with the solution.
+
+FIXME: Terminating the history is not properly indicated
+       in the menu. We should throw a signal.
+
+FIXME: There is noticeable decrease in speed, also. Perhaps,
+       there whole feature needs to be revisited therefore.
+       Disadvantage of a more elaborated, say block-oriented
+       scheme with wrap around would be it's complexity.
+*/
+
+//FIXME: tempory replacement for tmpfile
+//       this is here one for debugging purpose.
+
+//#define tmpfile xTmpFile
+
+// History File ///////////////////////////////////////////
+
+/*
+  A Row(X) data type which allows adding elements to the end.
+*/
+
+HistoryFile::HistoryFile()
+  : ion(-1),
+    length(0),
+    fileMap(0)
+{
+  if (tmpFile.open())
+  { 
+    tmpFile.setAutoRemove(true);
+    ion = tmpFile.handle();
+  }
+}
+
+HistoryFile::~HistoryFile()
+{
+    if (fileMap)
+        unmap();
+}
+
+//TODO:  Mapping the entire file in will cause problems if the history file becomes exceedingly large,
+//(ie. larger than available memory).  HistoryFile::map() should only map in sections of the file at a time,
+//to avoid this.
+void HistoryFile::map()
+{
+    assert( fileMap == 0 );
+
+    fileMap = (char*)mmap( 0 , length , PROT_READ , MAP_PRIVATE , ion , 0 );
+
+    //if mmap'ing fails, fall back to the read-lseek combination
+    if ( fileMap == MAP_FAILED )
+    {
+            readWriteBalance = 0; 
+            fileMap = 0;
+            //kWarning() << k_funcinfo << ": mmap'ing history failed.  errno = " << errno;
+	    kWarning() << ": mmap'ing history failed.  errno = " << errno;
+    }
+}
+
+void HistoryFile::unmap()
+{
+    int result = munmap( fileMap , length );
+    assert( result == 0 ); Q_UNUSED( result );
+
+    fileMap = 0;
+}
+
+bool HistoryFile::isMapped()
+{
+    return (fileMap != 0);
+}
+
+void HistoryFile::add(const unsigned char* bytes, int len)
+{
+  if ( fileMap )
+          unmap();
+        
+  readWriteBalance++;
+
+  int rc = 0;
+
+  //rc = KDE_lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryFile::add.seek"); return; }
+  rc = ::lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryFile::add.seek"); return; }
+  rc = write(ion,bytes,len);       if (rc < 0) { perror("HistoryFile::add.write"); return; }
+  length += rc;
+}
+
+void HistoryFile::get(unsigned char* bytes, int len, int loc)
+{
+  //count number of get() calls vs. number of add() calls.  
+  //If there are many more get() calls compared with add() 
+  //calls (decided by using MAP_THRESHOLD) then mmap the log
+  //file to improve performance.
+  readWriteBalance--;
+  if ( !fileMap && readWriteBalance < MAP_THRESHOLD )
+          map();
+
+  if ( fileMap )
+  {
+    for (int i=0;i<len;i++)
+            bytes[i]=fileMap[loc+i];
+  }
+  else
+  {    
+      int rc = 0;
+
+      if (loc < 0 || len < 0 || loc + len > length)
+        fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
+      //rc = KDE_lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryFile::get.seek"); return; }
+      rc = ::lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryFile::get.seek"); return; }
+      rc = read(ion,bytes,len);     if (rc < 0) { perror("HistoryFile::get.read"); return; }
+  }
+}
+
+int HistoryFile::len()
+{
+  return length;
+}
+
+
+// History Scroll abstract base class //////////////////////////////////////
+
+
+HistoryScroll::HistoryScroll(HistoryType* t)
+  : m_histType(t)
+{
+}
+
+HistoryScroll::~HistoryScroll()
+{
+  delete m_histType;
+}
+
+bool HistoryScroll::hasScroll()
+{
+  return true;
+}
+
+// History Scroll File //////////////////////////////////////
+
+/* 
+   The history scroll makes a Row(Row(Cell)) from
+   two history buffers. The index buffer contains
+   start of line positions which refere to the cells
+   buffer.
+
+   Note that index[0] addresses the second line
+   (line #1), while the first line (line #0) starts
+   at 0 in cells.
+*/
+
+HistoryScrollFile::HistoryScrollFile(const QString &logFileName)
+  : HistoryScroll(new HistoryTypeFile(logFileName)),
+  m_logFileName(logFileName)
+{
+}
+
+HistoryScrollFile::~HistoryScrollFile()
+{
+}
+ 
+int HistoryScrollFile::getLines()
+{
+  return index.len() / sizeof(int);
+}
+
+int HistoryScrollFile::getLineLen(int lineno)
+{
+  return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(Character);
+}
+
+bool HistoryScrollFile::isWrappedLine(int lineno)
+{
+  if (lineno>=0 && lineno <= getLines()) {
+    unsigned char flag;
+    lineflags.get((unsigned char*)&flag,sizeof(unsigned char),(lineno)*sizeof(unsigned char));
+    return flag;
+  }
+  return false;
+}
+
+int HistoryScrollFile::startOfLine(int lineno)
+{
+  if (lineno <= 0) return 0;
+  if (lineno <= getLines())
+    { 
+    
+    if (!index.isMapped())
+            index.map();
+    
+    int res;
+    index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
+    return res;
+    }
+  return cells.len();
+}
+
+void HistoryScrollFile::getCells(int lineno, int colno, int count, Character res[])
+{
+  cells.get((unsigned char*)res,count*sizeof(Character),startOfLine(lineno)+colno*sizeof(Character));
+}
+
+void HistoryScrollFile::addCells(const Character text[], int count)
+{
+  cells.add((unsigned char*)text,count*sizeof(Character));
+}
+
+void HistoryScrollFile::addLine(bool previousWrapped)
+{
+  if (index.isMapped())
+          index.unmap();
+
+  int locn = cells.len();
+  index.add((unsigned char*)&locn,sizeof(int));
+  unsigned char flags = previousWrapped ? 0x01 : 0x00;
+  lineflags.add((unsigned char*)&flags,sizeof(unsigned char));
+}
+
+
+// History Scroll Buffer //////////////////////////////////////
+HistoryScrollBuffer::HistoryScrollBuffer(unsigned int maxLineCount)
+  : HistoryScroll(new HistoryTypeBuffer(maxLineCount))
+   ,_historyBuffer()
+   ,_maxLineCount(0)
+   ,_usedLines(0)
+   ,_head(0)
+{
+  setMaxNbLines(maxLineCount);
+}
+
+HistoryScrollBuffer::~HistoryScrollBuffer()
+{
+    delete[] _historyBuffer;
+}
+
+void HistoryScrollBuffer::addCellsVector(const QVector<Character>& cells)
+{
+    _head++;
+    if ( _usedLines < _maxLineCount )
+        _usedLines++;
+
+    if ( _head >= _maxLineCount )
+    {
+        _head = 0;
+    }
+
+    _historyBuffer[bufferIndex(_usedLines-1)] = cells;
+    _wrappedLine[bufferIndex(_usedLines-1)] = false;
+}
+void HistoryScrollBuffer::addCells(const Character a[], int count)
+{
+  HistoryLine newLine(count);
+  qCopy(a,a+count,newLine.begin());
+
+  addCellsVector(newLine);
+}
+
+void HistoryScrollBuffer::addLine(bool previousWrapped)
+{
+    _wrappedLine[bufferIndex(_usedLines-1)] = previousWrapped;
+}
+
+int HistoryScrollBuffer::getLines()
+{
+    return _usedLines;
+}
+
+int HistoryScrollBuffer::getLineLen(int lineNumber)
+{
+  Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
+
+  if ( lineNumber < _usedLines )
+  {
+    return _historyBuffer[bufferIndex(lineNumber)].size();
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+bool HistoryScrollBuffer::isWrappedLine(int lineNumber)
+{
+  Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
+    
+  if (lineNumber < _usedLines)
+  {
+    //kDebug() << "Line" << lineNumber << "wrapped is" << _wrappedLine[bufferIndex(lineNumber)];
+    return _wrappedLine[bufferIndex(lineNumber)];
+  }
+  else
+    return false;
+}
+
+void HistoryScrollBuffer::getCells(int lineNumber, int startColumn, int count, Character buffer[])
+{
+  if ( count == 0 ) return;
+
+  Q_ASSERT( lineNumber < _maxLineCount );
+
+  if (lineNumber >= _usedLines) 
+  {
+    memset(buffer, 0, count * sizeof(Character));
+    return;
+  }
+  
+  const HistoryLine& line = _historyBuffer[bufferIndex(lineNumber)];
+
+  //kDebug() << "startCol " << startColumn;
+  //kDebug() << "line.size() " << line.size();
+  //kDebug() << "count " << count;
+
+  Q_ASSERT( startColumn <= line.size() - count );
+    
+  memcpy(buffer, line.constData() + startColumn , count * sizeof(Character));
+}
+
+void HistoryScrollBuffer::setMaxNbLines(unsigned int lineCount)
+{
+    HistoryLine* oldBuffer = _historyBuffer;
+    HistoryLine* newBuffer = new HistoryLine[lineCount];
+    
+    for ( int i = 0 ; i < qMin(_usedLines,(int)lineCount) ; i++ )
+    {
+        newBuffer[i] = oldBuffer[bufferIndex(i)];
+    }
+    
+    _usedLines = qMin(_usedLines,(int)lineCount);
+    _maxLineCount = lineCount;
+    _head = ( _usedLines == _maxLineCount ) ? 0 : _usedLines-1;
+
+    _historyBuffer = newBuffer;
+    delete[] oldBuffer;
+
+    _wrappedLine.resize(lineCount);
+    dynamic_cast<HistoryTypeBuffer*>(m_histType)->m_nbLines = lineCount;
+}
+
+int HistoryScrollBuffer::bufferIndex(int lineNumber)
+{
+    Q_ASSERT( lineNumber >= 0 );
+    Q_ASSERT( lineNumber < _maxLineCount );
+    Q_ASSERT( (_usedLines == _maxLineCount) || lineNumber <= _head );
+
+    if ( _usedLines == _maxLineCount )
+    {
+        return (_head+lineNumber+1) % _maxLineCount;
+    }
+    else
+    {   
+        return lineNumber;
+    }
+}
+
+
+// History Scroll None //////////////////////////////////////
+
+HistoryScrollNone::HistoryScrollNone()
+  : HistoryScroll(new HistoryTypeNone())
+{
+}
+
+HistoryScrollNone::~HistoryScrollNone()
+{
+}
+
+bool HistoryScrollNone::hasScroll()
+{
+  return false;
+}
+
+int  HistoryScrollNone::getLines()
+{
+  return 0;
+}
+
+int  HistoryScrollNone::getLineLen(int)
+{
+  return 0;
+}
+
+bool HistoryScrollNone::isWrappedLine(int /*lineno*/)
+{
+  return false;
+}
+
+void HistoryScrollNone::getCells(int, int, int, Character [])
+{
+}
+
+void HistoryScrollNone::addCells(const Character [], int)
+{
+}
+
+void HistoryScrollNone::addLine(bool)
+{
+}
+
+// History Scroll BlockArray //////////////////////////////////////
+
+HistoryScrollBlockArray::HistoryScrollBlockArray(size_t size)
+  : HistoryScroll(new HistoryTypeBlockArray(size))
+{
+  m_blockArray.setHistorySize(size); // nb. of lines.
+}
+
+HistoryScrollBlockArray::~HistoryScrollBlockArray()
+{
+}
+
+int  HistoryScrollBlockArray::getLines()
+{
+  return m_lineLengths.count();
+}
+
+int  HistoryScrollBlockArray::getLineLen(int lineno)
+{
+    if ( m_lineLengths.contains(lineno) )
+        return m_lineLengths[lineno];
+    else
+        return 0;
+}
+
+bool HistoryScrollBlockArray::isWrappedLine(int /*lineno*/)
+{
+  return false;
+}
+
+void HistoryScrollBlockArray::getCells(int lineno, int colno,
+                                       int count, Character res[])
+{
+  if (!count) return;
+
+  const Block *b = m_blockArray.at(lineno);
+
+  if (!b) {
+    memset(res, 0, count * sizeof(Character)); // still better than random data
+    return;
+  }
+
+  assert(((colno + count) * sizeof(Character)) < ENTRIES);
+  memcpy(res, b->data + (colno * sizeof(Character)), count * sizeof(Character));
+}
+
+void HistoryScrollBlockArray::addCells(const Character a[], int count)
+{
+  Block *b = m_blockArray.lastBlock();
+  
+  if (!b) return;
+
+  // put cells in block's data
+  assert((count * sizeof(Character)) < ENTRIES);
+
+  memset(b->data, 0, ENTRIES);
+
+  memcpy(b->data, a, count * sizeof(Character));
+  b->size = count * sizeof(Character);
+
+  size_t res = m_blockArray.newBlock();
+  assert (res > 0);
+  Q_UNUSED( res );
+
+  m_lineLengths.insert(m_blockArray.getCurrent(), count);
+}
+
+void HistoryScrollBlockArray::addLine(bool)
+{
+}
+
+////////////////////////////////////////////////////////////////
+// Compact History Scroll //////////////////////////////////////
+////////////////////////////////////////////////////////////////
+void* CompactHistoryBlock::allocate ( size_t length )
+{
+ Q_ASSERT ( length > 0 );
+  if ( tail-blockStart+length > blockLength )
+    return NULL;
+
+  void* block = tail;
+  tail += length;
+  //kDebug() << "allocated " << length << " bytes at address " << block;
+  allocCount++;
+  return block;
+}
+
+void CompactHistoryBlock::deallocate ( )
+{
+  allocCount--;
+  Q_ASSERT ( allocCount >= 0 );
+}
+
+void* CompactHistoryBlockList::allocate(size_t size)
+{
+  CompactHistoryBlock* block;
+  if ( list.isEmpty() || list.last()->remaining() < size)
+  {
+    block = new CompactHistoryBlock();
+    list.append ( block );
+    //kDebug() << "new block created, remaining " << block->remaining() << "number of blocks=" << list.size();
+  }
+  else
+  {
+    block = list.last();
+    //kDebug() << "old block used, remaining " << block->remaining();
+  }
+  return block->allocate(size);
+}
+
+void CompactHistoryBlockList::deallocate(void* ptr)
+{
+  Q_ASSERT( !list.isEmpty());
+  
+  int i=0;  
+  CompactHistoryBlock *block = list.at(i);
+  while ( i<list.size() && !block->contains(ptr) )
+  { 
+    i++;
+    block=list.at(i);
+  }
+
+  Q_ASSERT( i<list.size() );
+  
+  block->deallocate();
+
+  if (!block->isInUse())
+  {
+    list.removeAt(i);
+    delete block;
+    //kDebug() << "block deleted, new size = " << list.size();
+  }
+}
+
+CompactHistoryBlockList::~CompactHistoryBlockList()
+{
+  qDeleteAll ( list.begin(), list.end() );
+  list.clear();
+}
+
+void* CompactHistoryLine::operator new (size_t size, CompactHistoryBlockList& blockList)
+{
+  return blockList.allocate(size);
+}
+
+CompactHistoryLine::CompactHistoryLine ( const TextLine& line, CompactHistoryBlockList& bList ) 
+  : blockList(bList),
+    formatLength(0)
+{
+  length=line.size();
+      
+  if (line.size() > 0) {
+    formatLength=1;
+    int k=1;
+  
+    // count number of different formats in this text line
+    Character c = line[0];
+    while ( k<length )
+    {
+      if ( !(line[k].equalsFormat(c)))
+      {
+        formatLength++; // format change detected
+        c=line[k];
+      }
+      k++;
+    }
+  
+    //kDebug() << "number of different formats in string: " << formatLength;
+    formatArray = (CharacterFormat*) blockList.allocate(sizeof(CharacterFormat)*formatLength);
+    Q_ASSERT (formatArray!=NULL);
+    text = (quint16*) blockList.allocate(sizeof(quint16)*line.size());
+    Q_ASSERT (text!=NULL);
+  
+    length=line.size();
+    formatLength=formatLength;
+    wrapped=false;
+  
+    // record formats and their positions in the format array
+    c=line[0];
+    formatArray[0].setFormat ( c );
+    formatArray[0].startPos=0;                        // there's always at least 1 format (for the entire line, unless a change happens)
+  
+    k=1;                                              // look for possible format changes
+    int j=1;
+    while ( k<length && j<formatLength )
+    {
+      if (!(line[k].equalsFormat(c)))
+      {
+        c=line[k];
+        formatArray[j].setFormat(c);
+        formatArray[j].startPos=k;
+        //kDebug() << "format entry " << j << " at pos " << formatArray[j].startPos << " " << &(formatArray[j].startPos) ;
+        j++;
+      }
+      k++;
+    }
+  
+    // copy character values
+    for ( int i=0; i<line.size(); i++ )
+    {
+      text[i]=line[i].character;
+      //kDebug() << "char " << i << " at mem " << &(text[i]);
+    }
+  }
+  //kDebug() << "line created, length " << length << " at " << &(length);
+}
+
+CompactHistoryLine::~CompactHistoryLine()
+{
+  //kDebug() << "~CHL";
+  if (length>0) {
+    blockList.deallocate(text);
+    blockList.deallocate(formatArray);
+  }
+  blockList.deallocate(this);  
+}
+
+void CompactHistoryLine::getCharacter ( int index, Character &r )
+{
+  Q_ASSERT ( index < length );
+  int formatPos=0;
+  while ( ( formatPos+1 ) < formatLength && index >= formatArray[formatPos+1].startPos )
+    formatPos++;
+
+  r.character=text[index];
+  r.rendition = formatArray[formatPos].rendition;
+  r.foregroundColor = formatArray[formatPos].fgColor;
+  r.backgroundColor = formatArray[formatPos].bgColor;
+}
+
+void CompactHistoryLine::getCharacters ( Character* array, int length, int startColumn )
+{
+  Q_ASSERT ( startColumn >= 0 && length >= 0 );
+  Q_ASSERT ( startColumn+length <= ( int ) getLength() );
+
+  for ( int i=startColumn; i<length+startColumn; i++ )
+  {
+    getCharacter ( i, array[i-startColumn] );
+  }
+}
+
+CompactHistoryScroll::CompactHistoryScroll ( unsigned int maxLineCount )
+    : HistoryScroll ( new CompactHistoryType ( maxLineCount ) )
+    ,lines()
+    ,blockList()
+{
+  //kDebug() << "scroll of length " << maxLineCount << " created";
+  setMaxNbLines ( maxLineCount );
+}
+
+CompactHistoryScroll::~CompactHistoryScroll()
+{
+  qDeleteAll ( lines.begin(), lines.end() );
+  lines.clear();
+}
+
+void CompactHistoryScroll::addCellsVector ( const TextLine& cells )
+{
+  CompactHistoryLine *line;
+  line = new(blockList) CompactHistoryLine ( cells, blockList );
+
+  if ( lines.size() > ( int ) _maxLineCount )
+  {
+    delete lines.takeAt ( 0 );
+  }
+  lines.append ( line );
+}
+
+void CompactHistoryScroll::addCells ( const Character a[], int count )
+{
+  TextLine newLine ( count );
+  qCopy ( a,a+count,newLine.begin() );
+  addCellsVector ( newLine );
+}
+
+void CompactHistoryScroll::addLine ( bool previousWrapped )
+{
+  CompactHistoryLine *line = lines.last();
+  //kDebug() << "last line at address " << line;
+  line->setWrapped(previousWrapped);
+}
+
+int CompactHistoryScroll::getLines()
+{
+  return lines.size();
+}
+
+int CompactHistoryScroll::getLineLen ( int lineNumber )
+{
+  Q_ASSERT ( lineNumber >= 0 && lineNumber < lines.size() );
+  CompactHistoryLine* line = lines[lineNumber];
+  //kDebug() << "request for line at address " << line;
+  return line->getLength();
+}
+
+
+void CompactHistoryScroll::getCells ( int lineNumber, int startColumn, int count, Character buffer[] )
+{
+  if ( count == 0 ) return;
+  Q_ASSERT ( lineNumber < lines.size() );
+  CompactHistoryLine* line = lines[lineNumber];
+  Q_ASSERT ( startColumn >= 0 );
+  Q_ASSERT ( (unsigned int)startColumn <= line->getLength() - count );
+  line->getCharacters ( buffer, count, startColumn );
+}
+
+void CompactHistoryScroll::setMaxNbLines ( unsigned int lineCount )
+{
+  _maxLineCount = lineCount;
+
+  while (lines.size() > (int) lineCount) {
+    delete lines.takeAt(0);
+  }
+  //kDebug() << "set max lines to: " << _maxLineCount;
+}
+
+bool CompactHistoryScroll::isWrappedLine ( int lineNumber )
+{
+  Q_ASSERT ( lineNumber < lines.size() );
+  return lines[lineNumber]->isWrapped();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// History Types
+//////////////////////////////////////////////////////////////////////
+
+HistoryType::HistoryType()
+{
+}
+
+HistoryType::~HistoryType()
+{
+}
+
+//////////////////////////////
+
+HistoryTypeNone::HistoryTypeNone()
+{
+}
+
+bool HistoryTypeNone::isEnabled() const
+{
+  return false;
+}
+
+HistoryScroll* HistoryTypeNone::scroll(HistoryScroll *old) const
+{
+  delete old;
+  return new HistoryScrollNone();
+}
+
+int HistoryTypeNone::maximumLineCount() const
+{
+  return 0;
+}
+
+//////////////////////////////
+
+HistoryTypeBlockArray::HistoryTypeBlockArray(size_t size)
+  : m_size(size)
+{
+}
+
+bool HistoryTypeBlockArray::isEnabled() const
+{
+  return true;
+}
+
+int HistoryTypeBlockArray::maximumLineCount() const
+{
+  return m_size;
+}
+
+HistoryScroll* HistoryTypeBlockArray::scroll(HistoryScroll *old) const
+{
+  delete old;
+  return new HistoryScrollBlockArray(m_size);
+}
+
+
+//////////////////////////////
+
+HistoryTypeBuffer::HistoryTypeBuffer(unsigned int nbLines)
+  : m_nbLines(nbLines)
+{
+}
+
+bool HistoryTypeBuffer::isEnabled() const
+{
+  return true;
+}
+
+int HistoryTypeBuffer::maximumLineCount() const
+{
+  return m_nbLines;
+}
+
+HistoryScroll* HistoryTypeBuffer::scroll(HistoryScroll *old) const
+{
+  if (old)
+  {
+    HistoryScrollBuffer *oldBuffer = dynamic_cast<HistoryScrollBuffer*>(old);
+    if (oldBuffer)
+    {
+       oldBuffer->setMaxNbLines(m_nbLines);
+       return oldBuffer;
+    }
+
+    HistoryScroll *newScroll = new HistoryScrollBuffer(m_nbLines);
+    int lines = old->getLines();
+    int startLine = 0;
+    if (lines > (int) m_nbLines)
+       startLine = lines - m_nbLines;
+
+    Character line[LINE_SIZE];
+    for(int i = startLine; i < lines; i++)
+    {
+       int size = old->getLineLen(i);
+       if (size > LINE_SIZE)
+       {
+          Character *tmp_line = new Character[size];
+          old->getCells(i, 0, size, tmp_line);
+          newScroll->addCells(tmp_line, size);
+          newScroll->addLine(old->isWrappedLine(i));
+          delete [] tmp_line;
+       }
+       else
+       {
+          old->getCells(i, 0, size, line);
+          newScroll->addCells(line, size);
+          newScroll->addLine(old->isWrappedLine(i));
+       }
+    }
+    delete old;
+    return newScroll;
+  }
+  return new HistoryScrollBuffer(m_nbLines);
+}
+
+//////////////////////////////
+
+HistoryTypeFile::HistoryTypeFile(const QString& fileName)
+  : m_fileName(fileName)
+{
+}
+
+bool HistoryTypeFile::isEnabled() const
+{
+  return true;
+}
+
+const QString& HistoryTypeFile::getFileName() const
+{
+  return m_fileName;
+}
+
+HistoryScroll* HistoryTypeFile::scroll(HistoryScroll *old) const
+{
+  if (dynamic_cast<HistoryFile *>(old)) 
+     return old; // Unchanged.
+
+  HistoryScroll *newScroll = new HistoryScrollFile(m_fileName);
+
+  Character line[LINE_SIZE];
+  int lines = (old != 0) ? old->getLines() : 0;
+  for(int i = 0; i < lines; i++)
+  {
+     int size = old->getLineLen(i);
+     if (size > LINE_SIZE)
+     {
+        Character *tmp_line = new Character[size];
+        old->getCells(i, 0, size, tmp_line);
+        newScroll->addCells(tmp_line, size);
+        newScroll->addLine(old->isWrappedLine(i));
+        delete [] tmp_line;
+     }
+     else
+     {
+        old->getCells(i, 0, size, line);
+        newScroll->addCells(line, size);
+        newScroll->addLine(old->isWrappedLine(i));
+     }
+  }
+
+  delete old;
+  return newScroll; 
+}
+
+int HistoryTypeFile::maximumLineCount() const
+{
+  return 0;
+}
+
+//////////////////////////////
+
+CompactHistoryType::CompactHistoryType ( unsigned int nbLines )
+    : m_nbLines ( nbLines )
+{
+}
+
+bool CompactHistoryType::isEnabled() const
+{
+  return true;
+}
+
+int CompactHistoryType::maximumLineCount() const
+{
+  return m_nbLines;
+}
+
+HistoryScroll* CompactHistoryType::scroll ( HistoryScroll *old ) const
+{
+  if ( old )
+  {
+    CompactHistoryScroll *oldBuffer = dynamic_cast<CompactHistoryScroll*> ( old );
+    if ( oldBuffer )
+    {
+      oldBuffer->setMaxNbLines ( m_nbLines );
+      return oldBuffer;
+    }
+    delete old;
+  }
+  return new CompactHistoryScroll ( m_nbLines );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/History.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,494 @@
+/*
+    This file is part of Konsole, an X terminal.
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef TEHISTORY_H
+#define TEHISTORY_H
+
+// Qt
+#include <QtCore/QBitRef>
+#include <QtCore/QHash>
+#include <QtCore/QVector>
+#include <QtCore/QTemporaryFile>
+
+// KDE
+//#include <ktemporaryfile.h>
+
+// Konsole
+#include "konsole_export.h"
+#include "BlockArray.h"
+#include "Character.h"
+
+// map
+#include <sys/mman.h>
+
+namespace Konsole
+{
+
+#if 1
+/*
+   An extendable tmpfile(1) based buffer.
+*/
+
+class HistoryFile
+{
+public:
+  HistoryFile();
+  virtual ~HistoryFile();
+
+  virtual void add(const unsigned char* bytes, int len);
+  virtual void get(unsigned char* bytes, int len, int loc);
+  virtual int  len();
+
+  //mmaps the file in read-only mode
+  void map();
+  //un-mmaps the file
+  void unmap();
+  //returns true if the file is mmap'ed
+  bool isMapped();
+
+
+private:
+  int  ion;
+  int  length;
+  QTemporaryFile tmpFile;
+
+  //pointer to start of mmap'ed file data, or 0 if the file is not mmap'ed
+  char* fileMap;
+ 
+  //incremented whenver 'add' is called and decremented whenever
+  //'get' is called.
+  //this is used to detect when a large number of lines are being read and processed from the history
+  //and automatically mmap the file for better performance (saves the overhead of many lseek-read calls).
+  int readWriteBalance;
+
+  //when readWriteBalance goes below this threshold, the file will be mmap'ed automatically
+  static const int MAP_THRESHOLD = -1000;
+};
+#endif
+
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+// Abstract base class for file and buffer versions
+//////////////////////////////////////////////////////////////////////
+class HistoryType;
+
+class HistoryScroll
+{
+public:
+  HistoryScroll(HistoryType*);
+ virtual ~HistoryScroll();
+
+  virtual bool hasScroll();
+
+  // access to history
+  virtual int  getLines() = 0;
+  virtual int  getLineLen(int lineno) = 0;
+  virtual void getCells(int lineno, int colno, int count, Character res[]) = 0;
+  virtual bool isWrappedLine(int lineno) = 0;
+
+  // backward compatibility (obsolete)
+  Character   getCell(int lineno, int colno) { Character res; getCells(lineno,colno,1,&res); return res; }
+
+  // adding lines.
+  virtual void addCells(const Character a[], int count) = 0;
+  // convenience method - this is virtual so that subclasses can take advantage
+  // of QVector's implicit copying
+  virtual void addCellsVector(const QVector<Character>& cells)
+  {
+    addCells(cells.data(),cells.size());
+  }
+
+  virtual void addLine(bool previousWrapped=false) = 0;
+
+  //
+  // FIXME:  Passing around constant references to HistoryType instances
+  // is very unsafe, because those references will no longer
+  // be valid if the history scroll is deleted.
+  //
+  const HistoryType& getType() { return *m_histType; }
+
+protected:
+  HistoryType* m_histType;
+
+};
+
+#if 1
+
+//////////////////////////////////////////////////////////////////////
+// File-based history (e.g. file log, no limitation in length)
+//////////////////////////////////////////////////////////////////////
+
+class HistoryScrollFile : public HistoryScroll
+{
+public:
+  HistoryScrollFile(const QString &logFileName);
+  virtual ~HistoryScrollFile();
+
+  virtual int  getLines();
+  virtual int  getLineLen(int lineno);
+  virtual void getCells(int lineno, int colno, int count, Character res[]);
+  virtual bool isWrappedLine(int lineno);
+
+  virtual void addCells(const Character a[], int count);
+  virtual void addLine(bool previousWrapped=false);
+
+private:
+  int startOfLine(int lineno);
+
+  QString m_logFileName;
+  HistoryFile index; // lines Row(int)
+  HistoryFile cells; // text  Row(Character)
+  HistoryFile lineflags; // flags Row(unsigned char)
+};
+
+
+//////////////////////////////////////////////////////////////////////
+// Buffer-based history (limited to a fixed nb of lines)
+//////////////////////////////////////////////////////////////////////
+class HistoryScrollBuffer : public HistoryScroll
+{
+public:
+  typedef QVector<Character> HistoryLine;
+
+  HistoryScrollBuffer(unsigned int maxNbLines = 1000);
+  virtual ~HistoryScrollBuffer();
+
+  virtual int  getLines();
+  virtual int  getLineLen(int lineno);
+  virtual void getCells(int lineno, int colno, int count, Character res[]);
+  virtual bool isWrappedLine(int lineno);
+
+  virtual void addCells(const Character a[], int count);
+  virtual void addCellsVector(const QVector<Character>& cells);
+  virtual void addLine(bool previousWrapped=false);
+
+  void setMaxNbLines(unsigned int nbLines);
+  unsigned int maxNbLines() { return _maxLineCount; }
+  
+
+private:
+  int bufferIndex(int lineNumber);
+
+  HistoryLine* _historyBuffer;
+  QBitArray _wrappedLine;
+  int _maxLineCount;
+  int _usedLines;  
+  int _head;
+  
+  //QVector<histline*> m_histBuffer;
+  //QBitArray m_wrappedLine;
+  //unsigned int m_maxNbLines;
+  //unsigned int m_nbLines;
+  //unsigned int m_arrayIndex;
+  //bool         m_buffFilled;
+};
+
+/*class HistoryScrollBufferV2 : public HistoryScroll
+{
+public:
+  virtual int  getLines();
+  virtual int  getLineLen(int lineno);
+  virtual void getCells(int lineno, int colno, int count, Character res[]);
+  virtual bool isWrappedLine(int lineno);
+
+  virtual void addCells(const Character a[], int count);
+  virtual void addCells(const QVector<Character>& cells);
+  virtual void addLine(bool previousWrapped=false);
+
+};*/
+
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Nothing-based history (no history :-)
+//////////////////////////////////////////////////////////////////////
+class HistoryScrollNone : public HistoryScroll
+{
+public:
+  HistoryScrollNone();
+  virtual ~HistoryScrollNone();
+
+  virtual bool hasScroll();
+
+  virtual int  getLines();
+  virtual int  getLineLen(int lineno);
+  virtual void getCells(int lineno, int colno, int count, Character res[]);
+  virtual bool isWrappedLine(int lineno);
+
+  virtual void addCells(const Character a[], int count);
+  virtual void addLine(bool previousWrapped=false);
+};
+
+//////////////////////////////////////////////////////////////////////
+// BlockArray-based history
+//////////////////////////////////////////////////////////////////////
+class HistoryScrollBlockArray : public HistoryScroll
+{
+public:
+  HistoryScrollBlockArray(size_t size);
+  virtual ~HistoryScrollBlockArray();
+
+  virtual int  getLines();
+  virtual int  getLineLen(int lineno);
+  virtual void getCells(int lineno, int colno, int count, Character res[]);
+  virtual bool isWrappedLine(int lineno);
+
+  virtual void addCells(const Character a[], int count);
+  virtual void addLine(bool previousWrapped=false);
+
+protected:
+  BlockArray m_blockArray;
+  QHash<int,size_t> m_lineLengths;
+};
+
+//////////////////////////////////////////////////////////////////////
+// History using compact storage
+// This implementation uses a list of fixed-sized blocks
+// where history lines are allocated in (avoids heap fragmentation)
+//////////////////////////////////////////////////////////////////////
+typedef QVector<Character> TextLine;
+
+class CharacterFormat
+{
+public:
+  bool equalsFormat(const CharacterFormat &other) const {
+    return other.rendition==rendition && other.fgColor==fgColor && other.bgColor==bgColor;
+  }
+
+  bool equalsFormat(const Character &c) const {
+    return c.rendition==rendition && c.foregroundColor==fgColor && c.backgroundColor==bgColor;
+  }
+
+  void setFormat(const Character& c) {
+    rendition=c.rendition;
+    fgColor=c.foregroundColor;
+    bgColor=c.backgroundColor;
+  }
+
+  CharacterColor fgColor, bgColor;
+  quint16 startPos;
+  quint8 rendition;
+};
+
+class CompactHistoryBlock
+{
+public:
+  
+  CompactHistoryBlock(){
+    blockLength = 4096*64; // 256kb
+    head = (quint8*) mmap(0, blockLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+    //head = (quint8*) malloc(blockLength);
+    Q_ASSERT(head != MAP_FAILED);
+    tail = blockStart = head;
+    allocCount=0;
+  }
+  
+  virtual ~CompactHistoryBlock(){
+    //free(blockStart);
+    munmap(blockStart, blockLength);
+  }
+  
+  virtual unsigned int remaining(){ return blockStart+blockLength-tail;}
+  virtual unsigned  length() { return blockLength; }
+  virtual void* allocate(size_t length);
+  virtual bool contains(void *addr) {return addr>=blockStart && addr<(blockStart+blockLength);}
+  virtual void deallocate();
+  virtual bool isInUse(){ return allocCount!=0; } ;
+
+private:
+  size_t blockLength;
+  quint8* head;
+  quint8* tail;
+  quint8* blockStart;
+  int allocCount;
+};
+
+class CompactHistoryBlockList {
+public:
+  CompactHistoryBlockList() {};
+  ~CompactHistoryBlockList();
+
+  void *allocate( size_t size );
+  void deallocate(void *);
+  int length() {return list.size();}
+private:
+  QList<CompactHistoryBlock*> list;
+};
+
+class CompactHistoryLine
+{
+public:
+  CompactHistoryLine(const TextLine&, CompactHistoryBlockList& blockList);
+  virtual ~CompactHistoryLine();
+
+  // custom new operator to allocate memory from custom pool instead of heap
+  static void *operator new( size_t size, CompactHistoryBlockList& blockList);
+  static void operator delete( void *) { /* do nothing, deallocation from pool is done in destructor*/ } ;
+
+  virtual void getCharacters(Character* array, int length, int startColumn) ;
+  virtual void getCharacter(int index, Character &r) ;
+  virtual bool isWrapped() const {return wrapped;};
+  virtual void setWrapped(bool isWrapped) { wrapped=isWrapped;};
+  virtual unsigned int getLength() const {return length;};
+
+protected:
+  CompactHistoryBlockList& blockList;
+  CharacterFormat* formatArray;
+  quint16 length;
+  quint16* text;
+  quint16 formatLength;
+  bool wrapped;
+};
+
+class CompactHistoryScroll : public HistoryScroll
+{
+  typedef QList<CompactHistoryLine*> HistoryArray;
+
+public:
+  CompactHistoryScroll(unsigned int maxNbLines = 1000);
+  virtual ~CompactHistoryScroll();
+
+  virtual int  getLines();
+  virtual int  getLineLen(int lineno);
+  virtual void getCells(int lineno, int colno, int count, Character res[]);
+  virtual bool isWrappedLine(int lineno);
+
+  virtual void addCells(const Character a[], int count);
+  virtual void addCellsVector(const TextLine& cells);
+  virtual void addLine(bool previousWrapped=false);
+
+  void setMaxNbLines(unsigned int nbLines);
+  unsigned int maxNbLines() const { return _maxLineCount; }
+
+private:
+  bool hasDifferentColors(const TextLine& line) const;
+  HistoryArray lines;
+  CompactHistoryBlockList blockList;
+  
+  unsigned int _maxLineCount;
+};
+
+//////////////////////////////////////////////////////////////////////
+// History type
+//////////////////////////////////////////////////////////////////////
+
+class HistoryType
+{
+public:
+  HistoryType();
+  virtual ~HistoryType();
+
+  /**
+   * Returns true if the history is enabled ( can store lines of output )
+   * or false otherwise. 
+   */
+  virtual bool isEnabled()           const = 0;
+  /**
+   * Returns true if the history size is unlimited.
+   */
+  bool isUnlimited() const { return maximumLineCount() == 0; }
+  /**
+   * Returns the maximum number of lines which this history type
+   * can store or 0 if the history can store an unlimited number of lines.
+   */
+  virtual int maximumLineCount()    const = 0;
+
+  virtual HistoryScroll* scroll(HistoryScroll *) const = 0;
+};
+
+class HistoryTypeNone : public HistoryType
+{
+public:
+  HistoryTypeNone();
+
+  virtual bool isEnabled() const;
+  virtual int maximumLineCount() const;
+
+  virtual HistoryScroll* scroll(HistoryScroll *) const;
+};
+
+class HistoryTypeBlockArray : public HistoryType
+{
+public:
+  HistoryTypeBlockArray(size_t size);
+  
+  virtual bool isEnabled() const;
+  virtual int maximumLineCount() const;
+
+  virtual HistoryScroll* scroll(HistoryScroll *) const;
+
+protected:
+  size_t m_size;
+};
+
+#if 1 
+class HistoryTypeFile : public HistoryType
+{
+public:
+  HistoryTypeFile(const QString& fileName=QString());
+
+  virtual bool isEnabled() const;
+  virtual const QString& getFileName() const;
+  virtual int maximumLineCount() const;
+
+  virtual HistoryScroll* scroll(HistoryScroll *) const;
+
+protected:
+  QString m_fileName;
+};
+
+
+class HistoryTypeBuffer : public HistoryType
+{
+    friend class HistoryScrollBuffer;
+
+public:
+  HistoryTypeBuffer(unsigned int nbLines);
+   
+  virtual bool isEnabled() const;
+  virtual int maximumLineCount() const;
+  
+  virtual HistoryScroll* scroll(HistoryScroll *) const;
+
+protected:
+  unsigned int m_nbLines;
+};
+
+class CompactHistoryType : public HistoryType
+{
+public:
+  CompactHistoryType(unsigned int size);
+  
+  virtual bool isEnabled() const;
+  virtual int maximumLineCount() const;
+
+  virtual HistoryScroll* scroll(HistoryScroll *) const;
+
+protected:
+  unsigned int m_nbLines;
+};
+
+
+#endif
+
+}
+
+#endif // TEHISTORY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/HistorySizeDialog.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,168 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "HistorySizeDialog.h"
+
+// Qt
+#include <QtGui/QButtonGroup>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QCheckBox>
+#include <QtGui/QLabel>
+#include <QtGui/QRadioButton>
+#include <QtGui/QWidget>
+
+// KDE
+#include <KLocalizedString>
+#include <KNumInput>
+
+// Konsole
+#include "SessionManager.h"
+
+using namespace Konsole;
+
+HistorySizeDialog::HistorySizeDialog( QWidget* parent )
+    :  KDialog(parent)
+    ,  _noHistoryButton(0)
+    ,  _fixedHistoryButton(0)
+    ,  _unlimitedHistoryButton(0)
+    ,  _saveToCurrentProfileButton(0)
+    ,  _lineCountBox(0)
+    ,  _defaultMode(FixedSizeHistory)
+    ,  _defaultLineCount(1000)
+{
+    // basic dialog properties
+    setPlainCaption( i18n("Scrollback Options") );
+    setButtons(  Default | Ok | Cancel );
+    setDefaultButton(Ok);
+    setModal( false );
+
+    // dialog widgets
+    QWidget* dialogWidget = new QWidget(this);
+    setMainWidget(dialogWidget);
+
+    QVBoxLayout* dialogLayout = new QVBoxLayout(dialogWidget);
+
+    QButtonGroup* modeGroup = new QButtonGroup(this);
+
+    _noHistoryButton = new QRadioButton( i18n("No scrollback") );
+    _fixedHistoryButton = new QRadioButton( i18n("Fixed size scrollback: ") );
+    _unlimitedHistoryButton = new QRadioButton( i18n("Unlimited scrollback") );
+    _saveToCurrentProfileButton = new QCheckBox( i18n("Save to current profile") );
+
+    modeGroup->addButton(_noHistoryButton);
+    modeGroup->addButton(_fixedHistoryButton);
+    modeGroup->addButton(_unlimitedHistoryButton);
+
+    _lineCountBox = new KIntSpinBox(this);
+
+    // minimum lines = 1 ( for 0 lines , "No History" mode should be used instead )
+    // maximum lines is abritrarily chosen, I do not think it is sensible to allow this
+    // to be set to a very large figure because that will use large amounts of memory,
+    // if a very large log is required, "Unlimited History" mode should be used
+    _lineCountBox->setRange( 1 , 100000 );
+
+    // 1000 lines was the default in the KDE 3 series
+    // using that for now
+    _lineCountBox->setValue( _defaultLineCount );
+
+    _lineCountBox->setSingleStep( _defaultLineCount / 10 );
+
+    QLabel* lineCountLabel = new QLabel(i18n("lines"),this);
+    QHBoxLayout* lineCountLayout = new QHBoxLayout();
+
+    _fixedHistoryButton->setFocusProxy(_lineCountBox);
+
+    connect( _fixedHistoryButton , SIGNAL(clicked()) , _lineCountBox , SLOT(selectAll()) );
+    lineCountLayout->addWidget(_fixedHistoryButton);
+    lineCountLayout->addWidget(_lineCountBox);
+    lineCountLayout->addWidget(lineCountLabel);
+
+    dialogLayout->addWidget(_noHistoryButton);
+    dialogLayout->addLayout(lineCountLayout);
+    dialogLayout->addWidget(_unlimitedHistoryButton);
+    dialogLayout->insertSpacing(3, 10);
+    dialogLayout->addWidget(_saveToCurrentProfileButton);
+
+    // select the fixed size mode by default
+    _fixedHistoryButton->click();
+    _fixedHistoryButton->setFocus( Qt::OtherFocusReason );
+
+    connect(this,SIGNAL(defaultClicked()),this,SLOT(useDefaults()));
+
+    connect(this,SIGNAL(accepted()),this,SLOT(emitOptionsChanged()));
+}
+
+void HistorySizeDialog::emitOptionsChanged()
+{
+    emit optionsChanged( mode() , lineCount(), saveToCurrentProfile() );
+}
+
+void HistorySizeDialog::setDefaultMode( HistoryMode mode ) { _defaultMode = mode; }
+HistorySizeDialog::HistoryMode HistorySizeDialog::defaultMode() const { return _defaultMode; }
+void HistorySizeDialog::setDefaultLineCount( int count ) { _defaultLineCount = count; }
+int HistorySizeDialog::defaultLineCount() const { return _defaultLineCount; }
+bool HistorySizeDialog::saveToCurrentProfile() const { return _saveToCurrentProfileButton->isChecked(); }
+
+void HistorySizeDialog::useDefaults()
+{
+    setMode( _defaultMode );
+    setLineCount( _defaultLineCount );
+    _saveToCurrentProfileButton->setChecked(false);
+}
+
+void HistorySizeDialog::setMode( HistoryMode mode )
+{
+    if ( mode == NoHistory )
+    {
+        _noHistoryButton->setChecked(true);
+    } else if ( mode == FixedSizeHistory )
+    {
+        _fixedHistoryButton->setChecked(true);
+    } else if ( mode == UnlimitedHistory )
+    {
+        _unlimitedHistoryButton->setChecked(true);
+    }
+}
+
+HistorySizeDialog::HistoryMode HistorySizeDialog::mode() const
+{
+    if ( _noHistoryButton->isChecked() )
+        return NoHistory;
+    else if ( _fixedHistoryButton->isChecked() )
+        return FixedSizeHistory;
+    else if ( _unlimitedHistoryButton->isChecked() )
+        return UnlimitedHistory;
+
+    Q_ASSERT(false);
+    return NoHistory;
+}
+
+int HistorySizeDialog::lineCount() const
+{
+    return _lineCountBox->value();
+}
+
+void HistorySizeDialog::setLineCount(int lines)
+{
+    _lineCountBox->setValue(lines);
+}
+
+
+#include "HistorySizeDialog.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/HistorySizeDialog.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,134 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef HISTORYSIZEDIALOG_H
+#define HISTORYSIZEDIALOG_H
+
+// KDE
+#include <KDialog>
+
+class QAbstractButton;
+class KIntSpinBox;
+
+namespace Konsole
+{
+
+/**
+ * A dialog which allows the user to select the number of lines of output
+ * which are remembered for a session. 
+ */
+class HistorySizeDialog : public KDialog
+{
+Q_OBJECT
+
+public:
+    /**
+     * Construct a new history size dialog.
+     */
+    HistorySizeDialog( QWidget* parent );
+
+    /** Specifies the type of history scroll */
+    enum HistoryMode
+    {
+        /** 
+         * No history.  Lines of output are lost
+         * as soon as they are scrolled off-screen.
+         */ 
+        NoHistory,
+        /**
+         * A history which stores up to a fixed number of lines
+         * in memory. 
+         */
+        FixedSizeHistory,
+        /**
+         * An 'unlimited' history which stores lines of output in
+         * a file on disk.
+         */
+        UnlimitedHistory
+    };
+
+
+    /** Specifies the history mode. */
+    void setMode( HistoryMode mode );
+    /** Returns the history mode chosen by the user. */
+    HistoryMode mode() const;
+    /** 
+     * Returns the number of lines of history to remember.
+     * This is only valid when mode() == FixedSizeHistory,
+     * and returns 0 otherwise.
+     */
+    int lineCount() const;
+    /** Sets the number of lines for the fixed size history mode. */
+    void setLineCount(int lines);
+
+    /** 
+     * Sets the default history mode.  When the user clicks on the "Defaults" button,
+     * this mode will be used.
+     */
+    void setDefaultMode( HistoryMode mode );
+
+    /** Returns the default mode, as set with setDefaultMode() */
+    HistoryMode defaultMode() const;
+
+    /** 
+     * Sets the default line count.  When the user clicks on the "Defaults" button,
+     * the line count will be set to this number.
+     */
+    void setDefaultLineCount( int count );
+
+    /** Returns the default line count, as set with setDefaultLineCount() */
+    int defaultLineCount() const;
+
+    bool saveToCurrentProfile() const;
+
+signals:
+    /**
+     * Emitted when the user changes the scroll-back mode or line count and
+     * accepts the change by pressing the OK button
+     *
+     * @param mode The current history mode.  This is a value from the HistoryMode enum.
+     * @param lineCount The current line count.  This is only applicable if mode is
+     * FixedSizeHistory
+     * @param saveToCurrentProfile Determines if the changes are saved to current profile.
+     */
+    void optionsChanged(int mode , int lineCount, bool saveToCurrentProfile);
+
+private slots:
+    // changes the mode and line count back to the defaults
+    // specified with setDefaultMode() and setDefaultLineCount()
+    void useDefaults();
+
+    // fires the optionsChanged() signal with the current mode
+    // and line count as arguments
+    void emitOptionsChanged();
+
+private:
+    QAbstractButton* _noHistoryButton;
+    QAbstractButton* _fixedHistoryButton;
+    QAbstractButton* _unlimitedHistoryButton;
+    QAbstractButton* _saveToCurrentProfileButton;
+    KIntSpinBox* _lineCountBox;   
+
+    HistoryMode _defaultMode;
+    int _defaultLineCount; 
+};
+
+}
+
+#endif // HISTORYSIZEDIALOG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/IncrementalSearchBar.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,265 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "IncrementalSearchBar.h"
+
+// Qt
+#include <QtGui/QCheckBox>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QProgressBar>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QTimer>
+#include <QtGui/QToolButton>
+
+// KDE
+#include <KColorScheme>
+#include <KLineEdit>
+#include <KLocale>
+#include <KIcon>
+
+using namespace Konsole;
+
+IncrementalSearchBar::IncrementalSearchBar(Features features , QWidget* parent)
+    : QWidget(parent)
+    , _foundMatch(false)
+    , _matchCaseBox(0)
+    , _matchRegExpBox(0)
+    , _highlightBox(0)
+    , _searchEdit(0)
+    , _continueLabel(0)
+{
+    QHBoxLayout* layout = new QHBoxLayout(this);
+  
+    QToolButton* close = new QToolButton(this);
+    close->setObjectName( QLatin1String("close-button" ));
+    close->setToolTip( i18n("Close the search bar") );
+    close->setAutoRaise(true);
+    close->setIcon(KIcon("dialog-close"));
+    connect( close , SIGNAL(clicked()) , this , SIGNAL(closeClicked()) );
+
+    QLabel* findLabel = new QLabel(i18n("Find:"),this);
+    _searchEdit = new KLineEdit(this);
+    _searchEdit->setClearButtonShown(true);
+    _searchEdit->installEventFilter(this);
+    _searchEdit->setObjectName( QLatin1String("search-edit" ));
+    _searchEdit->setToolTip( i18n("Enter the text to search for here") );
+
+    // text box may be a minimum of 6 characters wide and a maximum of 10 characters wide
+    // (since the maxWidth metric is used here, more characters probably will fit in than 6
+    //  and 10)
+    QFontMetrics metrics(_searchEdit->font());
+    int maxWidth = metrics.maxWidth();
+    _searchEdit->setMinimumWidth(maxWidth*6);
+    _searchEdit->setMaximumWidth(maxWidth*10);
+
+    _searchTimer = new QTimer(this);
+    _searchTimer->setInterval(250);
+    _searchTimer->setSingleShot(true);
+    connect( _searchTimer , SIGNAL(timeout()) , this , SLOT(notifySearchChanged()) );
+    connect( _searchEdit , SIGNAL(clearButtonClicked()) , this , SLOT(clearLineEdit()) );
+    connect( _searchEdit , SIGNAL(textChanged(const QString&)) , _searchTimer , SLOT(start()));
+
+    QToolButton* findNext = new QToolButton(this);
+    findNext->setObjectName( QLatin1String("find-next-button" ));
+    findNext->setText(i18nc("@action:button Go to the next phrase", "Next"));
+    findNext->setAutoRaise(true);
+    findNext->setIcon( KIcon("go-down-search") );
+    findNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+    findNext->setToolTip( i18n("Find the next match for the current search phrase") );
+    connect( findNext , SIGNAL(clicked()) , this , SIGNAL(findNextClicked()) );
+
+    QToolButton* findPrev = new QToolButton(this);
+    findPrev->setObjectName( QLatin1String("find-previous-button" ));
+    findPrev->setText(i18nc("@action:button Go to the previous phrase", "Previous"));
+    findPrev->setAutoRaise(true);
+    findPrev->setIcon( KIcon("go-up-search") );
+    findPrev->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+    findPrev->setToolTip( i18n("Find the previous match for the current search phrase") );
+    connect( findPrev , SIGNAL(clicked()) , this , SIGNAL(findPreviousClicked()) );
+
+    if ( features & HighlightMatches )
+    {
+        _highlightBox = new QCheckBox( i18n("Highlight all") , this );
+        _highlightBox->setObjectName( QLatin1String("highlight-matches-box" ));
+        _highlightBox->setToolTip( i18n("Sets whether matching text should be highlighted") );
+        _highlightBox->setChecked(true);
+        connect( _highlightBox , SIGNAL(toggled(bool)) , this , 
+                 SIGNAL(highlightMatchesToggled(bool)) );
+    }
+
+    if ( features & MatchCase )
+    {
+        _matchCaseBox = new QCheckBox( i18n("Match case") , this );
+        _matchCaseBox->setObjectName( QLatin1String("match-case-box" ));
+        _matchCaseBox->setToolTip( i18n("Sets whether the search is case sensitive") );
+        connect( _matchCaseBox , SIGNAL(toggled(bool)) , this , SIGNAL(matchCaseToggled(bool)) );
+    }
+
+    if ( features & RegExp )
+    {
+        _matchRegExpBox = new QCheckBox( i18n("Match regular expression") , this );
+        _matchRegExpBox->setObjectName( QLatin1String("match-regexp-box" ));
+        _matchRegExpBox->setToolTip( i18n("Sets whether the search phrase is interpreted as normal text or"
+                      " as a regular expression") );
+        connect( _matchRegExpBox , SIGNAL(toggled(bool)) , this , SIGNAL(matchRegExpToggled(bool)) );
+    }
+
+    QProgressBar* _progress = new QProgressBar(this);
+    _progress->setMinimum(0);
+    _progress->setMaximum(0);
+    _progress->setVisible(false);
+
+    QLabel* _continueLabel = new QLabel(this);
+    _continueLabel->setVisible(false);
+
+    layout->addWidget(close);
+    layout->addWidget(findLabel);
+    layout->addWidget(_searchEdit);
+    layout->addWidget(findNext);
+    layout->addWidget(findPrev);
+
+    // optional features
+    if ( features & HighlightMatches ) layout->addWidget(_highlightBox);
+    if ( features & MatchCase        ) layout->addWidget(_matchCaseBox);
+    if ( features & RegExp           ) layout->addWidget(_matchRegExpBox);
+    
+    layout->addWidget(_progress);
+    layout->addWidget(_continueLabel);
+    layout->addStretch();
+
+    layout->setContentsMargins(4, 4, 4, 4);
+
+    setLayout(layout);
+}
+void IncrementalSearchBar::notifySearchChanged()
+{
+    emit searchChanged( searchText() );
+}
+QString IncrementalSearchBar::searchText()
+{
+    return _searchEdit->text();
+}
+bool IncrementalSearchBar::highlightMatches()
+{
+    if ( !_highlightBox )
+    {
+        return true;
+    }
+    else
+    {
+        return _highlightBox->isChecked();
+    }
+}
+bool IncrementalSearchBar::matchCase()
+{
+    if ( !_matchCaseBox )
+    {
+        return false;
+    }
+    else
+    {
+        return _matchCaseBox->isChecked();
+    }
+}
+bool IncrementalSearchBar::matchRegExp()
+{
+    if ( !_matchRegExpBox )
+    {
+        return false;
+    }
+    else
+    {
+        return _matchRegExpBox->isChecked();
+    }
+}
+
+bool IncrementalSearchBar::eventFilter(QObject* watched , QEvent* event)
+{
+    if ( watched == _searchEdit )
+    {
+        if ( event->type() == QEvent::KeyPress )
+        {
+            QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
+
+            if ( keyEvent->key() == Qt::Key_Escape )
+            {
+                emit closeClicked();
+                return true;
+            }
+        }        
+    }
+        
+    return QWidget::eventFilter(watched,event);
+}
+
+void IncrementalSearchBar::setVisible(bool visible)
+{
+    QWidget::setVisible(visible);
+
+    if ( visible )
+    {
+        //TODO - Check if this is the correct reason value to use here
+        _searchEdit->setFocus( Qt::ActiveWindowFocusReason );
+        _searchEdit->selectAll();
+    }
+}
+
+void IncrementalSearchBar::setFoundMatch( bool match )
+{
+    if ( !match && !_searchEdit->text().isEmpty() )
+    {
+        KStatefulBrush backgroundBrush(KColorScheme::View,KColorScheme::NegativeBackground);
+
+        QString styleSheet = QString("QLineEdit{ background-color:%1 }")
+                             .arg(backgroundBrush.brush(_searchEdit).color().name());
+
+        _searchEdit->setStyleSheet( styleSheet );
+    }
+    else
+    {
+        _searchEdit->setStyleSheet( QString() );
+    }
+}
+
+void IncrementalSearchBar::setContinueFlag( Continue flag )
+{
+    if ( flag == ContinueFromTop )
+    {
+        _continueLabel->setText( i18n("Search reached bottom, continued from top.") );
+        _continueLabel->show();
+    } 
+    else if ( flag == ContinueFromBottom )
+    {
+        _continueLabel->setText( i18n("Search reached top, continued from bottom.") );
+        _continueLabel->show();
+    } 
+    else if ( flag == ClearContinue )
+    {
+        _continueLabel->hide();
+    }
+}
+
+void IncrementalSearchBar::clearLineEdit()
+{
+    _searchEdit->setStyleSheet( QString() );
+}
+
+#include "IncrementalSearchBar.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/IncrementalSearchBar.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,195 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef INCREMENTALSEARCHBAR_H
+#define INCREMENTALSEARCHBAR_H
+
+// Qt
+#include <QtGui/QWidget>
+
+class QCheckBox;
+class QLabel;
+class QProgressBar;
+class QTimer;
+class KLineEdit;
+
+namespace Konsole
+{
+
+/** 
+ * A widget which allows users to search incrementally through a document for a 
+ * a text string or regular expression.
+ *
+ * The widget consists of a text box into which the user can enter their search text and
+ * buttons to trigger a search for the next and previous matches for the search text.
+ *
+ * When the search text is changed, the searchChanged() signal is emitted.  A search through
+ * the document for the new text should begin immediately and the active view of the document
+ * should jump to display any matches if found.  setFoundMatch() should be called whenever the
+ * search text changes to indicate whether a match for the text was found in the document.
+ * 
+ * findNextClicked() and findPreviousClicked() signals are emitted when the user presses buttons 
+ * to find next and previous matches respectively.
+ *
+ * The search bar has a number of optional features which can be enabled or disabled by passing
+ * a set of Features flags to the constructor.
+ *
+ * An optional checkbox can be displayed to indicate whether all matches in the document 
+ * for searchText() should be highlighted.  
+ * The highlightMatchesToggled() signal is emitted when this checkbox is toggled.
+ *
+ * The two further optional checkboxes allow the user to control the matching process.  
+ * The first indicates whether searches are case sensitive.  
+ * The matchCaseToggled() signal is emitted when this is changed.
+ * The second indicates whether the search text should be treated as a plain string or 
+ * as a regular expression.
+ * The matchRegExpToggled() signal is emitted when this is changed.
+ */
+class IncrementalSearchBar : public QWidget
+{
+Q_OBJECT
+
+public:
+    enum Continue
+    {
+        /** 
+         * Indicates that the search has reached the bottom of the document and has been continued from
+         * the top 
+         */
+        ContinueFromTop,
+        /**
+         * Indicates that the search has reached the top of the document and has been continued from
+         * the bottom
+         */
+        ContinueFromBottom,
+
+        /** Clears the Continue flag */
+        ClearContinue
+    };
+
+    /** 
+     * This enum defines the features which can be supported by an implementation of
+     * an incremental search bar
+     */
+    enum Features
+    {
+        /** search facility supports highlighting of all matches */
+        HighlightMatches = 1,
+        /** search facility supports case-sensitive and case-insensitive search */
+        MatchCase        = 2,
+        /** search facility supports regular expressions */
+        RegExp           = 4,
+        /** search facility supports all features */
+        AllFeatures      = HighlightMatches | MatchCase | RegExp
+    };
+
+    /** 
+     * Constructs a new incremental search bar with the given parent widget 
+     * @p features specifies the features which should be made available to the user.
+     */
+    explicit IncrementalSearchBar(Features features , QWidget* parent = 0);
+
+    /** 
+     * Sets an indicator for the user as to whether or not a match for the 
+     * current search text was found in the document.
+     *
+     * The indicator will not be shown if the search text is empty ( because
+     * the user has not yet entered a query ).
+     *
+     * @param match True if a match was found or false otherwise.  If true,
+     * and the search text is non-empty, an indicator that no matches were
+     * found will be shown.
+     */
+    void setFoundMatch( bool match );
+
+    /**
+     * Sets a flag to indicate that the current search for matches has reached the top or bottom of
+     * the document and has been continued again from the other end of the document.
+     *
+     * This flag will be cleared when the user presses the buttons to find a next or previous match.
+     */
+    void setContinueFlag( Continue flag );
+
+    /** Returns the current search text */
+    QString searchText();
+    /** 
+     * Returns whether matches for the current search text should be highlighted in the document. 
+     * Always returns true if the highlight matches checkbox is not visible. 
+     */
+    bool highlightMatches();
+    /** 
+     * Returns whether matching for the current search text should be case sensitive.
+     * Always returns false if the match case checkbox is not visible.
+     */
+    bool matchCase();
+    /** 
+     * Returns whether the current search text should be treated as plain text or a regular expression 
+     * Always returns false if the match regular expression checkbox is not visible.
+     */
+    bool matchRegExp();
+
+    // reimplemented
+    virtual void setVisible( bool visible );
+signals:
+    /** Emitted when the text entered in the search box is altered */
+    void searchChanged( const QString& text );
+    /** Emitted when the user clicks the button to find the next match */
+    void findNextClicked();
+    /** Emitted when the user clicks the button to find the previous match */
+    void findPreviousClicked();
+    /** 
+     * Emitted when the user toggles the checkbox to indicate whether
+     * matches for the search text should be highlighted
+     */
+    void highlightMatchesToggled(bool);
+    /**
+     * Emitted when the user toggles the checkbox to indicate whether
+     * matching for the search text should be case sensitive
+     */
+    void matchCaseToggled(bool);
+    /**
+     * Emitted when the user toggles the checkbox to indicate whether
+     * the search text should be treated as a plain string or a regular expression 
+     */
+    void matchRegExpToggled(bool);
+    /** Emitted when the close button is clicked */
+    void closeClicked();
+
+protected:
+    virtual bool eventFilter( QObject* watched , QEvent* event );
+
+private slots:
+    void notifySearchChanged();
+    void clearLineEdit();
+
+private:
+    bool _foundMatch;
+    QCheckBox* _matchCaseBox;
+    QCheckBox* _matchRegExpBox;
+    QCheckBox* _highlightBox;
+
+    KLineEdit* _searchEdit;
+    QLabel* _continueLabel;
+    QProgressBar* _progress;
+
+    QTimer* _searchTimer;
+};
+
+}
+#endif // INCREMENTALSEARCHBAR_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/KeyBindingEditor.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,241 @@
+/*
+    Copyright 2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "KeyBindingEditor.h"
+
+// Qt
+#include <QtGui/QHeaderView>
+#include <QtGui/QKeyEvent>
+
+#include <KDebug>
+
+// Konsole
+#include "ui_KeyBindingEditor.h"
+#include "KeyboardTranslator.h"
+
+using namespace Konsole;
+
+KeyBindingEditor::KeyBindingEditor(QWidget* parent)
+    : QWidget(parent)
+    , _translator(new KeyboardTranslator( QString() ))
+{
+    _ui = new Ui::KeyBindingEditor();
+    _ui->setupUi(this);
+
+    // description edit
+    connect( _ui->descriptionEdit , SIGNAL(textChanged(const QString&)) , this , SLOT(setDescription(const QString&)) );
+
+    // key bindings table
+    _ui->keyBindingTable->setColumnCount(2);
+
+    QStringList labels;
+    labels << i18n("Key Combination") << i18n("Output");
+
+    _ui->keyBindingTable->setHorizontalHeaderLabels(labels);
+    _ui->keyBindingTable->horizontalHeader()->setStretchLastSection(true);
+    _ui->keyBindingTable->verticalHeader()->hide();
+    _ui->keyBindingTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+
+    // add and remove buttons
+    _ui->addEntryButton->setIcon( KIcon("list-add") );
+    _ui->removeEntryButton->setIcon( KIcon("list-remove") );
+
+    connect( _ui->removeEntryButton , SIGNAL(clicked()) , this , SLOT(removeSelectedEntry()) );
+    connect( _ui->addEntryButton , SIGNAL(clicked()) , this , SLOT(addNewEntry()) );
+    
+    // test area
+    _ui->testAreaInputEdit->installEventFilter(this);
+}
+
+KeyBindingEditor::~KeyBindingEditor()
+{
+    delete _ui;
+}
+
+void KeyBindingEditor::removeSelectedEntry()
+{
+    QList<QTableWidgetItem*> selectedList =  _ui->keyBindingTable->selectedItems();
+    QList<QTableWidgetItem*> uniqueList;
+    
+    //Filter unique items
+    QListIterator<QTableWidgetItem*> iter( selectedList );
+    while ( iter.hasNext() )
+    {
+        QTableWidgetItem* item = iter.next();
+        if (item->column() == 1) //Select item at the first column
+            item = _ui->keyBindingTable->item(item->row(),0);
+
+        if ( !uniqueList.contains(item) )
+            uniqueList.append(item);
+    }
+
+    iter = QListIterator<QTableWidgetItem*>( uniqueList );
+    while ( iter.hasNext() )
+    {     
+        // get the first item in the row which has the entry
+        QTableWidgetItem* item = iter.next();
+
+        KeyboardTranslator::Entry existing = item->data(Qt::UserRole).
+                                                    value<KeyboardTranslator::Entry>();
+        
+        _translator->removeEntry(existing);
+    
+        _ui->keyBindingTable->removeRow( item->row() );
+    }
+}
+
+void KeyBindingEditor::addNewEntry()
+{
+   _ui->keyBindingTable->insertRow( _ui->keyBindingTable->rowCount() );
+
+   int newRowCount = _ui->keyBindingTable->rowCount();
+
+   // block signals here to avoid triggering bindingTableItemChanged() slot call
+   _ui->keyBindingTable->blockSignals(true);
+
+   _ui->keyBindingTable->setItem(newRowCount-1,0,new QTableWidgetItem() );
+   _ui->keyBindingTable->setItem(newRowCount-1,1,new QTableWidgetItem() );
+
+   _ui->keyBindingTable->blockSignals(false);
+
+   // make sure user can see new row
+   _ui->keyBindingTable->scrollToItem(_ui->keyBindingTable->item(newRowCount-1,0));
+}
+
+bool KeyBindingEditor::eventFilter( QObject* watched , QEvent* event )
+{
+    if ( watched == _ui->testAreaInputEdit )
+    {
+       if ( event->type() == QEvent::KeyPress )
+       {
+            QKeyEvent* keyEvent = (QKeyEvent*)event;
+
+            // The state here is currently set to the state that a newly started 
+            // terminal in Konsole will be in ( which is also the same as the 
+            // state just after a reset ), this has 'Ansi' turned on and all other
+            // states off.
+            //
+            // TODO: It may be useful to be able to specify the state in the 'test input' 
+            // area, but preferably not in a way which clutters the UI with lots of 
+            // checkboxes.
+            //
+            const KeyboardTranslator::States states = KeyboardTranslator::AnsiState;
+
+            KeyboardTranslator::Entry entry = _translator->findEntry( keyEvent->key() , 
+                                                                      keyEvent->modifiers(), 
+                                                                      states );
+
+            if ( !entry.isNull() )
+            {
+                _ui->testAreaInputEdit->setText(entry.conditionToString());
+                _ui->testAreaOutputEdit->setText(entry.resultToString(true,keyEvent->modifiers()));
+            }
+            else
+            {
+                _ui->testAreaInputEdit->setText(keyEvent->text());
+                _ui->testAreaOutputEdit->setText(keyEvent->text());
+            }
+
+            keyEvent->accept();
+            return true;
+       } 
+    }
+    return false;
+}
+
+void KeyBindingEditor::setDescription(const QString& newDescription)
+{
+     _ui->descriptionEdit->setText(newDescription);
+    
+     if ( _translator )
+         _translator->setDescription(newDescription);
+}
+QString KeyBindingEditor::description() const
+{
+    return _ui->descriptionEdit->text();
+}
+
+void KeyBindingEditor::setup(const KeyboardTranslator* translator)
+{
+    if ( _translator )
+        delete _translator;
+
+    _translator = new KeyboardTranslator(*translator);
+
+    // setup description edit
+    _ui->descriptionEdit->setClearButtonShown(true);
+    _ui->descriptionEdit->setText(translator->description());
+
+    // setup key binding table
+    setupKeyBindingTable(translator);
+}
+
+KeyboardTranslator* KeyBindingEditor::translator() const
+{
+    return _translator;
+}
+
+void KeyBindingEditor::bindingTableItemChanged(QTableWidgetItem* item)
+{
+   QTableWidgetItem* key = _ui->keyBindingTable->item( item->row() , 0 );
+   KeyboardTranslator::Entry existing = key->data(Qt::UserRole).value<KeyboardTranslator::Entry>();
+
+   QString condition = key->text();
+   QString result = _ui->keyBindingTable->item( item->row() , 1 )->text();
+
+   KeyboardTranslator::Entry entry = KeyboardTranslatorReader::createEntry(condition,result);
+   _translator->replaceEntry(existing,entry);
+
+    // block signals to prevent this slot from being called repeatedly
+   _ui->keyBindingTable->blockSignals(true);
+
+   key->setData(Qt::UserRole,QVariant::fromValue(entry));
+
+   _ui->keyBindingTable->blockSignals(false);
+}
+
+void KeyBindingEditor::setupKeyBindingTable(const KeyboardTranslator* translator)
+{
+    disconnect( _ui->keyBindingTable , SIGNAL(itemChanged(QTableWidgetItem*)) , this , 
+            SLOT(bindingTableItemChanged(QTableWidgetItem*)) );
+
+    QList<KeyboardTranslator::Entry> entries = translator->entries();
+    _ui->keyBindingTable->setRowCount(entries.count());
+
+    for ( int row = 0 ; row < entries.count() ; row++ )
+    {
+        const KeyboardTranslator::Entry& entry = entries.at(row);
+
+        QTableWidgetItem* keyItem = new QTableWidgetItem(entry.conditionToString());
+        keyItem->setData( Qt::UserRole , QVariant::fromValue(entry) );
+
+        QTableWidgetItem* textItem = new QTableWidgetItem(QString(entry.resultToString()));
+
+        _ui->keyBindingTable->setItem(row,0,keyItem);
+        _ui->keyBindingTable->setItem(row,1,textItem);
+    }
+    _ui->keyBindingTable->sortItems(0);
+
+    connect( _ui->keyBindingTable , SIGNAL(itemChanged(QTableWidgetItem*)) , this , 
+            SLOT(bindingTableItemChanged(QTableWidgetItem*)) );
+}
+
+#include "KeyBindingEditor.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/KeyBindingEditor.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,105 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef KEYBINDINGEDITOR_H
+#define KEYBINDINGEDITOR_H
+
+// Qt
+#include <QtGui/QWidget>
+
+class QTableWidgetItem;
+
+namespace Ui
+{
+    class KeyBindingEditor;
+}
+
+namespace Konsole
+{
+
+class KeyboardTranslator;
+
+/**
+ * A dialog which allows the user to edit a key bindings list 
+ * which maps between key combinations input by the user and 
+ * the character sequence sent to the terminal when those 
+ * combinations are pressed.
+ *
+ * The dialog can be initialised with the settings of an
+ * existing key bindings list using the setup() method.
+ *
+ * The dialog creates a copy of the supplied keyboard translator
+ * to which any changes are applied.  The modified translator 
+ * can be retrieved using the translator() method.
+ */
+class KeyBindingEditor : public QWidget
+{
+Q_OBJECT
+
+public:
+    /** Constructs a new key bindings editor with the specified parent. */
+    KeyBindingEditor(QWidget* parent = 0);
+    virtual ~KeyBindingEditor();
+
+    /** 
+     * Intialises the dialog with the bindings and other settings
+     * from the specified @p translator.
+     */
+    void setup(const KeyboardTranslator* translator);
+
+    /**
+     * Returns the modified translator describing the changes to the bindings
+     * and other settings which the user made.
+     */
+    KeyboardTranslator* translator() const;
+
+    /**
+     * Returns the text of the editor's description field.
+     */
+    QString description() const;
+
+    // reimplemented to handle test area input
+    virtual bool eventFilter( QObject* watched , QEvent* event );
+
+public slots:
+    /** 
+     * Sets the text of the editor's description field.
+     */
+    void setDescription(const QString& description);
+
+private slots:
+    void bindingTableItemChanged(QTableWidgetItem* item);
+    void removeSelectedEntry();
+    void addNewEntry();
+
+private:
+    void setupKeyBindingTable(const KeyboardTranslator* translator);
+
+    Ui::KeyBindingEditor* _ui;
+    
+    // translator to which modifications are made as the user makes
+    // changes in the UI.
+    // this is initialized as a copy of the translator specified
+    // when setup() is called
+    KeyboardTranslator* _translator;
+};
+
+}
+
+#endif //KEYBINDINGEDITOR_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/KeyboardTranslator.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,979 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "KeyboardTranslator.h"
+
+// System
+#include <ctype.h>
+#include <stdio.h>
+
+// Qt
+#include <QtCore/QBuffer>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextStream>
+#include <QtGui/QKeySequence>
+#include <QtCore/QDir>
+#include <QtCore/QStringList>
+#include <QtCore/QDebug>
+#include <QtCore/QDataStream>
+
+// KDE
+#include "konsole_export.h"
+//#include <KDebug>
+//#include <KLocale>
+//#include <KStandardDirs>
+
+using namespace Konsole;
+
+
+const QByteArray KeyboardTranslatorManager::defaultTranslatorText(
+"keyboard \"Fallback Key Translator\"\n"
+"key Tab : \"\\t\""
+);
+
+KeyboardTranslatorManager::KeyboardTranslatorManager()
+    : _haveLoadedAll(false)
+{
+}
+KeyboardTranslatorManager::~KeyboardTranslatorManager()
+{
+    qDeleteAll(_translators);
+}
+QString KeyboardTranslatorManager::findTranslatorPath(const QString& name)
+{
+  return QString("kb-layouts/" + name + ".keytab");
+  // return KGlobal::dirs()->findResource("data","konsole/"+name+".keytab");
+}
+void KeyboardTranslatorManager::findTranslators()
+{
+  //QStringList list = KGlobal::dirs()->findAllResources("data",
+  //                                                     "konsole/*.keytab",
+  //                                                     KStandardDirs::NoDuplicates);
+
+    QDir dir("kb-layouts/");
+    QStringList filters;
+    filters << "*.keytab";
+    dir.setNameFilters(filters);
+    QStringList list = dir.entryList(filters);
+
+    // add the name of each translator to the list and associated
+    // the name with a null pointer to indicate that the translator
+    // has not yet been loaded from disk
+    QStringListIterator listIter(list);
+    while (listIter.hasNext())
+    {
+        QString translatorPath = listIter.next();
+
+        QString name = QFileInfo(translatorPath).baseName();
+       
+        if ( !_translators.contains(name) ) 
+            _translators.insert(name,0);
+    }
+
+    _haveLoadedAll = true;
+}
+
+const KeyboardTranslator* KeyboardTranslatorManager::findTranslator(const QString& name)
+{
+    if ( name.isEmpty() )
+        return defaultTranslator();
+
+    if ( _translators.contains(name) && _translators[name] != 0 )
+        return _translators[name];
+
+    KeyboardTranslator* translator = loadTranslator(name);
+
+    if ( translator != 0 )
+        _translators[name] = translator;
+    else if ( !name.isEmpty() )
+      kWarning() << "Unable to load translator" << name.toStdString();
+
+    return translator;
+}
+
+bool KeyboardTranslatorManager::saveTranslator(const KeyboardTranslator* translator)
+{
+  //const QString path = KGlobal::dirs()->saveLocation("data","konsole/")+translator->name()
+  //         +".keytab";
+  const QString path = ".keytab";
+
+    //kDebug() << "Saving translator to" << path;
+
+    QFile destination(path);
+    if (!destination.open(QIODevice::WriteOnly | QIODevice::Text))
+    {
+        kWarning() << "Unable to save keyboard translation:" 
+                   << destination.errorString().toStdString();
+        return false;
+    }
+
+    {
+        KeyboardTranslatorWriter writer(&destination);
+        writer.writeHeader(translator->description());
+    
+        QListIterator<KeyboardTranslator::Entry> iter(translator->entries());
+        while ( iter.hasNext() )
+            writer.writeEntry(iter.next());
+    }
+
+    destination.close();
+
+    return true;
+}
+
+KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(const QString& name)
+{
+    const QString& path = findTranslatorPath(name);
+
+    QFile source(path); 
+    if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text))
+        return 0;
+
+    return loadTranslator(&source,name);
+}
+
+const KeyboardTranslator* KeyboardTranslatorManager::defaultTranslator()
+{
+    // Try to find the default.keytab file if it exists, otherwise
+    // fall back to the hard-coded one
+    const KeyboardTranslator* translator = findTranslator("default");
+    if (!translator)
+    {
+        QBuffer textBuffer;
+        textBuffer.setData(defaultTranslatorText);
+        textBuffer.open(QIODevice::ReadOnly);
+        translator = loadTranslator(&textBuffer,"fallback");
+    }
+    return translator;
+}
+
+KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(QIODevice* source,const QString& name)
+{
+    KeyboardTranslator* translator = new KeyboardTranslator(name);
+    KeyboardTranslatorReader reader(source);
+    translator->setDescription( reader.description() );
+    while ( reader.hasNextEntry() )
+        translator->addEntry(reader.nextEntry());
+
+    source->close();
+
+    if ( !reader.parseError() )
+    {
+        return translator;
+    }
+    else
+    {
+        delete translator;
+        return 0;
+    }
+}
+
+KeyboardTranslatorWriter::KeyboardTranslatorWriter(QIODevice* destination)
+: _destination(destination)
+{
+    Q_ASSERT( destination && destination->isWritable() );
+
+    _writer = new QTextStream(_destination);
+}
+KeyboardTranslatorWriter::~KeyboardTranslatorWriter()
+{
+    delete _writer;
+}
+void KeyboardTranslatorWriter::writeHeader( const QString& description )
+{
+    *_writer << "keyboard \"" << description << '\"' << '\n';
+}
+void KeyboardTranslatorWriter::writeEntry( const KeyboardTranslator::Entry& entry )
+{
+    QString result;
+    if ( entry.command() != KeyboardTranslator::NoCommand )
+        result = entry.resultToString();
+    else
+        result = '\"' + entry.resultToString() + '\"';
+
+    *_writer << "key " << entry.conditionToString() << " : " << result << '\n';
+}
+
+
+// each line of the keyboard translation file is one of:
+//
+// - keyboard "name"
+// - key KeySequence : "characters"
+// - key KeySequence : CommandName
+//
+// KeySequence begins with the name of the key ( taken from the Qt::Key enum )
+// and is followed by the keyboard modifiers and state flags ( with + or - in front
+// of each modifier or flag to indicate whether it is required ).  All keyboard modifiers
+// and flags are optional, if a particular modifier or state is not specified it is 
+// assumed not to be a part of the sequence.  The key sequence may contain whitespace
+//
+// eg:  "key Up+Shift : scrollLineUp"
+//      "key Next-Shift : "\E[6~"
+//
+// (lines containing only whitespace are ignored, parseLine assumes that comments have
+// already been removed)
+//
+
+KeyboardTranslatorReader::KeyboardTranslatorReader( QIODevice* source )
+    : _source(source)
+    , _hasNext(false)
+{
+   // read input until we find the description
+   while ( _description.isEmpty() && !source->atEnd() )
+   {
+        QList<Token> tokens = tokenize( QString(source->readLine()) );
+        if ( !tokens.isEmpty() && tokens.first().type == Token::TitleKeyword )
+            _description = i18n(tokens[1].text.toLatin1().data());
+   }
+   // read first entry (if any)
+   readNext();
+}
+void KeyboardTranslatorReader::readNext() 
+{
+    // find next entry
+    while ( !_source->atEnd() )
+    {
+        const QList<Token>& tokens = tokenize( QString(_source->readLine()) );
+        if ( !tokens.isEmpty() && tokens.first().type == Token::KeyKeyword )
+        {
+            KeyboardTranslator::States flags = KeyboardTranslator::NoState;
+            KeyboardTranslator::States flagMask = KeyboardTranslator::NoState;
+            Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+            Qt::KeyboardModifiers modifierMask = Qt::NoModifier;
+
+            int keyCode = Qt::Key_unknown;
+
+            decodeSequence(tokens[1].text.toLower(),
+                           keyCode,
+                           modifiers,
+                           modifierMask,
+                           flags,
+                           flagMask); 
+
+            KeyboardTranslator::Command command = KeyboardTranslator::NoCommand;
+            QByteArray text;
+
+            // get text or command
+            if ( tokens[2].type == Token::OutputText )
+            {
+                text = tokens[2].text.toLocal8Bit();
+            }
+            else if ( tokens[2].type == Token::Command )
+            {
+                // identify command
+                if (!parseAsCommand(tokens[2].text,command))
+		  kWarning() << "Command" << tokens[2].text.toStdString() << "not understood.";
+            }
+
+            KeyboardTranslator::Entry newEntry;
+            newEntry.setKeyCode( keyCode );
+            newEntry.setState( flags );
+            newEntry.setStateMask( flagMask );
+            newEntry.setModifiers( modifiers );
+            newEntry.setModifierMask( modifierMask );
+            newEntry.setText( text );
+            newEntry.setCommand( command );
+
+            _nextEntry = newEntry;
+
+            _hasNext = true;
+
+            return;
+        }
+    } 
+
+    _hasNext = false;
+}
+
+bool KeyboardTranslatorReader::parseAsCommand(const QString& text,KeyboardTranslator::Command& command) 
+{
+    if ( text.compare("erase",Qt::CaseInsensitive) == 0 )
+        command = KeyboardTranslator::EraseCommand;
+    else if ( text.compare("scrollpageup",Qt::CaseInsensitive) == 0 )
+        command = KeyboardTranslator::ScrollPageUpCommand;
+    else if ( text.compare("scrollpagedown",Qt::CaseInsensitive) == 0 )
+        command = KeyboardTranslator::ScrollPageDownCommand;
+    else if ( text.compare("scrolllineup",Qt::CaseInsensitive) == 0 )
+        command = KeyboardTranslator::ScrollLineUpCommand;
+    else if ( text.compare("scrolllinedown",Qt::CaseInsensitive) == 0 )
+        command = KeyboardTranslator::ScrollLineDownCommand;
+    else if ( text.compare("scrolllock",Qt::CaseInsensitive) == 0 )
+        command = KeyboardTranslator::ScrollLockCommand;
+    else
+        return false;
+
+    return true;
+}
+
+bool KeyboardTranslatorReader::decodeSequence(const QString& text,
+                                              int& keyCode,
+                                              Qt::KeyboardModifiers& modifiers,
+                                              Qt::KeyboardModifiers& modifierMask,
+                                              KeyboardTranslator::States& flags,
+                                              KeyboardTranslator::States& flagMask)
+{
+    bool isWanted = true; 
+    bool endOfItem = false;
+    QString buffer;
+
+    Qt::KeyboardModifiers tempModifiers = modifiers;
+    Qt::KeyboardModifiers tempModifierMask = modifierMask;
+    KeyboardTranslator::States tempFlags = flags;
+    KeyboardTranslator::States tempFlagMask = flagMask;
+
+    for ( int i = 0 ; i < text.count() ; i++ )
+    {
+        const QChar& ch = text[i];
+        bool isFirstLetter = i == 0;
+        bool isLastLetter = ( i == text.count()-1 );
+        endOfItem = true;
+        if ( ch.isLetterOrNumber() )
+        {
+            endOfItem = false;
+            buffer.append(ch);
+        } else if ( isFirstLetter )
+        {
+            buffer.append(ch);
+        }
+
+        if ( (endOfItem || isLastLetter) && !buffer.isEmpty() )
+        {
+            Qt::KeyboardModifier itemModifier = Qt::NoModifier;
+            int itemKeyCode = 0;
+            KeyboardTranslator::State itemFlag = KeyboardTranslator::NoState;
+
+            if ( parseAsModifier(buffer,itemModifier) )
+            {
+                tempModifierMask |= itemModifier;
+
+                if ( isWanted )
+                    tempModifiers |= itemModifier;
+            }
+            else if ( parseAsStateFlag(buffer,itemFlag) )
+            {
+                tempFlagMask |= itemFlag;
+
+                if ( isWanted )
+                    tempFlags |= itemFlag;
+            }
+            else if ( parseAsKeyCode(buffer,itemKeyCode) )
+                keyCode = itemKeyCode;
+            else
+                kWarning() << "Unable to parse key binding item:" << buffer.toStdString();
+
+            buffer.clear();
+        }
+
+        // check if this is a wanted / not-wanted flag and update the 
+        // state ready for the next item
+        if ( ch == '+' )
+           isWanted = true;
+        else if ( ch == '-' )
+           isWanted = false; 
+    } 
+
+    modifiers = tempModifiers;
+    modifierMask = tempModifierMask;
+    flags = tempFlags;
+    flagMask = tempFlagMask;
+
+    return true;
+}
+
+bool KeyboardTranslatorReader::parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier)
+{
+    if ( item == "shift" )
+        modifier = Qt::ShiftModifier;
+    else if ( item == "ctrl" || item == "control" )
+        modifier = Qt::ControlModifier;
+    else if ( item == "alt" )
+        modifier = Qt::AltModifier;
+    else if ( item == "meta" )
+        modifier = Qt::MetaModifier;
+    else if ( item == "keypad" )
+        modifier = Qt::KeypadModifier;
+    else
+        return false;
+
+    return true;
+}
+bool KeyboardTranslatorReader::parseAsStateFlag(const QString& item , KeyboardTranslator::State& flag)
+{
+    if ( item == "appcukeys" || item == "appcursorkeys" )
+        flag = KeyboardTranslator::CursorKeysState;
+    else if ( item == "ansi" )
+        flag = KeyboardTranslator::AnsiState;
+    else if ( item == "newline" )
+        flag = KeyboardTranslator::NewLineState;
+    else if ( item == "appscreen" )
+        flag = KeyboardTranslator::AlternateScreenState;
+    else if ( item == "anymod" || item == "anymodifier" )
+        flag = KeyboardTranslator::AnyModifierState;
+    else if ( item == "appkeypad" )
+        flag = KeyboardTranslator::ApplicationKeypadState;
+    else
+        return false;
+
+    return true;
+}
+bool KeyboardTranslatorReader::parseAsKeyCode(const QString& item , int& keyCode)
+{
+    QKeySequence sequence = QKeySequence::fromString(item);
+    if ( !sequence.isEmpty() )
+    {
+        keyCode = sequence[0];
+
+        if ( sequence.count() > 1 )
+        {
+            kWarning() << "Unhandled key codes in sequence: " << item.toStdString();
+        }
+    }
+    // additional cases implemented for backwards compatibility with KDE 3
+    else if ( item == "prior" )
+        keyCode = Qt::Key_PageUp;
+    else if ( item == "next" )
+        keyCode = Qt::Key_PageDown;
+    else
+        return false;
+
+    return true;
+}
+
+QString KeyboardTranslatorReader::description() const
+{
+    return _description;
+}
+bool KeyboardTranslatorReader::hasNextEntry()
+{
+    return _hasNext;
+}
+KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& condition , 
+                                                                 const QString& result )
+{
+    QString entryString("keyboard \"temporary\"\nkey ");
+    entryString.append(condition);
+    entryString.append(" : ");
+
+    // if 'result' is the name of a command then the entry result will be that command,
+    // otherwise the result will be treated as a string to echo when the key sequence
+    // specified by 'condition' is pressed
+    KeyboardTranslator::Command command;
+    if (parseAsCommand(result,command))
+        entryString.append(result);
+    else
+        entryString.append('\"' + result + '\"');
+
+    QByteArray array = entryString.toUtf8();
+    QBuffer buffer(&array);
+    buffer.open(QIODevice::ReadOnly);
+    KeyboardTranslatorReader reader(&buffer);
+
+    KeyboardTranslator::Entry entry;
+    if ( reader.hasNextEntry() )
+        entry = reader.nextEntry();
+
+    return entry;
+}
+
+KeyboardTranslator::Entry KeyboardTranslatorReader::nextEntry() 
+{
+    Q_ASSERT( _hasNext );
+    KeyboardTranslator::Entry entry = _nextEntry;
+    readNext();
+    return entry;
+}
+bool KeyboardTranslatorReader::parseError()
+{
+    return false;
+}
+QList<KeyboardTranslatorReader::Token> KeyboardTranslatorReader::tokenize(const QString& line)
+{
+    QString text = line;
+
+    // remove comments 
+    bool inQuotes = false;
+    int commentPos = -1;
+    for (int i=text.length()-1;i>=0;i--)
+    {
+        QChar ch = text[i];
+        if (ch == '\"')
+            inQuotes = !inQuotes;
+        else if (ch == '#' && !inQuotes)
+            commentPos = i;
+    }
+    if (commentPos != -1)
+        text.remove(commentPos,text.length());
+
+    text = text.simplified();
+   
+    // title line: keyboard "title"
+    static QRegExp title("keyboard\\s+\"(.*)\"");
+    // key line: key KeySequence : "output"
+    // key line: key KeySequence : command
+    static QRegExp key("key\\s+([\\w\\+\\s\\-\\*\\.]+)\\s*:\\s*(\"(.*)\"|\\w+)");
+
+    QList<Token> list;
+    if ( text.isEmpty() ) 
+    {
+        return list;
+    }
+
+    if ( title.exactMatch(text) )
+    {
+        Token titleToken = { Token::TitleKeyword , QString() };
+        Token textToken = { Token::TitleText , title.capturedTexts()[1] };
+    
+        list << titleToken << textToken;
+    }
+    else if  ( key.exactMatch(text) )
+    {
+        Token keyToken = { Token::KeyKeyword , QString() };
+        Token sequenceToken = { Token::KeySequence , key.capturedTexts()[1].remove(' ') };
+
+        list << keyToken << sequenceToken;
+
+        if ( key.capturedTexts()[3].isEmpty() )
+        {
+            // capturedTexts()[2] is a command
+            Token commandToken = { Token::Command , key.capturedTexts()[2] };
+            list << commandToken;    
+        }   
+        else
+        {
+            // capturedTexts()[3] is the output string
+           Token outputToken = { Token::OutputText , key.capturedTexts()[3] };
+           list << outputToken;
+        }    
+    }
+    else
+    {
+        kWarning() << "Line in keyboard translator file could not be understood:" << text.toStdString();
+    }
+
+    return list;
+}
+
+QList<QString> KeyboardTranslatorManager::allTranslators() 
+{
+    if ( !_haveLoadedAll )
+    {
+        findTranslators();
+    }
+
+    return _translators.keys();
+}
+
+KeyboardTranslator::Entry::Entry()
+: _keyCode(0)
+, _modifiers(Qt::NoModifier)
+, _modifierMask(Qt::NoModifier)
+, _state(NoState)
+, _stateMask(NoState)
+, _command(NoCommand)
+{
+}
+
+bool KeyboardTranslator::Entry::operator==(const Entry& rhs) const
+{
+    return _keyCode == rhs._keyCode &&
+           _modifiers == rhs._modifiers &&
+           _modifierMask == rhs._modifierMask &&
+           _state == rhs._state &&
+           _stateMask == rhs._stateMask &&
+           _command == rhs._command &&
+           _text == rhs._text;
+}
+
+bool KeyboardTranslator::Entry::matches(int keyCode , 
+                                        Qt::KeyboardModifiers modifiers,
+                                        States testState) const
+{
+    if ( _keyCode != keyCode )
+        return false;
+
+    if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) ) 
+        return false;
+
+    // if modifiers is non-zero, the 'any modifier' state is implicit
+    if ( modifiers != 0 )
+        testState |= AnyModifierState;
+
+    if ( (testState & _stateMask) != (_state & _stateMask) )
+        return false;
+
+    // special handling for the 'Any Modifier' state, which checks for the presence of 
+    // any or no modifiers.  In this context, the 'keypad' modifier does not count.
+    bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier;
+    bool wantAnyModifier = _state & KeyboardTranslator::AnyModifierState;
+    if ( _stateMask & KeyboardTranslator::AnyModifierState )
+    {
+        if ( wantAnyModifier != anyModifiersSet )
+           return false;
+    }
+    
+    return true;
+}
+QByteArray KeyboardTranslator::Entry::escapedText(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
+{
+    QByteArray result(text(expandWildCards,modifiers));
+
+    for ( int i = 0 ; i < result.count() ; i++ )
+    {
+        char ch = result[i];
+        char replacement = 0;
+
+        switch ( ch )
+        {
+            case 27 : replacement = 'E'; break;
+            case 8  : replacement = 'b'; break;
+            case 12 : replacement = 'f'; break;
+            case 9  : replacement = 't'; break;
+            case 13 : replacement = 'r'; break;
+            case 10 : replacement = 'n'; break;
+            default:
+                // any character which is not printable is replaced by an equivalent
+                // \xhh escape sequence (where 'hh' are the corresponding hex digits)
+                if ( !QChar(ch).isPrint() )
+                    replacement = 'x';
+        }
+
+        if ( replacement == 'x' )
+        {
+            result.replace(i,1,"\\x"+QByteArray(1,ch).toHex()); 
+        } else if ( replacement != 0 )
+        {
+            result.remove(i,1);
+            result.insert(i,'\\');
+            result.insert(i+1,replacement);
+        }
+    }
+
+    return result;
+}
+QByteArray KeyboardTranslator::Entry::unescape(const QByteArray& input) const
+{
+    QByteArray result(input);
+
+    for ( int i = 0 ; i < result.count()-1 ; i++ )
+    {
+
+        QByteRef ch = result[i];
+        if ( ch == '\\' )
+        {
+           char replacement[2] = {0,0};
+           int charsToRemove = 2;
+           bool escapedChar = true;
+
+           switch ( result[i+1] )
+           {
+              case 'E' : replacement[0] = 27; break;
+              case 'b' : replacement[0] = 8 ; break;
+              case 'f' : replacement[0] = 12; break;
+              case 't' : replacement[0] = 9 ; break;
+              case 'r' : replacement[0] = 13; break;
+              case 'n' : replacement[0] = 10; break;
+              case 'x' :
+                 {
+                    // format is \xh or \xhh where 'h' is a hexadecimal
+                    // digit from 0-9 or A-F which should be replaced
+                    // with the corresponding character value
+                    char hexDigits[3] = {0};
+
+                    if ( (i < result.count()-2) && isxdigit(result[i+2]) )
+                            hexDigits[0] = result[i+2];
+                    if ( (i < result.count()-3) && isxdigit(result[i+3]) )
+                            hexDigits[1] = result[i+3];
+
+                    unsigned charValue = 0;
+                    sscanf(hexDigits,"%x",&charValue);
+
+                    replacement[0] = (char)charValue; 
+                    charsToRemove = 2 + strlen(hexDigits);
+                  }
+              break;
+              default:
+                  escapedChar = false;
+           }
+
+           if ( escapedChar )
+               result.replace(i,charsToRemove,replacement);
+        }
+    }
+
+    return result;
+}
+
+void KeyboardTranslator::Entry::insertModifier( QString& item , int modifier ) const
+{
+    if ( !(modifier & _modifierMask) )
+        return;
+
+    if ( modifier & _modifiers )
+        item += '+';
+    else
+        item += '-';
+
+    if ( modifier == Qt::ShiftModifier )
+        item += "Shift";
+    else if ( modifier == Qt::ControlModifier )
+        item += "Ctrl";
+    else if ( modifier == Qt::AltModifier )
+        item += "Alt";
+    else if ( modifier == Qt::MetaModifier )
+        item += "Meta";
+    else if ( modifier == Qt::KeypadModifier )
+        item += "KeyPad";
+}
+void KeyboardTranslator::Entry::insertState( QString& item , int state ) const
+{
+    if ( !(state & _stateMask) )
+        return;
+
+    if ( state & _state )
+        item += '+' ;
+    else
+        item += '-' ;
+
+    if ( state == KeyboardTranslator::AlternateScreenState )
+        item += "AppScreen";
+    else if ( state == KeyboardTranslator::NewLineState )
+        item += "NewLine";
+    else if ( state == KeyboardTranslator::AnsiState )
+        item += "Ansi";
+    else if ( state == KeyboardTranslator::CursorKeysState )
+        item += "AppCursorKeys";
+    else if ( state == KeyboardTranslator::AnyModifierState )
+        item += "AnyModifier";
+    else if ( state == KeyboardTranslator::ApplicationKeypadState )
+        item += "AppKeypad";
+}
+QString KeyboardTranslator::Entry::resultToString(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
+{
+    if ( !_text.isEmpty() )
+        return escapedText(expandWildCards,modifiers);
+    else if ( _command == EraseCommand )
+        return "Erase";
+    else if ( _command == ScrollPageUpCommand )
+        return "ScrollPageUp";
+    else if ( _command == ScrollPageDownCommand )
+        return "ScrollPageDown";
+    else if ( _command == ScrollLineUpCommand )
+        return "ScrollLineUp";
+    else if ( _command == ScrollLineDownCommand )
+        return "ScrollLineDown";
+    else if ( _command == ScrollLockCommand )
+        return "ScrollLock";
+
+    return QString();
+}
+QString KeyboardTranslator::Entry::conditionToString() const
+{
+    QString result = QKeySequence(_keyCode).toString();
+
+    insertModifier( result , Qt::ShiftModifier );
+    insertModifier( result , Qt::ControlModifier );
+    insertModifier( result , Qt::AltModifier );
+    insertModifier( result , Qt::MetaModifier );
+    insertModifier( result , Qt::KeypadModifier );
+
+    insertState( result , KeyboardTranslator::AlternateScreenState );
+    insertState( result , KeyboardTranslator::NewLineState );
+    insertState( result , KeyboardTranslator::AnsiState );
+    insertState( result , KeyboardTranslator::CursorKeysState );
+    insertState( result , KeyboardTranslator::AnyModifierState );
+    insertState( result , KeyboardTranslator::ApplicationKeypadState );
+
+    return result;
+}
+
+KeyboardTranslator::KeyboardTranslator(const QString& name)
+: _name(name)
+{
+}
+
+void KeyboardTranslator::setDescription(const QString& description) 
+{
+    _description = description;
+}
+QString KeyboardTranslator::description() const
+{
+    return _description;
+}
+void KeyboardTranslator::setName(const QString& name)
+{
+    _name = name;
+}
+QString KeyboardTranslator::name() const
+{
+    return _name;
+}
+
+QList<KeyboardTranslator::Entry> KeyboardTranslator::entries() const
+{
+    return _entries.values();
+}
+
+void KeyboardTranslator::addEntry(const Entry& entry)
+{
+    const int keyCode = entry.keyCode();
+    _entries.insert(keyCode,entry);
+}
+void KeyboardTranslator::replaceEntry(const Entry& existing , const Entry& replacement)
+{
+    if ( !existing.isNull() )
+        _entries.remove(existing.keyCode(),existing);
+    _entries.insert(replacement.keyCode(),replacement);
+}
+void KeyboardTranslator::removeEntry(const Entry& entry)
+{
+    _entries.remove(entry.keyCode(),entry);
+}
+KeyboardTranslator::Entry KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const
+{
+    foreach(const Entry& entry, _entries.values(keyCode))
+    {
+        if ( entry.matches(keyCode,modifiers,state) )
+            return entry;
+    }
+    return Entry(); // entry not found
+}
+void KeyboardTranslatorManager::addTranslator(KeyboardTranslator* translator)
+{
+    _translators.insert(translator->name(),translator);
+
+    if ( !saveTranslator(translator) )
+        kWarning() << "Unable to save translator" << translator->name().toStdString()
+                   << "to disk.";
+}
+bool KeyboardTranslatorManager::deleteTranslator(const QString& name)
+{
+    Q_ASSERT( _translators.contains(name) );
+
+    // locate and delete
+    QString path = findTranslatorPath(name);
+    if ( QFile::remove(path) )
+    {
+        _translators.remove(name);
+        return true; 
+    }
+    else
+    {
+        kWarning() << "Failed to remove translator - " << path.toStdString();
+        return false;
+    }
+}
+
+/**
+ * @internal
+ */
+typedef void (*KdeCleanUpFunction)();
+
+/**
+ * @internal
+ *
+ * Helper class for K_GLOBAL_STATIC to clean up the object on library unload or application
+ * shutdown.
+ */
+class KCleanUpGlobalStatic
+{
+    public:
+        KdeCleanUpFunction func;
+
+        inline ~KCleanUpGlobalStatic() { func(); }
+};
+
+
+
+#ifdef Q_CC_MSVC
+/**
+ * @internal
+ *
+ * MSVC seems to give anonymous structs the same name which fails at link time. So instead we name
+ * the struct and hope that by adding the line number to the name it's unique enough to never clash.
+ */
+# define K_GLOBAL_STATIC_STRUCT_NAME(NAME) _k_##NAME##__LINE__
+#else
+/**
+ * @internal
+ *
+ * Make the struct of the K_GLOBAL_STATIC anonymous.
+ */
+# define K_GLOBAL_STATIC_STRUCT_NAME(NAME)
+#endif
+
+
+
+#define K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)                            \
+static QBasicAtomicPointer<TYPE > _k_static_##NAME = Q_BASIC_ATOMIC_INITIALIZER(0); \
+static bool _k_static_##NAME##_destroyed;                                      \
+static struct K_GLOBAL_STATIC_STRUCT_NAME(NAME)                                \
+{                                                                              \
+    inline bool isDestroyed() const                                            \
+    {                                                                          \
+        return _k_static_##NAME##_destroyed;                                   \
+    }                                                                          \
+    inline bool exists() const                                                 \
+    {                                                                          \
+        return _k_static_##NAME != 0;                                          \
+    }                                                                          \
+    inline operator TYPE*()                                                    \
+    {                                                                          \
+        return operator->();                                                   \
+    }                                                                          \
+    inline TYPE *operator->()                                                  \
+    {                                                                          \
+        if (!_k_static_##NAME) {                                               \
+            if (isDestroyed()) {                                               \
+                qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \
+                       "Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__);  \
+            }                                                                  \
+            TYPE *x = new TYPE ARGS;                                           \
+            if (!_k_static_##NAME.testAndSetOrdered(0, x)                      \
+                && _k_static_##NAME != x ) {                                   \
+                delete x;                                                      \
+            } else {                                                           \
+                static KCleanUpGlobalStatic cleanUpObject = { destroy };       \
+            }                                                                  \
+        }                                                                      \
+        return _k_static_##NAME;                                               \
+    }                                                                          \
+    inline TYPE &operator*()                                                   \
+    {                                                                          \
+        return *operator->();                                                  \
+    }                                                                          \
+    static void destroy()                                                      \
+    {                                                                          \
+        _k_static_##NAME##_destroyed = true;                                   \
+        TYPE *x = _k_static_##NAME;                                            \
+        _k_static_##NAME = 0;                                                  \
+        delete x;                                                              \
+    }                                                                          \
+} NAME;
+
+#define K_GLOBAL_STATIC(TYPE, NAME) K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
+
+K_GLOBAL_STATIC( KeyboardTranslatorManager , theKeyboardTranslatorManager )
+KeyboardTranslatorManager* KeyboardTranslatorManager::instance()
+{
+    return theKeyboardTranslatorManager;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/KeyboardTranslator.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,584 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef KEYBOARDTRANSLATOR_H
+#define KEYBOARDTRANSLATOR_H
+
+// Qt
+#include <QtCore/QHash>
+#include <QtCore/QList>
+#include <QtGui/QKeySequence>
+#include <QtCore/QMetaType>
+#include <QtCore/QVarLengthArray>
+
+// Konsole
+#include "konsole_export.h"
+
+class QIODevice;
+class QTextStream;
+
+namespace Konsole
+{
+
+/** 
+ * A convertor which maps between key sequences pressed by the user and the
+ * character strings which should be sent to the terminal and commands
+ * which should be invoked when those character sequences are pressed.
+ *
+ * Konsole supports multiple keyboard translators, allowing the user to
+ * specify the character sequences which are sent to the terminal
+ * when particular key sequences are pressed.
+ *
+ * A key sequence is defined as a key code, associated keyboard modifiers
+ * (Shift,Ctrl,Alt,Meta etc.) and state flags which indicate the state
+ * which the terminal must be in for the key sequence to apply.
+ */
+class KeyboardTranslator
+{
+public:
+    /** 
+     * The meaning of a particular key sequence may depend upon the state which
+     * the terminal emulation is in.  Therefore findEntry() may return a different
+     * Entry depending upon the state flags supplied.
+     *
+     * This enum describes the states which may be associated with with a particular
+     * entry in the keyboard translation entry.
+     */
+    enum State
+    {
+        /** Indicates that no special state is active */
+        NoState = 0,
+        /**
+         * TODO More documentation
+         */
+        NewLineState = 1,
+        /** 
+         * Indicates that the terminal is in 'Ansi' mode.
+         * TODO: More documentation
+         */
+        AnsiState = 2,
+        /**
+         * TODO More documentation
+         */
+        CursorKeysState = 4,
+        /**
+         * Indicates that the alternate screen ( typically used by interactive programs
+         * such as screen or vim ) is active 
+         */
+        AlternateScreenState = 8,
+        /** Indicates that any of the modifier keys is active. */ 
+        AnyModifierState = 16,
+        /** Indicates that the numpad is in application mode. */
+        ApplicationKeypadState = 32
+    };
+    Q_DECLARE_FLAGS(States,State)
+
+    /**
+     * This enum describes commands which are associated with particular key sequences.
+     */
+    enum Command
+    {
+        /** Indicates that no command is associated with this command sequence */
+        NoCommand = 0,
+        /** TODO Document me */
+        SendCommand = 1,
+        /** Scroll the terminal display up one page */
+        ScrollPageUpCommand = 2,
+        /** Scroll the terminal display down one page */
+        ScrollPageDownCommand = 4,
+        /** Scroll the terminal display up one line */
+        ScrollLineUpCommand = 8,
+        /** Scroll the terminal display down one line */
+        ScrollLineDownCommand = 16,
+        /** Toggles scroll lock mode */
+        ScrollLockCommand = 32,
+        /** Echos the operating system specific erase character. */
+        EraseCommand = 64
+    };
+    Q_DECLARE_FLAGS(Commands,Command)
+
+    /**
+     * Represents an association between a key sequence pressed by the user
+     * and the character sequence and commands associated with it for a particular
+     * KeyboardTranslator.
+     */
+    class Entry
+    {
+    public:
+        /** 
+         * Constructs a new entry for a keyboard translator.
+         */
+        Entry();
+
+        /** 
+         * Returns true if this entry is null.
+         * This is true for newly constructed entries which have no properties set. 
+         */
+        bool isNull() const;
+
+        /** Returns the commands associated with this entry */
+        Command command() const;
+        /** Sets the command associated with this entry. */
+        void setCommand(Command command);
+
+        /** 
+         * Returns the character sequence associated with this entry, optionally replacing 
+         * wildcard '*' characters with numbers to indicate the keyboard modifiers being pressed.
+         *
+         * TODO: The numbers used to replace '*' characters are taken from the Konsole/KDE 3 code.
+         * Document them. 
+         *
+         * @param expandWildCards Specifies whether wild cards (occurrences of the '*' character) in
+         * the entry should be replaced with a number to indicate the modifier keys being pressed. 
+         *
+         * @param modifiers The keyboard modifiers being pressed.
+         */
+        QByteArray text(bool expandWildCards = false,
+                        Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
+
+        /** Sets the character sequence associated with this entry */
+        void setText(const QByteArray& text);
+
+        /** 
+         * Returns the character sequence associated with this entry,
+         * with any non-printable characters replaced with escape sequences.
+         *
+         * eg. \\E for Escape, \\t for tab, \\n for new line.
+         *
+         * @param expandWildCards See text()
+         * @param modifiers See text()
+         */
+        QByteArray escapedText(bool expandWildCards = false,
+                               Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
+
+        /** Returns the character code ( from the Qt::Key enum ) associated with this entry */
+        int keyCode() const;
+        /** Sets the character code associated with this entry */
+        void setKeyCode(int keyCode);
+
+        /** 
+         * Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry. 
+         * If a modifier is set in modifierMask() but not in modifiers(), this means that the entry
+         * only matches when that modifier is NOT pressed.
+         *
+         * If a modifier is not set in modifierMask() then the entry matches whether the modifier
+         * is pressed or not. 
+         */
+        Qt::KeyboardModifiers modifiers() const;
+
+        /** Returns the keyboard modifiers which are valid in this entry.  See modifiers() */
+        Qt::KeyboardModifiers modifierMask() const;
+
+        /** See modifiers() */
+        void setModifiers( Qt::KeyboardModifiers modifiers );
+        /** See modifierMask() and modifiers() */
+        void setModifierMask( Qt::KeyboardModifiers modifiers );
+
+        /** 
+         * Returns a bitwise-OR of the enabled state flags associated with this entry. 
+         * If flag is set in stateMask() but not in state(), this means that the entry only 
+         * matches when the terminal is NOT in that state.
+         *
+         * If a state is not set in stateMask() then the entry matches whether the terminal
+         * is in that state or not. 
+         */
+        States state() const;
+
+        /** Returns the state flags which are valid in this entry.  See state() */
+        States stateMask() const;
+
+        /** See state() */
+        void setState( States state );
+        /** See stateMask() */
+        void setStateMask( States mask );
+
+        /** 
+         * Returns the key code and modifiers associated with this entry 
+         * as a QKeySequence
+         */
+        //QKeySequence keySequence() const;
+
+        /** 
+         * Returns this entry's conditions ( ie. its key code, modifier and state criteria )
+         * as a string.
+         */
+        QString conditionToString() const;
+
+        /**
+         * Returns this entry's result ( ie. its command or character sequence )
+         * as a string.
+         *
+         * @param expandWildCards See text()
+         * @param modifiers See text()
+         */
+        QString resultToString(bool expandWildCards = false,
+                               Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
+
+        /** 
+         * Returns true if this entry matches the given key sequence, specified
+         * as a combination of @p keyCode , @p modifiers and @p state.
+         */
+        bool matches( int keyCode , 
+                      Qt::KeyboardModifiers modifiers , 
+                      States flags ) const;
+
+        bool operator==(const Entry& rhs) const;
+       
+    private:
+        void insertModifier( QString& item , int modifier ) const;
+        void insertState( QString& item , int state ) const;
+        QByteArray unescape(const QByteArray& text) const;
+
+        int _keyCode;
+        Qt::KeyboardModifiers _modifiers;
+        Qt::KeyboardModifiers _modifierMask;
+        States _state;
+        States _stateMask;
+
+        Command _command;
+        QByteArray _text;
+    };
+
+    /** Constructs a new keyboard translator with the given @p name */
+    KeyboardTranslator(const QString& name);
+   
+    //KeyboardTranslator(const KeyboardTranslator& other);
+
+    /** Returns the name of this keyboard translator */
+    QString name() const;
+
+    /** Sets the name of this keyboard translator */
+    void setName(const QString& name);
+
+    /** Returns the descriptive name of this keyboard translator */
+    QString description() const;
+
+    /** Sets the descriptive name of this keyboard translator */
+    void setDescription(const QString& description);
+
+    /**
+     * Looks for an entry in this keyboard translator which matches the given
+     * key code, keyboard modifiers and state flags.
+     * 
+     * Returns the matching entry if found or a null Entry otherwise ( ie.
+     * entry.isNull() will return true )
+     *
+     * @param keyCode A key code from the Qt::Key enum
+     * @param modifiers A combination of modifiers
+     * @param state Optional flags which specify the current state of the terminal
+     */
+    Entry findEntry(int keyCode , 
+                    Qt::KeyboardModifiers modifiers , 
+                    States state = NoState) const;
+
+    /** 
+     * Adds an entry to this keyboard translator's table.  Entries can be looked up according
+     * to their key sequence using findEntry()
+     */
+    void addEntry(const Entry& entry);
+
+    /**
+     * Replaces an entry in the translator.  If the @p existing entry is null,
+     * then this is equivalent to calling addEntry(@p replacement)
+     */
+    void replaceEntry(const Entry& existing , const Entry& replacement);
+
+    /**
+     * Removes an entry from the table.
+     */
+    void removeEntry(const Entry& entry);
+
+    /** Returns a list of all entries in the translator. */
+    QList<Entry> entries() const;
+
+private:
+
+    QMultiHash<int,Entry> _entries; // entries in this keyboard translation,
+                                                 // entries are indexed according to
+                                                 // their keycode
+    QString _name;
+    QString _description;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::States)
+Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::Commands)
+
+/** 
+ * Parses the contents of a Keyboard Translator (.keytab) file and 
+ * returns the entries found in it.
+ *
+ * Usage example:
+ *
+ * @code
+ *  QFile source( "/path/to/keytab" );
+ *  source.open( QIODevice::ReadOnly );
+ *
+ *  KeyboardTranslator* translator = new KeyboardTranslator( "name-of-translator" );
+ *
+ *  KeyboardTranslatorReader reader(source);
+ *  while ( reader.hasNextEntry() )
+ *      translator->addEntry(reader.nextEntry());
+ *
+ *  source.close();
+ *
+ *  if ( !reader.parseError() )
+ *  {
+ *      // parsing succeeded, do something with the translator
+ *  } 
+ *  else
+ *  {
+ *      // parsing failed
+ *  }
+ * @endcode
+ */
+class KeyboardTranslatorReader
+{
+public:
+    /** Constructs a new reader which parses the given @p source */
+    KeyboardTranslatorReader( QIODevice* source );
+
+    /** 
+     * Returns the description text. 
+     * TODO: More documentation 
+     */
+    QString description() const;
+
+    /** Returns true if there is another entry in the source stream */
+    bool hasNextEntry();
+    /** Returns the next entry found in the source stream */
+    KeyboardTranslator::Entry nextEntry(); 
+
+    /** 
+     * Returns true if an error occurred whilst parsing the input or
+     * false if no error occurred.
+     */
+    bool parseError();
+
+    /**
+     * Parses a condition and result string for a translator entry
+     * and produces a keyboard translator entry.
+     *
+     * The condition and result strings are in the same format as in  
+     */
+    static KeyboardTranslator::Entry createEntry( const QString& condition ,
+                                                  const QString& result );
+private:
+    struct Token
+    {
+        enum Type
+        {
+            TitleKeyword,
+            TitleText,
+            KeyKeyword,
+            KeySequence,
+            Command,
+            OutputText
+        };
+        Type type;
+        QString text;
+    };
+    QList<Token> tokenize(const QString&);
+    void readNext();
+    bool decodeSequence(const QString& , 
+                                int& keyCode,
+                                Qt::KeyboardModifiers& modifiers,
+                                Qt::KeyboardModifiers& modifierMask,
+                                KeyboardTranslator::States& state,
+                                KeyboardTranslator::States& stateFlags);
+
+    static bool parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier);
+    static bool parseAsStateFlag(const QString& item , KeyboardTranslator::State& state);
+    static bool parseAsKeyCode(const QString& item , int& keyCode);
+       static bool parseAsCommand(const QString& text , KeyboardTranslator::Command& command);
+
+    QIODevice* _source;
+    QString _description;
+    KeyboardTranslator::Entry _nextEntry;
+    bool _hasNext;
+};
+
+/** Writes a keyboard translation to disk. */
+class KeyboardTranslatorWriter
+{
+public:
+    /** 
+     * Constructs a new writer which saves data into @p destination.
+     * The caller is responsible for closing the device when writing is complete.
+     */
+    KeyboardTranslatorWriter(QIODevice* destination);
+    ~KeyboardTranslatorWriter();
+
+    /** 
+     * Writes the header for the keyboard translator. 
+     * @param description Description of the keyboard translator. 
+     */
+    void writeHeader( const QString& description );
+    /** Writes a translator entry. */
+    void writeEntry( const KeyboardTranslator::Entry& entry ); 
+
+private:
+    QIODevice* _destination;  
+    QTextStream* _writer;
+};
+
+/**
+ * Manages the keyboard translations available for use by terminal sessions,
+ * see KeyboardTranslator.
+ */
+class KONSOLEPRIVATE_EXPORT KeyboardTranslatorManager
+{
+public:
+    /** 
+     * Constructs a new KeyboardTranslatorManager and loads the list of
+     * available keyboard translations.
+     *
+     * The keyboard translations themselves are not loaded until they are
+     * first requested via a call to findTranslator()
+     */
+    KeyboardTranslatorManager();
+    ~KeyboardTranslatorManager();
+
+    /**
+     * Adds a new translator.  If a translator with the same name 
+     * already exists, it will be replaced by the new translator.
+     *
+     * TODO: More documentation.
+     */
+    void addTranslator(KeyboardTranslator* translator);
+
+    /**
+     * Deletes a translator.  Returns true on successful deletion or false otherwise.
+     *
+     * TODO: More documentation
+     */
+    bool deleteTranslator(const QString& name);
+
+    /** Returns the default translator for Konsole. */
+    const KeyboardTranslator* defaultTranslator();
+
+    /** 
+     * Returns the keyboard translator with the given name or 0 if no translator
+     * with that name exists.
+     *
+     * The first time that a translator with a particular name is requested,
+     * the on-disk .keyboard file is loaded and parsed.  
+     */
+    const KeyboardTranslator* findTranslator(const QString& name);
+    /**
+     * Returns a list of the names of available keyboard translators.
+     *
+     * The first time this is called, a search for available 
+     * translators is started.
+     */
+    QList<QString> allTranslators();
+
+    /** Returns the global KeyboardTranslatorManager instance. */
+   static KeyboardTranslatorManager* instance();
+
+private:
+    static const QByteArray defaultTranslatorText;
+    
+    void findTranslators(); // locate the available translators
+    KeyboardTranslator* loadTranslator(const QString& name); // loads the translator 
+                                                             // with the given name
+    KeyboardTranslator* loadTranslator(QIODevice* device,const QString& name);
+
+    bool saveTranslator(const KeyboardTranslator* translator);
+    QString findTranslatorPath(const QString& name);
+    
+    QHash<QString,KeyboardTranslator*> _translators; // maps translator-name -> KeyboardTranslator
+                                                     // instance
+    bool _haveLoadedAll;
+};
+
+inline int KeyboardTranslator::Entry::keyCode() const { return _keyCode; }
+inline void KeyboardTranslator::Entry::setKeyCode(int keyCode) { _keyCode = keyCode; }
+
+inline void KeyboardTranslator::Entry::setModifiers( Qt::KeyboardModifiers modifier ) 
+{ 
+    _modifiers = modifier;
+}
+inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifiers() const { return _modifiers; }
+
+inline void  KeyboardTranslator::Entry::setModifierMask( Qt::KeyboardModifiers mask ) 
+{ 
+   _modifierMask = mask; 
+}
+inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifierMask() const { return _modifierMask; }
+
+inline bool KeyboardTranslator::Entry::isNull() const
+{
+    return ( *this == Entry() );
+}
+
+inline void KeyboardTranslator::Entry::setCommand( Command command )
+{ 
+    _command = command; 
+}
+inline KeyboardTranslator::Command KeyboardTranslator::Entry::command() const { return _command; }
+
+inline void KeyboardTranslator::Entry::setText( const QByteArray& text )
+{ 
+    _text = unescape(text);
+}
+inline int oneOrZero(int value)
+{
+    return value ? 1 : 0;
+}
+inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards,Qt::KeyboardModifiers modifiers) const 
+{
+    QByteArray expandedText = _text;
+    
+    if (expandWildCards)
+    {
+        int modifierValue = 1;
+        modifierValue += oneOrZero(modifiers & Qt::ShiftModifier);
+        modifierValue += oneOrZero(modifiers & Qt::AltModifier)     << 1;
+        modifierValue += oneOrZero(modifiers & Qt::ControlModifier) << 2;
+
+        for (int i=0;i<_text.length();i++) 
+        {
+            if (expandedText[i] == '*')
+                expandedText[i] = '0' + modifierValue;
+        }
+    }
+
+    return expandedText; 
+}
+
+inline void KeyboardTranslator::Entry::setState( States state )
+{ 
+    _state = state; 
+}
+inline KeyboardTranslator::States KeyboardTranslator::Entry::state() const { return _state; }
+
+inline void KeyboardTranslator::Entry::setStateMask( States stateMask )
+{ 
+    _stateMask = stateMask; 
+}
+inline KeyboardTranslator::States KeyboardTranslator::Entry::stateMask() const { return _stateMask; }
+
+}
+
+Q_DECLARE_METATYPE(Konsole::KeyboardTranslator::Entry)
+Q_DECLARE_METATYPE(const Konsole::KeyboardTranslator*)
+
+#endif // KEYBOARDTRANSLATOR_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/LineFont.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,21 @@
+// WARNING: Autogenerated by "fontembedder ./linefont.src".
+// You probably do not want to hand-edit this!
+
+static const quint32 LineChars[] = {
+    0x00007c00, 0x000fffe0, 0x00421084, 0x00e739ce, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00427000, 0x004e7380, 0x00e77800, 0x00ef7bc0, 
+    0x00421c00, 0x00439ce0, 0x00e73c00, 0x00e7bde0, 0x00007084, 0x000e7384, 0x000079ce, 0x000f7bce, 
+    0x00001c84, 0x00039ce4, 0x00003dce, 0x0007bdee, 0x00427084, 0x004e7384, 0x004279ce, 0x00e77884, 
+    0x00e779ce, 0x004f7bce, 0x00ef7bc4, 0x00ef7bce, 0x00421c84, 0x00439ce4, 0x00423dce, 0x00e73c84, 
+    0x00e73dce, 0x0047bdee, 0x00e7bde4, 0x00e7bdee, 0x00427c00, 0x0043fce0, 0x004e7f80, 0x004fffe0, 
+    0x004fffe0, 0x00e7fde0, 0x006f7fc0, 0x00efffe0, 0x00007c84, 0x0003fce4, 0x000e7f84, 0x000fffe4, 
+    0x00007dce, 0x0007fdee, 0x000f7fce, 0x000fffee, 0x00427c84, 0x0043fce4, 0x004e7f84, 0x004fffe4, 
+    0x00427dce, 0x00e77c84, 0x00e77dce, 0x0047fdee, 0x004e7fce, 0x00e7fde4, 0x00ef7f84, 0x004fffee, 
+    0x00efffe4, 0x00e7fdee, 0x00ef7fce, 0x00efffee, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
+    0x000f83e0, 0x00a5294a, 0x004e1380, 0x00a57800, 0x00ad0bc0, 0x004390e0, 0x00a53c00, 0x00a5a1e0, 
+    0x000e1384, 0x0000794a, 0x000f0b4a, 0x000390e4, 0x00003d4a, 0x0007a16a, 0x004e1384, 0x00a5694a, 
+    0x00ad2b4a, 0x004390e4, 0x00a52d4a, 0x00a5a16a, 0x004f83e0, 0x00a57c00, 0x00ad83e0, 0x000f83e4, 
+    0x00007d4a, 0x000f836a, 0x004f93e4, 0x00a57d4a, 0x00ad836a, 0x00000000, 0x00000000, 0x00000000, 
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00001c00, 0x00001084, 0x00007000, 0x00421000, 
+    0x00039ce0, 0x000039ce, 0x000e7380, 0x00e73800, 0x000e7f80, 0x00e73884, 0x0003fce0, 0x004239ce
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/MainWindow.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,527 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "MainWindow.h"
+#include "SessionManager.h"
+
+// Qt
+#include <QtGui/QBoxLayout>
+
+// KDE
+#include <KAcceleratorManager>
+#include <KAction>
+#include <KActionCollection>
+#include <KActionMenu>
+#include <KApplication>
+#include <KCmdLineArgs>
+#include <KShortcutsDialog>
+#include <KLocale>
+#include <KMenu>
+#include <KMenuBar>
+#include <KMessageBox>
+#include <KService>
+#include <KToggleAction>
+#include <KToggleFullScreenAction>
+#include <KToolInvocation>
+#include <KStandardAction>
+#include <KStandardGuiItem>
+#include <KWindowSystem>
+#include <KXMLGUIFactory>
+#include <KNotifyConfigWidget>
+
+// Konsole
+#include "BookmarkHandler.h"
+#include "IncrementalSearchBar.h"
+#include "RemoteConnectionDialog.h"
+#include "SessionController.h"
+#include "ProfileList.h"
+#include "ManageProfilesDialog.h"
+#include "Session.h"
+#include "ViewManager.h"
+#include "ViewSplitter.h"
+
+using namespace Konsole;
+
+static bool useTransparency()
+{
+    KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+    bool compositingAvailable = KWindowSystem::compositingActive() ||
+                                args->isSet("force-transparency");
+    return compositingAvailable && args->isSet("transparency");
+}
+
+MainWindow::MainWindow()
+ : KXmlGuiWindow() ,
+   _bookmarkHandler(0),
+   _pluggedController(0),
+   _menuBarVisibilitySet(false)
+{
+    if (useTransparency()) {
+        setAttribute(Qt::WA_TranslucentBackground);
+        setAttribute(Qt::WA_NoSystemBackground, false);
+    }
+
+    // create actions for menus
+    setupActions();
+
+    // create view manager
+        _viewManager = new ViewManager(this,actionCollection());
+    connect( _viewManager , SIGNAL(empty()) , this , SLOT(close()) );
+    connect( _viewManager , SIGNAL(activeViewChanged(SessionController*)) , this ,
+            SLOT(activeViewChanged(SessionController*)) );
+    connect( _viewManager , SIGNAL(unplugController(SessionController*)) , this ,
+            SLOT(disconnectController(SessionController*)) );
+    connect( _viewManager , SIGNAL(viewPropertiesChanged(const QList<ViewProperties*>&)) ,
+           bookmarkHandler() , SLOT(setViews(const QList<ViewProperties*>&)) );
+
+    connect( _viewManager , SIGNAL(setMenuBarVisibleRequest(bool)) , this ,
+            SLOT(setMenuBarVisibleOnce(bool)) );
+    connect( _viewManager , SIGNAL(setSaveGeometryOnExitRequest(bool)) , this ,
+	    SLOT(setSaveGeometryOnExit(bool)) );
+    connect( _viewManager , SIGNAL(newViewRequest(Profile::Ptr)) , 
+        this , SLOT(newFromProfile(Profile::Ptr)) );
+    connect( _viewManager , SIGNAL(newViewRequest()) , 
+        this , SLOT(newTab()));
+
+    // create main window widgets
+    setupWidgets();
+
+    // disable automatically generated accelerators in top-level
+    // menu items - to avoid conflicting with Alt+[Letter] shortcuts
+    // in terminal applications
+    KAcceleratorManager::setNoAccel(menuBar());
+    // create menus
+    createGUI();
+    // remove accelerators for standard menu items (eg. &File, &View, &Edit)
+    // etc. which are defined in kdelibs/kdeui/xmlgui/ui_standards.rc, again,
+    // to avoid conflicting with Alt+[Letter] terminal shortcuts
+    //
+    // TODO - Modify XMLGUI so that it allows the text for standard actions
+    // defined in ui_standards.rc to be re-defined in the local application
+    // XMLGUI file (konsoleui.rc in this case) - the text for standard items
+    // can then be redefined there to exclude the standard accelerators
+    removeMenuAccelerators();
+    // replace standard shortcuts which cannot be used in a terminal
+    // (as they are reserved for use by terminal programs)
+    correctShortcuts();
+
+    // enable save and restore of window size
+    setAutoSaveSettings("MainWindow",true);
+}
+void MainWindow::removeMenuAccelerators()
+{
+    foreach(QAction* menuItem, menuBar()->actions())
+    {
+        QString itemText = menuItem->text();
+        itemText = KGlobal::locale()->removeAcceleratorMarker(itemText);
+        menuItem->setText(itemText);
+    }
+}
+void MainWindow::setMenuBarVisibleOnce(bool visible)
+{
+    if (_menuBarVisibilitySet || menuBar()->isTopLevelMenu() )
+        return;
+
+    menuBar()->setVisible(visible);
+    _toggleMenuBarAction->setChecked(visible);
+
+    _menuBarVisibilitySet = true;
+}
+
+void MainWindow::setSaveGeometryOnExit(bool save)
+{
+    setAutoSaveSettings("MainWindow",save);
+}
+
+void MainWindow::correctShortcuts()
+{
+    // replace F1 shortcut for help contents
+    QAction* helpAction = actionCollection()->action("help_contents");
+
+    Q_ASSERT( helpAction );
+
+    helpAction->setShortcut(QKeySequence());
+   
+    // replace Ctrl+B shortcut for bookmarks
+    // TODO - Make this configurable
+    QAction* bookmarkAction = actionCollection()->action("add_bookmark");
+    Q_ASSERT(bookmarkAction);
+    bookmarkAction->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_B));
+}
+
+void MainWindow::setDefaultProfile(Profile::Ptr profile)
+{
+    _defaultProfile = profile;
+}
+Profile::Ptr MainWindow::defaultProfile() const
+{
+    return _defaultProfile;
+}
+
+ViewManager* MainWindow::viewManager() const
+{
+    return _viewManager;
+}
+
+void MainWindow::disconnectController(SessionController* controller)
+{
+    disconnect( controller , SIGNAL(titleChanged(ViewProperties*))
+                     , this , SLOT(activeViewTitleChanged(ViewProperties*)) );
+
+    // KXmlGuiFactory::removeClient() will try to access actions associated
+    // with the controller internally, which may not be valid after the controller
+    // itself is no longer valid (after the associated session and or view have
+    // been destroyed)
+    if (controller->isValid())
+        guiFactory()->removeClient(controller);
+
+    controller->setSearchBar(0);
+}
+
+void MainWindow::activeViewChanged(SessionController* controller)
+{
+    // associate bookmark menu with current session
+    bookmarkHandler()->setActiveView(controller);
+    disconnect( bookmarkHandler() , SIGNAL(openUrl(const KUrl&)) , 0 , 0 );
+    connect( bookmarkHandler() , SIGNAL(openUrl(const KUrl&)) , controller ,
+             SLOT(openUrl(const KUrl&)) );
+
+    if ( _pluggedController )
+        disconnectController(_pluggedController);
+
+    // listen for title changes from the current session
+    Q_ASSERT( controller );
+
+    connect( controller , SIGNAL(titleChanged(ViewProperties*)) ,
+            this , SLOT(activeViewTitleChanged(ViewProperties*)) );
+
+    controller->setShowMenuAction( _toggleMenuBarAction );
+    guiFactory()->addClient(controller);
+
+    // set the current session's search bar
+    controller->setSearchBar( searchBar() );
+
+    // update session title to match newly activated session
+    activeViewTitleChanged(controller);
+
+    _pluggedController = controller;
+}
+
+void MainWindow::activeViewTitleChanged(ViewProperties* properties)
+{
+    setPlainCaption(properties->title());
+}
+
+IncrementalSearchBar* MainWindow::searchBar() const
+{
+    return _viewManager->searchBar();
+}
+
+void MainWindow::setupActions()
+{
+    KActionCollection* collection = actionCollection();
+
+    // File Menu
+    _newTabMenuAction = new KActionMenu(KIcon("tab-new"), i18n("&New Tab"), collection);
+    _newTabMenuAction->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_T) );
+    _newTabMenuAction->setShortcutConfigurable(true);
+    _newTabMenuAction->setAutoRepeat( false );
+    connect(_newTabMenuAction, SIGNAL(triggered()), this, SLOT(newTab()));
+    collection->addAction("new-tab", _newTabMenuAction);
+
+    KAction* action = collection->addAction("new-window");
+    action->setIcon( KIcon("window-new") );
+    action->setText( i18n("New &Window") );
+    action->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_N) );
+    action->setAutoRepeat( false );
+    connect( action , SIGNAL(triggered()) , this , SLOT(newWindow()) );
+
+    action = collection->addAction("remote-connection");
+    action->setText( i18n("Remote Connection...") );
+    action->setIcon( KIcon("network-connect") );
+    action->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_R) );
+    connect( action , SIGNAL(triggered()) , this , SLOT(showRemoteConnectionDialog()) );
+
+    action = KStandardAction::quit( this , SLOT(close()) , collection );
+    // the default shortcut for quit is typically Ctrl+[Some Letter, usually Q] but that is reserved for
+    // use by terminal applications
+    action->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Q) );
+
+    // Bookmark Menu
+    KActionMenu* bookmarkMenu = new KActionMenu(i18n("&Bookmarks") , collection );
+    _bookmarkHandler = new BookmarkHandler( collection , bookmarkMenu->menu() , true , this );
+    collection->addAction("bookmark" , bookmarkMenu);
+
+    connect( _bookmarkHandler , SIGNAL(openUrls(QList<KUrl>)) , this , SLOT(openUrls(QList<KUrl>)) );
+
+    //TODO: The 'Add Bookmark' menu action currently has a Ctrl+B shortcut by
+    //      default which cannot be overridden
+    //NOTE: This is currently handled by correctShortcuts()
+
+    // View Menu
+    _toggleMenuBarAction = KStandardAction::showMenubar(menuBar(), SLOT(setVisible(bool)), collection);
+    _toggleMenuBarAction->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_M) );
+
+    // Hide the Show/Hide menubar item if the menu bar is a MacOS-style menu bar
+    if ( menuBar()->isTopLevelMenu() )
+        _toggleMenuBarAction->setVisible(false);
+
+    // Full Screen
+    action = KStandardAction::fullScreen(this, SLOT(viewFullScreen(bool)), this, collection);
+    action->setShortcut( QKeySequence() );
+
+    // Settings Menu
+    KStandardAction::configureNotifications( this , SLOT(configureNotifications()) , collection  );
+    KStandardAction::keyBindings( this , SLOT(showShortcutsDialog()) , collection  );
+
+    action = collection->addAction("configure-profiles");
+    action->setText( i18n("Configure Profiles...") );
+    action->setIcon( KIcon("configure") );
+    connect( action, SIGNAL(triggered()) , this , SLOT(showManageProfilesDialog()) );
+
+}
+
+void MainWindow::viewFullScreen(bool fullScreen)
+{
+    if ( fullScreen )
+        setWindowState( windowState() | Qt::WindowFullScreen );
+    else
+        setWindowState( windowState() & ~Qt::WindowFullScreen );
+}
+
+BookmarkHandler* MainWindow::bookmarkHandler() const
+{
+    return _bookmarkHandler;
+}
+
+void MainWindow::setSessionList(ProfileList* list)
+{
+    sessionListChanged(list->actions());
+
+    connect( list , SIGNAL(profileSelected(Profile::Ptr)) , this ,
+            SLOT(newFromProfile(Profile::Ptr)) );
+
+    connect( list , SIGNAL(actionsChanged(const QList<QAction*>&)) , this ,
+            SLOT(sessionListChanged(const QList<QAction*>&)) );
+}
+
+void MainWindow::sessionListChanged(const QList<QAction*>& actions)
+{
+    // Update the 'New Tab' KActionMenu
+    KMenu *newTabMenu = _newTabMenuAction->menu();
+    newTabMenu->clear();
+    foreach (QAction *action, actions) {
+        newTabMenu->addAction(action);
+
+        // NOTE: _defaultProfile seems to not work here, sigh.
+        Profile::Ptr profile = SessionManager::instance()->defaultProfile();
+        if (profile && profile->name() == action->text()) {
+            action->setIcon(KIcon(profile->icon(), NULL, QStringList("emblem-favorite")));
+            newTabMenu->setDefaultAction(action);
+            QFont font = action->font();
+            font.setBold(true);
+            action->setFont(font);
+        }
+    }
+
+}
+
+QString MainWindow::activeSessionDir() const
+{
+    if ( _pluggedController )
+        return _pluggedController->currentDir();
+    else
+        return QString();
+}
+
+void MainWindow::openUrls(const QList<KUrl>& urls)
+{
+    foreach( const KUrl& url , urls )
+    {
+        if ( url.isLocalFile() )
+            emit newSessionRequest( _defaultProfile , url.path() , _viewManager );
+
+        else if ( url.protocol() == "ssh" )
+            emit newSSHSessionRequest( _defaultProfile , url , _viewManager );
+    }
+}
+
+void MainWindow::newTab()
+{
+    emit newSessionRequest( _defaultProfile , activeSessionDir() , _viewManager);
+}
+
+void MainWindow::newWindow()
+{
+    emit newWindowRequest( _defaultProfile , activeSessionDir() );
+}
+
+bool MainWindow::queryClose()
+{
+    if (kapp->sessionSaving() ||
+        _viewManager->viewProperties().count() < 2)
+        return true;
+
+    int result = KMessageBox::warningYesNoCancel(this,
+                i18n("You have multiple tabs in this window, "
+                     "are you sure you want to quit?"),
+                i18n("Confirm Close"),
+                KStandardGuiItem::quit(),
+                KGuiItem(i18n("Close Current Tab"), "tab-close"),
+                KStandardGuiItem::cancel(),
+                "CloseAllTabs");
+
+    switch (result)
+    {
+    case KMessageBox::Yes:
+        return true;
+    case KMessageBox::No:
+        if (_pluggedController && _pluggedController->session())
+        {
+            disconnectController(_pluggedController);
+            _pluggedController->session()->close();
+        }
+        return false;
+    case KMessageBox::Cancel:
+        return false;
+    }
+
+    return true;
+}
+
+void MainWindow::saveProperties(KConfigGroup& group)
+{
+    if (_defaultProfile)
+        group.writePathEntry("Default Profile", _defaultProfile->path());
+    _viewManager->saveSessions(group);
+}
+
+void MainWindow::readProperties(const KConfigGroup& group)
+{
+    SessionManager *manager = SessionManager::instance();
+    QString profilePath = group.readPathEntry("Default Profile", QString());
+    Profile::Ptr profile = manager->defaultProfile();
+    if (!profilePath.isEmpty()) 
+        profile = manager->loadProfile(profilePath);
+    setDefaultProfile(profile);
+    _viewManager->restoreSessions(group);
+}
+
+void MainWindow::saveGlobalProperties(KConfig* config)
+{
+    SessionManager::instance()->saveSessions(config);
+}
+
+void MainWindow::readGlobalProperties(KConfig* config)
+{
+    SessionManager::instance()->restoreSessions(config);
+}
+
+void MainWindow::syncActiveShortcuts(KActionCollection* dest, const KActionCollection* source)
+{
+    foreach(QAction* qAction, source->actions()) 
+    {
+        if (KAction* kAction = qobject_cast<KAction*>(qAction))
+        {
+           if (KAction* destKAction = qobject_cast<KAction*>(dest->action(kAction->objectName())))
+               destKAction->setShortcut(kAction->shortcut(KAction::ActiveShortcut),KAction::ActiveShortcut);
+        }
+    }
+}
+void MainWindow::showShortcutsDialog()
+{
+    KShortcutsDialog dialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, this);
+
+    // add actions from this window and the current session controller
+    foreach(KXMLGUIClient* client, guiFactory()->clients())
+                dialog.addCollection(client->actionCollection());
+
+    if (dialog.configure())
+    {
+        // sync shortcuts for non-session actions (defined in "konsoleui.rc") in other main windows
+        foreach(QWidget* widget, QApplication::topLevelWidgets())
+        {
+            MainWindow* window = qobject_cast<MainWindow*>(widget);
+            if (window && window != this)
+                syncActiveShortcuts(window->actionCollection(),actionCollection());
+        }
+        // sync shortcuts for session actions (defined in "sessionui.rc") in other session controllers.
+        // Controllers which are currently plugged in (ie. their actions are part of the current menu)
+        // must be updated immediately via syncActiveShortcuts().  Other controllers will be updated
+        // when they are plugged into a main window.
+        foreach(SessionController* controller, SessionController::allControllers())
+        {
+            controller->reloadXML();
+            if (controller->factory() && controller != _pluggedController)
+                syncActiveShortcuts(controller->actionCollection(),_pluggedController->actionCollection());
+        }
+    }
+}
+
+void MainWindow::newFromProfile(Profile::Ptr profile)
+{
+    emit newSessionRequest(profile, activeSessionDir(), _viewManager);
+}
+void MainWindow::showManageProfilesDialog()
+{
+    ManageProfilesDialog* dialog = new ManageProfilesDialog(this);
+    dialog->show();
+}
+
+void MainWindow::showRemoteConnectionDialog()
+{
+//    RemoteConnectionDialog dialog(this);
+//    if ( dialog.exec() == QDialog::Accepted )
+//        emit newSessionRequest(dialog.sessionKey(),QString(),_viewManager);
+}
+
+void MainWindow::setupWidgets()
+{
+    QWidget* widget = new QWidget(this);
+    QVBoxLayout* layout = new QVBoxLayout();
+
+    layout->addWidget( _viewManager->widget() );
+    layout->setContentsMargins(0, 0, 0, 0);
+    layout->setSpacing(0);
+
+    widget->setLayout(layout);
+
+    setCentralWidget(widget);
+}
+
+void MainWindow::configureNotifications()
+{
+    KNotifyConfigWidget::configure( this );
+}
+
+void MainWindow::showEvent(QShowEvent *event)
+{
+    // This code from Konqueror.
+    // We need to check if our toolbars are shown/hidden here, and set
+    // our menu items accordingly. We can't do it in the constructor because
+    // view profiles store toolbar info, and that info is read after
+    // construct time.
+    _toggleMenuBarAction->setChecked( !menuBar()->isHidden() );
+    // Call parent method
+    KXmlGuiWindow::showEvent(event);
+}
+
+#include "MainWindow.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/MainWindow.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,213 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef KONSOLEMAINWINDOW_H
+#define KONSOLEMAINWINDOW_H
+
+// Qt
+#include <QtCore/QPointer>
+
+// KDE
+#include <KXmlGuiWindow>
+#include <KUrl>
+
+// Local
+#include "Profile.h"
+
+class KAction;
+class KActionMenu;
+class KToggleAction;
+
+namespace Konsole
+{
+
+class IncrementalSearchBar;
+class ViewManager;
+class ViewProperties;
+class SessionController;
+class ProfileList;
+class BookmarkHandler;
+
+/**
+ * The main window.  This contains the menus and an area which contains the terminal displays.
+ *
+ * The main window does not create the views or the container widgets which hold the views.
+ * This is done by the ViewManager class.  When a MainWindow is instantiated, it creates
+ * a new ViewManager.  The ViewManager can then be used to create new terminal displays
+ * inside the window.
+ *
+ * Do not construct new main windows directly, use Application's newMainWindow() method.
+ */
+class MainWindow : public KXmlGuiWindow
+{
+    Q_OBJECT
+
+    public:
+        /** 
+         * Constructs a new main window.  Do not create new main windows directly, use Application's
+         * newMainWindow() method instead.
+         */
+        MainWindow();
+
+        /**
+         * Returns the view manager associated with this window.  The view manager can be used to 
+         * create new views on particular session objects inside this window.
+         */
+        ViewManager* viewManager() const;
+
+        /**
+         * Returns the search bar.
+         * TODO - More documentation
+         */
+        IncrementalSearchBar* searchBar() const;
+
+        /** Sets the list of sessions to be displayed in the File menu */
+        void setSessionList(ProfileList* list);
+
+        /**
+         * Returns the bookmark handler associated with this window.
+         */
+        BookmarkHandler* bookmarkHandler() const;
+
+        /**
+         * Sets the default profile for this window.
+         * This is the default value for the profile argument
+         * when the newSessionRequest() and newWindow() signals 
+         * are emitted.
+         */
+        void setDefaultProfile(Profile::Ptr profile);
+
+        /**
+         * Returns the default profile for this window.
+         * See setDefaultProfile()
+         */
+        Profile::Ptr defaultProfile() const;
+
+        
+    signals:
+        /** 
+         * Emitted by the main window to request the creation of a new session.
+         *
+         * @param profile The profile to use to create the new session.
+         * @param directory Initial working directory for the new session or empty 
+         * if the default working directory associated with the profile should be used.
+         * @param view The view manager owned by this main window 
+         */
+        void newSessionRequest(Profile::Ptr profile,
+                               const QString& directory,
+                               ViewManager* view);
+
+        /**
+         * Emitted by the main window to request the creation of a new SSH session.
+         *
+         * @param profile The profile to use to create the new session.
+         * @param url URL for the new session
+         * @param view The view manager owned by this main window
+         */
+        void newSSHSessionRequest(Profile::Ptr profile,
+                                  const KUrl& url,
+                                  ViewManager* view);
+
+        /**
+         * Emitted by the main window to request the creation of a 
+         * new session in a new window.
+         *
+         * @param profile The profile to use to create the 
+         * first session in the new window.
+         * @param directory Initial working directory for the new window or empty
+         * if the default working directory associated with the profile should
+         * be used.
+         */
+        void newWindowRequest(Profile::Ptr profile,
+                              const QString& directory);
+
+        /**
+         * Emitted by the main window to request the current session to close.
+         */
+        void closeActiveSessionRequest();
+
+    protected:
+        // Reimplemented for internal reasons.
+        virtual void showEvent(QShowEvent *event);
+
+        // reimplemented from KMainWindow
+        virtual bool queryClose();
+        virtual void saveProperties(KConfigGroup& group);
+        virtual void readProperties(const KConfigGroup& group);
+        virtual void saveGlobalProperties(KConfig* config);
+        virtual void readGlobalProperties(KConfig* config);
+
+    private slots:
+        void newTab();
+        void newWindow();
+        void showManageProfilesDialog();
+        void showRemoteConnectionDialog();
+        void showShortcutsDialog();
+        void newFromProfile(Profile::Ptr profile);
+        void activeViewChanged(SessionController* controller);
+        void disconnectController(SessionController* controller);
+        void activeViewTitleChanged(ViewProperties*);
+
+        void sessionListChanged(const QList<QAction*>& actions);
+        void viewFullScreen(bool fullScreen);
+        void configureNotifications();
+
+        // single shot call to set the visibility of the menu bar.  Has no 
+        // effect if the menu bar is a MacOS-style top-level menu
+        void setMenuBarVisibleOnce(bool visible);
+
+        void setSaveGeometryOnExit(bool visible);
+
+        void openUrls(const QList<KUrl>& urls);
+
+    private:
+        void correctShortcuts();
+        void removeMenuAccelerators();
+        void setupActions();
+        void setupWidgets();
+        QString activeSessionDir() const;
+
+        // sets the active shortcuts of actions in 'dest' to the shortcuts of actions
+        // with the same name in 'source' (see KAction::ActiveShortcut)
+        static void syncActiveShortcuts(KActionCollection* dest, const KActionCollection* source);
+
+    private:
+        ViewManager*  _viewManager;
+        BookmarkHandler* _bookmarkHandler;
+        KToggleAction* _toggleMenuBarAction;
+        KActionMenu *_newTabMenuAction;
+
+        QPointer<SessionController> _pluggedController;
+
+        Profile::Ptr _defaultProfile;
+        bool _menuBarVisibilitySet;
+};
+
+}
+
+#endif // KONSOLEMAINWINDOW_H
+
+/*
+  Local Variables:
+  mode: c++
+  c-file-style: "stroustrup"
+  indent-tabs-mode: nil
+  tab-width: 4
+  End:
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Makefile	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,676 @@
+# CMAKE generated file: DO NOT EDIT!
+# Generated by "Unix Makefiles" Generator, CMake Version 2.8
+
+# Default target executed when no arguments are given to make.
+default_target: all
+.PHONY : default_target
+
+#=============================================================================
+# Special targets provided by cmake.
+
+# Disable implicit rules so canoncical targets will work.
+.SUFFIXES:
+
+# Remove some rules from gmake that .SUFFIXES does not remove.
+SUFFIXES =
+
+.SUFFIXES: .hpux_make_needs_suffix_list
+
+# Suppress display of executed commands.
+$(VERBOSE).SILENT:
+
+# A target that is always out of date.
+cmake_force:
+.PHONY : cmake_force
+
+#=============================================================================
+# Set environment variables for the build.
+
+# The shell in which to execute make rules.
+SHELL = /bin/sh
+
+# The CMake executable.
+CMAKE_COMMAND = /usr/bin/cmake
+
+# The command to remove a file.
+RM = /usr/bin/cmake -E remove -f
+
+# The program to use to edit the cache.
+CMAKE_EDIT_COMMAND = /usr/bin/ccmake
+
+# The top-level source directory on which CMake was run.
+CMAKE_SOURCE_DIR = /home/jacob/octave/gui/konsole
+
+# The top-level build directory on which CMake was run.
+CMAKE_BINARY_DIR = /home/jacob/octave/gui/konsole
+
+#=============================================================================
+# Targets provided globally by CMake.
+
+# Special rule for the target edit_cache
+edit_cache:
+	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
+	/usr/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+.PHONY : edit_cache
+
+# Special rule for the target edit_cache
+edit_cache/fast: edit_cache
+.PHONY : edit_cache/fast
+
+# Special rule for the target rebuild_cache
+rebuild_cache:
+	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
+	/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
+.PHONY : rebuild_cache
+
+# Special rule for the target rebuild_cache
+rebuild_cache/fast: rebuild_cache
+.PHONY : rebuild_cache/fast
+
+# The main all target
+all: cmake_check_build_system
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/jacob/octave/gui/konsole/CMakeFiles /home/jacob/octave/gui/konsole/CMakeFiles/progress.marks
+	$(MAKE) -f CMakeFiles/Makefile2 all
+	$(CMAKE_COMMAND) -E cmake_progress_start /home/jacob/octave/gui/konsole/CMakeFiles 0
+.PHONY : all
+
+# The main clean target
+clean:
+	$(MAKE) -f CMakeFiles/Makefile2 clean
+.PHONY : clean
+
+# The main clean target
+clean/fast: clean
+.PHONY : clean/fast
+
+# Prepare targets for installation.
+preinstall: all
+	$(MAKE) -f CMakeFiles/Makefile2 preinstall
+.PHONY : preinstall
+
+# Prepare targets for installation.
+preinstall/fast:
+	$(MAKE) -f CMakeFiles/Makefile2 preinstall
+.PHONY : preinstall/fast
+
+# clear depends
+depend:
+	$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
+.PHONY : depend
+
+#=============================================================================
+# Target rules for targets named qtermwidget
+
+# Build rule for target.
+qtermwidget: cmake_check_build_system
+	$(MAKE) -f CMakeFiles/Makefile2 qtermwidget
+.PHONY : qtermwidget
+
+# fast build rule for target.
+qtermwidget/fast:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/build
+.PHONY : qtermwidget/fast
+
+BlockArray.o: BlockArray.cpp.o
+.PHONY : BlockArray.o
+
+# target to build an object file
+BlockArray.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/BlockArray.cpp.o
+.PHONY : BlockArray.cpp.o
+
+BlockArray.i: BlockArray.cpp.i
+.PHONY : BlockArray.i
+
+# target to preprocess a source file
+BlockArray.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/BlockArray.cpp.i
+.PHONY : BlockArray.cpp.i
+
+BlockArray.s: BlockArray.cpp.s
+.PHONY : BlockArray.s
+
+# target to generate assembly for a file
+BlockArray.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/BlockArray.cpp.s
+.PHONY : BlockArray.cpp.s
+
+Emulation.o: Emulation.cpp.o
+.PHONY : Emulation.o
+
+# target to build an object file
+Emulation.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Emulation.cpp.o
+.PHONY : Emulation.cpp.o
+
+Emulation.i: Emulation.cpp.i
+.PHONY : Emulation.i
+
+# target to preprocess a source file
+Emulation.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Emulation.cpp.i
+.PHONY : Emulation.cpp.i
+
+Emulation.s: Emulation.cpp.s
+.PHONY : Emulation.s
+
+# target to generate assembly for a file
+Emulation.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Emulation.cpp.s
+.PHONY : Emulation.cpp.s
+
+Filter.o: Filter.cpp.o
+.PHONY : Filter.o
+
+# target to build an object file
+Filter.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Filter.cpp.o
+.PHONY : Filter.cpp.o
+
+Filter.i: Filter.cpp.i
+.PHONY : Filter.i
+
+# target to preprocess a source file
+Filter.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Filter.cpp.i
+.PHONY : Filter.cpp.i
+
+Filter.s: Filter.cpp.s
+.PHONY : Filter.s
+
+# target to generate assembly for a file
+Filter.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Filter.cpp.s
+.PHONY : Filter.cpp.s
+
+History.o: History.cpp.o
+.PHONY : History.o
+
+# target to build an object file
+History.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/History.cpp.o
+.PHONY : History.cpp.o
+
+History.i: History.cpp.i
+.PHONY : History.i
+
+# target to preprocess a source file
+History.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/History.cpp.i
+.PHONY : History.cpp.i
+
+History.s: History.cpp.s
+.PHONY : History.s
+
+# target to generate assembly for a file
+History.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/History.cpp.s
+.PHONY : History.cpp.s
+
+KeyboardTranslator.o: KeyboardTranslator.cpp.o
+.PHONY : KeyboardTranslator.o
+
+# target to build an object file
+KeyboardTranslator.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/KeyboardTranslator.cpp.o
+.PHONY : KeyboardTranslator.cpp.o
+
+KeyboardTranslator.i: KeyboardTranslator.cpp.i
+.PHONY : KeyboardTranslator.i
+
+# target to preprocess a source file
+KeyboardTranslator.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/KeyboardTranslator.cpp.i
+.PHONY : KeyboardTranslator.cpp.i
+
+KeyboardTranslator.s: KeyboardTranslator.cpp.s
+.PHONY : KeyboardTranslator.s
+
+# target to generate assembly for a file
+KeyboardTranslator.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/KeyboardTranslator.cpp.s
+.PHONY : KeyboardTranslator.cpp.s
+
+ProcessInfo.o: ProcessInfo.cpp.o
+.PHONY : ProcessInfo.o
+
+# target to build an object file
+ProcessInfo.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ProcessInfo.cpp.o
+.PHONY : ProcessInfo.cpp.o
+
+ProcessInfo.i: ProcessInfo.cpp.i
+.PHONY : ProcessInfo.i
+
+# target to preprocess a source file
+ProcessInfo.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ProcessInfo.cpp.i
+.PHONY : ProcessInfo.cpp.i
+
+ProcessInfo.s: ProcessInfo.cpp.s
+.PHONY : ProcessInfo.s
+
+# target to generate assembly for a file
+ProcessInfo.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ProcessInfo.cpp.s
+.PHONY : ProcessInfo.cpp.s
+
+Pty.o: Pty.cpp.o
+.PHONY : Pty.o
+
+# target to build an object file
+Pty.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Pty.cpp.o
+.PHONY : Pty.cpp.o
+
+Pty.i: Pty.cpp.i
+.PHONY : Pty.i
+
+# target to preprocess a source file
+Pty.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Pty.cpp.i
+.PHONY : Pty.cpp.i
+
+Pty.s: Pty.cpp.s
+.PHONY : Pty.s
+
+# target to generate assembly for a file
+Pty.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Pty.cpp.s
+.PHONY : Pty.cpp.s
+
+Screen.o: Screen.cpp.o
+.PHONY : Screen.o
+
+# target to build an object file
+Screen.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Screen.cpp.o
+.PHONY : Screen.cpp.o
+
+Screen.i: Screen.cpp.i
+.PHONY : Screen.i
+
+# target to preprocess a source file
+Screen.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Screen.cpp.i
+.PHONY : Screen.cpp.i
+
+Screen.s: Screen.cpp.s
+.PHONY : Screen.s
+
+# target to generate assembly for a file
+Screen.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Screen.cpp.s
+.PHONY : Screen.cpp.s
+
+ScreenWindow.o: ScreenWindow.cpp.o
+.PHONY : ScreenWindow.o
+
+# target to build an object file
+ScreenWindow.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ScreenWindow.cpp.o
+.PHONY : ScreenWindow.cpp.o
+
+ScreenWindow.i: ScreenWindow.cpp.i
+.PHONY : ScreenWindow.i
+
+# target to preprocess a source file
+ScreenWindow.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ScreenWindow.cpp.i
+.PHONY : ScreenWindow.cpp.i
+
+ScreenWindow.s: ScreenWindow.cpp.s
+.PHONY : ScreenWindow.s
+
+# target to generate assembly for a file
+ScreenWindow.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ScreenWindow.cpp.s
+.PHONY : ScreenWindow.cpp.s
+
+Session.o: Session.cpp.o
+.PHONY : Session.o
+
+# target to build an object file
+Session.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Session.cpp.o
+.PHONY : Session.cpp.o
+
+Session.i: Session.cpp.i
+.PHONY : Session.i
+
+# target to preprocess a source file
+Session.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Session.cpp.i
+.PHONY : Session.cpp.i
+
+Session.s: Session.cpp.s
+.PHONY : Session.s
+
+# target to generate assembly for a file
+Session.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Session.cpp.s
+.PHONY : Session.cpp.s
+
+ShellCommand.o: ShellCommand.cpp.o
+.PHONY : ShellCommand.o
+
+# target to build an object file
+ShellCommand.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ShellCommand.cpp.o
+.PHONY : ShellCommand.cpp.o
+
+ShellCommand.i: ShellCommand.cpp.i
+.PHONY : ShellCommand.i
+
+# target to preprocess a source file
+ShellCommand.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ShellCommand.cpp.i
+.PHONY : ShellCommand.cpp.i
+
+ShellCommand.s: ShellCommand.cpp.s
+.PHONY : ShellCommand.s
+
+# target to generate assembly for a file
+ShellCommand.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/ShellCommand.cpp.s
+.PHONY : ShellCommand.cpp.s
+
+TerminalCharacterDecoder.o: TerminalCharacterDecoder.cpp.o
+.PHONY : TerminalCharacterDecoder.o
+
+# target to build an object file
+TerminalCharacterDecoder.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/TerminalCharacterDecoder.cpp.o
+.PHONY : TerminalCharacterDecoder.cpp.o
+
+TerminalCharacterDecoder.i: TerminalCharacterDecoder.cpp.i
+.PHONY : TerminalCharacterDecoder.i
+
+# target to preprocess a source file
+TerminalCharacterDecoder.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/TerminalCharacterDecoder.cpp.i
+.PHONY : TerminalCharacterDecoder.cpp.i
+
+TerminalCharacterDecoder.s: TerminalCharacterDecoder.cpp.s
+.PHONY : TerminalCharacterDecoder.s
+
+# target to generate assembly for a file
+TerminalCharacterDecoder.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/TerminalCharacterDecoder.cpp.s
+.PHONY : TerminalCharacterDecoder.cpp.s
+
+TerminalDisplay.o: TerminalDisplay.cpp.o
+.PHONY : TerminalDisplay.o
+
+# target to build an object file
+TerminalDisplay.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/TerminalDisplay.cpp.o
+.PHONY : TerminalDisplay.cpp.o
+
+TerminalDisplay.i: TerminalDisplay.cpp.i
+.PHONY : TerminalDisplay.i
+
+# target to preprocess a source file
+TerminalDisplay.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/TerminalDisplay.cpp.i
+.PHONY : TerminalDisplay.cpp.i
+
+TerminalDisplay.s: TerminalDisplay.cpp.s
+.PHONY : TerminalDisplay.s
+
+# target to generate assembly for a file
+TerminalDisplay.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/TerminalDisplay.cpp.s
+.PHONY : TerminalDisplay.cpp.s
+
+Vt102Emulation.o: Vt102Emulation.cpp.o
+.PHONY : Vt102Emulation.o
+
+# target to build an object file
+Vt102Emulation.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Vt102Emulation.cpp.o
+.PHONY : Vt102Emulation.cpp.o
+
+Vt102Emulation.i: Vt102Emulation.cpp.i
+.PHONY : Vt102Emulation.i
+
+# target to preprocess a source file
+Vt102Emulation.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Vt102Emulation.cpp.i
+.PHONY : Vt102Emulation.cpp.i
+
+Vt102Emulation.s: Vt102Emulation.cpp.s
+.PHONY : Vt102Emulation.s
+
+# target to generate assembly for a file
+Vt102Emulation.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/Vt102Emulation.cpp.s
+.PHONY : Vt102Emulation.cpp.s
+
+konsole_wcwidth.o: konsole_wcwidth.cpp.o
+.PHONY : konsole_wcwidth.o
+
+# target to build an object file
+konsole_wcwidth.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/konsole_wcwidth.cpp.o
+.PHONY : konsole_wcwidth.cpp.o
+
+konsole_wcwidth.i: konsole_wcwidth.cpp.i
+.PHONY : konsole_wcwidth.i
+
+# target to preprocess a source file
+konsole_wcwidth.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/konsole_wcwidth.cpp.i
+.PHONY : konsole_wcwidth.cpp.i
+
+konsole_wcwidth.s: konsole_wcwidth.cpp.s
+.PHONY : konsole_wcwidth.s
+
+# target to generate assembly for a file
+konsole_wcwidth.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/konsole_wcwidth.cpp.s
+.PHONY : konsole_wcwidth.cpp.s
+
+kprocess.o: kprocess.cpp.o
+.PHONY : kprocess.o
+
+# target to build an object file
+kprocess.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kprocess.cpp.o
+.PHONY : kprocess.cpp.o
+
+kprocess.i: kprocess.cpp.i
+.PHONY : kprocess.i
+
+# target to preprocess a source file
+kprocess.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kprocess.cpp.i
+.PHONY : kprocess.cpp.i
+
+kprocess.s: kprocess.cpp.s
+.PHONY : kprocess.s
+
+# target to generate assembly for a file
+kprocess.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kprocess.cpp.s
+.PHONY : kprocess.cpp.s
+
+kpty.o: kpty.cpp.o
+.PHONY : kpty.o
+
+# target to build an object file
+kpty.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kpty.cpp.o
+.PHONY : kpty.cpp.o
+
+kpty.i: kpty.cpp.i
+.PHONY : kpty.i
+
+# target to preprocess a source file
+kpty.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kpty.cpp.i
+.PHONY : kpty.cpp.i
+
+kpty.s: kpty.cpp.s
+.PHONY : kpty.s
+
+# target to generate assembly for a file
+kpty.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kpty.cpp.s
+.PHONY : kpty.cpp.s
+
+kptydevice.o: kptydevice.cpp.o
+.PHONY : kptydevice.o
+
+# target to build an object file
+kptydevice.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kptydevice.cpp.o
+.PHONY : kptydevice.cpp.o
+
+kptydevice.i: kptydevice.cpp.i
+.PHONY : kptydevice.i
+
+# target to preprocess a source file
+kptydevice.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kptydevice.cpp.i
+.PHONY : kptydevice.cpp.i
+
+kptydevice.s: kptydevice.cpp.s
+.PHONY : kptydevice.s
+
+# target to generate assembly for a file
+kptydevice.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kptydevice.cpp.s
+.PHONY : kptydevice.cpp.s
+
+kptyprocess.o: kptyprocess.cpp.o
+.PHONY : kptyprocess.o
+
+# target to build an object file
+kptyprocess.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kptyprocess.cpp.o
+.PHONY : kptyprocess.cpp.o
+
+kptyprocess.i: kptyprocess.cpp.i
+.PHONY : kptyprocess.i
+
+# target to preprocess a source file
+kptyprocess.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kptyprocess.cpp.i
+.PHONY : kptyprocess.cpp.i
+
+kptyprocess.s: kptyprocess.cpp.s
+.PHONY : kptyprocess.s
+
+# target to generate assembly for a file
+kptyprocess.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/kptyprocess.cpp.s
+.PHONY : kptyprocess.cpp.s
+
+qtermwidget.o: qtermwidget.cpp.o
+.PHONY : qtermwidget.o
+
+# target to build an object file
+qtermwidget.cpp.o:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/qtermwidget.cpp.o
+.PHONY : qtermwidget.cpp.o
+
+qtermwidget.i: qtermwidget.cpp.i
+.PHONY : qtermwidget.i
+
+# target to preprocess a source file
+qtermwidget.cpp.i:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/qtermwidget.cpp.i
+.PHONY : qtermwidget.cpp.i
+
+qtermwidget.s: qtermwidget.cpp.s
+.PHONY : qtermwidget.s
+
+# target to generate assembly for a file
+qtermwidget.cpp.s:
+	$(MAKE) -f CMakeFiles/qtermwidget.dir/build.make CMakeFiles/qtermwidget.dir/qtermwidget.cpp.s
+.PHONY : qtermwidget.cpp.s
+
+# Help Target
+help:
+	@echo "The following are some of the valid targets for this Makefile:"
+	@echo "... all (the default if no target is provided)"
+	@echo "... clean"
+	@echo "... depend"
+	@echo "... edit_cache"
+	@echo "... qtermwidget"
+	@echo "... rebuild_cache"
+	@echo "... BlockArray.o"
+	@echo "... BlockArray.i"
+	@echo "... BlockArray.s"
+	@echo "... Emulation.o"
+	@echo "... Emulation.i"
+	@echo "... Emulation.s"
+	@echo "... Filter.o"
+	@echo "... Filter.i"
+	@echo "... Filter.s"
+	@echo "... History.o"
+	@echo "... History.i"
+	@echo "... History.s"
+	@echo "... KeyboardTranslator.o"
+	@echo "... KeyboardTranslator.i"
+	@echo "... KeyboardTranslator.s"
+	@echo "... ProcessInfo.o"
+	@echo "... ProcessInfo.i"
+	@echo "... ProcessInfo.s"
+	@echo "... Pty.o"
+	@echo "... Pty.i"
+	@echo "... Pty.s"
+	@echo "... Screen.o"
+	@echo "... Screen.i"
+	@echo "... Screen.s"
+	@echo "... ScreenWindow.o"
+	@echo "... ScreenWindow.i"
+	@echo "... ScreenWindow.s"
+	@echo "... Session.o"
+	@echo "... Session.i"
+	@echo "... Session.s"
+	@echo "... ShellCommand.o"
+	@echo "... ShellCommand.i"
+	@echo "... ShellCommand.s"
+	@echo "... TerminalCharacterDecoder.o"
+	@echo "... TerminalCharacterDecoder.i"
+	@echo "... TerminalCharacterDecoder.s"
+	@echo "... TerminalDisplay.o"
+	@echo "... TerminalDisplay.i"
+	@echo "... TerminalDisplay.s"
+	@echo "... Vt102Emulation.o"
+	@echo "... Vt102Emulation.i"
+	@echo "... Vt102Emulation.s"
+	@echo "... konsole_wcwidth.o"
+	@echo "... konsole_wcwidth.i"
+	@echo "... konsole_wcwidth.s"
+	@echo "... kprocess.o"
+	@echo "... kprocess.i"
+	@echo "... kprocess.s"
+	@echo "... kpty.o"
+	@echo "... kpty.i"
+	@echo "... kpty.s"
+	@echo "... kptydevice.o"
+	@echo "... kptydevice.i"
+	@echo "... kptydevice.s"
+	@echo "... kptyprocess.o"
+	@echo "... kptyprocess.i"
+	@echo "... kptyprocess.s"
+	@echo "... qtermwidget.o"
+	@echo "... qtermwidget.i"
+	@echo "... qtermwidget.s"
+.PHONY : help
+
+
+
+#=============================================================================
+# Special targets to cleanup operation of make.
+
+# Special rule to run CMake to check the build system integrity.
+# No rule that depends on this can have commands that come from listfiles
+# because they might be regenerated.
+cmake_check_build_system:
+	$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
+.PHONY : cmake_check_build_system
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ManageProfilesDialog.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,514 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ManageProfilesDialog.h"
+
+// Qt
+#include <QtGui/QCheckBox>
+#include <QtGui/QHeaderView>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QItemEditorCreator>
+#include <QtCore/QMetaEnum>
+#include <QtGui/QScrollBar>
+#include <QtGui/QShowEvent>
+#include <QtGui/QStandardItem>
+
+// KDE
+#include <KKeySequenceWidget>
+#include <KDebug>
+
+// Konsole
+#include "EditProfileDialog.h"
+#include "SessionManager.h"
+#include "ui_ManageProfilesDialog.h"
+
+using namespace Konsole;
+
+ManageProfilesDialog::ManageProfilesDialog(QWidget* parent)
+    : KDialog(parent)
+    , _sessionModel(new QStandardItemModel(this))
+{
+    setCaption(i18nc("@title:window", "Manage Profiles"));
+    setButtons( KDialog::Ok | KDialog::Apply | KDialog::Cancel ); 
+
+    connect( this, SIGNAL(applyClicked()) , this , SLOT(setMenuOrder()) );
+
+    _ui = new Ui::ManageProfilesDialog();
+    _ui->setupUi(mainWidget());
+
+    // hide vertical header
+    _ui->sessionTable->verticalHeader()->hide();
+    _ui->sessionTable->setItemDelegateForColumn(FavoriteStatusColumn,new FavoriteItemDelegate(this));
+    _ui->sessionTable->setItemDelegateForColumn(ShortcutColumn,new ShortcutItemDelegate(this));
+    _ui->sessionTable->setEditTriggers(_ui->sessionTable->editTriggers() | QAbstractItemView::SelectedClicked);
+    _ui->sessionTable->setShowGrid(false);
+
+    // update table and listen for changes to the session types
+    connect( SessionManager::instance() , SIGNAL(profileAdded(Profile::Ptr)) , this,
+             SLOT(addItems(Profile::Ptr)) );
+    connect( SessionManager::instance() , SIGNAL(profileRemoved(Profile::Ptr)) , this,
+             SLOT(removeItems(Profile::Ptr)) );
+    connect( SessionManager::instance() , SIGNAL(profileChanged(Profile::Ptr)) , this,
+             SLOT(updateItems(Profile::Ptr)) );
+    connect( SessionManager::instance() , 
+                SIGNAL(favoriteStatusChanged(Profile::Ptr,bool)) , this ,
+                SLOT(updateFavoriteStatus(Profile::Ptr,bool)) );
+    populateTable();
+    
+    // resize the session table to the full width of the table
+    _ui->sessionTable->horizontalHeader()->setHighlightSections(false);
+    _ui->sessionTable->resizeColumnsToContents();
+    
+    // allow a larger width for the shortcut column to account for the 
+    // increased with needed by the shortcut editor compared with just
+    // displaying the text of the shortcut
+    _ui->sessionTable->setColumnWidth(ShortcutColumn,
+                _ui->sessionTable->columnWidth(ShortcutColumn)+100);
+
+    // setup buttons
+    connect( _ui->newSessionButton , SIGNAL(clicked()) , this , SLOT(newType()) );
+    connect( _ui->editSessionButton , SIGNAL(clicked()) , this , SLOT(editSelected()) );
+    connect( _ui->deleteSessionButton , SIGNAL(clicked()) , this , SLOT(deleteSelected()) );
+    connect( _ui->setAsDefaultButton , SIGNAL(clicked()) , this , SLOT(setSelectedAsDefault()) );
+}
+
+void ManageProfilesDialog::showEvent(QShowEvent*)
+{
+    Q_ASSERT( _ui->sessionTable->model() );
+
+    // try to ensure that all the text in all the columns is visible initially.
+    // FIXME:  this is not a good solution, look for a more correct way to do this
+
+    int totalWidth = 0;
+    int columnCount = _ui->sessionTable->model()->columnCount();
+
+    for ( int i = 0 ; i < columnCount ; i++ )
+        totalWidth += _ui->sessionTable->columnWidth(i);
+
+    // the margin is added to account for the space taken by the resize grips
+    // between the columns, this ensures that a horizontal scroll bar is not added 
+    // automatically
+    int margin = style()->pixelMetric( QStyle::PM_HeaderGripMargin ) * columnCount;
+    _ui->sessionTable->setMinimumWidth( totalWidth + margin );
+    _ui->sessionTable->horizontalHeader()->setStretchLastSection(true);
+}
+
+ManageProfilesDialog::~ManageProfilesDialog()
+{
+    delete _ui;
+}
+void ManageProfilesDialog::itemDataChanged(QStandardItem* item)
+{
+   if ( item->column() == ShortcutColumn )
+   {
+        QKeySequence sequence = QKeySequence::fromString(item->text());
+        SessionManager::instance()->setShortcut(item->data(ShortcutRole).value<Profile::Ptr>(),
+                                                sequence); 
+   } 
+}
+
+void ManageProfilesDialog::setMenuOrder(void)
+{
+    return;
+// TODO fix 
+/*
+    for (int i=0;i<_sessionModel->rowCount();i++)
+    {
+    }
+
+    SessionManager::instance()->setMenuOrder();
+*/
+}
+
+int ManageProfilesDialog::rowForProfile(const Profile::Ptr info) const
+{
+    for (int i=0;i<_sessionModel->rowCount();i++)
+    {
+        if (_sessionModel->item(i,ProfileNameColumn)->data(ProfileKeyRole)
+            .value<Profile::Ptr>() == info)
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+void ManageProfilesDialog::removeItems(const Profile::Ptr info)
+{
+    int row = rowForProfile(info);
+    if (row < 0)
+        return;
+    _sessionModel->removeRow(row);
+}
+void ManageProfilesDialog::updateItems(const Profile::Ptr info)
+{
+    int row = rowForProfile(info);
+    if (row < 0)
+        return;
+
+    QList<QStandardItem*> items;
+    items << _sessionModel->item(row,ProfileNameColumn);
+    items << _sessionModel->item(row,FavoriteStatusColumn);
+    items << _sessionModel->item(row,ShortcutColumn);
+    updateItemsForProfile(info,items);
+}
+void ManageProfilesDialog::updateItemsForProfile(const Profile::Ptr info, QList<QStandardItem*>& items) const
+{
+    // Profile Name
+    items[ProfileNameColumn]->setText(info->name());
+    if ( !info->icon().isEmpty() )
+       items[ProfileNameColumn]->setIcon( KIcon(info->icon()) );
+
+    items[ProfileNameColumn]->setData(QVariant::fromValue(info),ProfileKeyRole);
+
+    // Favorite Status
+    const bool isFavorite = SessionManager::instance()->findFavorites().contains(info);
+    if ( isFavorite )
+       items[FavoriteStatusColumn]->setData(KIcon("dialog-ok-apply"),Qt::DecorationRole);
+    else
+       items[FavoriteStatusColumn]->setData(KIcon(),Qt::DecorationRole);
+    items[FavoriteStatusColumn]->setData(QVariant::fromValue(info),ProfileKeyRole);
+
+    // Shortcut
+    QString shortcut = SessionManager::instance()->shortcut(info).
+                           toString();
+    items[ShortcutColumn]->setText(shortcut);
+    items[ShortcutColumn]->setData(QVariant::fromValue(info),ShortcutRole);
+}
+void ManageProfilesDialog::addItems(const Profile::Ptr profile) 
+{
+    if (profile->isHidden())
+        return;
+
+    QList<QStandardItem*> items;
+    for (int i=0;i<3;i++)
+        items << new QStandardItem;
+    updateItemsForProfile(profile,items);
+    _sessionModel->appendRow(items);
+}
+void ManageProfilesDialog::populateTable()
+{
+    Q_ASSERT(!_ui->sessionTable->model());
+    
+    _ui->sessionTable->setModel(_sessionModel);
+    // ensure profiles list is complete
+    // this may be expensive, but will only be done the first time
+    // that the dialog is shown. 
+    SessionManager::instance()->loadAllProfiles();
+
+    _sessionModel->clear();
+    // setup session table
+    _sessionModel->setHorizontalHeaderLabels( QStringList() << i18nc("@title:column Profile label", "Name")
+                                                            << i18nc("@title:column Display profile in file menu", "Show in Menu") 
+                                                            << i18nc("@title:column Profile shortcut text", "Shortcut") );
+
+    QList<Profile::Ptr> profiles = SessionManager::instance()->loadedProfiles();
+    SessionManager::instance()->sortProfiles(profiles);
+
+    foreach(const Profile::Ptr &info, profiles)
+    {
+        addItems(info);
+    }
+    updateDefaultItem();
+
+    connect( _sessionModel , SIGNAL(itemChanged(QStandardItem*)) , this , 
+            SLOT(itemDataChanged(QStandardItem*)) );
+
+    // listen for changes in the table selection and update the state of the form's buttons
+    // accordingly.
+    //
+    // it appears that the selection model is changed when the model itself is replaced,
+    // so the signals need to be reconnected each time the model is updated.
+    connect( _ui->sessionTable->selectionModel() , 
+            SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)) , this ,
+            SLOT(tableSelectionChanged(const QItemSelection&)) );
+
+    _ui->sessionTable->selectRow(0);
+    tableSelectionChanged( _ui->sessionTable->selectionModel()->selection() );
+}
+void ManageProfilesDialog::updateDefaultItem()
+{
+    Profile::Ptr defaultProfile = SessionManager::instance()->defaultProfile();
+
+    for ( int i = 0 ; i < _sessionModel->rowCount() ; i++ )
+    {
+        QStandardItem* item = _sessionModel->item(i);
+        QFont font = item->font();
+
+        bool isDefault = ( defaultProfile == item->data().value<Profile::Ptr>() );
+
+        if ( isDefault && !font.bold() )
+        {
+            item->setIcon(KIcon(defaultProfile->icon(), NULL, QStringList("emblem-favorite")));
+            font.setBold(true);
+            item->setFont(font);
+        } 
+        else if ( !isDefault && font.bold() )
+        {
+            item->setIcon(KIcon(defaultProfile->icon()));
+            font.setBold(false);
+            item->setFont(font);
+        } 
+    }
+}
+void ManageProfilesDialog::tableSelectionChanged(const QItemSelection&)
+{
+    const int selectedRows = _ui->sessionTable->selectionModel()->selectedRows().count();
+    const SessionManager* manager = SessionManager::instance();
+    const bool isNotDefault = (selectedRows > 0) && currentProfile() != manager->defaultProfile();
+    const int rowIndex = _ui->sessionTable->currentIndex().row();
+
+    _ui->newSessionButton->setEnabled(selectedRows < 2);
+    _ui->editSessionButton->setEnabled(selectedRows > 0);
+    // do not allow the default session type to be removed
+    _ui->deleteSessionButton->setEnabled(isNotDefault);
+    _ui->setAsDefaultButton->setEnabled(isNotDefault && (selectedRows < 2)); 
+
+    // TODO handle multiple moves
+    // TODO re-enable when saving profile order works - khindenburg
+//    _ui->moveUpButton->setEnabled((selectedRows == 1) && (rowIndex > 0));
+//    _ui->moveDownButton->setEnabled((selectedRows == 1) && (rowIndex < (_sessionModel->rowCount()-1)));
+
+    _ui->sessionTable->selectRow(rowIndex);
+}
+void ManageProfilesDialog::deleteSelected()
+{
+    foreach(const Profile::Ptr &profile, selectedProfiles())
+    {
+        if (profile != SessionManager::instance()->defaultProfile())
+            SessionManager::instance()->deleteProfile(profile);
+    }
+}
+void ManageProfilesDialog::setSelectedAsDefault()
+{
+    SessionManager::instance()->setDefaultProfile(currentProfile());
+    // do not allow the new default session type to be removed
+    _ui->deleteSessionButton->setEnabled(false);
+    _ui->setAsDefaultButton->setEnabled(false);
+
+    // update font of new default item
+    updateDefaultItem(); 
+}
+
+void ManageProfilesDialog::moveUpSelected()
+{
+    Q_ASSERT(_sessionModel);
+
+    const int rowIndex = _ui->sessionTable->currentIndex().row();
+    const QList<QStandardItem*>items = _sessionModel->takeRow(rowIndex);
+    _sessionModel->insertRow(rowIndex-1, items);
+    _ui->sessionTable->selectRow(rowIndex-1);
+}
+
+void ManageProfilesDialog::moveDownSelected()
+{
+    Q_ASSERT(_sessionModel);
+
+    const int rowIndex = _ui->sessionTable->currentIndex().row();
+    const QList<QStandardItem*>items = _sessionModel->takeRow(rowIndex);
+    _sessionModel->insertRow(rowIndex+1, items);
+    _ui->sessionTable->selectRow(rowIndex+1);
+}
+
+void ManageProfilesDialog::newType()
+{
+    EditProfileDialog dialog(this);
+ 
+    // setup a temporary profile which is a clone of the selected profile 
+    // or the default if no profile is selected
+    Profile::Ptr sourceProfile;
+    
+    Profile::Ptr selectedProfile = currentProfile();
+    if ( !selectedProfile ) 
+        sourceProfile = SessionManager::instance()->defaultProfile();
+    else
+        sourceProfile = selectedProfile; 
+
+    Q_ASSERT( sourceProfile );
+
+    Profile::Ptr newProfile = Profile::Ptr(new Profile(SessionManager::instance()->fallbackProfile()));
+    newProfile->clone(sourceProfile,true);
+    newProfile->setProperty(Profile::Name, i18nc("@item This will be used as part of the file name", "New Profile"));
+    newProfile->setProperty(Profile::MenuIndex, QString("0"));
+
+    dialog.setProfile(newProfile); 
+    dialog.selectProfileName();
+
+    if ( dialog.exec() == QDialog::Accepted )
+    {
+        SessionManager::instance()->addProfile(newProfile);
+        SessionManager::instance()->setFavorite(newProfile,true);
+        SessionManager::instance()->changeProfile(newProfile, newProfile->setProperties());
+    }
+}
+void ManageProfilesDialog::editSelected()
+{
+    EditProfileDialog dialog(this);
+    // the dialog will delete the profile group when it is destroyed
+    ProfileGroup* group = new ProfileGroup;
+    foreach(const Profile::Ptr &profile,selectedProfiles())
+        group->addProfile(profile);
+    group->updateValues();
+
+    dialog.setProfile(Profile::Ptr(group));
+    dialog.exec();
+}
+QList<Profile::Ptr> ManageProfilesDialog::selectedProfiles() const
+{
+    QList<Profile::Ptr> list;
+    QItemSelectionModel* selection = _ui->sessionTable->selectionModel();
+    if (!selection)
+        return list; 
+
+    foreach(const QModelIndex& index, selection->selectedIndexes())
+    {
+        if (index.column() == ProfileNameColumn)
+            list << index.data(ProfileKeyRole).value<Profile::Ptr>();
+    }
+
+    return list;
+}
+Profile::Ptr ManageProfilesDialog::currentProfile() const
+{
+    QItemSelectionModel* selection = _ui->sessionTable->selectionModel();
+
+    if ( !selection || selection->selectedRows().count() != 1 )
+        return Profile::Ptr();
+
+    return  selection->
+            selectedIndexes().first().data(ProfileKeyRole).value<Profile::Ptr>();
+}
+void ManageProfilesDialog::updateFavoriteStatus(Profile::Ptr profile, bool favorite)
+{
+    Q_ASSERT( _sessionModel );
+
+    int rowCount = _sessionModel->rowCount();
+    for (int i=0;i < rowCount;i++)
+    {
+        QModelIndex index = _sessionModel->index(i,FavoriteStatusColumn);
+        if (index.data(ProfileKeyRole).value<Profile::Ptr>() ==
+            profile )
+        {
+            const KIcon icon = favorite ? KIcon("dialog-ok-apply") : KIcon();
+            _sessionModel->setData(index,icon,Qt::DecorationRole);
+        }
+    }
+}
+void ManageProfilesDialog::setShortcutEditorVisible(bool visible)
+{
+    _ui->sessionTable->setColumnHidden(ShortcutColumn,!visible);    
+}
+void StyledBackgroundPainter::drawBackground(QPainter* painter, const QStyleOptionViewItem& option,
+        const QModelIndex&)
+{
+    const QStyleOptionViewItemV3* v3option = qstyleoption_cast<const QStyleOptionViewItemV3*>(&option);
+    const QWidget* widget = v3option ? v3option->widget : 0;
+
+    QStyle* style = widget ? widget->style() : QApplication::style();
+    
+    style->drawPrimitive(QStyle::PE_PanelItemViewItem,&option,painter,widget);
+}
+
+FavoriteItemDelegate::FavoriteItemDelegate(QObject* parent)
+    : QStyledItemDelegate(parent)
+{
+}
+void FavoriteItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+    // See implementation of QStyledItemDelegate::paint()
+    QStyleOptionViewItemV4 opt = option;
+    initStyleOption(&opt,index);
+
+    StyledBackgroundPainter::drawBackground(painter,opt,index);
+
+    int margin = (opt.rect.height()-opt.decorationSize.height())/2;
+    margin++;
+
+    opt.rect.setTop(opt.rect.top()+margin);
+    opt.rect.setBottom(opt.rect.bottom()-margin);
+
+    QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
+    icon.paint(painter,opt.rect,Qt::AlignCenter);
+}
+
+bool FavoriteItemDelegate::editorEvent(QEvent* event,QAbstractItemModel*,
+                                    const QStyleOptionViewItem&,const QModelIndex& index)
+{
+     if ( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress 
+         || event->type() == QEvent::MouseButtonDblClick )
+     {
+         Profile::Ptr profile = index.data(ManageProfilesDialog::ProfileKeyRole).value<Profile::Ptr>();
+         const bool isFavorite = !SessionManager::instance()->findFavorites().contains(profile);
+                                             
+        SessionManager::instance()->setFavorite(profile,
+                                            isFavorite);
+     }
+     
+     return true; 
+}
+ShortcutItemDelegate::ShortcutItemDelegate(QObject* parent)
+    : QStyledItemDelegate(parent)
+{
+}
+void ShortcutItemDelegate::editorModified(const QKeySequence& keys)
+{
+    Q_UNUSED(keys);
+    //kDebug() << keys.toString();
+
+    KKeySequenceWidget* editor = qobject_cast<KKeySequenceWidget*>(sender());
+    Q_ASSERT(editor);
+    _modifiedEditors.insert(editor);
+}
+void ShortcutItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
+                                    const QModelIndex& index) const
+{
+    _itemsBeingEdited.remove(index);
+    
+    if (!_modifiedEditors.contains(editor))
+        return;
+
+    QString shortcut = qobject_cast<KKeySequenceWidget*>(editor)->keySequence().toString();
+    model->setData(index,shortcut,Qt::DisplayRole);
+
+    _modifiedEditors.remove(editor);
+}
+
+QWidget* ShortcutItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const
+{
+    _itemsBeingEdited.insert(index);
+
+    KKeySequenceWidget* editor = new KKeySequenceWidget(parent);
+    editor->setFocusPolicy(Qt::StrongFocus);
+    editor->setModifierlessAllowed(false);
+    QString shortcutString = index.data(Qt::DisplayRole).toString();
+    editor->setKeySequence(QKeySequence::fromString(shortcutString));
+    connect(editor,SIGNAL(keySequenceChanged(QKeySequence)),this,SLOT(editorModified(QKeySequence)));
+    editor->captureKeySequence();
+    return editor;
+}
+void ShortcutItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, 
+                        const QModelIndex& index) const
+{
+    if (_itemsBeingEdited.contains(index))
+        StyledBackgroundPainter::drawBackground(painter,option,index);
+    else
+        QStyledItemDelegate::paint(painter,option,index);
+}
+
+#include "ManageProfilesDialog.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ManageProfilesDialog.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,166 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef MANAGEPROFILESDIALOG_H
+#define MANAGEPROFILESDIALOG_H
+
+// Qt
+#include <QtGui/QStyledItemDelegate>
+#include <QtCore/QSet>
+
+// KDE
+#include <KDialog>
+
+// Konsole
+#include "Profile.h"
+
+class QItemSelection;
+class QShowEvent;
+class QStandardItem;
+class QStandardItemModel;
+class QTableView;
+
+namespace Ui
+{
+    class ManageProfilesDialog;
+}
+
+namespace Konsole
+{
+
+/**
+ * A dialog which lists the available types of profiles and allows
+ * the user to add new profiles, and remove or edit existing
+ * profile types.
+ */
+class KONSOLEPRIVATE_EXPORT ManageProfilesDialog : public KDialog
+{
+Q_OBJECT
+
+
+friend class FavoriteItemDelegate;
+friend class ShortcutItemDelegate;
+friend class ::QTableView;
+
+public:
+    /** Constructs a new profile type with the specified parent. */
+    ManageProfilesDialog(QWidget* parent = 0);
+    virtual ~ManageProfilesDialog();
+
+    /** 
+     * Specifies whether the shorcut editor should be show.
+     * The shortcut editor allows shortcuts to be associated with 
+     * profiles.  When a shortcut is changed, the dialog will call
+     * SessionManager::instance()->setShortcut() to update the shortcut
+     * associated with the profile.
+     *
+     * By default the editor is visible.
+     */
+    void setShortcutEditorVisible(bool visible);
+
+protected:
+    virtual void showEvent(QShowEvent* event);
+
+private slots:
+    void deleteSelected();
+    void setSelectedAsDefault();
+    void newType();
+    void editSelected();
+    void moveUpSelected();
+    void moveDownSelected();
+
+    void itemDataChanged(QStandardItem* item);
+
+    // enables or disables Edit/Delete/Set as Default buttons when the 
+    // selection changes
+    void tableSelectionChanged(const QItemSelection&);
+
+    void updateFavoriteStatus(Profile::Ptr profile, bool favorite);
+
+    void addItems(const Profile::Ptr);
+    void updateItems(const Profile::Ptr);
+    void removeItems(const Profile::Ptr);
+
+    void setMenuOrder(void);
+
+private:
+    Profile::Ptr currentProfile() const; 
+    QList<Profile::Ptr> selectedProfiles() const; 
+
+    // updates the font of the items to match
+    // their default / non-default profile status
+    void updateDefaultItem(); 
+    void updateItemsForProfile(const Profile::Ptr profile, QList<QStandardItem*>& items) const;
+    // updates the profile table to be in sync with the 
+    // session manager
+    void populateTable();
+    int rowForProfile(const Profile::Ptr info) const;
+
+    Ui::ManageProfilesDialog* _ui;
+    QStandardItemModel* _sessionModel;
+
+    static const int ProfileNameColumn = 0;
+    static const int FavoriteStatusColumn = 1;
+    static const int ShortcutColumn = 2;
+    static const int ProfileKeyRole = Qt::UserRole + 1;
+    static const int ShortcutRole = Qt::UserRole + 1;
+};
+
+class StyledBackgroundPainter 
+{
+public:
+    static void drawBackground(QPainter* painter, const QStyleOptionViewItem& option,
+                const QModelIndex& index);
+};
+
+class FavoriteItemDelegate : public QStyledItemDelegate
+{
+public:
+    FavoriteItemDelegate(QObject* parent = 0);
+
+    virtual bool editorEvent(QEvent* event,QAbstractItemModel* model,
+                             const QStyleOptionViewItem& option,const QModelIndex& index);
+    virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, 
+                        const QModelIndex& index) const;
+};
+
+class ShortcutItemDelegate : public QStyledItemDelegate
+{
+Q_OBJECT
+
+public:
+    ShortcutItemDelegate(QObject* parent = 0);
+
+    virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
+    virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, 
+                                    const QModelIndex& index) const;
+    virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, 
+                        const QModelIndex& index) const;
+
+private slots:
+    void editorModified(const QKeySequence& keys);
+
+private:
+    mutable QSet<QWidget*> _modifiedEditors;
+    mutable QSet<QModelIndex> _itemsBeingEdited;
+};
+
+}
+#endif // MANAGEPROFILESDIALOG_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Part.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,307 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "Part.h"
+
+// Qt
+#include <QtCore/QStringList>
+#include <QDir>
+
+// KDE
+#include <KAction>
+#include <KActionCollection>
+#include <KDebug>
+#include <KLocale>
+#include <KWindowSystem>
+#include <KPluginFactory>
+#include <kdeversion.h>
+#include <kde_file.h>
+
+// Konsole
+#include "ColorScheme.h"
+#include "EditProfileDialog.h"
+#include "Emulation.h"
+#include "KeyboardTranslator.h"
+#include "ManageProfilesDialog.h"
+#include "Session.h"
+#include "SessionController.h"
+#include "SessionManager.h"
+#include "TerminalDisplay.h"
+#include "ViewManager.h"
+#include "MainWindow.h"
+
+#include <config-konsole.h>
+
+using namespace Konsole;
+
+K_PLUGIN_FACTORY(KonsolePartFactory, registerPlugin<Konsole::Part>();)
+K_EXPORT_PLUGIN(KonsolePartFactory("konsole"))
+
+
+Part::Part(QWidget* parentWidget , QObject* parent, const QVariantList&)
+ : KParts::ReadOnlyPart(parent)
+  ,_viewManager(0)
+  ,_pluggedController(0)
+  ,_manageProfilesAction(0)
+{
+    // make sure the konsole catalog is loaded
+    KGlobal::locale()->insertCatalog("konsole");
+
+
+
+    // setup global actions
+    createGlobalActions();
+
+    // create view widget
+    _viewManager = new ViewManager(this,actionCollection());
+    _viewManager->setNavigationMethod( ViewManager::NoNavigation );
+
+    connect( _viewManager , SIGNAL(activeViewChanged(SessionController*)) , this ,
+           SLOT(activeViewChanged(SessionController*)) );
+    connect( _viewManager , SIGNAL(empty()) , this , SLOT(terminalExited()) );
+    connect( _viewManager , SIGNAL(newViewRequest()) , this , SLOT(newTab()) );
+
+    _viewManager->widget()->setParent(parentWidget);
+
+    setWidget(_viewManager->widget());
+    actionCollection()->addAssociatedWidget(_viewManager->widget());
+    foreach (QAction* action, actionCollection()->actions())
+        action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
+
+    // Enable translucency support.
+    _viewManager->widget()->setAttribute(Qt::WA_TranslucentBackground, true);
+    TerminalDisplay::HAVE_TRANSPARENCY = KWindowSystem::compositingActive();
+
+    // create basic session
+    createSession();
+}
+Part::~Part()
+{
+    SessionManager::instance()->saveState();
+}
+void Part::createGlobalActions()
+{
+    _manageProfilesAction = new QAction(i18n("Configure Profiles..."),this);
+    connect(_manageProfilesAction,SIGNAL(triggered()),this,SLOT(showManageProfilesDialog()));
+}
+void Part::setupActionsForSession(SessionController* session)
+{
+    KActionCollection* collection = session->actionCollection();
+    collection->addAction("configure-profiles",_manageProfilesAction);
+}
+bool Part::openFile()
+{
+    return false;
+}
+void Part::terminalExited()
+{
+    deleteLater();
+}
+void Part::newTab()
+{
+    createSession();
+    showShellInDir( QString() );
+}
+Session* Part::activeSession() const
+{
+    if ( _viewManager->activeViewController() )
+    {
+        Q_ASSERT( _viewManager->activeViewController()->session());
+
+        return _viewManager->activeViewController()->session();
+    }
+    else
+    {
+        return 0;
+    }
+}
+void Part::startProgram( const QString& program,
+                           const QStringList& arguments )
+{
+    Q_ASSERT( activeSession() );
+
+    if ( !activeSession()->isRunning() )
+    {
+        if ( !program.isEmpty() && !arguments.isEmpty() )
+        {
+            activeSession()->setProgram(program);
+            activeSession()->setArguments(arguments);
+        }
+
+        activeSession()->run();
+    }
+}
+void Part::openTeletype(int fd)
+{
+    Q_ASSERT( activeSession() );
+
+    activeSession()->openTeletype(fd);
+}
+void Part::showShellInDir( const QString& dir )
+{
+    Q_ASSERT( activeSession() );
+
+    if ( !activeSession()->isRunning() )
+    {
+        if ( !dir.isEmpty() )
+            activeSession()->setInitialWorkingDirectory(dir);
+        activeSession()->run();
+    }
+}
+void Part::sendInput( const QString& text )
+{
+    Q_ASSERT( activeSession() );
+    activeSession()->emulation()->sendText(text);
+}
+
+int Part::terminalProcessId()
+{
+    Q_ASSERT( activeSession() );
+
+    return activeSession()->processId();
+
+}
+
+int Part::foregroundProcessId()
+{
+    Q_ASSERT( activeSession() );
+
+    if (activeSession()->isForegroundProcessActive()) {
+        return activeSession()->foregroundProcessId();
+    } else {
+        return -1;
+    }
+}
+
+QString Part::foregroundProcessName()
+{
+    Q_ASSERT( activeSession() );
+
+    if (activeSession()->isForegroundProcessActive()) {
+        return activeSession()->foregroundProcessName();
+    } else {
+        return "";
+    }
+}
+
+Session* Part::createSession(const Profile::Ptr profile)
+{
+    Session* session = SessionManager::instance()->createSession(profile);
+    _viewManager->createView(session);
+
+    return session;
+}
+void Part::activeViewChanged(SessionController* controller)
+{
+    Q_ASSERT( controller );
+    Q_ASSERT( controller->view() );
+
+    // remove existing controller
+    if (_pluggedController)
+    {
+        removeChildClient (_pluggedController);
+        disconnect(_pluggedController,SIGNAL(titleChanged(ViewProperties*)),this,
+                    SLOT(activeViewTitleChanged(ViewProperties*)));
+    }
+
+    // insert new controller
+    setupActionsForSession(controller);
+    insertChildClient(controller);
+    connect(controller,SIGNAL(titleChanged(ViewProperties*)),this,
+            SLOT(activeViewTitleChanged(ViewProperties*)));
+    activeViewTitleChanged(controller);
+
+    const char* displaySignal = SIGNAL(overrideShortcutCheck(QKeyEvent*,bool&));
+    const char* partSlot = SLOT(overrideTerminalShortcut(QKeyEvent*,bool&));
+
+    disconnect(controller->view(),displaySignal,this,partSlot);
+    connect(controller->view(),displaySignal,this,partSlot);
+
+    _pluggedController = controller;
+}
+void Part::overrideTerminalShortcut(QKeyEvent* event, bool& override)
+{
+    // override all shortcuts in the embedded terminal by default
+    override = true;
+    emit overrideShortcut(event,override);
+}
+void Part::activeViewTitleChanged(ViewProperties* properties)
+{
+    emit setWindowCaption(properties->title());
+}
+void Part::showManageProfilesDialog()
+{
+    showManageProfilesDialog(_viewManager->widget());
+}
+void Part::showManageProfilesDialog(QWidget* parent)
+{
+    ManageProfilesDialog* dialog = new ManageProfilesDialog(parent);
+    dialog->setAttribute(Qt::WA_DeleteOnClose);
+    dialog->setShortcutEditorVisible(false);
+    dialog->show();
+}
+void Part::showEditCurrentProfileDialog(QWidget* parent)
+{
+    Q_ASSERT( activeSession() );
+
+    EditProfileDialog* dialog = new EditProfileDialog(parent);
+    dialog->setAttribute(Qt::WA_DeleteOnClose);
+    dialog->setProfile( SessionManager::instance()->sessionProfile(activeSession()) );
+    dialog->show();
+}
+void Part::changeSessionSettings(const QString& text)
+{
+    // send a profile change command, the escape code format
+    // is the same as the normal X-Term commands used to change the window title or icon,
+    // but with a magic value of '50' for the parameter which specifies what to change
+    Q_ASSERT( activeSession() );
+    QByteArray buffer;
+    buffer.append("\033]50;").append(text.toUtf8()).append('\a');
+
+    activeSession()->emulation()->receiveData(buffer.constData(),buffer.length());
+}
+
+// Konqueror integration
+bool Part::openUrl( const KUrl & _url )
+{
+    if ( url() == _url ) {
+        emit completed();
+        return true;
+    }
+
+    setUrl( _url );
+    emit setWindowCaption( _url.pathOrUrl() );
+    //kdDebug(1211) << "Set Window Caption to " << url.pathOrUrl();
+    emit started( 0 );
+
+    if ( _url.isLocalFile() /*&& b_openUrls*/ ) {
+        KDE_struct_stat buff;
+        KDE_stat( QFile::encodeName( _url.path() ), &buff );
+        QString text = ( S_ISDIR( buff.st_mode ) ? _url.path() : _url.directory() );
+        showShellInDir( text );
+    } else {
+        showShellInDir( QDir::homePath() );
+    }
+
+    emit completed();
+    return true;
+}
+
+#include "Part.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Part.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,162 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef PART_H
+#define PART_H
+
+// KDE
+#include <KParts/Part>
+#include <kde_terminal_interface_v2.h>
+#include <QVariantList>
+
+// Konsole
+#include "Profile.h"
+
+class QAction;
+class QStringList;
+class QKeyEvent;
+
+namespace Konsole
+{
+class Session;
+class SessionController;
+class ViewManager;
+class ViewProperties;
+
+/**
+ * A re-usable terminal emulator component using the KParts framework which can
+ * be used to embed terminal emulators into other applications.
+ */
+class Part : public KParts::ReadOnlyPart , public TerminalInterfaceV2
+{
+Q_OBJECT
+    Q_INTERFACES(TerminalInterface TerminalInterfaceV2)
+public:
+    /** Constructs a new Konsole part with the specified parent. */
+    explicit Part(QWidget* parentWidget , QObject* parent, const QVariantList&);
+    virtual ~Part();
+
+    /** Reimplemented from TerminalInterface. */
+    virtual void startProgram( const QString& program,
+                               const QStringList& arguments );
+    /** Reimplemented from TerminalInterface. */
+    virtual void showShellInDir( const QString& dir );
+    /** Reimplemented from TerminalInterface. */
+    virtual void sendInput( const QString& text );
+
+    /** Reimplemented from TerminalInterfaceV2. */
+    virtual int terminalProcessId();
+
+    /** Reimplemented from TerminalInterfaceV2. */
+    virtual int foregroundProcessId();
+
+    /** Reimplemented from TerminalInterfaceV2. */
+    virtual QString foregroundProcessName();
+
+public slots:
+    /**
+     * Shows the dialog used to manage profiles in Konsole.  The dialog
+     * will be non-modal and will delete itself when it is closed.
+     *
+     * This is experimental API and not guaranteed to be present in later
+     * KDE 4 releases.
+     *
+     * @param parent The parent widget of the new dialog.
+     */
+    void showManageProfilesDialog(QWidget* parent);
+    /**
+     * Shows the dialog used to edit the profile used by the active session.  The
+     * dialog will be non-modal and will delete itself when it is closed.
+     *
+     * This is experimental API and not guaranteed to be present in later KDE 4
+     * releases.
+     *
+     * @param parent The parent widget of the new dialog.
+     */
+    void showEditCurrentProfileDialog(QWidget* parent);
+    /**
+     * Sends a profile change command to the active session.  This is equivalent to using
+     * the konsoleprofile tool within the session to change its settings.  The @p text string
+     * is a semi-colon separated list of property=value pairs, eg. "colors=Linux Colors"
+     *
+     * See the documentation for konsoleprofile for information on the format of @p text
+     *
+     * This is experimental API and not guaranteed to be present in later KDE 4 releases.
+     */
+    void changeSessionSettings(const QString& text);
+
+    /**
+     * Connects to an existing pseudo-teletype. See Session::openTeletype().
+     * This must be called before the session is started by startProgram(),
+     * or showShellInDir()
+     *
+     * @param ptyMasterFd The file descriptor of the pseudo-teletype (pty) master
+     */
+    void openTeletype(int ptyMasterFd);
+
+signals:
+    /**
+     * Emitted when the key sequence for a shortcut, which is also a valid terminal key sequence,
+     * is pressed while the terminal has focus.  By responding to this signal, the
+     * controlling application can choose whether to execute the action associated with
+     * the shortcut or ignore the shortcut and send the key
+     * sequence to the terminal application.
+     *
+     * In the embedded terminal, shortcuts are overridden and sent to the terminal by default.
+     * Set @p override to false to prevent this happening and allow the shortcut to be triggered
+     * normally.
+     *
+     * overrideShortcut() is not called for shortcuts which are not valid terminal key sequences,
+     * eg. shortcuts with two or more modifiers.
+     *
+     * @param event Describes the keys that were pressed.
+     * @param override Set this to false to prevent the terminal display from overriding the shortcut
+     */
+    void overrideShortcut(QKeyEvent* event, bool& override);
+
+protected:
+    /** Reimplemented from KParts::PartBase. */
+    virtual bool openFile();
+    virtual bool openUrl(const KUrl & url);
+
+private slots:
+    // creates a new session using the specified profile.
+    // call the run() method on the returned Session instance to begin the session
+    Session* createSession(const Profile::Ptr profile = Profile::Ptr());
+    void activeViewChanged(SessionController* controller);
+    void activeViewTitleChanged(ViewProperties* properties);
+    void showManageProfilesDialog();
+    void terminalExited();
+    void newTab();
+    void overrideTerminalShortcut(QKeyEvent*,bool& override);
+
+private:
+    Session* activeSession() const;
+    void setupActionsForSession(SessionController* session);
+    void createGlobalActions();
+
+private:
+    ViewManager* _viewManager;
+    SessionController* _pluggedController;
+    QAction* _manageProfilesAction;
+};
+
+}
+
+#endif // PART_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ProcessInfo.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,1122 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.countm>
+
+    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 "ProcessInfo.h"
+//#include <config-konsole.h>
+
+// Unix
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <pwd.h>
+
+// Qt
+//#include <KDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QRegExp>
+#include <QtCore/QTextStream>
+#include <QtCore/QStringList>
+#include <QtCore/QSet>
+
+// KDE
+#include "konsole_export.h"
+//#include <KConfigGroup>
+//#include <KGlobal>
+//#include <KSharedConfig>
+//#include <KUser>
+
+#if defined(Q_OS_MAC)
+#include <sys/sysctl.h>
+#include <libproc.h>
+#ifdef HAVE_SYS_PROC_INFO_H
+#include <sys/proc_info.h>
+#endif
+#ifdef HAVE_SYS_PROC_H
+#include <sys/proc.h>
+#endif
+//#include <kde_file.h>
+#define KDE_struct_stat struct stat
+#define KDE_stat ::stat
+#endif
+
+#if defined(Q_OS_FREEBSD)
+#include <sys/sysctl.h> //krazy:exclude=includes
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/syslimits.h>
+#include <libutil.h>
+#endif
+
+using namespace Konsole;
+
+ProcessInfo::ProcessInfo(int pid , bool enableEnvironmentRead)
+    : _fields( ARGUMENTS | ENVIRONMENT ) // arguments and environments
+                                         // are currently always valid,
+                                         // they just return an empty
+                                         // vector / map respectively
+                                         // if no arguments
+                                         // or environment bindings
+                                         // have been explicitly set
+    , _enableEnvironmentRead(enableEnvironmentRead)
+    , _pid(pid)
+    , _parentPid(0)
+    , _foregroundPid(0)
+    , _userId(0)
+    , _lastError(NoError)
+    , _userName(QString())
+    , _userHomeDir(QString())
+{
+}
+
+ProcessInfo::Error ProcessInfo::error() const { return _lastError; }
+void ProcessInfo::setError(Error error) { _lastError = error; }
+
+void ProcessInfo::update() 
+{
+    readProcessInfo(_pid,_enableEnvironmentRead);
+}
+
+QString ProcessInfo::validCurrentDir() const
+{
+   bool ok = false;
+
+   // read current dir, if an error occurs try the parent as the next
+   // best option
+   int currentPid = parentPid(&ok);
+   QString dir = currentDir(&ok);
+   while ( !ok && currentPid != 0 )
+   {
+       ProcessInfo* current = ProcessInfo::newInstance(currentPid);
+       current->update();
+       currentPid = current->parentPid(&ok); 
+       dir = current->currentDir(&ok);
+       delete current;
+   }
+
+   return dir;
+}
+
+QString ProcessInfo::format(const QString& input) const
+{
+   bool ok = false;
+
+   QString output(input);
+
+   // search for and replace known marker
+   output.replace("%u",userName());
+   output.replace("%n",name(&ok));
+   output.replace("%c",formatCommand(name(&ok),arguments(&ok),ShortCommandFormat));
+   output.replace("%C",formatCommand(name(&ok),arguments(&ok),LongCommandFormat));
+   
+   QString dir = validCurrentDir();
+   if (output.contains("%D"))
+   {
+      QString homeDir = userHomeDir();
+      QString tempDir = dir;
+      // Change User's Home Dir w/ ~ only at the beginning
+      if (tempDir.startsWith(homeDir))
+      {
+         tempDir.remove(0, homeDir.length());
+         tempDir.prepend('~');
+      }
+      output.replace("%D", tempDir);
+   }
+   output.replace("%d",formatShortDir(dir));
+   
+   // remove any remaining %[LETTER] sequences
+   // output.replace(QRegExp("%\\w"), QString());
+
+   return output;
+}
+
+QString ProcessInfo::formatCommand(const QString& name, 
+                                   const QVector<QString>& arguments,
+                                   CommandFormat format) const
+{
+    Q_UNUSED(name);
+    Q_UNUSED(format);
+
+    // TODO Implement me
+    return QStringList(QList<QString>::fromVector(arguments)).join(" ");
+}
+
+QSet<QString> ProcessInfo::_commonDirNames;
+
+QSet<QString> ProcessInfo::commonDirNames() 
+{
+  // JPS: Don't know of a good replacement for this in QT
+  /*
+    if ( _commonDirNames.isEmpty() )
+    {
+        KSharedConfigPtr config = KGlobal::config();
+        KConfigGroup configGroup = config->group("ProcessInfo");
+
+        QStringList defaults = QStringList() 
+                             << "src" << "build" << "debug" << "release" 
+                             << "bin" << "lib"   << "libs"  << "tmp" 
+                             << "doc" << "docs"  << "data"  << "share"
+                             << "examples" << "icons" << "pics" << "plugins" 
+                             << "tests" << "media" << "l10n" << "include" 
+                             << "includes" << "locale" << "ui";
+
+        _commonDirNames = QSet<QString>::fromList(configGroup.readEntry("CommonDirNames",defaults));
+
+    }
+  */
+    return _commonDirNames;
+}
+
+QString ProcessInfo::formatShortDir(const QString& input) const
+{
+    QString result;
+
+    QStringList parts = input.split( QDir::separator() );
+
+    // temporarily hard-coded
+    QSet<QString> dirNamesToShorten = commonDirNames();
+
+    QListIterator<QString> iter(parts);
+    iter.toBack();
+
+    // go backwards through the list of the path's parts
+    // adding abbreviations of common directory names
+    // and stopping when we reach a dir name which is not
+    // in the commonDirNames set
+    while ( iter.hasPrevious() )
+    {
+        QString part = iter.previous();
+
+        if ( dirNamesToShorten.contains(part) )
+        {
+            result.prepend(QDir::separator() + part[0]);
+        }
+        else
+        {
+            result.prepend(part);
+            break;
+        }
+    }
+
+    return result;
+}
+
+QVector<QString> ProcessInfo::arguments(bool* ok) const
+{
+    *ok = _fields & ARGUMENTS;
+
+    return _arguments;
+}
+
+QMap<QString,QString> ProcessInfo::environment(bool* ok) const
+{
+    *ok = _fields & ENVIRONMENT;
+
+    return _environment;
+}
+
+bool ProcessInfo::isValid() const
+{
+    return _fields & PROCESS_ID;
+}
+
+int ProcessInfo::pid(bool* ok) const
+{
+    *ok = _fields & PROCESS_ID;
+
+    return _pid;
+}
+
+int ProcessInfo::parentPid(bool* ok) const
+{
+    *ok = _fields & PARENT_PID;
+
+    return _parentPid;
+}
+
+int ProcessInfo::foregroundPid(bool* ok) const
+{
+    *ok = _fields & FOREGROUND_PID;
+
+    return _foregroundPid;
+}
+
+QString ProcessInfo::name(bool* ok) const
+{
+    *ok = _fields & NAME;
+
+    return _name;
+}
+
+int ProcessInfo::userId(bool* ok) const
+{
+    *ok = _fields & UID;
+
+    return _userId;
+}
+
+QString ProcessInfo::userName() const
+{
+    return _userName;
+}
+
+QString ProcessInfo::userHomeDir() const
+{
+    return _userHomeDir;
+}
+
+void ProcessInfo::setPid(int pid)
+{
+    _pid = pid;
+    _fields |= PROCESS_ID;
+}
+
+void ProcessInfo::setUserId(int uid)
+{
+    _userId = uid;
+    _fields |= UID;
+}
+
+void ProcessInfo::setUserName(const QString& name)
+{
+    _userName = name;
+    setUserHomeDir();
+}
+
+void ProcessInfo::setUserHomeDir()
+{
+    QString usersName = userName();
+    // JPS: I don't know a good QT replacement
+    //if (!usersName.isEmpty())
+    //    _userHomeDir = KUser(usersName).homeDir();
+    //else
+        _userHomeDir = QDir::homePath();
+}
+
+void ProcessInfo::setParentPid(int pid)
+{
+    _parentPid = pid;
+    _fields |= PARENT_PID;
+}
+void ProcessInfo::setForegroundPid(int pid)
+{
+    _foregroundPid = pid;
+    _fields |= FOREGROUND_PID;
+}
+
+QString ProcessInfo::currentDir(bool* ok) const
+{
+    if (ok)
+        *ok = _fields & CURRENT_DIR;
+
+    return _currentDir;
+}
+void ProcessInfo::setCurrentDir(const QString& dir)
+{
+    _fields |= CURRENT_DIR;
+    _currentDir = dir;
+}
+
+void ProcessInfo::setName(const QString& name)
+{
+    _name = name;
+    _fields |= NAME;
+}
+void ProcessInfo::addArgument(const QString& argument)
+{
+    _arguments << argument;    
+}
+
+void ProcessInfo::addEnvironmentBinding(const QString& name , const QString& value)
+{
+    _environment.insert(name,value);
+}
+
+void ProcessInfo::setFileError( QFile::FileError error )
+{
+    switch ( error )
+    {
+        case PermissionsError:
+            setError( PermissionsError );
+            break;
+        case NoError:
+            setError( NoError );
+            break;
+        default:
+            setError( UnknownError );
+    }
+}
+
+//
+// ProcessInfo::newInstance() is way at the bottom so it can see all of the
+// implementations of the UnixProcessInfo abstract class.
+//
+
+NullProcessInfo::NullProcessInfo(int pid,bool enableEnvironmentRead)
+    : ProcessInfo(pid,enableEnvironmentRead)
+{
+}
+
+bool NullProcessInfo::readProcessInfo(int /*pid*/ , bool /*enableEnvironmentRead*/)
+{
+    return false;
+}
+
+void NullProcessInfo::readUserName()
+{
+}
+
+UnixProcessInfo::UnixProcessInfo(int pid,bool enableEnvironmentRead)
+    : ProcessInfo(pid,enableEnvironmentRead)
+{
+}
+
+bool UnixProcessInfo::readProcessInfo(int pid , bool enableEnvironmentRead)
+{
+    bool ok = readProcInfo(pid);
+    if (ok)
+    {
+        ok |= readArguments(pid);
+        ok |= readCurrentDir(pid);
+        if ( enableEnvironmentRead )
+        {
+            ok |= readEnvironment(pid);
+        }
+    }
+    return ok;
+}
+
+void UnixProcessInfo::readUserName()
+{
+    bool ok = false;
+    int uid = userId(&ok);
+    if (!ok) return;
+
+    struct passwd passwdStruct;
+    struct passwd *getpwResult;
+    char *getpwBuffer;
+    long getpwBufferSize;
+    int getpwStatus;
+
+    getpwBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX);
+    if (getpwBufferSize == -1)
+        getpwBufferSize = 16384;
+
+    getpwBuffer = new char[getpwBufferSize];
+    if (getpwBuffer == NULL)
+        return;
+    getpwStatus = getpwuid_r(uid, &passwdStruct, getpwBuffer, getpwBufferSize, &getpwResult);
+    if (getpwResult != NULL)
+        setUserName(QString(passwdStruct.pw_name));
+    else
+        setUserName(QString());
+    delete [] getpwBuffer;
+}
+
+
+class LinuxProcessInfo : public UnixProcessInfo
+{
+public:
+    LinuxProcessInfo(int pid, bool env) :
+        UnixProcessInfo(pid,env)
+    {
+    }
+
+private:
+    virtual bool readProcInfo(int pid)
+    {
+        // indicies of various fields within the process status file which
+        // contain various information about the process
+        const int PARENT_PID_FIELD = 3;
+        const int PROCESS_NAME_FIELD = 1;
+        const int GROUP_PROCESS_FIELD = 7;
+
+        QString parentPidString;
+        QString processNameString;
+        QString foregroundPidString;
+        QString uidLine;
+        QString uidString;
+        QStringList uidStrings;
+
+        // For user id read process status file ( /proc/<pid>/status )
+        //  Can not use getuid() due to it does not work for 'su'
+        QFile statusInfo( QString("/proc/%1/status").arg(pid) );
+        if ( statusInfo.open(QIODevice::ReadOnly) )
+        {
+            QTextStream stream(&statusInfo);
+            QString statusLine;
+            do {
+                statusLine = stream.readLine(0);
+                if (statusLine.startsWith(QLatin1String("Uid:")))
+                    uidLine = statusLine;
+            } while (!statusLine.isNull() && uidLine.isNull());
+
+            uidStrings << uidLine.split('\t', QString::SkipEmptyParts);
+            // Must be 5 entries: 'Uid: %d %d %d %d' and
+            // uid string must be less than 5 chars (uint)
+            if (uidStrings.size() == 5)
+                uidString = uidStrings[1];
+            if (uidString.size() > 5)
+                uidString.clear();
+
+            bool ok = false;
+            int uid = uidString.toInt(&ok);
+            if (ok)
+                setUserId(uid);
+            readUserName();
+        }
+        else
+        {
+            setFileError( statusInfo.error() );
+            return false;
+        }
+
+
+        // read process status file ( /proc/<pid/stat )
+        //
+        // the expected file format is a list of fields separated by spaces, using
+        // parenthesies to escape fields such as the process name which may itself contain
+        // spaces:
+        //
+        // FIELD FIELD (FIELD WITH SPACES) FIELD FIELD
+        //
+        QFile processInfo( QString("/proc/%1/stat").arg(pid) );
+        if ( processInfo.open(QIODevice::ReadOnly) )
+        {
+            QTextStream stream(&processInfo);
+            QString data = stream.readAll();
+
+            int stack = 0;
+            int field = 0;
+            int pos = 0;
+
+            while (pos < data.count())
+            {
+                QChar c = data[pos];
+
+                if ( c == '(' )
+                    stack++;
+                else if ( c == ')' )
+                    stack--;
+                else if ( stack == 0 && c == ' ' )
+                    field++;
+                else
+                {
+                    switch ( field )
+                    {
+                        case PARENT_PID_FIELD:
+                            parentPidString.append(c);
+                            break;
+                        case PROCESS_NAME_FIELD:
+                            processNameString.append(c);
+                            break;
+                        case GROUP_PROCESS_FIELD:
+                            foregroundPidString.append(c);
+                            break;
+                    }
+                }
+
+                pos++;
+            }
+        }
+        else
+        {
+            setFileError( processInfo.error() );
+            return false;
+        }
+
+        // check that data was read successfully
+        bool ok = false;
+        int foregroundPid = foregroundPidString.toInt(&ok);
+        if (ok)
+            setForegroundPid(foregroundPid);
+
+        int parentPid = parentPidString.toInt(&ok);
+        if (ok)
+            setParentPid(parentPid);
+
+        if (!processNameString.isEmpty())
+            setName(processNameString);
+
+        // update object state
+        setPid(pid);
+
+        return ok;
+    }
+
+    virtual bool readArguments(int pid)
+    {
+        // read command-line arguments file found at /proc/<pid>/cmdline
+        // the expected format is a list of strings delimited by null characters,
+        // and ending in a double null character pair.
+
+        QFile argumentsFile( QString("/proc/%1/cmdline").arg(pid) );
+        if ( argumentsFile.open(QIODevice::ReadOnly) )
+        {
+            QTextStream stream(&argumentsFile);
+            QString data = stream.readAll();
+
+            QStringList argList = data.split( QChar('\0') );
+
+            foreach ( const QString &entry , argList )
+            {
+                if (!entry.isEmpty())
+                    addArgument(entry);
+            }
+        }
+        else
+        {
+            setFileError( argumentsFile.error() );
+        }
+
+        return true;
+    }
+
+    virtual bool readCurrentDir(int pid)
+    {
+        QFileInfo info( QString("/proc/%1/cwd").arg(pid) );
+
+        const bool readable = info.isReadable();
+
+        if ( readable && info.isSymLink() )
+        {
+            setCurrentDir( info.symLinkTarget() );
+            return true;
+        }
+        else
+        {
+            if ( !readable )
+                setError( PermissionsError );
+            else
+                setError( UnknownError );
+
+            return false;
+        }
+    }
+
+    virtual bool readEnvironment(int pid)
+    {
+        // read environment bindings file found at /proc/<pid>/environ
+        // the expected format is a list of KEY=VALUE strings delimited by null
+        // characters and ending in a double null character pair.
+
+        QFile environmentFile( QString("/proc/%1/environ").arg(pid) );
+        if ( environmentFile.open(QIODevice::ReadOnly) )
+        {
+            QTextStream stream(&environmentFile);
+            QString data = stream.readAll();
+
+            QStringList bindingList = data.split( QChar('\0') );
+
+            foreach( const QString &entry , bindingList )
+            {
+                QString name;
+                QString value;
+
+                int splitPos = entry.indexOf('=');
+
+                if ( splitPos != -1 )
+                {
+                    name = entry.mid(0,splitPos);
+                    value = entry.mid(splitPos+1,-1);
+
+                    addEnvironmentBinding(name,value);
+                }
+            }
+        }
+        else
+        {
+            setFileError( environmentFile.error() );
+        }
+
+        return true;
+    }
+} ;
+
+#if defined(Q_OS_FREEBSD)
+class FreeBSDProcessInfo : public UnixProcessInfo
+{
+public:
+    FreeBSDProcessInfo(int pid, bool readEnvironment) :
+        UnixProcessInfo(pid, readEnvironment)
+    {
+    }
+
+private:
+    virtual bool readProcInfo(int pid)
+    {
+        int managementInfoBase[4];
+        size_t mibLength;
+        struct kinfo_proc* kInfoProc;
+
+        managementInfoBase[0] = CTL_KERN;
+        managementInfoBase[1] = KERN_PROC;
+        managementInfoBase[2] = KERN_PROC_PID;
+        managementInfoBase[3] = pid;
+
+        if (sysctl(managementInfoBase, 4, NULL, &mibLength, NULL, 0) == -1)
+            return false;
+
+        kInfoProc = new struct kinfo_proc [mibLength];
+
+        if (sysctl(managementInfoBase, 4, kInfoProc, &mibLength, NULL, 0) == -1)
+        {
+            delete [] kInfoProc;
+            return false;
+        }
+
+#if defined(__DragonFly__)
+        setName(kInfoProc->kp_comm);
+        setPid(kInfoProc->kp_pid);
+        setParentPid(kInfoProc->kp_ppid);
+        setForegroundPid(kInfoProc->kp_pgid);
+        setUserId(kInfoProc->kp_uid);
+#else
+        setName(kInfoProc->ki_comm);
+        setPid(kInfoProc->ki_pid);
+        setParentPid(kInfoProc->ki_ppid);
+        setForegroundPid(kInfoProc->ki_pgid);
+        setUserId(kInfoProc->ki_uid);
+#endif
+
+        readUserName();
+
+        delete [] kInfoProc;
+        return true;
+    }
+
+    virtual bool readArguments(int pid)
+    {
+        char args[ARG_MAX];
+        int managementInfoBase[4];
+        size_t len;
+
+        managementInfoBase[0] = CTL_KERN;
+        managementInfoBase[1] = KERN_PROC;
+        managementInfoBase[2] = KERN_PROC_PID;
+        managementInfoBase[3] = pid;
+
+        len = sizeof(args);
+        if (sysctl(managementInfoBase, 4, args, &len, NULL, 0) == -1)
+            return false;
+
+        const QStringList argumentList = QString(args).split(QChar('\0'));
+
+        for (QStringList::const_iterator it = argumentList.begin(); it != argumentList.end(); ++it)
+        {
+            addArgument(*it);
+        }
+
+        return true;
+    }
+
+    virtual bool readEnvironment(int pid)
+    {
+        // Not supported in FreeBSD?
+        return false;
+    }
+
+    virtual bool readCurrentDir(int pid)
+    {
+#if defined(__DragonFly__)
+        char buf[PATH_MAX];
+        int managementInfoBase[4];
+        size_t len;
+
+        managementInfoBase[0] = CTL_KERN;
+        managementInfoBase[1] = KERN_PROC;
+        managementInfoBase[2] = KERN_PROC_CWD;
+        managementInfoBase[3] = pid;
+
+        len = sizeof(buf);
+        if (sysctl(managementInfoBase, 4, buf, &len, NULL, 0) == -1)
+            return false;
+
+        setCurrentDir(buf);
+
+        return true;
+#else
+        int numrecords;
+        struct kinfo_file* info = 0;
+
+        info = kinfo_getfile(pid, &numrecords);
+
+        if (!info)
+            return false;
+
+        for (int i = 0; i < numrecords; ++i)
+        {
+            if (info[i].kf_fd == KF_FD_TYPE_CWD)
+            {
+                setCurrentDir(info[i].kf_path);
+
+                free(info);
+                return true;
+            }
+        }
+
+        free(info);
+        return false;
+#endif
+    }
+} ;
+#endif
+
+#if defined(Q_OS_MAC)
+class MacProcessInfo : public UnixProcessInfo
+{
+public:
+    MacProcessInfo(int pid, bool env) :
+        UnixProcessInfo(pid, env)
+    {
+    }
+
+private:
+    virtual bool readProcInfo(int pid)
+    {
+        int managementInfoBase[4];
+        size_t mibLength;
+        struct kinfo_proc* kInfoProc;
+        KDE_struct_stat statInfo;
+
+        // Find the tty device of 'pid' (Example: /dev/ttys001)
+        managementInfoBase[0] = CTL_KERN;
+        managementInfoBase[1] = KERN_PROC;
+        managementInfoBase[2] = KERN_PROC_PID;
+        managementInfoBase[3] = pid;
+
+        if (sysctl(managementInfoBase, 4, NULL, &mibLength, NULL, 0) == -1)
+        {
+            return false;
+        } 
+        else
+        {
+            kInfoProc = new struct kinfo_proc [mibLength];
+            if (sysctl(managementInfoBase, 4, kInfoProc, &mibLength, NULL, 0) == -1)
+            {
+                delete [] kInfoProc;
+                return false;
+            }
+            else
+            { 
+                QString deviceNumber = QString(devname(((&kInfoProc->kp_eproc)->e_tdev), S_IFCHR));
+                QString fullDeviceName =  QString("/dev/") + deviceNumber.rightJustified(3, '0');
+                delete [] kInfoProc;
+
+                QByteArray deviceName = fullDeviceName.toLatin1();
+                const char* ttyName = deviceName.data();
+
+                if (KDE_stat(ttyName, &statInfo) != 0)
+                    return false;
+
+                // Find all processes attached to ttyName
+                managementInfoBase[0] = CTL_KERN;
+                managementInfoBase[1] = KERN_PROC;
+                managementInfoBase[2] = KERN_PROC_TTY;
+                managementInfoBase[3] = statInfo.st_rdev;
+
+                mibLength = 0;
+                if (sysctl(managementInfoBase, sizeof(managementInfoBase)/sizeof(int), NULL, &mibLength, NULL, 0) == -1)
+                    return false;
+
+                kInfoProc = new struct kinfo_proc [mibLength];
+                if (sysctl(managementInfoBase, sizeof(managementInfoBase)/sizeof(int), kInfoProc, &mibLength, NULL, 0) == -1)
+                    return false;
+
+                // The foreground program is the first one
+                setName(QString(kInfoProc->kp_proc.p_comm));
+
+                delete [] kInfoProc;
+            }
+        }
+        return true;
+    }
+
+    virtual bool readArguments(int pid)
+    {
+        Q_UNUSED(pid);
+        return false;
+    }
+    virtual bool readCurrentDir(int pid)
+    {
+        struct proc_vnodepathinfo vpi;
+        int nb = proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi));
+        if (nb == sizeof(vpi))
+        {
+            setCurrentDir(QString(vpi.pvi_cdir.vip_path));
+            return true;
+        }
+        return false;
+    }
+    virtual bool readEnvironment(int pid)
+    {
+        Q_UNUSED(pid);
+        return false;
+    }
+} ;
+#endif
+
+#ifdef Q_OS_SOLARIS
+    // The procfs structure definition requires off_t to be
+    // 32 bits, which only applies if FILE_OFFSET_BITS=32.
+    // Futz around here to get it to compile regardless,
+    // although some of the structure sizes might be wrong.
+    // Fortunately, the structures we actually use don't use
+    // off_t, and we're safe.
+    #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS==64)
+        #undef _FILE_OFFSET_BITS
+    #endif
+    #include <procfs.h>
+#else
+    // On non-Solaris platforms, define a fake psinfo structure
+    // so that the SolarisProcessInfo class can be compiled
+    //
+    // That avoids the trap where you change the API and
+    // don't notice it in #ifdeffed platform-specific parts
+    // of the code.
+    struct psinfo {
+        int pr_ppid;
+        int pr_pgid;
+        char* pr_fname;
+        char* pr_psargs;
+    } ;
+    static const int PRARGSZ=1;
+#endif
+
+class SolarisProcessInfo : public UnixProcessInfo
+{
+public:
+    SolarisProcessInfo(int pid, bool readEnvironment) 
+    : UnixProcessInfo(pid,readEnvironment)
+    {
+    }
+private:
+    virtual bool readProcInfo(int pid)
+    {
+        QFile psinfo( QString("/proc/%1/psinfo").arg(pid) );
+        if ( psinfo.open( QIODevice::ReadOnly ) )
+        {
+            struct psinfo info;
+            if (psinfo.read((char *)&info,sizeof(info)) != sizeof(info))
+            {
+                return false;
+            }
+
+            setParentPid(info.pr_ppid);
+            setForegroundPid(info.pr_pgid);
+            setName(info.pr_fname);
+            setPid(pid);
+
+            // Bogus, because we're treating the arguments as one single string
+            info.pr_psargs[PRARGSZ-1]=0;
+            addArgument(info.pr_psargs);
+        }
+        return true;
+    }
+
+    virtual bool readArguments(int /*pid*/)
+    {
+        // Handled in readProcInfo()
+        return false;
+    }
+
+    virtual bool readEnvironment(int /*pid*/)
+    {
+        // Not supported in Solaris
+        return false;
+    }
+
+    virtual bool readCurrentDir(int pid)
+    {
+        QFileInfo info( QString("/proc/%1/path/cwd").arg(pid) );
+        const bool readable = info.isReadable();
+
+        if ( readable && info.isSymLink() )
+        {
+            setCurrentDir( info.symLinkTarget() );
+            return true;
+        }
+        else
+        {
+            if ( !readable )
+                setError( PermissionsError );
+            else
+                setError( UnknownError );
+
+            return false;
+        }
+    }
+} ;
+
+SSHProcessInfo::SSHProcessInfo(const ProcessInfo& process)
+ : _process(process)
+{
+    bool ok = false;
+
+    // check that this is a SSH process
+    const QString& name = _process.name(&ok);
+
+    if ( !ok || name != "ssh" )
+    {
+        if ( !ok )
+            kWarning() << "Could not read process info";
+        else
+            kWarning() << "Process is not a SSH process";
+
+        return;
+    }
+
+    // read arguments
+    const QVector<QString>& args = _process.arguments(&ok); 
+
+    // SSH options
+    // these are taken from the SSH manual ( accessed via 'man ssh' )
+    
+    // options which take no arguments
+    static const QString noOptionsArguments("1246AaCfgkMNnqsTtVvXxY"); 
+    // options which take one argument
+    static const QString singleOptionArguments("bcDeFiLlmOopRSw");
+
+    if ( ok )
+    {
+         // find the username, host and command arguments
+         //
+         // the username/host is assumed to be the first argument 
+         // which is not an option
+         // ( ie. does not start with a dash '-' character )
+         // or an argument to a previous option.
+         //
+         // the command, if specified, is assumed to be the argument following
+         // the username and host
+         //
+         // note that we skip the argument at index 0 because that is the
+         // program name ( expected to be 'ssh' in this case )
+         for ( int i = 1 ; i < args.count() ; i++ )
+         {
+            // if this argument is an option then skip it, plus any 
+            // following arguments which refer to this option
+            if ( args[i].startsWith('-') )
+            {
+                QChar argChar = ( args[i].length() > 1 ) ? args[i][1] : '\0';
+
+                if ( noOptionsArguments.contains(argChar) )
+                    continue;
+                else if ( singleOptionArguments.contains(argChar) )
+                {
+                    i++;
+                    continue;
+                }
+            }
+
+            // check whether the host has been found yet
+            // if not, this must be the username/host argument 
+            if ( _host.isEmpty() )
+            {
+                // check to see if only a hostname is specified, or whether
+                // both a username and host are specified ( in which case they
+                // are separated by an '@' character:  username@host )
+            
+                int separatorPosition = args[i].indexOf('@');
+                if ( separatorPosition != -1 )
+                {
+                    // username and host specified
+                    _user = args[i].left(separatorPosition);
+                    _host = args[i].mid(separatorPosition+1);
+                }
+                else
+                {
+                    // just the host specified
+                    _host = args[i];
+                }
+            }
+            else
+            {
+                // host has already been found, this must be the command argument
+                _command = args[i];
+            }
+
+         }
+    }
+    else
+    {
+        kWarning() << "Could not read arguments";
+        
+        return;
+    }
+}
+
+QString SSHProcessInfo::userName() const
+{
+    return _user;
+}
+QString SSHProcessInfo::host() const
+{
+    return _host;
+}
+QString SSHProcessInfo::command() const
+{
+    return _command;
+}
+QString SSHProcessInfo::format(const QString& input) const
+{
+    QString output(input);
+   
+    // test whether host is an ip address
+    // in which case 'short host' and 'full host'
+    // markers in the input string are replaced with
+    // the full address
+    bool isIpAddress = false;
+   
+    struct in_addr address;
+    if ( inet_aton(_host.toLocal8Bit().constData(),&address) != 0 )
+        isIpAddress = true;
+    else
+        isIpAddress = false;
+
+    // search for and replace known markers
+    output.replace("%u",_user);
+
+    if ( isIpAddress )
+        output.replace("%h",_host);
+    else
+        output.replace("%h",_host.left(_host.indexOf('.')));
+    
+    output.replace("%H",_host);
+    output.replace("%c",_command);
+
+    return output;
+}
+
+ProcessInfo* ProcessInfo::newInstance(int pid,bool enableEnvironmentRead)
+{
+#ifdef Q_OS_LINUX
+    return new LinuxProcessInfo(pid,enableEnvironmentRead);
+#elif defined(Q_OS_SOLARIS)
+    return new SolarisProcessInfo(pid,enableEnvironmentRead);
+#elif defined(Q_OS_MAC)
+    return new MacProcessInfo(pid,enableEnvironmentRead);
+#elif defined(Q_OS_FREEBSD)
+    return new FreeBSDProcessInfo(pid,enableEnvironmentRead);
+#else
+    return new NullProcessInfo(pid,enableEnvironmentRead);
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ProcessInfo.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,466 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef PROCESSINFO_H
+#define PROCESSINFO_H
+
+// Qt
+#include <QtCore/QFile>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QVector>
+
+namespace Konsole
+{
+
+/**
+ * Takes a snapshot of the state of a process and provides access to 
+ * information such as the process name, parent process,
+ * the foreground process in the controlling terminal,
+ * the arguments with which the process was started and the 
+ * environment.
+ *
+ * To create a new snapshot, construct a new ProcessInfo instance,
+ * using ProcessInfo::newInstance(),
+ * passing the process identifier of the process you are interested in.
+ *
+ * After creating a new instance, call the update() method to take a 
+ * snapshot of the current state of the process.
+ *
+ * Before calling any additional methods, check that the process state
+ * was read successfully using the isValid() method.
+ *
+ * Each accessor method which provides information about the process state ( such as pid(), 
+ * currentDir(), name() ) takes a pointer to a boolean as an argument.  If the information
+ * requested was read successfully then the boolean is set to true, otherwise it is set
+ * to false, in which case the return value from the function should be ignored.
+ * If this boolean is set to false, it may indicate an error reading the process information,
+ * or it may indicate that the information is not available on the current platform. 
+ *
+ * eg.
+ *
+ * @code
+ *   ProcessInfo* info = ProcessInfo::newInstance(pid);
+ *   info->update();
+ *
+ *   if ( info->isValid() )
+ *   {
+ *      bool ok;
+ *      QString value = info->name(&ok);
+ *
+ *      if ( ok ) kDebug() << "process name - " << name;
+ *      int parentPid = info->parentPid(&ok);
+ *      if ( ok ) kDebug() << "parent process - " << parentPid;
+ *      int foregroundPid = info->foregroundColororegroundPid(&ok);
+ *      if ( ok ) kDebug() << "foreground process - " << foregroundPid;
+ *   }
+ * @endcode
+ */
+class ProcessInfo
+{
+public:
+    /**
+     * Constructs a new instance of a suitable ProcessInfo sub-class for 
+     * the current platform which provides information about a given process.
+     *
+     * @param pid The pid of the process to examine
+     * @param readEnvironment Specifies whether environment bindings should
+     * be read.  If this is false, then environment() calls will
+     * always fail.  This is an optimization to avoid the overhead
+     * of reading the (potentially large) environment data when it
+     * is not required. 
+     */
+    static ProcessInfo* newInstance(int pid,bool readEnvironment = false);
+
+    virtual ~ProcessInfo() {}
+
+    /** 
+     * Updates the information about the process.  This must
+     * be called before attempting to use any of the accessor methods.
+     */
+    void update();
+
+    /** Returns true if the process state was read successfully. */ 
+    bool isValid() const;
+    /** 
+     * Returns the process id.  
+     *
+     * @param ok Set to true if the process id was read successfully or false otherwise 
+     */
+    int pid(bool* ok) const;
+    /** 
+     * Returns the id of the parent process id was read successfully or false otherwise
+     * 
+     * @param ok Set to true if the parent process id
+     */
+    int parentPid(bool* ok) const;
+    
+    /** 
+     * Returns the id of the current foreground process 
+     *
+     * NOTE:  Using the foregroundProcessGroup() method of the Pty
+     * instance associated with the terminal of interest is preferred
+     * over using this method.
+     *
+     * @param ok Set to true if the foreground process id was read successfully or false otherwise
+     */
+    int foregroundPid(bool* ok) const;
+    
+    /* Returns the user id of the process */
+    int userId(bool* ok) const;
+
+    /** Returns the user's name of the process */
+    QString userName() const;
+   
+    /** Returns the user's home directory of the process */
+    QString userHomeDir() const;
+
+    /** Returns the name of the current process */
+    QString name(bool* ok) const;
+   
+    /** 
+     * Returns the command-line arguments which the process
+     * was started with.
+     *
+     * The first argument is the name used to launch the process.
+     *
+     * @param ok Set to true if the arguments were read successfully or false otherwise.
+     */
+    QVector<QString> arguments(bool* ok) const;
+    /**
+     * Returns the environment bindings which the process
+     * was started with.
+     * In the returned map, the key is the name of the environment variable,
+     * and the value is the corresponding value.
+     *
+     * @param ok Set to true if the environment bindings were read successfully or false otherwise
+     */
+    QMap<QString,QString> environment(bool* ok) const;
+
+    /**
+     * Returns the current working directory of the process
+     *
+     * @param ok Set to true if the current working directory was read successfully or false otherwise
+     */
+    QString currentDir(bool* ok) const;
+
+    /**
+     * Returns the current working directory of the process (or its parent)
+     */
+    QString validCurrentDir() const;
+
+    /** Forces the user home directory to be calculated */
+    void setUserHomeDir();
+
+    /**
+     * Parses an input string, looking for markers beginning with a '%' 
+     * character and returns a string with the markers replaced
+     * with information from this process description.
+     * <br>
+     * The markers recognised are:
+     * <ul>
+     * <li> %u - Name of the user which owns the process. </li>
+     * <li> %n - Replaced with the name of the process.   </li>
+     * <li> %d - Replaced with the last part of the path name of the 
+     *      process' current working directory.
+     *      
+     *      (eg. if the current directory is '/home/bob' then
+     *      'bob' would be returned)
+     * </li>
+     * <li> %D - Replaced with the current working directory of the process. </li>
+     * </ul>
+     */
+    QString format(const QString& text) const;
+
+    /** 
+     * This enum describes the errors which can occur when trying to read 
+     * a process's information.
+     */
+    enum Error
+    {
+        /** No error occurred. */
+        NoError,
+        /** The nature of the error is unknown. */
+        UnknownError,
+        /** Konsole does not have permission to obtain the process information. */
+        PermissionsError
+    };
+
+    /**
+     * Returns the last error which occurred.
+     */
+    Error error() const;
+
+protected:
+    /**
+     * Constructs a new process instance.  You should not call the constructor
+     * of ProcessInfo or its subclasses directly.  Instead use the 
+     * static ProcessInfo::newInstance() method which will return
+     * a suitable ProcessInfo instance for the current platform.
+     */ 
+    explicit ProcessInfo(int pid , bool readEnvironment = false);
+
+    /** 
+     * This is called on construction to read the process state 
+     * Subclasses should reimplement this function to provide
+     * platform-specific process state reading functionality.
+     *
+     * When called, readProcessInfo() should attempt to read all
+     * of the necessary state information.  If the attempt is successful,
+     * it should set the process id using setPid(), and update
+     * the other relevant information using setParentPid(), setName(),
+     * setArguments() etc.
+     *
+     * Calls to isValid() will return true only if the process id
+     * has been set using setPid()
+     *
+     * @param pid The process id of the process to read
+     * @param readEnvironment Specifies whether the environment bindings
+     *                        for the process should be read
+     */
+    virtual bool readProcessInfo(int pid , bool readEnvironment) = 0;
+
+    /* Read the user name */
+    virtual void readUserName(void) = 0;
+
+    /** Sets the process id associated with this ProcessInfo instance */
+    void setPid(int pid);
+    /** Sets the parent process id as returned by parentPid() */
+    void setParentPid(int pid);
+    /** Sets the foreground process id as returend by foregroundPid() */
+    void setForegroundPid(int pid);
+    /** Sets the user id associated with this ProcessInfo instance */
+    void setUserId(int uid);
+    /** Sets the user name of the process as set by readUserName() */
+    void setUserName(const QString& name);
+    /** Sets the name of the process as returned by name() */
+    void setName(const QString& name);
+    /** Sets the current working directory for the process */
+    void setCurrentDir(const QString& dir);
+
+    /** Sets the error */
+    void setError( Error error );
+
+    /** Convenience method.  Sets the error based on a QFile error code. */ 
+    void setFileError( QFile::FileError error ); 
+
+    /** 
+     * Adds a commandline argument for the process, as returned
+     * by arguments()
+     */
+    void addArgument(const QString& argument);
+    /**
+     * Adds an environment binding for the process, as returned by
+     * environment()
+     *
+     * @param name The name of the environment variable, eg. "PATH"
+     * @param value The value of the environment variable, eg. "/bin"
+     */
+    void addEnvironmentBinding(const QString& name , const QString& value);
+
+private:
+    // takes a full directory path and returns a
+    // shortened version suitable for display in 
+    // space-constrained UI elements (eg. tabs)
+    QString formatShortDir(const QString& dirPath) const;
+
+    enum CommandFormat
+    {
+        ShortCommandFormat,
+        LongCommandFormat
+    };
+    // takes a process name and its arguments and produces formatted output
+    QString formatCommand(const QString& name , const QVector<QString>& arguments , 
+                          CommandFormat format) const;
+
+    // valid bits for _fields variable, ensure that
+    // _fields is changed to an int if more than 8 fields are added
+    enum FIELD_BITS
+    {
+        PROCESS_ID          = 1,
+        PARENT_PID          = 2,
+        FOREGROUND_PID      = 4,
+        ARGUMENTS           = 8,
+        ENVIRONMENT         = 16,
+        NAME                = 32,
+        CURRENT_DIR         = 64,
+        UID                 =128 
+    };
+
+    char _fields; // a bitmap indicating which fields are valid
+                  // used to set the "ok" parameters for the public
+                  // accessor functions
+
+    bool _enableEnvironmentRead; // specifies whether to read the environment
+                                 // bindings when update() is called
+    int _pid;  
+    int _parentPid;
+    int _foregroundPid;
+    int _userId;  
+
+    Error _lastError;
+
+    QString _name;
+    QString _userName;
+    QString _userHomeDir;
+    QString _currentDir;
+
+    QVector<QString> _arguments;
+    QMap<QString,QString> _environment;
+
+    static QSet<QString> commonDirNames();
+    static QSet<QString> _commonDirNames;
+};
+
+/** 
+ * Implementation of ProcessInfo which does nothing.
+ * Used on platforms where a suitable ProcessInfo subclass is not 
+ * available.
+ *
+ * isValid() will always return false for instances of NullProcessInfo
+ */
+class NullProcessInfo : public ProcessInfo
+{
+public:
+    /** 
+     * Constructs a new NullProcessInfo instance.
+     * See ProcessInfo::newInstance()
+     */
+    explicit NullProcessInfo(int pid,bool readEnvironment = false);
+protected:
+    virtual bool readProcessInfo(int pid,bool readEnvironment);
+    virtual void readUserName(void);
+};
+
+/**
+ * Implementation of ProcessInfo for Unix platforms which uses
+ * the /proc filesystem
+ */
+class UnixProcessInfo : public ProcessInfo
+{
+public:
+    /** 
+     * Constructs a new instance of UnixProcessInfo.
+     * See ProcessInfo::newInstance()
+     */
+    explicit UnixProcessInfo(int pid,bool readEnvironment = false);
+
+protected:
+    /** 
+     * Implementation of ProcessInfo::readProcessInfo(); calls the
+     * four private methods below in turn.
+     */
+    virtual bool readProcessInfo(int pid , bool readEnvironment);
+
+    virtual void readUserName(void);
+
+private:
+    /**
+     * Read the standard process information -- PID, parent PID, foreground PID.
+     * @param pid process ID to use
+     * @return true on success
+     */
+    virtual bool readProcInfo(int pid)=0;
+
+    /**
+     * Read the environment of the process. Sets _environment.
+     * @param pid process ID to use
+     * @return true on success
+     */
+    virtual bool readEnvironment(int pid)=0;
+
+    /**
+     * Determine what arguments were passed to the process. Sets _arguments.
+     * @param pid process ID to use
+     * @return true on success
+     */
+    virtual bool readArguments(int pid)=0;
+
+    /**
+     * Determine the current directory of the process.
+     * @param pid process ID to use
+     * @return true on success
+     */
+    virtual bool readCurrentDir(int pid)=0;
+};
+
+/** 
+ * Lightweight class which provides additional information about SSH processes.
+ */
+class SSHProcessInfo
+{
+public:
+    /** 
+     * Constructs a new SSHProcessInfo instance which provides additional
+     * information about the specified SSH process.
+     *
+     * @param process A ProcessInfo instance for a SSH process.
+     */
+    SSHProcessInfo(const ProcessInfo& process);
+
+    /** 
+     * Returns the user name which the user initially logged into on
+     * the remote computer.
+     */
+    QString userName() const;
+
+    /**
+     * Returns the host which the user has connected to.
+     */
+    QString host() const;
+
+    /** 
+     * Returns the command which the user specified to execute on the 
+     * remote computer when starting the SSH process.
+     */
+    QString command() const;
+
+    /**
+     * Operates in the same way as ProcessInfo::format(), except
+     * that the set of markers understood is different:
+     *
+     * %u - Replaced with user name which the user initially logged
+     *      into on the remote computer.
+     * %h - Replaced with the first part of the host name which
+     *      is connected to.
+     * %H - Replaced with the full host name of the computer which
+     *      is connected to.
+     * %c - Replaced with the command which the user specified
+     *      to execute when starting the SSH process.
+     */
+    QString format(const QString& input) const;
+
+private:
+    const ProcessInfo& _process;
+    QString _user;
+    QString _host;
+    QString _command;
+};
+
+}
+#endif //PROCESSINFO_H
+
+/*
+  Local Variables:
+  mode: c++
+  c-file-style: "stroustrup"
+  indent-tabs-mode: nil
+  tab-width: 4
+  End:
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Profile.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,553 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "Profile.h"
+
+// Qt
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextCodec>
+
+// KDE
+#include <KConfigGroup>
+#include <KDesktopFile>
+#include <KGlobal>
+#include <KGlobalSettings>
+#include <KLocale>
+#include <KDebug>
+#include <KStandardDirs>
+
+// System
+#include <unistd.h>
+
+// Konsole
+#include "ShellCommand.h"
+
+using namespace Konsole;
+
+// mappings between property enum values and names
+//
+// multiple names are defined for some property values,
+// in these cases, the "proper" string name comes first,
+// as that is used when reading/writing profiles from/to disk
+//
+// the other names are usually shorter versions for convenience
+// when parsing konsoleprofile commands
+static const char GENERAL_GROUP[] = "General";
+static const char KEYBOARD_GROUP[] = "Keyboard";
+static const char APPEARANCE_GROUP[] = "Appearance";
+static const char SCROLLING_GROUP[] = "Scrolling";
+static const char TERMINAL_GROUP[] = "Terminal Features";
+static const char CURSOR_GROUP[] = "Cursor Options";
+static const char INTERACTION_GROUP[] = "Interaction Options";
+static const char ENCODING_GROUP[] = "Encoding Options";
+
+const Profile::PropertyInfo Profile::DefaultPropertyNames[] =
+{
+    // General
+      { Path , "Path" , 0 , QVariant::String }
+    , { Name , "Name" , GENERAL_GROUP , QVariant::String }
+    , { Title , "Title" , 0 , QVariant::String }
+    , { Icon , "Icon" , GENERAL_GROUP , QVariant::String }
+    , { Command , "Command" , 0 , QVariant::String }
+    , { Arguments , "Arguments" , 0 , QVariant::StringList }
+    , { Environment , "Environment" , GENERAL_GROUP , QVariant::StringList }
+    , { Directory , "Directory" , GENERAL_GROUP , QVariant::String }
+    , { LocalTabTitleFormat , "LocalTabTitleFormat" , GENERAL_GROUP , QVariant::String }
+    , { LocalTabTitleFormat , "tabtitle" , 0 , QVariant::String }
+    , { RemoteTabTitleFormat , "RemoteTabTitleFormat" , GENERAL_GROUP , QVariant::String }
+    , { ShowMenuBar , "ShowMenuBar" , GENERAL_GROUP , QVariant::Bool }
+    , { SaveGeometryOnExit , "SaveGeometryOnExit" , GENERAL_GROUP , QVariant::Bool }
+    , { TabBarMode , "TabBarMode" , GENERAL_GROUP , QVariant::Int }
+    , { TabBarPosition , "TabBarPosition" , GENERAL_GROUP , QVariant::Int }
+    , { StartInCurrentSessionDir , "StartInCurrentSessionDir" , GENERAL_GROUP , QVariant::Bool }
+    , { ShowNewAndCloseTabButtons, "ShowNewAndCloseTabButtons" , GENERAL_GROUP , QVariant::Bool }
+    , { MenuIndex, "MenuIndex" , GENERAL_GROUP , QVariant::String }
+
+    // Appearance
+    , { Font , "Font" , APPEARANCE_GROUP , QVariant::Font }
+    , { ColorScheme , "ColorScheme" , APPEARANCE_GROUP , QVariant::String }
+    , { ColorScheme , "colors" , 0 , QVariant::String }
+    , { AntiAliasFonts, "AntiAliasFonts" , APPEARANCE_GROUP , QVariant::Bool }
+    , { BoldIntense, "BoldIntense", APPEARANCE_GROUP, QVariant::Bool }
+    
+    // Keyboard
+    , { KeyBindings , "KeyBindings" , KEYBOARD_GROUP , QVariant::String }
+    
+    // Scrolling
+    , { HistoryMode , "HistoryMode" , SCROLLING_GROUP , QVariant::Int }
+    , { HistorySize , "HistorySize" , SCROLLING_GROUP , QVariant::Int } 
+    , { ScrollBarPosition , "ScrollBarPosition" , SCROLLING_GROUP , QVariant::Int }
+   
+       // Terminal Features
+    , { BlinkingTextEnabled , "BlinkingTextEnabled" , TERMINAL_GROUP , QVariant::Bool }
+    , { FlowControlEnabled , "FlowControlEnabled" , TERMINAL_GROUP , QVariant::Bool }
+    , { AllowProgramsToResizeWindow , "AllowProgramsToResizeWindow" , TERMINAL_GROUP , QVariant::Bool }
+    , { BidiRenderingEnabled , "BidiRenderingEnabled" , TERMINAL_GROUP , QVariant::Bool }
+    , { BlinkingCursorEnabled , "BlinkingCursorEnabled" , TERMINAL_GROUP , QVariant::Bool }
+    
+    // Cursor 
+    , { UseCustomCursorColor , "UseCustomCursorColor" , CURSOR_GROUP , QVariant::Bool}
+    , { CursorShape , "CursorShape" , CURSOR_GROUP , QVariant::Int}
+    , { CustomCursorColor , "CustomCursorColor" , CURSOR_GROUP , QVariant::Color }
+
+    // Interaction
+    , { WordCharacters , "WordCharacters" , INTERACTION_GROUP , QVariant::String }
+    , { TripleClickMode , "TripleClickSelectsFromCursor" , INTERACTION_GROUP , QVariant::Bool }
+
+    // Encoding
+    , { DefaultEncoding , "DefaultEncoding" , ENCODING_GROUP , QVariant::String }
+
+    , { (Property)0 , 0 , 0, QVariant::Invalid }
+};
+
+QHash<QString,Profile::PropertyInfo> Profile::_propertyInfoByName;
+QHash<Profile::Property,Profile::PropertyInfo> Profile::_infoByProperty;
+
+void Profile::fillTableWithDefaultNames()
+{
+    static bool filledDefaults = false;
+
+    if ( filledDefaults )
+        return;
+
+    const PropertyInfo* iter = DefaultPropertyNames;
+    while ( iter->name != 0 )
+    {
+       registerProperty(*iter);
+       iter++;
+    }
+
+   filledDefaults = true; 
+}
+
+FallbackProfile::FallbackProfile()
+ : Profile()
+{
+    // Fallback settings
+    setProperty(Name,i18n("Shell"));
+    // magic path for the fallback profile which is not a valid 
+    // non-directory file name
+    setProperty(Path,"FALLBACK/"); 
+    setProperty(Command,qgetenv("SHELL"));
+    setProperty(Icon,"utilities-terminal");
+    setProperty(Arguments,QStringList() << qgetenv("SHELL"));
+    setProperty(Environment,QStringList() << "TERM=xterm");
+    setProperty(LocalTabTitleFormat,"%d : %n");
+    setProperty(RemoteTabTitleFormat,"%H (%u)");
+    setProperty(TabBarMode,AlwaysShowTabBar);
+    setProperty(TabBarPosition,TabBarBottom);
+    setProperty(ShowMenuBar,true);
+    setProperty(SaveGeometryOnExit,true);
+    setProperty(StartInCurrentSessionDir,true);
+    setProperty(ShowNewAndCloseTabButtons,false);
+    setProperty(MenuIndex,"0");
+
+    setProperty(KeyBindings,"default");
+    setProperty(ColorScheme,"Linux"); //use DarkPastels when is start support blue ncurses UI properly
+    setProperty(Font,KGlobalSettings::fixedFont());
+
+    setProperty(HistoryMode,FixedSizeHistory);
+    setProperty(HistorySize,1000);
+    setProperty(ScrollBarPosition,ScrollBarRight);
+    
+    setProperty(FlowControlEnabled,true);
+    setProperty(AllowProgramsToResizeWindow,true);
+    setProperty(BlinkingTextEnabled,true);
+    
+    setProperty(BlinkingCursorEnabled,false);
+    setProperty(BidiRenderingEnabled,false);
+    setProperty(CursorShape,BlockCursor);
+    setProperty(UseCustomCursorColor,false);
+    setProperty(CustomCursorColor,Qt::black);
+
+    setProperty(DefaultEncoding,QString(QTextCodec::codecForLocale()->name()));
+    setProperty(AntiAliasFonts,true);
+    setProperty(BoldIntense,true);
+
+    // default taken from KDE 3
+    setProperty(WordCharacters,":@-./_~?&=%+#");
+
+    // Fallback should not be shown in menus
+    setHidden(true);
+}
+Profile::Profile(Profile::Ptr parent)
+    : _parent(parent)
+     ,_hidden(false)
+{
+}
+void Profile::clone(Profile::Ptr profile, bool differentOnly)
+{
+    const PropertyInfo* properties = DefaultPropertyNames;
+    while (properties->name != 0)
+    {
+        Property current = properties->property;
+        QVariant otherValue = profile->property<QVariant>(current);
+        switch (current)
+        {
+            case Name:
+            case Path:
+                break;
+            default:
+                if (!differentOnly || 
+                    property<QVariant>(current) != 
+                    otherValue)
+                {
+                    setProperty(current,otherValue);
+                }
+        }
+        properties++;
+    }
+}
+Profile::~Profile()
+{
+}
+bool Profile::isHidden() const { return _hidden; }
+void Profile::setHidden(bool hidden) { _hidden = hidden; }
+
+void Profile::setParent(Profile::Ptr parent) { _parent = parent; }
+const Profile::Ptr Profile::parent() const { return _parent; }
+
+bool Profile::isEmpty() const
+{
+    return _propertyValues.isEmpty();
+}
+QHash<Profile::Property,QVariant> Profile::setProperties() const
+{
+    return _propertyValues;
+}
+void Profile::setProperty(Property property , const QVariant& value)
+{
+    _propertyValues.insert(property,value);
+}
+bool Profile::isPropertySet(Property property) const
+{
+    return _propertyValues.contains(property);
+}
+
+bool Profile::isNameRegistered(const QString& name) 
+{
+    // insert default names into table the first time this is called
+    fillTableWithDefaultNames();
+
+    return _propertyInfoByName.contains(name);
+}
+
+Profile::Property Profile::lookupByName(const QString& name)
+{
+    // insert default names into table the first time this is called
+    fillTableWithDefaultNames();
+
+    return _propertyInfoByName[name.toLower()].property;
+}
+QString Profile::primaryNameForProperty(Property property)
+{
+    // insert default names into table the first time this is called
+    fillTableWithDefaultNames();
+
+    return _infoByProperty[property].name;
+}
+QList<QString> Profile::namesForProperty(Property property)
+{
+    // insert default names into table the first time this is called
+    fillTableWithDefaultNames();
+
+    return QList<QString>() << primaryNameForProperty(property);
+}
+void Profile::registerProperty(const PropertyInfo& info) 
+{
+    _propertyInfoByName.insert(QString(info.name).toLower(),info);
+
+    // only allow one property -> name map
+    // (multiple name -> property mappings are allowed though)
+    if ( !_infoByProperty.contains(info.property) )
+        _infoByProperty.insert(info.property,info);
+}
+
+int Profile::menuIndexAsInt() const
+{
+    bool ok;
+    int index = menuIndex().toInt(&ok, 10);
+    if (ok) return index;
+    return 0;
+}
+
+QString KDE4ProfileWriter::getPath(const Profile::Ptr info)
+{
+    QString newPath;
+
+    if ( info->isPropertySet(Profile::Path) && 
+         info->path().startsWith(KGlobal::dirs()->saveLocation("data", "konsole/")) )
+    {
+        newPath = info->path();
+    }
+    else
+    {
+        // use the profile name + ".profile" and save it in $KDEHOME
+        newPath = KGlobal::dirs()->saveLocation("data","konsole/") + info->name() + ".profile";
+    }
+
+    //kDebug(1211) << "Saving profile under name: " << newPath;
+
+    return newPath;
+}
+void KDE4ProfileWriter::writeProperties(KConfig& config,
+                                        const Profile::Ptr profile,
+                                        const Profile::PropertyInfo* properties) 
+{
+    const char* groupName = 0;
+    KConfigGroup group;
+    
+    while (properties->name != 0)    
+    {
+        if (properties->group != 0)
+        {
+            if (groupName == 0 || strcmp(groupName,properties->group) != 0)
+            {
+                group = config.group(properties->group);
+                groupName = properties->group;
+            }
+
+            if ( profile->isPropertySet(properties->property) )
+                group.writeEntry(QString(properties->name),
+                            profile->property<QVariant>(properties->property));
+        }
+
+        properties++;
+    }
+}
+bool KDE4ProfileWriter::writeProfile(const QString& path , const Profile::Ptr profile)
+{
+    KConfig config(path,KConfig::NoGlobals);
+
+    KConfigGroup general = config.group(GENERAL_GROUP);
+
+    // Parent profile if set, when loading the profile in future, the parent
+    // must be loaded as well if it exists.
+    if ( profile->parent() )
+        general.writeEntry("Parent",profile->parent()->path());
+
+    if (    profile->isPropertySet(Profile::Command) 
+         || profile->isPropertySet(Profile::Arguments) )
+        general.writeEntry("Command",
+                ShellCommand(profile->command(),profile->arguments()).fullCommand());
+
+    // Write remaining properties
+    writeProperties(config,profile,Profile::DefaultPropertyNames);
+
+    return true;
+}
+
+QStringList KDE4ProfileReader::findProfiles()
+{
+    return KGlobal::dirs()->findAllResources("data","konsole/*.profile",
+            KStandardDirs::NoDuplicates);
+}
+void KDE4ProfileReader::readProperties(const KConfig& config, Profile::Ptr profile,
+                                       const Profile::PropertyInfo* properties)
+{
+    const char* groupName = 0;
+    KConfigGroup group;
+
+    while (properties->name != 0)
+    {
+        if (properties->group != 0)
+        {
+            if (groupName == 0 || strcmp(groupName,properties->group) != 0)
+            {
+                group = config.group(properties->group);
+                groupName = properties->group;
+            }
+        
+            QString name(properties->name);
+
+            if (group.hasKey(name))
+                profile->setProperty(properties->property,
+                                     group.readEntry(name,QVariant(properties->type)));
+
+        }
+        
+        properties++;
+    }
+}
+
+bool KDE4ProfileReader::readProfile(const QString& path , Profile::Ptr profile , QString& parentProfile)
+{
+    if (!QFile::exists(path))
+        return false;
+
+    KConfig config(path,KConfig::NoGlobals);
+
+    KConfigGroup general = config.group(GENERAL_GROUP);
+    if (general.hasKey("Parent"))
+        parentProfile = general.readEntry("Parent");
+
+    if ( general.hasKey("Command") )
+    {
+        ShellCommand shellCommand(general.readEntry("Command"));
+
+        profile->setProperty(Profile::Command,shellCommand.command());
+        profile->setProperty(Profile::Arguments,shellCommand.arguments());
+    }
+
+    // Read remaining properties
+    readProperties(config,profile,Profile::DefaultPropertyNames);
+
+    return true;
+}
+QStringList KDE3ProfileReader::findProfiles()
+{
+    return KGlobal::dirs()->findAllResources("data", "konsole/*.desktop", 
+            KStandardDirs::NoDuplicates);
+}
+bool KDE3ProfileReader::readProfile(const QString& path , Profile::Ptr profile , QString& parentProfile)
+{
+    if (!QFile::exists(path))
+        return false;
+
+    // KDE 3 profiles do not have parents
+    parentProfile.clear();
+
+    KDesktopFile* desktopFile = new KDesktopFile(path);
+    KConfigGroup* config = new KConfigGroup( desktopFile->desktopGroup() );
+
+    if ( config->hasKey("Name") )
+        profile->setProperty(Profile::Name,config->readEntry("Name"));
+
+    //kDebug() << "reading KDE 3 profile " << profile->name();
+
+    if ( config->hasKey("Icon") )
+        profile->setProperty(Profile::Icon,config->readEntry("Icon"));
+    if ( config->hasKey("Exec") )
+    {
+        const QString& fullCommand = config->readEntry("Exec");
+        ShellCommand shellCommand(fullCommand);
+    
+        profile->setProperty(Profile::Command,shellCommand.command());
+        profile->setProperty(Profile::Arguments,shellCommand.arguments());
+    }
+    if ( config->hasKey("Schema") )
+    {
+        profile->setProperty(Profile::ColorScheme,config->readEntry("Schema").replace
+                                            (".schema",QString()));        
+    }
+    if ( config->hasKey("defaultfont") )
+    {
+        profile->setProperty(Profile::Font,config->readEntry("defaultfont"));
+    }
+    if ( config->hasKey("KeyTab") )
+    {
+        profile->setProperty(Profile::KeyBindings,config->readEntry("KeyTab"));
+    }
+    if ( config->hasKey("Term") )
+    {
+        profile->setProperty(Profile::Environment,
+                QStringList() << "TERM="+config->readEntry("Term"));
+    }
+    if ( config->hasKey("Cwd") )
+    {
+        profile->setProperty(Profile::Directory,config->readEntry("Cwd"));
+    }
+
+    delete desktopFile;
+    delete config;
+
+    return true;
+}
+
+QHash<Profile::Property,QVariant> ProfileCommandParser::parse(const QString& input)
+{
+    QHash<Profile::Property,QVariant> changes;
+
+    // regular expression to parse profile change requests.
+    //
+    // format: property=value;property=value ...
+    //
+    // where 'property' is a word consisting only of characters from A-Z
+    // where 'value' is any sequence of characters other than a semi-colon
+    //
+    static QRegExp regExp("([a-zA-Z]+)=([^;]+)");
+
+    int offset = 0;
+    while ( regExp.indexIn(input,offset) != -1 )
+    {
+        if ( regExp.capturedTexts().count() == 3 )
+        {
+            Profile::Property property = Profile::lookupByName(
+                                                regExp.capturedTexts()[1]);
+            const QString value = regExp.capturedTexts()[2];
+            changes.insert(property,value);
+        }
+
+        offset = input.indexOf(';',offset) + 1;
+        if ( offset == 0 )
+            break;
+    }
+
+    return changes;
+}
+
+void ProfileGroup::updateValues()
+{
+    const PropertyInfo* properties = Profile::DefaultPropertyNames;
+    while (properties->name != 0)
+    {
+        // the profile group does not store a value for some properties
+        // (eg. name, path) if even they are equal between profiles - 
+        //
+        // the exception is when the group has only one profile in which
+        // case it behaves like a standard Profile
+        if (_profiles.count() > 1 && 
+            !canInheritProperty(properties->property))
+        {
+            properties++;
+            continue;
+        }
+
+        QVariant value;
+        for (int i=0;i<_profiles.count();i++)
+        {   
+            QVariant profileValue = _profiles[i]->property<QVariant>(properties->property);
+            if (value.isNull())
+                value = profileValue; 
+            else if (value != profileValue)
+            {
+                value = QVariant();
+                break;
+            }
+        }   
+        Profile::setProperty(properties->property,value);
+        properties++;
+    }
+}
+void ProfileGroup::setProperty(Property property, const QVariant& value)
+{
+    if (_profiles.count() > 1 && !canInheritProperty(property))
+        return;
+
+    Profile::setProperty(property,value);
+    foreach(Profile::Ptr profile,_profiles)
+        profile->setProperty(property,value);
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Profile.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,634 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef PROFILE_H
+#define PROFILE_H
+
+// Qt
+#include <QtCore/QHash>
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+
+#include <QtGui/QFont>
+
+// KDE
+#include <KSharedPtr>
+#include <KDebug>
+
+// Konsole
+#include "konsole_export.h"
+
+class KConfig;
+
+namespace Konsole
+{
+class ProfileGroup;
+
+/**
+ * Represents a terminal set-up which can be used to 
+ * set the initial state of new terminal sessions or applied
+ * to existing sessions.  Profiles consist of a number of named
+ * properties, which can be retrieved using property() and
+ * set using setProperty().  isPropertySet() can be used to check
+ * whether a particular property has been set in a profile.
+ *
+ * Profiles support a simple form of inheritance.  When a new Profile
+ * is constructed, a pointer to a parent profile can be passed to
+ * the constructor.  When querying a particular property of a profile
+ * using property(), the profile will return its own value for that 
+ * property if one has been set or otherwise it will return the
+ * parent's value for that property.  
+ *
+ * Profiles can be loaded from disk using ProfileReader instances
+ * and saved to disk using ProfileWriter instances.
+ */
+class KONSOLEPRIVATE_EXPORT Profile : public QSharedData 
+{
+
+friend class KDE4ProfileReader;
+friend class KDE4ProfileWriter;
+friend class ProfileGroup;
+
+public:
+    typedef KSharedPtr<Profile> Ptr;
+    typedef KSharedPtr<ProfileGroup> GroupPtr;
+
+    /**
+     * This enum describes the available properties
+     * which a Profile may consist of.
+     *
+     * Properties can be set using setProperty() and read
+     * using property()
+     */
+    enum Property
+    {
+        /** (QString) Path to the profile's configuration file on-disk. */
+        Path,   
+        /** (QString) The descriptive name of this profile. */
+        Name,   
+        /** (QString) Title of this profile that will be displayed. */
+        Title, 
+        /** (QString) The name of the icon associated with this profile.  This 
+         * is used in menus and tabs to represent the profile. 
+         */
+        Icon, 
+        /** (QString) The command to execute ( excluding arguments ) when creating a new terminal
+         * session using this profile.
+         */
+        Command,   
+        /** (QStringList) The arguments which are passed to the program specified by
+         * the Command property when creating a new terminal session using this profile.
+         */ 
+        Arguments,
+        /** (QStringList) Additional environment variables ( in the form of NAME=VALUE pairs )
+         * which are passed to the program specified by the Command property
+         * when creating a new terminal session using this profile. 
+         */ 
+        Environment,
+        /** (QString) The initial working directory for sessions created using this profile. */ 
+        Directory,
+        /** (QString) The format used for tab titles when running normal commands. */
+        LocalTabTitleFormat,   
+        /** (QString) The format used for tab titles when the session is running 
+         * a remote command (eg. SSH) */ 
+        RemoteTabTitleFormat,   
+        /** (bool) Specifies whether the menu bar should be shown in the main application window. */
+        ShowMenuBar,    
+        SaveGeometryOnExit,
+        /** (TabBarModeEnum) Specifies when the tab bar should be shown in
+         * the main application window. */ 
+        TabBarMode,    
+        /** (QFont) The font to use in terminal displays using this profile. */
+        Font,           
+        /** (QString) 
+         * The name of the color scheme to use in terminal displays using this profile. 
+         * Color schemes are managed by the ColorSchemeManager class. 
+         */
+        ColorScheme,   
+        /** (QString) The name of the key bindings. 
+         * Key bindings are managed by the KeyboardTranslatorManager class. 
+         */
+        KeyBindings, 
+        /** (HistoryModeEnum) Specifies the storage type used for keeping the output produced
+         * by terminal sessions using this profile.
+         */
+        HistoryMode,
+        /** (int) Specifies the number of lines of output to remember in terminal sessions
+         * using this profile.  Once the limit is reached, the oldest lines are lost.
+         * Only applicable if the HistoryMode property is FixedSizeHistory
+         */
+        HistorySize,
+        /** (ScrollBarPositionEnum) Specifies the position of the scroll bar in 
+         * terminal displays using this profile.
+         */
+        ScrollBarPosition,  
+        /** (bool) Specifies whether the terminal will enable Bidirectional text display */
+        BidiRenderingEnabled,
+        /** (bool) Specifies whether text in terminal displays is allowed to blink. */
+        BlinkingTextEnabled,       
+        /** (bool) Specifies whether the flow control keys ( typically Ctrl+S , Ctrl+Q )
+         * have any effect.  Also known as Xon/Xoff
+         */ 
+        FlowControlEnabled,
+        /** (bool) Specifies whether programs running in the terminal are allowed to 
+         * resize the terminal display. 
+         */
+        AllowProgramsToResizeWindow,
+        /** (bool) Specifies whether the cursor blinks ( in a manner similar 
+         * to text editing applications )
+         */
+        BlinkingCursorEnabled,
+        /** (bool) If true, terminal displays use a fixed color to draw the cursor,
+         * specified by the CustomCursorColor property.  Otherwise the cursor changes
+         * color to match the character underneath it.
+         */
+        UseCustomCursorColor,
+        /** (CursorShapeEnum) The shape used by terminal displays to represent the cursor. */ 
+        CursorShape,           
+        /** (QColor) The color used by terminal displays to draw the cursor.  Only applicable
+         * if the UseCustomCursorColor property is true. */ 
+        CustomCursorColor,        
+        /** (QString) A string consisting of the characters used to delimit words when
+         * selecting text in the terminal display.
+         */
+        WordCharacters,
+        /** (TabBarPositionEnum) Position of the tab-bar relative to the terminal displays. */
+        TabBarPosition,
+        /** (bool) If true, the triple click selects from current word onwards. Otherwise
+         * selects whole line.
+         */
+        TripleClickMode,
+        /** (String) Default text codec */
+        DefaultEncoding,
+        /** (bool) Whether fonts should be aliased or not */
+        AntiAliasFonts,
+        /** (bool) Whether new sessions should be started in the same directory as the 
+         * currently active session. */
+        BoldIntense,
+        /** (bool) Whether character with intense colors should be rendered in bold font
+         * or just in bright color. */
+        StartInCurrentSessionDir,
+        /** (bool) Whether a 'New Tab' and 'Close Tab' buttons should be shown on the tab bar */
+        ShowNewAndCloseTabButtons,
+        /** Index of profile in the File Menu
+         * In future, format will be #.#.# to account for levels
+         */
+        MenuIndex
+    };
+
+    /** 
+     * This enum describes the available modes for showing or hiding the tab bar. 
+     */
+    enum TabBarModeEnum
+    {
+        /** The tab bar is never shown. */
+        AlwaysHideTabBar   = 0,
+        /** The tab bar is shown if there are multiple tabs open or hidden otherwise. */
+        ShowTabBarAsNeeded = 1,
+        /** The tab bar is always shown. */
+        AlwaysShowTabBar   = 2
+    };
+
+    /** 
+     * This enum describes the available tab bar positions. 
+     */
+    enum TabBarPositionEnum
+    {
+        /** Show tab bar below displays. */
+        TabBarBottom = 0,
+        /** Show tab bar above displays. */
+        TabBarTop    = 1
+    };
+
+    /** 
+     * This enum describes the modes available to remember lines of output produced 
+     * by the terminal. 
+     */
+    enum HistoryModeEnum
+    {
+        /** No output is remembered.  As soon as lines of text are scrolled off-screen they are lost. */
+        DisableHistory   = 0,
+        /** A fixed number of lines of output are remembered.  Once the limit is reached, the oldest
+         * lines are lost. */
+        FixedSizeHistory = 1,
+        /** All output is remembered for the duration of the session.  
+         * Typically this means that lines are recorded to
+         * a file as they are scrolled off-screen.
+         */
+        UnlimitedHistory = 2
+    };
+
+    /**
+     * This enum describes the positions where the terminal display's scroll bar may be placed.
+     */
+    enum ScrollBarPositionEnum
+    {
+        /** Show the scroll-bar on the left of the terminal display. */
+        ScrollBarLeft   = 0,
+        /** Show the scroll-bar on the right of the terminal display. */
+        ScrollBarRight  = 1,
+        /** Do not show the scroll-bar. */
+        ScrollBarHidden = 2
+    };
+
+    /** This enum describes the shapes used to draw the cursor in terminal displays. */
+    enum CursorShapeEnum
+    {
+        /** Use a solid rectangular block to draw the cursor. */
+        BlockCursor     = 0,
+        /** Use an 'I' shape, similar to that used in text editing applications, to draw the cursor. */
+        IBeamCursor     = 1,
+        /** Draw a line underneath the cursor's position. */
+        UnderlineCursor = 2
+    };
+
+    /**
+     * Constructs a new profile
+     *
+     * @param parent The parent profile.  When querying the value of a property
+     * using property(), if the property has not been set in this profile then
+     * the parent's value for the property will be returned instead.
+     */
+    explicit Profile(Ptr parent = Ptr());
+    virtual ~Profile(); 
+
+    /**
+     * Copies all properties except Name and Path from the specified @p profile
+     * into this profile
+     *
+     * @param profile The profile to copy properties from
+     * @param differentOnly If true, only properties in @p profile which have a
+     * different value from this profile's current value (either set via
+     * setProperty() or inherited from the parent profile) will be set.
+     */
+    void clone(Ptr profile, bool differentOnly = true);
+
+    /** 
+     * Changes the parent profile.  When calling the property() method,
+     * if the specified property has not been set for this profile,
+     * the parent's value for the property will be returned instead.
+     */
+    void setParent(Ptr parent);
+
+    /** Returns the parent profile. */
+    const Ptr parent() const;
+
+    /** Returns this profile as a group or null if this profile is not a group. */
+    const GroupPtr asGroup() const;
+    GroupPtr asGroup();
+
+    /** 
+     * Returns the current value of the specified @p property, cast to type T.
+     * Internally properties are stored using the QVariant type and cast to T
+     * using QVariant::value<T>();
+     *
+     * If the specified @p property has not been set in this profile,
+     * and a non-null parent was specified in the Profile's constructor,
+     * the parent's value for @p property will be returned.
+     */
+    template <class T>
+    T property(Property property) const;
+    
+    /** Sets the value of the specified @p property to @p value. */
+    virtual void setProperty(Property property,const QVariant& value);
+    /** Returns true if the specified property has been set in this Profile instance. */
+    virtual bool isPropertySet(Property property) const;
+
+    /** Returns a map of the properties set in this Profile instance. */
+    virtual QHash<Property,QVariant> setProperties() const;
+
+    /** Returns true if no properties have been set in this Profile instance. */
+    bool isEmpty() const;
+
+    /** 
+     * Returns true if this is a 'hidden' profile which should not be displayed
+     * in menus or saved to disk.
+     *
+     * This is used for the fallback profile, in case there are no profiles on 
+     * disk which can be loaded, or for overlay profiles created to handle
+     * command-line arguments which change profile properties.
+     */
+    bool isHidden() const;
+
+    /** Specifies whether this is a hidden profile.  See isHidden() */
+    void setHidden(bool hidden);
+
+    //
+    // Convenience methods for property() and setProperty() go here
+    //
+
+    /** Convenience method for property<QString>(Profile::Path) */
+    QString path() const { return property<QString>(Profile::Path); }
+
+    /** Convenience method for property<QString>(Profile::Name) */
+    QString name() const { return property<QString>(Profile::Name); }
+    
+    /** Convenience method for property<QString>(Profile::Directory) */
+    QString defaultWorkingDirectory() const 
+            { return property<QString>(Profile::Directory); }
+
+    /** Convenience method for property<QString>(Profile::Icon) */
+    QString icon() const { return property<QString>(Profile::Icon); }
+
+    /** Convenience method for property<QString>(Profile::Command) */
+    QString command() const { return property<QString>(Profile::Command); }
+
+    /** Convenience method for property<QStringList>(Profile::Arguments) */
+    QStringList arguments() const { return property<QStringList>(Profile::Arguments); }
+
+    /** Convenience method for property<QFont>(Profile::Font) */
+    QFont font() const { return property<QFont>(Profile::Font); }
+
+    /** Convenience method for property<QString>(Profile::ColorScheme) */
+    QString colorScheme() const { return property<QString>(Profile::ColorScheme); }
+
+    /** Convenience method for property<QStringList>(Profile::Environment) */
+    QStringList environment() const { return property<QStringList>(Profile::Environment); }
+
+    /** Convenience method for property<QString>(Profile::MenuIndex) */
+    QString menuIndex() const { return property<QString>(Profile::MenuIndex); }
+
+    int menuIndexAsInt() const;
+
+    /**
+     * Returns true if @p name has been associated with an element
+     * from the Property enum or false otherwise.
+     */
+    static bool isNameRegistered(const QString& name);
+
+    /** 
+     * Returns the element from the Property enum associated with the 
+     * specified @p name.
+     *
+     * @param name The name of the property to look for, this is case insensitive.
+     */
+    static Property lookupByName(const QString& name);
+    /**
+     * Returns the string names associated with the specified @p property from
+     * the Property enum, in the order the associations were created using
+     * registerName()
+     */
+    static QList<QString> namesForProperty(Property property);
+
+    /** 
+     * Returns the primary name for the specified @p property.
+     * TODO More documentation
+     */
+    static QString primaryNameForProperty(Property property);
+
+private:
+    struct PropertyInfo;
+    // Defines a new property, this property is then available
+    // to all Profile instances.
+    static void registerProperty(const PropertyInfo& info); 
+
+    // fills the table with default names for profile properties
+    // the first time it is called.
+    // subsequent calls return immediately
+    static void fillTableWithDefaultNames();
+
+    // returns true if the property can be inherited
+    static bool canInheritProperty(Property property);
+
+    QHash<Property,QVariant> _propertyValues;
+    Ptr _parent;
+
+    bool _hidden;
+
+    static QHash<QString,PropertyInfo> _propertyInfoByName;
+    static QHash<Property,PropertyInfo> _infoByProperty;
+    
+    // Describes a property.  Each property has a name and group
+    // which is used when saving/loading the profile.
+    struct PropertyInfo
+    {
+        Property property;
+        const char* name;
+        const char* group;
+        QVariant::Type type;
+    };
+    static const PropertyInfo DefaultPropertyNames[];
+};
+
+template <class T>
+inline T Profile::property(Property theProperty) const
+{
+    return property<QVariant>(theProperty).value<T>();
+}
+template <>
+inline QVariant Profile::property(Property property) const
+{
+    if ( _propertyValues.contains(property) ) {
+        return _propertyValues[property];
+    }
+    else if ( _parent && canInheritProperty(property) ) {
+        return _parent->property<QVariant>(property);
+    }
+    else {
+        return QVariant();
+    }
+}
+inline bool Profile::canInheritProperty(Property property) 
+{ return property != Name && property != Path; }
+
+
+/** 
+ * A profile which contains a number of default settings for various properties.
+ * This can be used as a parent for other profiles or a fallback in case
+ * a profile cannot be loaded from disk.
+ */
+class KONSOLEPRIVATE_EXPORT FallbackProfile : public Profile
+{
+public:
+    FallbackProfile();
+};
+
+/** 
+ * A composite profile which allows a group of profiles to be treated as one.
+ * When setting a property, the new value is applied to all profiles in the group.
+ * When reading a property, if all profiles in the group have the same value
+ * then that value is returned, otherwise the result is null.
+ *
+ * Profiles can be added to the group using addProfile().  When all profiles
+ * have been added updateValues() must be called
+ * to sync the group's property values with those of the group's profiles.
+ *
+ * The Profile::Name and Profile::Path properties are unique to individual profiles,
+ * setting these properties on a ProfileGroup has no effect.
+ */
+class KONSOLEPRIVATE_EXPORT ProfileGroup : public Profile
+{
+public:
+    typedef KSharedPtr<ProfileGroup> Ptr;
+
+    /** Construct a new profile group, which is hidden by default. */
+    ProfileGroup(Profile::Ptr parent = Profile::Ptr());
+
+    /** Add a profile to the group.  Calling setProperty() will update this profile.
+     * When creating a group, add the profiles to the group then call updateValues() to 
+     * make the group's property values reflect the profiles currently in the group. */
+    void addProfile(Profile::Ptr profile)
+    { _profiles.append(profile); }
+
+    /** Remove a profile from the group.  Calling setProperty() will no longer
+     * affect this profile. */
+    void removeProfile(Profile::Ptr profile)
+    { _profiles.removeAll(profile); }
+
+    /** Returns the profiles in this group .*/
+    QList<Profile::Ptr> profiles() const
+    { return _profiles; }
+
+    /** 
+     * Updates the property values in this ProfileGroup to match those from 
+     * the group's profiles() 
+     *
+     * For each available property, if each profile in the group has the same value then
+     * the ProfileGroup will use that value for the property.  Otherwise the value for the property
+     * will be set to a null QVariant
+     *
+     * Some properties such as the name and the path of the profile
+     * will always be set to null if the group has more than one profile.
+     */
+    void updateValues();
+
+    /** Sets the value of @p property in each of the group's profiles to @p value. */
+    void setProperty(Property property, const QVariant& value);
+
+private:
+    QList<Profile::Ptr> _profiles;
+};
+inline ProfileGroup::ProfileGroup(Profile::Ptr parent)
+: Profile(parent)
+{
+    setHidden(true);
+}
+inline const Profile::GroupPtr Profile::asGroup() const
+{
+    const Profile::GroupPtr ptr(dynamic_cast<ProfileGroup*>(
+                                const_cast<Profile*>(this)));
+    return ptr;
+}
+inline Profile::GroupPtr Profile::asGroup()
+{
+    return Profile::GroupPtr(dynamic_cast<ProfileGroup*>(this));
+}
+
+/** Interface for all classes which can load profile settings from a file. */
+class ProfileReader
+{
+public:
+    virtual ~ProfileReader() {}
+    /** Returns a list of paths to profiles which this reader can read. */
+    virtual QStringList findProfiles() { return QStringList(); }
+    /** 
+     * Attempts to read a profile from @p path and 
+     * save the property values described into @p profile.
+     *
+     * Returns true if the profile was successfully read or false otherwise.
+     *
+     * @param path Path to the profile to read
+     * @param profile Pointer to the Profile the settings will be read into
+     * @param parentProfile Receives the name of the parent profile specified in
+     */
+    virtual bool readProfile(const QString& path , Profile::Ptr profile , QString& parentProfile) = 0;
+};
+/** Reads a KDE 3 profile .desktop file. */
+class KDE3ProfileReader : public ProfileReader
+{
+public:
+    virtual QStringList findProfiles();
+    virtual bool readProfile(const QString& path , Profile::Ptr profile, QString& parentProfile);
+};
+/** Reads a KDE 4 .profile file. */
+class KDE4ProfileReader : public ProfileReader
+{
+public:
+    virtual QStringList findProfiles();
+    virtual bool readProfile(const QString& path , Profile::Ptr profile, QString& parentProfile);
+private:
+    void readProperties(const KConfig& config, Profile::Ptr profile, 
+                        const Profile::PropertyInfo* properties);
+};
+/** Interface for all classes which can write profile settings to a file. */
+class ProfileWriter
+{
+public:
+    virtual ~ProfileWriter() {}
+    /** 
+     * Returns a suitable path-name for writing 
+     * @p profile to. The path-name should be accepted by
+     * the corresponding ProfileReader class.
+     */
+    virtual QString getPath(const Profile::Ptr profile) = 0;
+    /**
+     * Writes the properties and values from @p profile to the file specified by
+     * @p path.  This profile should be readable by the corresponding ProfileReader class.
+     */
+    virtual bool writeProfile(const QString& path , const Profile::Ptr profile) = 0;
+};
+/** Writes a KDE 4 .profile file. */
+class KDE4ProfileWriter : public ProfileWriter
+{
+public:
+    virtual QString getPath(const Profile::Ptr profile);
+    virtual bool writeProfile(const QString& path , const Profile::Ptr profile);
+
+private:
+    void writeProperties(KConfig& config, const Profile::Ptr profile, 
+                         const Profile::PropertyInfo* properties);
+};
+
+/** 
+ * Parses an input string consisting of property names
+ * and assigned values and returns a table of properties
+ * and values.
+ *
+ * The input string will typically look like this:
+ *
+ * @code
+ *   PropertyName=Value;PropertyName=Value ...
+ * @endcode 
+ *
+ * For example:
+ *
+ * @code
+ *   Icon=konsole;Directory=/home/bob
+ * @endcode
+ */
+class KONSOLEPRIVATE_EXPORT ProfileCommandParser
+{
+public:
+    /**
+     * Parses an input string consisting of property names
+     * and assigned values and returns a table of 
+     * properties and values.
+     */
+    QHash<Profile::Property,QVariant> parse(const QString& input);
+
+};
+
+}
+Q_DECLARE_METATYPE(Konsole::Profile::Ptr)
+
+#endif // PROFILE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ProfileList.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,185 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ProfileList.h"
+
+// Qt
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <KDebug>
+
+// KDE
+#include <KIcon>
+#include <KLocalizedString>
+
+// Konsole
+#include "SessionManager.h"
+
+using namespace Konsole;
+
+ProfileList::ProfileList(bool addShortcuts , QObject* parent)
+    : QObject(parent)
+    , _addShortcuts(addShortcuts)
+    , _emptyListAction(0)
+{
+    SessionManager* manager = SessionManager::instance();
+
+    // construct the list of favorite session types
+    _group = new QActionGroup(this);
+ 
+    // Even when there are no profiles in the menu list, allow user to 
+    // create new tabs from the menu
+    _emptyListAction = new QAction(i18n("Default profile"),_group);
+
+    // TODO - Handle re-sorts when user changes profile names
+
+    QList<Profile::Ptr> list = manager->sortedFavorites();
+
+    QListIterator<Profile::Ptr> iter(list);
+
+    while (iter.hasNext())
+    {
+        favoriteChanged(iter.next(),true);        
+    }
+
+    connect( _group , SIGNAL(triggered(QAction*)) , this , SLOT(triggered(QAction*)) );
+
+
+    // listen for future changes to the session list
+    connect( manager , SIGNAL(favoriteStatusChanged(Profile::Ptr,bool)) , this ,
+             SLOT(favoriteChanged(Profile::Ptr,bool)) );
+    connect( manager , SIGNAL(shortcutChanged(Profile::Ptr,QKeySequence)) , this , 
+             SLOT(shortcutChanged(Profile::Ptr,QKeySequence)) );
+    connect( manager , SIGNAL(profileChanged(Profile::Ptr)) , this , 
+             SLOT(profileChanged(Profile::Ptr)) );
+}
+void ProfileList::updateEmptyAction() 
+{
+    Q_ASSERT( _group );
+    Q_ASSERT( _emptyListAction );
+
+    // show empty list action when it is the only action
+    // in the group
+    const bool showEmptyAction = _group->actions().count() == 1;
+
+    if ( showEmptyAction != _emptyListAction->isVisible() )
+        _emptyListAction->setVisible(showEmptyAction);
+}
+QAction* ProfileList::actionForKey(Profile::Ptr key) const
+{        
+    QListIterator<QAction*> iter(_group->actions());
+    while ( iter.hasNext() )
+    {
+        QAction* next = iter.next();
+        if ( next->data().value<Profile::Ptr>() == key )
+            return next;
+    }
+    return 0; // not found
+}
+
+void ProfileList::profileChanged(Profile::Ptr key)
+{
+    QAction* action = actionForKey(key);
+    if ( action )
+        updateAction(action,key);
+}
+
+void ProfileList::updateAction(QAction* action , Profile::Ptr info)
+{
+    Q_ASSERT(action);
+    Q_ASSERT(info);
+
+    action->setText(info->name());
+    action->setIcon(KIcon(info->icon()));
+}
+void ProfileList::shortcutChanged(Profile::Ptr info,const QKeySequence& sequence)
+{
+    if ( !_addShortcuts )
+        return;
+
+    QAction* action = actionForKey(info);
+
+    if ( action )
+    {
+        action->setShortcut(sequence);
+    }
+}
+void ProfileList::syncWidgetActions(QWidget* widget, bool sync)
+{
+    if (!sync)
+    {
+        _registeredWidgets.remove(widget);
+        return;
+    }
+
+    _registeredWidgets.insert(widget);
+
+    const QList<QAction*> currentActions = widget->actions();
+    foreach(QAction* currentAction, currentActions)
+        widget->removeAction(currentAction);
+
+    widget->addActions(_group->actions());
+}
+void ProfileList::favoriteChanged(Profile::Ptr info,bool isFavorite)
+{
+    SessionManager* manager = SessionManager::instance();
+
+    if ( isFavorite )
+    {
+        QAction* action = new QAction(_group);
+        action->setData( QVariant::fromValue(info) );
+        
+        if ( _addShortcuts )
+        {
+            action->setShortcut(manager->shortcut(info));
+        }
+
+        updateAction(action,info);
+        
+        foreach(QWidget* widget,_registeredWidgets)
+            widget->addAction(action);
+        emit actionsChanged(_group->actions());
+    }
+    else
+    {
+        QAction* action = actionForKey(info);
+
+        if ( action )
+        {
+            _group->removeAction(action);
+            foreach(QWidget* widget,_registeredWidgets)
+                widget->removeAction(action);
+            emit actionsChanged(_group->actions());
+        }
+    }
+
+    updateEmptyAction();
+}
+void ProfileList::triggered(QAction* action)
+{
+    emit profileSelected( action->data().value<Profile::Ptr>() );
+}
+
+QList<QAction*> ProfileList::actions()
+{
+    return _group->actions();
+}
+
+#include "ProfileList.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ProfileList.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,108 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef PROFILELIST_H
+#define PROFILELIST_H
+
+#include <QtCore/QList>
+#include <QtCore/QSet>
+#include <QtCore/QObject>
+
+#include "Profile.h"
+#include "konsole_export.h"
+
+class QAction;
+class QActionGroup;
+class QKeySequence;
+
+namespace Konsole
+{
+
+class Profile;
+
+/** 
+ * ProfileList provides a list of actions which represent session profiles 
+ * that a SessionManager can create a session from.  
+ *
+ * These actions can be plugged into a GUI.
+ *
+ * Currently only profiles marked as favorites in the SessionManager are included. 
+ *
+ * The user-data associated with each session can be passed to the createProfile() method of the 
+ * SessionManager to create a new terminal session. 
+ */
+class KONSOLEPRIVATE_EXPORT ProfileList : public QObject
+{
+Q_OBJECT
+
+public:
+    /** 
+     * Constructs a new session list which displays sessions 
+     * that can be created by @p manager 
+     *
+     * @param addShortcuts True if the shortcuts associated with profiles
+     * in the session manager should be added to the actions
+     * @param parent The parent GUI object
+     */
+    ProfileList(bool addShortcuts , QObject* parent);
+
+    /** 
+     * Returns a list of actions representing the types of sessions which can be created by
+     * manager().  
+     * The user-data associated with each action is the string key that can be passed to
+     * the manager to request creation of a new session. 
+     */
+    QList<QAction*> actions();
+
+    /** TODO: Document me */ 
+    void syncWidgetActions(QWidget* widget,bool sync);
+signals:
+   /** 
+    * Emitted when the user selects an action from the list.
+    * 
+    * @param profile The profile to select
+    */
+   void profileSelected(Profile::Ptr profile);
+   /**
+    * Emitted when the list of actions changes.
+    */
+   void actionsChanged(const QList<QAction*>& actions);
+
+private slots:
+    void triggered(QAction* action);
+    void favoriteChanged(Profile::Ptr profile, bool isFavorite);
+    void profileChanged(Profile::Ptr profile);
+    void shortcutChanged(Profile::Ptr profile, const QKeySequence& sequence);
+
+private:
+    QAction* actionForKey(Profile::Ptr profile) const;
+    void updateAction(QAction* action , Profile::Ptr profile);
+    void updateEmptyAction();
+
+    QActionGroup*   _group;
+    bool _addShortcuts;
+    
+    // action to show when the list is empty
+    QAction* _emptyListAction;
+    QSet<QWidget*> _registeredWidgets;
+}; 
+
+}
+
+#endif // PROFILELIST_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ProfileListWidget.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,96 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ProfileListWidget.h"
+
+// Qt
+#include <KDebug>
+#include <QtGui/QDrag>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QMimeData>
+
+static const char konsoleSessionMimeFormat[] = "konsole/session";
+
+ProfileListWidget::ProfileListWidget(QWidget* parent)
+    : QListWidget(parent)
+{
+    // use large icons so that there is a big area for the user to click
+    // on to switch between sessions
+    setIconSize( QSize(32,32) );
+
+    // turn the frame off
+    setFrameStyle( QFrame::NoFrame );
+
+    QPalette p = palette();
+    p.setBrush( QPalette::Base , QColor(220,220,220) );
+    setPalette(p);
+}
+
+void ProfileListWidget::startDrag(Qt::DropActions /*supportedActions*/)
+{
+    //kDebug() << "drag and drop started in session list widget";
+
+    QMimeData* mimeData = new QMimeData();
+
+    QByteArray data;
+    data.setNum(42);
+    mimeData->setData(konsoleSessionMimeFormat,data);
+
+    QDrag* drag = new QDrag(this);
+    drag->setMimeData(mimeData);
+
+    Qt::DropAction action = drag->start( Qt::MoveAction );
+
+    if ( action & Qt::MoveAction )
+    {
+        emit takeSessionEvent(currentRow());
+    }
+}
+
+void ProfileListWidget::dragEnterEvent(QDragEnterEvent* event)
+{
+    if ( event->mimeData()->hasFormat(konsoleSessionMimeFormat) )
+    {
+        event->accept();
+    }
+}
+
+void ProfileListWidget::dragMoveEvent(QDragMoveEvent* event)
+{
+    if ( event->mimeData()->hasFormat(konsoleSessionMimeFormat) )
+    {
+        event->setDropAction(Qt::MoveAction);
+        event->accept();
+    }
+}
+
+void ProfileListWidget::dropEvent(QDropEvent* event)
+{
+    if ( event->mimeData()->hasFormat(konsoleSessionMimeFormat) )
+    {
+        event->setDropAction(Qt::MoveAction);
+        event->accept();
+
+        emit dropSessionEvent( event->mimeData()->data(konsoleSessionMimeFormat).toInt() ); 
+    }
+}
+
+
+#include "ProfileListWidget.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ProfileListWidget.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,57 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef PROFILELISTWIDGET_H
+#define PROFILELISTWIDGET_H
+
+// Qt
+#include <QtGui/QListWidget>
+
+class ProfileListWidget : public QListWidget
+{
+Q_OBJECT
+
+public:
+    ProfileListWidget(QWidget* parent);
+
+signals:
+    void takeSessionEvent(int itemIndex);
+    void dropSessionEvent(int id); 
+
+protected:
+    virtual void startDrag(Qt::DropActions supportedActions);
+    virtual void dropEvent(QDropEvent* event);
+    virtual void dragEnterEvent(QDragEnterEvent* event);
+    virtual void dragMoveEvent(QDragMoveEvent* event);
+
+};
+
+/*class SessionListDelegate : public QAbstractItemDelegate
+{
+Q_OBJECT
+
+public:
+    virtual void paint(QPainter* painter , const QStyleOptionViewItem& option,
+                       const QModelIndex& index) const;
+
+    virtual QSize sizeHint( const QStyleOptionViewItem& option,
+                            const QModelIndex& index) const;
+};*/
+
+#endif // PROFILELISTWIDGET_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Pty.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,320 @@
+/*
+    This file is part of Konsole, an X terminal.
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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 "Pty.h"
+
+// System
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <termios.h>
+#include <signal.h>
+
+// Qt
+#include <QtCore/QStringList>
+
+// KDE
+//#include <KStandardDirs>
+//#include <KLocale>
+//#include <KDebug>
+//#include <KPty>
+//#include <KPtyDevice>
+//#include <kde_file.h>
+
+#include "kpty.h"
+#include "kptydevice.h"
+
+using namespace Konsole;
+
+void Pty::setWindowSize(int lines, int cols)
+{
+  _windowColumns = cols;
+  _windowLines = lines;
+
+  if (pty()->masterFd() >= 0)
+    pty()->setWinSize(lines, cols);
+}
+QSize Pty::windowSize() const
+{
+    return QSize(_windowColumns,_windowLines);
+}
+
+void Pty::setFlowControlEnabled(bool enable)
+{
+  _xonXoff = enable;
+
+  if (pty()->masterFd() >= 0)
+  {
+    struct ::termios ttmode;
+    pty()->tcGetAttr(&ttmode);
+    if (!enable)
+      ttmode.c_iflag &= ~(IXOFF | IXON);
+    else
+      ttmode.c_iflag |= (IXOFF | IXON);
+    if (!pty()->tcSetAttr(&ttmode))
+      kWarning() << "Unable to set terminal attributes.";
+  }
+}
+bool Pty::flowControlEnabled() const
+{
+    if (pty()->masterFd() >= 0)
+    {
+        struct ::termios ttmode;
+        pty()->tcGetAttr(&ttmode);
+        return ttmode.c_iflag & IXOFF &&
+               ttmode.c_iflag & IXON;
+    }  
+    kWarning() << "Unable to get flow control status, terminal not connected.";
+    return false;
+}
+
+void Pty::setUtf8Mode(bool enable)
+{
+#ifdef IUTF8 // XXX not a reasonable place to check it.
+  _utf8 = enable;
+
+  if (pty()->masterFd() >= 0)
+  {
+    struct ::termios ttmode;
+    pty()->tcGetAttr(&ttmode);
+    if (!enable)
+      ttmode.c_iflag &= ~IUTF8;
+    else
+      ttmode.c_iflag |= IUTF8;
+    if (!pty()->tcSetAttr(&ttmode))
+      kWarning() << "Unable to set terminal attributes.";
+  }
+#endif
+}
+
+void Pty::setErase(char erase)
+{
+  _eraseChar = erase;
+  
+  if (pty()->masterFd() >= 0)
+  {
+    struct ::termios ttmode;
+    pty()->tcGetAttr(&ttmode);
+    ttmode.c_cc[VERASE] = erase;
+    if (!pty()->tcSetAttr(&ttmode))
+      kWarning() << "Unable to set terminal attributes.";
+  }
+}
+
+char Pty::erase() const
+{
+    if (pty()->masterFd() >= 0)
+    {
+        struct ::termios ttyAttributes;
+        pty()->tcGetAttr(&ttyAttributes);
+        return ttyAttributes.c_cc[VERASE];
+    }
+
+    return _eraseChar;
+}
+
+void Pty::addEnvironmentVariables(const QStringList& environment)
+{
+    QListIterator<QString> iter(environment);
+    while (iter.hasNext())
+    {
+        QString pair = iter.next();
+
+        // split on the first '=' character
+        int pos = pair.indexOf('=');
+        
+        if ( pos >= 0 )
+        {
+            QString variable = pair.left(pos);
+            QString value = pair.mid(pos+1);
+
+            setEnv(variable,value);
+        }
+    }
+}
+
+int Pty::start(const QString& program, 
+               const QStringList& programArguments, 
+               const QStringList& environment, 
+               ulong winid, 
+               bool addToUtmp,
+               const QString& dbusService, 
+               const QString& dbusSession)
+{
+  clearProgram();
+
+  // For historical reasons, the first argument in programArguments is the 
+  // name of the program to execute, so create a list consisting of all
+  // but the first argument to pass to setProgram()
+  Q_ASSERT(programArguments.count() >= 1);
+  setProgram(program.toLatin1(),programArguments.mid(1));
+
+  addEnvironmentVariables(environment);
+
+  if ( !dbusService.isEmpty() )
+     setEnv("KONSOLE_DBUS_SERVICE",dbusService);
+  if ( !dbusSession.isEmpty() )
+     setEnv("KONSOLE_DBUS_SESSION", dbusSession);
+
+  setEnv("WINDOWID", QString::number(winid));
+
+  // unless the LANGUAGE environment variable has been set explicitly
+  // set it to a null string
+  // this fixes the problem where KCatalog sets the LANGUAGE environment
+  // variable during the application's startup to something which
+  // differs from LANG,LC_* etc. and causes programs run from
+  // the terminal to display messages in the wrong language
+  //
+  // this can happen if LANG contains a language which KDE
+  // does not have a translation for
+  //
+  // BR:149300
+  setEnv("LANGUAGE",QString(),false /* do not overwrite existing value if any */);
+
+  setUseUtmp(addToUtmp);
+
+  struct ::termios ttmode;
+  pty()->tcGetAttr(&ttmode);
+  if (!_xonXoff)
+    ttmode.c_iflag &= ~(IXOFF | IXON);
+  else
+    ttmode.c_iflag |= (IXOFF | IXON);
+#ifdef IUTF8 // XXX not a reasonable place to check it.
+  if (!_utf8)
+    ttmode.c_iflag &= ~IUTF8;
+  else
+    ttmode.c_iflag |= IUTF8;
+#endif
+
+  if (_eraseChar != 0)
+      ttmode.c_cc[VERASE] = _eraseChar;
+  
+  if (!pty()->tcSetAttr(&ttmode))
+    kWarning() << "Unable to set terminal attributes.";
+  
+  pty()->setWinSize(_windowLines, _windowColumns);
+
+  //KProcess::start();
+
+  if (!waitForStarted())
+      return -1;
+
+  return 0;
+}
+
+void Pty::setWriteable(bool writeable)
+{
+  //KDE_struct_stat sbuf;
+  struct stat sbuf;
+  //KDE_stat(pty()->ttyName(), &sbuf);
+  ::stat(pty()->ttyName(), &sbuf);
+  if (writeable)
+    chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP);
+  else
+    chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP|S_IWOTH));
+}
+
+Pty::Pty(int masterFd, QObject* parent)
+    : KPtyProcess(masterFd,parent)
+{
+    init();
+}
+Pty::Pty(QObject* parent)
+    : KPtyProcess(parent)
+{
+    init();
+}
+void Pty::init()
+{
+  _windowColumns = 0;
+  _windowLines = 0;
+  _eraseChar = 0;
+  _xonXoff = true;
+  _utf8 =true;
+
+  connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived()));
+  setPtyChannels(KPtyProcess::AllChannels);
+}
+
+Pty::~Pty()
+{
+}
+
+void Pty::sendData(const char* data, int length)
+{
+  if (!length)
+      return;
+  
+  if (!pty()->write(data,length)) 
+  {
+    kWarning() << "Pty::doSendJobs - Could not send input data to terminal process.";
+    return;
+  }
+}
+
+void Pty::dataReceived() 
+{
+     QByteArray data = pty()->readAll();
+    emit receivedData(data.constData(),data.count());
+}
+
+void Pty::lockPty(bool lock)
+{
+    Q_UNUSED(lock);
+
+// TODO: Support for locking the Pty
+  //if (lock)
+    //suspend();
+  //else
+    //resume();
+}
+
+int Pty::foregroundProcessGroup() const
+{
+    int pid = tcgetpgrp(pty()->masterFd());
+
+    if ( pid != -1 )
+    {
+        return pid;
+    } 
+
+    return 0;
+}
+
+void Pty::setupChildProcess()
+{
+    KPtyProcess::setupChildProcess();
+    
+    // reset all signal handlers
+    // this ensures that terminal applications respond to 
+    // signals generated via key sequences such as Ctrl+C
+    // (which sends SIGINT)
+    struct sigaction action;
+    sigemptyset(&action.sa_mask);
+    action.sa_handler = SIG_DFL;
+    action.sa_flags = 0;
+    for (int signal=1;signal < NSIG; signal++)
+        sigaction(signal,&action,0L);
+}
+
+
+#include "Pty.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Pty.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,209 @@
+/*
+    This file is part of Konsole, KDE's terminal emulator. 
+    
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef PTY_H
+#define PTY_H
+
+// Qt
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+#include <QtCore/QList>
+#include <QtCore/QSize>
+
+// KDE
+//#include <KPtyProcess>
+#include "kptyprocess.h"
+
+// Konsole
+#include "konsole_export.h"
+
+namespace Konsole
+{
+
+/**
+ * The Pty class is used to start the terminal process, 
+ * send data to it, receive data from it and manipulate 
+ * various properties of the pseudo-teletype interface
+ * used to communicate with the process.
+ *
+ * To use this class, construct an instance and connect
+ * to the sendData slot and receivedData signal to
+ * send data to or receive data from the process.
+ *
+ * To start the terminal process, call the start() method
+ * with the program name and appropriate arguments. 
+ */
+//class KONSOLEPRIVATE_EXPORT Pty: public KPtyProcess
+class KONSOLEPRIVATE_EXPORT Pty: public KPtyProcess
+{
+Q_OBJECT
+
+  public:
+    
+    /** 
+     * Constructs a new Pty.
+     * 
+     * Connect to the sendData() slot and receivedData() signal to prepare
+     * for sending and receiving data from the terminal process.
+     *
+     * To start the terminal process, call the run() method with the 
+     * name of the program to start and appropriate arguments.
+     */
+    explicit Pty(QObject* parent = 0);
+
+    /** 
+     * Construct a process using an open pty master.
+     * See KPtyProcess::KPtyProcess()
+     */
+    explicit Pty(int ptyMasterFd, QObject* parent = 0);
+
+    ~Pty();
+
+    /**
+     * Starts the terminal process.  
+     *
+     * Returns 0 if the process was started successfully or non-zero
+     * otherwise.
+     *
+     * @param program Path to the program to start
+     * @param arguments Arguments to pass to the program being started
+     * @param environment A list of key=value pairs which will be added
+     * to the environment for the new process.  At the very least this
+     * should include an assignment for the TERM environment variable.
+     * @param winid Specifies the value of the WINDOWID environment variable
+     * in the process's environment.
+     * @param addToUtmp Specifies whether a utmp entry should be created for
+     * the pty used.  See K3Process::setUsePty() 
+     * @param dbusService Specifies the value of the KONSOLE_DBUS_SERVICE 
+     * environment variable in the process's environment.
+     * @param dbusSession Specifies the value of the KONSOLE_DBUS_SESSION
+     * environment variable in the process's environment. 
+     */
+    int start( const QString& program, 
+               const QStringList& arguments, 
+               const QStringList& environment, 
+               ulong winid, 
+               bool addToUtmp,
+               const QString& dbusService,
+               const QString& dbusSession
+             );
+
+    /** TODO: Document me */
+    void setWriteable(bool writeable);
+
+    /** 
+     * Enables or disables Xon/Xoff flow control.  The flow control setting
+     * may be changed later by a terminal application, so flowControlEnabled()
+     * may not equal the value of @p on in the previous call to setFlowControlEnabled()
+     */
+    void setFlowControlEnabled(bool on);
+
+    /** Queries the terminal state and returns true if Xon/Xoff flow control is enabled. */
+    bool flowControlEnabled() const;
+
+    /** 
+     * Sets the size of the window (in lines and columns of characters) 
+     * used by this teletype.
+     */
+    void setWindowSize(int lines, int cols);
+    
+    /** Returns the size of the window used by this teletype.  See setWindowSize() */
+    QSize windowSize() const;
+
+    /** TODO Document me */
+    void setErase(char erase);
+
+    /** */
+    char erase() const;
+
+    /**
+     * Returns the process id of the teletype's current foreground
+     * process.  This is the process which is currently reading
+     * input sent to the terminal via. sendData()
+     *
+     * If there is a problem reading the foreground process group,
+     * 0 will be returned.
+     */
+    int foregroundProcessGroup() const;
+   
+  public slots:
+
+    /**
+     * Put the pty into UTF-8 mode on systems which support it.
+     */
+    void setUtf8Mode(bool on);
+
+    /**
+     * Suspend or resume processing of data from the standard 
+     * output of the terminal process.
+     *
+     * See K3Process::suspend() and K3Process::resume()
+     *
+     * @param lock If true, processing of output is suspended,
+     * otherwise processing is resumed.
+     */
+    void lockPty(bool lock);
+    
+    /** 
+     * Sends data to the process currently controlling the 
+     * teletype ( whose id is returned by foregroundProcessGroup() )
+     *
+     * @param buffer Pointer to the data to send.
+     * @param length Length of @p buffer.
+     */
+    void sendData(const char* buffer, int length);
+
+  signals:
+
+    /**
+     * Emitted when a new block of data is received from
+     * the teletype.
+     *
+     * @param buffer Pointer to the data received.
+     * @param length Length of @p buffer
+     */
+    void receivedData(const char* buffer, int length);
+   
+  protected:
+      void setupChildProcess();
+
+  private slots:
+    // called when data is received from the terminal process 
+    void dataReceived(); 
+    
+  private:
+      void init();
+
+    // takes a list of key=value pairs and adds them
+    // to the environment for the process
+    void addEnvironmentVariables(const QStringList& environment);
+
+    int  _windowColumns; 
+    int  _windowLines;
+    char _eraseChar;
+    bool _xonXoff;
+    bool _utf8;
+};
+
+}
+
+#endif // PTY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/RemoteConnectionDialog.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,87 @@
+/*
+    Copyright 2007 by Robert Knight <robertknight@gmail.com>
+
+    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 "RemoteConnectionDialog.h"
+
+// Qt
+#include <KDebug>
+
+// KDE
+#include <KLocale>
+
+// Konsole
+#include "SessionManager.h"
+
+#include "ui_RemoteConnectionDialog.h"
+
+using namespace Konsole;
+
+RemoteConnectionDialog::RemoteConnectionDialog(QWidget* parent)
+    : KDialog(parent)
+{
+    setCaption(i18n("New Remote Connection"));
+    setButtons( KDialog::Ok | KDialog::Cancel );
+    setButtonText( KDialog::Ok , i18n("Connect") );
+
+    _ui = new Ui::RemoteConnectionDialog();
+    _ui->setupUi(mainWidget());
+
+    // set initial UI state
+    _ui->userEdit->setFocus(Qt::OtherFocusReason);
+
+    _ui->userEdit->setClearButtonShown(true);
+    _ui->hostEdit->setClearButtonShown(true);
+}
+RemoteConnectionDialog::~RemoteConnectionDialog()
+{
+    delete _ui;
+}
+QString RemoteConnectionDialog::user() const
+{
+    return _ui->userEdit->text();
+}
+QString RemoteConnectionDialog::host() const
+{
+    return _ui->hostEdit->text();
+}
+QString RemoteConnectionDialog::service() const
+{
+    return "ssh";
+}
+
+QString RemoteConnectionDialog::sessionKey() const
+{
+ //   SessionManager* manager = SessionManager::instance();
+
+    /*MutableSessionInfo* customSession = 
+        new MutableSessionInfo(manager->defaultSessionType()->path());
+    customSession->setCommand( service() );
+    customSession->setName( i18n("%1 at %2",user(),host()) );
+    customSession->setArguments( QStringList() << customSession->command(true,true) << 
+            user() + '@' + host() );
+*/
+   //QString key = manager->addSessionType( customSession ); 
+
+    //kDebug() << "session key = " << key;
+
+    return QString();
+    //return key;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/RemoteConnectionDialog.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,52 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef REMOTECONNECTIONDIALOG_H
+#define REMOTECONNECTIONDIALOG_H
+
+// KDE
+#include <KDialog>
+
+namespace Ui
+{
+    class RemoteConnectionDialog;
+}
+
+namespace Konsole
+{
+
+class RemoteConnectionDialog : public KDialog
+{
+public:
+    RemoteConnectionDialog(QWidget* parent = 0 );
+    ~RemoteConnectionDialog();
+
+    QString user() const;
+    QString host() const;
+    QString service() const;
+
+    QString sessionKey() const;
+
+private:
+    Ui::RemoteConnectionDialog* _ui;
+};
+
+}
+
+#endif // REMOTECONNECTIONDIALOG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/RenameTabsDialog.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,98 @@
+/*
+    Copyright 2010 by Kurt Hindenburg <kurt.hindenburg@gmail.com>
+
+    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 "RenameTabsDialog.h"
+
+// Konsole
+#include "ui_RenameTabsDialog.h"
+
+using namespace Konsole;
+
+RenameTabsDialog::RenameTabsDialog(QWidget* parent)
+: KDialog(parent)
+{
+    setCaption(i18n("Rename Tab"));
+    setButtons( KDialog::Ok | KDialog::Cancel );
+
+    _ui = new Ui::RenameTabsDialog();
+    _ui->setupUi(mainWidget());
+    _ui->tabTitleEdit->setClearButtonShown(true);
+    _ui->remoteTabTitleEdit->setClearButtonShown(true);
+
+    // menus for local and remote tab title dynamic elements
+    TabTitleFormatAction* localTabTitleAction = new TabTitleFormatAction(this);
+    localTabTitleAction->setContext(Session::LocalTabTitle);
+    _ui->tabTitleEditButton->setMenu(localTabTitleAction->menu());
+    connect(localTabTitleAction, SIGNAL(dynamicElementSelected(const QString&)),
+             this, SLOT(insertTabTitleText(const QString&)));
+
+    TabTitleFormatAction* remoteTabTitleAction = new TabTitleFormatAction(this);
+    remoteTabTitleAction->setContext(Session::RemoteTabTitle);
+    _ui->remoteTabTitleEditButton->setMenu(remoteTabTitleAction->menu());
+    connect(remoteTabTitleAction, SIGNAL(dynamicElementSelected(const QString&)),
+             this, SLOT(insertRemoteTabTitleText(const QString&)));
+
+}
+
+RenameTabsDialog::~RenameTabsDialog()
+{
+    delete _ui;
+}
+
+void RenameTabsDialog::focusTabTitleText()
+{
+    _ui->tabTitleEdit->setFocus();
+}
+
+void RenameTabsDialog::focusRemoteTabTitleText()
+{
+    _ui->remoteTabTitleEdit->setFocus();
+}
+
+void RenameTabsDialog::setTabTitleText(const QString& text)
+{
+    _ui->tabTitleEdit->setText(text);
+}
+
+void RenameTabsDialog::setRemoteTabTitleText(const QString& text)
+{
+    _ui->remoteTabTitleEdit->setText(text);
+}
+
+QString RenameTabsDialog::tabTitleText() const
+{
+    return(_ui->tabTitleEdit->text());
+}
+
+QString RenameTabsDialog::remoteTabTitleText() const
+{
+    return(_ui->remoteTabTitleEdit->text());
+}
+
+void RenameTabsDialog::insertTabTitleText(const QString& text)
+{
+    _ui->tabTitleEdit->insert(text);
+}
+
+void RenameTabsDialog::insertRemoteTabTitleText(const QString& text)
+{
+    _ui->remoteTabTitleEdit->insert(text);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/RenameTabsDialog.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,65 @@
+/*
+    Copyright 2010 by Kurt Hindenburg <kurt.hindenburg@gmail.com>
+
+    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.
+*/
+
+#ifndef RENAMETABSDIALOG
+#define RENAMETABSDIALOG
+
+// Qt
+#include <QPointer>
+
+// KDE
+#include <KDialog>
+
+#include "Profile.h"
+#include "TabTitleFormatAction.h"
+
+namespace Ui
+{
+    class RenameTabsDialog;
+}
+
+namespace Konsole
+{
+
+class RenameTabsDialog : public KDialog
+{
+Q_OBJECT
+
+public:
+    RenameTabsDialog(QWidget* parent = 0);
+    ~RenameTabsDialog();
+    QString tabTitleText() const;
+    QString remoteTabTitleText() const;
+    void setTabTitleText(const QString&);
+    void setRemoteTabTitleText(const QString&);
+
+    void focusTabTitleText();
+    void focusRemoteTabTitleText();
+
+public slots:
+    void insertTabTitleText(const QString& text);
+    void insertRemoteTabTitleText(const QString& text);
+
+private:
+    Ui::RenameTabsDialog* _ui;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Screen.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,1360 @@
+/*
+   This file is part of Konsole, an X terminal.
+
+   Copyright 2007-2008 by Robert Knight <robert.knight@gmail.com>
+   Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+   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 "Screen.h"
+
+// Standard
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+// Qt
+#include <QtCore/QTextStream>
+#include <QtCore/QDate>
+
+// KDE
+//#include <kdebug.h>
+
+// Konsole
+#include "konsole_wcwidth.h"
+#include "TerminalCharacterDecoder.h"
+
+using namespace Konsole;
+
+//FIXME: this is emulation specific. Use false for xterm, true for ANSI.
+//FIXME: see if we can get this from terminfo.
+#define BS_CLEARS false
+
+//Macro to convert x,y position on screen to position within an image.
+//
+//Originally the image was stored as one large contiguous block of 
+//memory, so a position within the image could be represented as an
+//offset from the beginning of the block.  For efficiency reasons this
+//is no longer the case.  
+//Many internal parts of this class still use this representation for parameters and so on,
+//notably moveImage() and clearImage().
+//This macro converts from an X,Y position into an image offset.
+#ifndef loc
+#define loc(X,Y) ((Y)*columns+(X))
+#endif
+
+
+Character Screen::defaultChar = Character(' ',
+        CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
+        CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
+        DEFAULT_RENDITION);
+
+//#define REVERSE_WRAPPED_LINES  // for wrapped line debug
+
+    Screen::Screen(int l, int c)
+: lines(l),
+    columns(c),
+    screenLines(new ImageLine[lines+1] ),
+    _scrolledLines(0),
+    _droppedLines(0),
+    history(new HistoryScrollNone()),
+    cuX(0), cuY(0),
+    currentRendition(0),
+    _topMargin(0), _bottomMargin(0),
+    selBegin(0), selTopLeft(0), selBottomRight(0),
+    blockSelectionMode(false),
+    effectiveForeground(CharacterColor()), effectiveBackground(CharacterColor()), effectiveRendition(0),
+    lastPos(-1)
+{
+    lineProperties.resize(lines+1);
+    for (int i=0;i<lines+1;i++)
+        lineProperties[i]=LINE_DEFAULT;
+
+    initTabStops();
+    clearSelection();
+    reset();
+}
+
+/*! Destructor
+*/
+
+Screen::~Screen()
+{
+    delete[] screenLines;
+    delete history;
+}
+
+void Screen::cursorUp(int n)
+    //=CUU
+{
+    if (n == 0) n = 1; // Default
+    int stop = cuY < _topMargin ? 0 : _topMargin;
+    cuX = qMin(columns-1,cuX); // nowrap!
+    cuY = qMax(stop,cuY-n);
+}
+
+void Screen::cursorDown(int n)
+    //=CUD
+{
+    if (n == 0) n = 1; // Default
+    int stop = cuY > _bottomMargin ? lines-1 : _bottomMargin;
+    cuX = qMin(columns-1,cuX); // nowrap!
+    cuY = qMin(stop,cuY+n);
+}
+
+void Screen::cursorLeft(int n)
+    //=CUB
+{
+    if (n == 0) n = 1; // Default
+    cuX = qMin(columns-1,cuX); // nowrap!
+    cuX = qMax(0,cuX-n);
+}
+
+void Screen::cursorRight(int n)
+    //=CUF
+{
+    if (n == 0) n = 1; // Default
+    cuX = qMin(columns-1,cuX+n);
+}
+
+void Screen::setMargins(int top, int bot)
+    //=STBM
+{
+    if (top == 0) top = 1;      // Default
+    if (bot == 0) bot = lines;  // Default
+    top = top - 1;              // Adjust to internal lineno
+    bot = bot - 1;              // Adjust to internal lineno
+    if ( !( 0 <= top && top < bot && bot < lines ) )
+    { //Debug()<<" setRegion("<<top<<","<<bot<<") : bad range.";
+        return;                   // Default error action: ignore
+    }
+    _topMargin = top;
+    _bottomMargin = bot;
+    cuX = 0;
+    cuY = getMode(MODE_Origin) ? top : 0;
+
+}
+
+int Screen::topMargin() const
+{
+    return _topMargin;
+}
+int Screen::bottomMargin() const
+{
+    return _bottomMargin;
+}
+
+void Screen::index()
+    //=IND
+{
+    if (cuY == _bottomMargin)
+        scrollUp(1);
+    else if (cuY < lines-1)
+        cuY += 1;
+}
+
+void Screen::reverseIndex()
+    //=RI
+{
+    if (cuY == _topMargin)
+        scrollDown(_topMargin,1);
+    else if (cuY > 0)
+        cuY -= 1;
+}
+
+void Screen::nextLine()
+    //=NEL
+{
+    toStartOfLine(); index();
+}
+
+void Screen::eraseChars(int n)
+{
+    if (n == 0) n = 1; // Default
+    int p = qMax(0,qMin(cuX+n-1,columns-1));
+    clearImage(loc(cuX,cuY),loc(p,cuY),' ');
+}
+
+void Screen::deleteChars(int n)
+{
+    Q_ASSERT( n >= 0 );
+
+    // always delete at least one char
+    if (n == 0) 
+        n = 1; 
+
+    // if cursor is beyond the end of the line there is nothing to do
+    if ( cuX >= screenLines[cuY].count() )
+        return;
+
+    if ( cuX+n > screenLines[cuY].count() ) 
+        n = screenLines[cuY].count() - cuX;
+
+    Q_ASSERT( n >= 0 );
+    Q_ASSERT( cuX+n <= screenLines[cuY].count() );
+
+    screenLines[cuY].remove(cuX,n);
+}
+
+void Screen::insertChars(int n)
+{
+    if (n == 0) n = 1; // Default
+
+    if ( screenLines[cuY].size() < cuX )
+        screenLines[cuY].resize(cuX);
+
+    screenLines[cuY].insert(cuX,n,' ');
+
+    if ( screenLines[cuY].count() > columns )
+        screenLines[cuY].resize(columns);
+}
+
+void Screen::deleteLines(int n)
+{
+    if (n == 0) n = 1; // Default
+    scrollUp(cuY,n);
+}
+
+void Screen::insertLines(int n)
+{
+    if (n == 0) n = 1; // Default
+    scrollDown(cuY,n);
+}
+
+void Screen::setMode(int m)
+{
+    currentModes[m] = true;
+    switch(m)
+    {
+        case MODE_Origin : cuX = 0; cuY = _topMargin; break; //FIXME: home
+    }
+}
+
+void Screen::resetMode(int m)
+{
+    currentModes[m] = false;
+    switch(m)
+    {
+        case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
+    }
+}
+
+void Screen::saveMode(int m)
+{
+    savedModes[m] = currentModes[m];
+}
+
+void Screen::restoreMode(int m)
+{
+    currentModes[m] = savedModes[m];
+}
+
+bool Screen::getMode(int m) const
+{
+    return currentModes[m];
+}
+
+void Screen::saveCursor()
+{
+    savedState.cursorColumn = cuX;
+    savedState.cursorLine  = cuY;
+    savedState.rendition = currentRendition;
+    savedState.foreground = currentForeground;
+    savedState.background = currentBackground;
+}
+
+void Screen::restoreCursor()
+{
+    cuX     = qMin(savedState.cursorColumn,columns-1);
+    cuY     = qMin(savedState.cursorLine,lines-1);
+    currentRendition   = savedState.rendition; 
+    currentForeground   = savedState.foreground;
+    currentBackground   = savedState.background;
+    updateEffectiveRendition();
+}
+
+void Screen::resizeImage(int new_lines, int new_columns)
+{
+    if ((new_lines==lines) && (new_columns==columns)) return;
+
+    if (cuY > new_lines-1)
+    { // attempt to preserve focus and lines
+        _bottomMargin = lines-1; //FIXME: margin lost
+        for (int i = 0; i < cuY-(new_lines-1); i++)
+        {
+            addHistLine(); scrollUp(0,1);
+        }
+    }
+
+    // create new screen lines and copy from old to new
+
+    ImageLine* newScreenLines = new ImageLine[new_lines+1];
+    for (int i=0; i < qMin(lines-1,new_lines+1) ;i++)
+        newScreenLines[i]=screenLines[i];
+    for (int i=lines;(i > 0) && (i<new_lines+1);i++)
+        newScreenLines[i].resize( new_columns );
+
+    lineProperties.resize(new_lines+1);
+    for (int i=lines;(i > 0) && (i<new_lines+1);i++)
+        lineProperties[i] = LINE_DEFAULT;
+
+    clearSelection();
+
+    delete[] screenLines; 
+    screenLines = newScreenLines;
+
+    lines = new_lines;
+    columns = new_columns;
+    cuX = qMin(cuX,columns-1);
+    cuY = qMin(cuY,lines-1);
+
+    // FIXME: try to keep values, evtl.
+    _topMargin=0;
+    _bottomMargin=lines-1;
+    initTabStops();
+    clearSelection();
+}
+
+void Screen::setDefaultMargins()
+{
+    _topMargin = 0;
+    _bottomMargin = lines-1;
+}
+
+
+/*
+   Clarifying rendition here and in the display.
+
+   currently, the display's color table is
+   0       1       2 .. 9    10 .. 17
+   dft_fg, dft_bg, dim 0..7, intensive 0..7
+
+   currentForeground, currentBackground contain values 0..8;
+   - 0    = default color
+   - 1..8 = ansi specified color
+
+   re_fg, re_bg contain values 0..17
+   due to the TerminalDisplay's color table
+
+   rendition attributes are
+
+   attr           widget screen
+   -------------- ------ ------
+   RE_UNDERLINE     XX     XX    affects foreground only
+   RE_BLINK         XX     XX    affects foreground only
+   RE_BOLD          XX     XX    affects foreground only
+   RE_REVERSE       --     XX
+   RE_TRANSPARENT   XX     --    affects background only
+   RE_INTENSIVE     XX     --    affects foreground only
+
+   Note that RE_BOLD is used in both widget
+   and screen rendition. Since xterm/vt102
+   is to poor to distinguish between bold
+   (which is a font attribute) and intensive
+   (which is a color attribute), we translate
+   this and RE_BOLD in falls eventually appart
+   into RE_BOLD and RE_INTENSIVE.
+   */
+
+void Screen::reverseRendition(Character& p) const
+{ 
+    CharacterColor f = p.foregroundColor; 
+    CharacterColor b = p.backgroundColor;
+
+    p.foregroundColor = b; 
+    p.backgroundColor = f; //p->r &= ~RE_TRANSPARENT;
+}
+
+void Screen::updateEffectiveRendition()
+{
+    effectiveRendition = currentRendition;
+    if (currentRendition & RE_REVERSE)
+    {
+        effectiveForeground = currentBackground;
+        effectiveBackground = currentForeground;
+    }
+    else
+    {
+        effectiveForeground = currentForeground;
+        effectiveBackground = currentBackground;
+    }
+
+    if (currentRendition & RE_BOLD)
+        effectiveForeground.toggleIntensive();
+}
+
+void Screen::copyFromHistory(Character* dest, int startLine, int count) const
+{
+    Q_ASSERT( startLine >= 0 && count > 0 && startLine + count <= history->getLines() );
+
+    for (int line = startLine; line < startLine + count; line++) 
+    {
+        const int length = qMin(columns,history->getLineLen(line));
+        const int destLineOffset  = (line-startLine)*columns;
+
+        history->getCells(line,0,length,dest + destLineOffset);
+
+        for (int column = length; column < columns; column++) 
+            dest[destLineOffset+column] = defaultChar;
+
+        // invert selected text
+        if (selBegin !=-1)
+        {
+            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
+{
+    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;
+
+        for (int column = 0; column < columns; column++)
+        { 
+            int srcIndex = srcLineStartIndex + column; 
+            int destIndex = destLineStartIndex + column;
+
+            dest[destIndex] = screenLines[srcIndex/columns].value(srcIndex%columns,defaultChar);
+
+            // invert selected text
+            if (selBegin != -1 && isSelected(column,line + history->getLines()))
+                reverseRendition(dest[destIndex]); 
+        }
+
+    }
+}
+
+void Screen::getImage( Character* dest, int size, int startLine, int endLine ) const
+{
+    Q_ASSERT( startLine >= 0 );
+    Q_ASSERT( endLine >= startLine && endLine < history->getLines() + lines );
+
+    const int mergedLines = endLine - startLine + 1;
+
+    Q_ASSERT( size >= mergedLines * columns ); 
+    Q_UNUSED( size );
+
+    const int linesInHistoryBuffer = qBound(0,history->getLines()-startLine,mergedLines);
+    const int linesInScreenBuffer = mergedLines - linesInHistoryBuffer;
+
+    // copy lines from history buffer
+    if (linesInHistoryBuffer > 0)
+        copyFromHistory(dest,startLine,linesInHistoryBuffer); 
+
+    // copy lines from screen buffer
+    if (linesInScreenBuffer > 0)
+        copyFromScreen(dest + linesInHistoryBuffer*columns,
+                startLine + linesInHistoryBuffer - history->getLines(),
+                linesInScreenBuffer);
+
+    // invert display when in screen mode
+    if (getMode(MODE_Screen))
+    {
+        for (int i = 0; i < mergedLines*columns; i++)
+            reverseRendition(dest[i]); // for reverse display
+    }
+
+    // mark the character at the current cursor position
+    int cursorIndex = loc(cuX, cuY + linesInHistoryBuffer);
+    if(getMode(MODE_Cursor) && cursorIndex < columns*mergedLines)
+        dest[cursorIndex].rendition |= RE_CURSOR;
+}
+
+QVector<LineProperty> Screen::getLineProperties( int startLine , int endLine ) const
+{
+    Q_ASSERT( startLine >= 0 ); 
+    Q_ASSERT( endLine >= startLine && endLine < history->getLines() + lines );
+
+    const int mergedLines = endLine-startLine+1;
+    const int linesInHistory = qBound(0,history->getLines()-startLine,mergedLines);
+    const int linesInScreen = mergedLines - linesInHistory;
+
+    QVector<LineProperty> result(mergedLines);
+    int index = 0;
+
+    // copy properties for lines in history
+    for (int line = startLine; line < startLine + linesInHistory; line++) 
+    {
+        //TODO Support for line properties other than wrapped lines
+        if (history->isWrappedLine(line))
+        {
+            result[index] = (LineProperty)(result[index] | LINE_WRAPPED);
+        }
+        index++;
+    }
+
+    // copy properties for lines in screen buffer
+    const int firstScreenLine = startLine + linesInHistory - history->getLines();
+    for (int line = firstScreenLine; line < firstScreenLine+linesInScreen; line++)
+    {
+        result[index]=lineProperties[line];
+        index++;
+    }
+
+    return result;
+}
+
+void Screen::reset(bool clearScreen)
+{
+    setMode(MODE_Wrap  ); saveMode(MODE_Wrap  );  // wrap at end of margin
+    resetMode(MODE_Origin); saveMode(MODE_Origin);  // position refere to [1,1]
+    resetMode(MODE_Insert); saveMode(MODE_Insert);  // overstroke
+    setMode(MODE_Cursor);                         // cursor visible
+    resetMode(MODE_Screen);                         // screen not inverse
+    resetMode(MODE_NewLine);
+
+    _topMargin=0;
+    _bottomMargin=lines-1;
+
+    setDefaultRendition();
+    saveCursor();
+
+    if ( clearScreen )
+        clear();
+}
+
+void Screen::clear()
+{
+    clearEntireScreen();
+    home();
+}
+
+void Screen::backspace()
+{
+    cuX = qMin(columns-1,cuX); // nowrap!
+    cuX = qMax(0,cuX-1);
+
+    if (screenLines[cuY].size() < cuX+1)
+        screenLines[cuY].resize(cuX+1);
+
+    if (BS_CLEARS) 
+        screenLines[cuY][cuX].character = ' ';
+}
+
+void Screen::tab(int n)
+{
+    // note that TAB is a format effector (does not write ' ');
+    if (n == 0) n = 1;
+    while((n > 0) && (cuX < columns-1))
+    {
+        cursorRight(1); 
+        while((cuX < columns-1) && !tabStops[cuX]) 
+            cursorRight(1);
+        n--;
+    }
+}
+
+void Screen::backtab(int n)
+{
+    // note that TAB is a format effector (does not write ' ');
+    if (n == 0) n = 1;
+    while((n > 0) && (cuX > 0))
+    {
+        cursorLeft(1); while((cuX > 0) && !tabStops[cuX]) cursorLeft(1);
+        n--;
+    }
+}
+
+void Screen::clearTabStops()
+{
+    for (int i = 0; i < columns; i++) tabStops[i] = false;
+}
+
+void Screen::changeTabStop(bool set)
+{
+    if (cuX >= columns) return;
+    tabStops[cuX] = set;
+}
+
+void Screen::initTabStops()
+{
+    tabStops.resize(columns);
+
+    // Arrg! The 1st tabstop has to be one longer than the other.
+    // i.e. the kids start counting from 0 instead of 1.
+    // Other programs might behave correctly. Be aware.
+    for (int i = 0; i < columns; i++) 
+        tabStops[i] = (i%8 == 0 && i != 0);
+}
+
+void Screen::newLine()
+{
+    if (getMode(MODE_NewLine)) 
+        toStartOfLine();
+    index();
+}
+
+void Screen::checkSelection(int from, int to)
+{
+    if (selBegin == -1) 
+        return;
+    int scr_TL = loc(0, history->getLines());
+    //Clear entire selection if it overlaps region [from, to]
+    if ( (selBottomRight >= (from+scr_TL)) && (selTopLeft <= (to+scr_TL)) )
+        clearSelection();
+}
+
+void Screen::displayCharacter(unsigned short c)
+{
+    // Note that VT100 does wrapping BEFORE putting the character.
+    // This has impact on the assumption of valid cursor positions.
+    // We indicate the fact that a newline has to be triggered by
+    // putting the cursor one right to the last column of the screen.
+
+    int w = konsole_wcwidth(c);
+    if (w <= 0)
+        return;
+
+    if (cuX+w > columns) {
+        if (getMode(MODE_Wrap)) {
+            lineProperties[cuY] = (LineProperty)(lineProperties[cuY] | LINE_WRAPPED);
+            nextLine();
+        }
+        else
+            cuX = columns-w;
+    }
+
+    // ensure current line vector has enough elements
+    int size = screenLines[cuY].size();
+    if (size < cuX+w)
+    {
+        screenLines[cuY].resize(cuX+w);
+    }
+
+    if (getMode(MODE_Insert)) insertChars(w);
+
+    lastPos = loc(cuX,cuY);
+
+    // check if selection is still valid.
+    checkSelection(lastPos, lastPos);
+
+    Character& currentChar = screenLines[cuY][cuX];
+
+    currentChar.character = c;
+    currentChar.foregroundColor = effectiveForeground;
+    currentChar.backgroundColor = effectiveBackground;
+    currentChar.rendition = effectiveRendition;
+
+    int i = 0;
+    int newCursorX = cuX + w--;
+    while(w)
+    {
+        i++;
+
+        if ( screenLines[cuY].size() < cuX + i + 1 )
+            screenLines[cuY].resize(cuX+i+1);
+
+        Character& ch = screenLines[cuY][cuX + i];
+        ch.character = 0;
+        ch.foregroundColor = effectiveForeground;
+        ch.backgroundColor = effectiveBackground;
+        ch.rendition = effectiveRendition;
+
+        w--;
+    }
+    cuX = newCursorX;
+}
+
+void Screen::compose(const QString& /*compose*/)
+{
+    Q_ASSERT( 0 /*Not implemented yet*/ );
+
+    /*  if (lastPos == -1)
+        return;
+
+        QChar c(image[lastPos].character);
+        compose.prepend(c);
+    //compose.compose(); ### FIXME!
+    image[lastPos].character = compose[0].unicode();*/
+}
+
+int Screen::scrolledLines() const
+{
+    return _scrolledLines;
+}
+int Screen::droppedLines() const
+{
+    return _droppedLines;
+}
+void Screen::resetDroppedLines()
+{
+    _droppedLines = 0;
+}
+void Screen::resetScrolledLines()
+{
+    _scrolledLines = 0;
+}
+
+void Screen::scrollUp(int n)
+{
+    if (n == 0) n = 1; // Default
+    if (_topMargin == 0) addHistLine(); // history.history
+    scrollUp(_topMargin, n);
+}
+
+QRect Screen::lastScrolledRegion() const
+{
+    return _lastScrolledRegion;
+}
+
+void Screen::scrollUp(int from, int n)
+{
+    if (n <= 0 || from + n > _bottomMargin) return;
+
+    _scrolledLines -= n;
+    _lastScrolledRegion = QRect(0,_topMargin,columns-1,(_bottomMargin-_topMargin));
+
+    //FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds.
+    moveImage(loc(0,from),loc(0,from+n),loc(columns-1,_bottomMargin));
+    clearImage(loc(0,_bottomMargin-n+1),loc(columns-1,_bottomMargin),' ');
+}
+
+void Screen::scrollDown(int n)
+{
+    if (n == 0) n = 1; // Default
+    scrollDown(_topMargin, n);
+}
+
+void Screen::scrollDown(int from, int n)
+{
+    _scrolledLines += n;
+
+    //FIXME: make sure `topMargin', `bottomMargin', `from', `n' is in bounds.
+    if (n <= 0) 
+        return;
+    if (from > _bottomMargin) 
+        return;
+    if (from + n > _bottomMargin) 
+        n = _bottomMargin - from;
+    moveImage(loc(0,from+n),loc(0,from),loc(columns-1,_bottomMargin-n));
+    clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
+}
+
+void Screen::setCursorYX(int y, int x)
+{
+    setCursorY(y); setCursorX(x);
+}
+
+void Screen::setCursorX(int x)
+{
+    if (x == 0) x = 1; // Default
+    x -= 1; // Adjust
+    cuX = qMax(0,qMin(columns-1, x));
+}
+
+void Screen::setCursorY(int y)
+{
+    if (y == 0) y = 1; // Default
+    y -= 1; // Adjust
+    cuY = qMax(0,qMin(lines  -1, y + (getMode(MODE_Origin) ? _topMargin : 0) ));
+}
+
+void Screen::home()
+{
+    cuX = 0;
+    cuY = 0;
+}
+
+void Screen::toStartOfLine()
+{
+    cuX = 0;
+}
+
+int Screen::getCursorX() const
+{
+    return cuX;
+}
+
+int Screen::getCursorY() const
+{
+    return cuY;
+}
+
+void Screen::clearImage(int loca, int loce, char c)
+{ 
+    int scr_TL=loc(0,history->getLines());
+    //FIXME: check positions
+
+    //Clear entire selection if it overlaps region to be moved...
+    if ( (selBottomRight > (loca+scr_TL) )&&(selTopLeft < (loce+scr_TL)) )
+    {
+        clearSelection();
+    }
+
+    int topLine = loca/columns;
+    int bottomLine = loce/columns;
+
+    Character clearCh(c,currentForeground,currentBackground,DEFAULT_RENDITION);
+
+    //if the character being used to clear the area is the same as the
+    //default character, the affected lines can simply be shrunk.
+    bool isDefaultCh = (clearCh == Character());
+
+    for (int y=topLine;y<=bottomLine;y++)
+    {
+        lineProperties[y] = 0;
+
+        int endCol = ( y == bottomLine) ? loce%columns : columns-1;
+        int startCol = ( y == topLine ) ? loca%columns : 0;
+
+        QVector<Character>& line = screenLines[y];
+
+        if ( isDefaultCh && endCol == columns-1 )
+        {
+            line.resize(startCol);
+        }
+        else
+        {
+            if (line.size() < endCol + 1)
+                line.resize(endCol+1);
+
+            Character* data = line.data();
+            for (int i=startCol;i<=endCol;i++)
+                data[i]=clearCh;
+        }
+    }
+}
+
+void Screen::moveImage(int dest, int sourceBegin, int sourceEnd)
+{
+    Q_ASSERT( sourceBegin <= sourceEnd );
+
+    int lines=(sourceEnd-sourceBegin)/columns;
+
+    //move screen image and line properties:
+    //the source and destination areas of the image may overlap, 
+    //so it matters that we do the copy in the right order - 
+    //forwards if dest < sourceBegin or backwards otherwise.
+    //(search the web for 'memmove implementation' for details)
+    if (dest < sourceBegin)
+    {
+        for (int i=0;i<=lines;i++)
+        {
+            screenLines[ (dest/columns)+i ] = screenLines[ (sourceBegin/columns)+i ];
+            lineProperties[(dest/columns)+i]=lineProperties[(sourceBegin/columns)+i];
+        }
+    }
+    else
+    {
+        for (int i=lines;i>=0;i--)
+        {
+            screenLines[ (dest/columns)+i ] = screenLines[ (sourceBegin/columns)+i ];
+            lineProperties[(dest/columns)+i]=lineProperties[(sourceBegin/columns)+i];
+        }
+    }
+
+    if (lastPos != -1)
+    {
+        int diff = dest - sourceBegin; // Scroll by this amount
+        lastPos += diff;
+        if ((lastPos < 0) || (lastPos >= (lines*columns)))
+            lastPos = -1;
+    }
+
+    // Adjust selection to follow scroll.
+    if (selBegin != -1)
+    {
+        bool beginIsTL = (selBegin == selTopLeft);
+        int diff = dest - sourceBegin; // Scroll by this amount
+        int scr_TL=loc(0,history->getLines());
+        int srca = sourceBegin+scr_TL; // Translate index from screen to global
+        int srce = sourceEnd+scr_TL; // Translate index from screen to global
+        int desta = srca+diff;
+        int deste = srce+diff;
+
+        if ((selTopLeft >= srca) && (selTopLeft <= srce))
+            selTopLeft += diff;
+        else if ((selTopLeft >= desta) && (selTopLeft <= deste))
+            selBottomRight = -1; // Clear selection (see below)
+
+        if ((selBottomRight >= srca) && (selBottomRight <= srce))
+            selBottomRight += diff;
+        else if ((selBottomRight >= desta) && (selBottomRight <= deste))
+            selBottomRight = -1; // Clear selection (see below)
+
+        if (selBottomRight < 0)
+        {
+            clearSelection();
+        }
+        else
+        {
+            if (selTopLeft < 0)
+                selTopLeft = 0;
+        }
+
+        if (beginIsTL)
+            selBegin = selTopLeft;
+        else
+            selBegin = selBottomRight;
+    }
+}
+
+void Screen::clearToEndOfScreen()
+{
+    clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
+}
+
+void Screen::clearToBeginOfScreen()
+{
+    clearImage(loc(0,0),loc(cuX,cuY),' ');
+}
+
+void Screen::clearEntireScreen()
+{
+    // Add entire screen to history
+    for (int i = 0; i < (lines-1); i++)
+    {
+        addHistLine(); scrollUp(0,1);
+    }
+
+    clearImage(loc(0,0),loc(columns-1,lines-1),' ');
+}
+
+/*! fill screen with 'E'
+  This is to aid screen alignment
+  */
+
+void Screen::helpAlign()
+{
+    clearImage(loc(0,0),loc(columns-1,lines-1),'E');
+}
+
+void Screen::clearToEndOfLine()
+{
+    clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
+}
+
+void Screen::clearToBeginOfLine()
+{
+    clearImage(loc(0,cuY),loc(cuX,cuY),' ');
+}
+
+void Screen::clearEntireLine()
+{
+    clearImage(loc(0,cuY),loc(columns-1,cuY),' ');
+}
+
+void Screen::setRendition(int re)
+{
+    currentRendition |= re;
+    updateEffectiveRendition();
+}
+
+void Screen::resetRendition(int re)
+{
+    currentRendition &= ~re;
+    updateEffectiveRendition();
+}
+
+void Screen::setDefaultRendition()
+{
+    setForeColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR);
+    setBackColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR);
+    currentRendition   = DEFAULT_RENDITION;
+    updateEffectiveRendition();
+}
+
+void Screen::setForeColor(int space, int color)
+{
+    currentForeground = CharacterColor(space, color);
+
+    if ( currentForeground.isValid() ) 
+        updateEffectiveRendition();
+    else 
+        setForeColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR);
+}
+
+void Screen::setBackColor(int space, int color)
+{
+    currentBackground = CharacterColor(space, color);
+
+    if ( currentBackground.isValid() ) 
+        updateEffectiveRendition();
+    else
+        setBackColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR);
+}
+
+void Screen::clearSelection() 
+{
+    selBottomRight = -1;
+    selTopLeft = -1;
+    selBegin = -1;
+}
+
+void Screen::getSelectionStart(int& column , int& line) const
+{
+    if ( selTopLeft != -1 )
+    {
+        column = selTopLeft % columns;
+        line = selTopLeft / columns; 
+    }
+    else
+    {
+        column = cuX + getHistLines();
+        line = cuY + getHistLines();
+    }
+}
+void Screen::getSelectionEnd(int& column , int& line) const
+{
+    if ( selBottomRight != -1 )
+    {
+        column = selBottomRight % columns;
+        line = selBottomRight / columns;
+    }
+    else
+    {
+        column = cuX + getHistLines();
+        line = cuY + getHistLines();
+    } 
+}
+void Screen::setSelectionStart(const int x, const int y, const bool mode)
+{
+    selBegin = loc(x,y); 
+    /* FIXME, HACK to correct for x too far to the right... */
+    if (x == columns) selBegin--;
+
+    selBottomRight = selBegin;
+    selTopLeft = selBegin;
+    blockSelectionMode = mode;
+}
+
+void Screen::setSelectionEnd( const int x, const int y)
+{
+    if (selBegin == -1) 
+        return;
+
+    int endPos =  loc(x,y); 
+
+    if (endPos < selBegin)
+    {
+        selTopLeft = endPos;
+        selBottomRight = selBegin;
+    }
+    else
+    {
+        /* FIXME, HACK to correct for x too far to the right... */
+        if (x == columns) 
+            endPos--;
+
+        selTopLeft = selBegin;
+        selBottomRight = endPos;
+    }
+
+    // Normalize the selection in column mode
+    if (blockSelectionMode)
+    {
+        int topRow = selTopLeft / columns;
+        int topColumn = selTopLeft % columns;
+        int bottomRow = selBottomRight / columns;
+        int bottomColumn = selBottomRight % columns;
+
+        selTopLeft = loc(qMin(topColumn,bottomColumn),topRow);
+        selBottomRight = loc(qMax(topColumn,bottomColumn),bottomRow);
+    }
+}
+
+bool Screen::isSelected( const int x,const int y) const
+{
+    bool columnInSelection = true;
+    if (blockSelectionMode)
+    {
+        columnInSelection = x >= (selTopLeft % columns) &&
+            x <= (selBottomRight % columns);
+    }
+
+    int pos = loc(x,y);
+    return pos >= selTopLeft && pos <= selBottomRight && columnInSelection;
+}
+
+QString Screen::selectedText(bool preserveLineBreaks) const
+{
+    QString result;
+    QTextStream stream(&result, QIODevice::ReadWrite);
+
+    PlainTextDecoder decoder;
+    decoder.begin(&stream);
+    writeSelectionToStream(&decoder , preserveLineBreaks);
+    decoder.end();
+
+    return result;
+}
+
+bool Screen::isSelectionValid() const
+{
+    return selTopLeft >= 0 && selBottomRight >= 0;
+}
+
+void Screen::writeSelectionToStream(TerminalCharacterDecoder* decoder , 
+        bool preserveLineBreaks) const
+{
+    if (!isSelectionValid())
+        return;
+    writeToStream(decoder,selTopLeft,selBottomRight,preserveLineBreaks);
+}
+
+void Screen::writeToStream(TerminalCharacterDecoder* decoder, 
+        int startIndex, int endIndex,
+        bool preserveLineBreaks) const
+{
+    int top = startIndex / columns;    
+    int left = startIndex % columns;
+
+    int bottom = endIndex / columns;
+    int right = endIndex % columns;
+
+    Q_ASSERT( top >= 0 && left >= 0 && bottom >= 0 && right >= 0 );
+
+    for (int y=top;y<=bottom;y++)
+    {
+        int start = 0;
+        if ( y == top || blockSelectionMode ) start = left;
+
+        int count = -1;
+        if ( y == bottom || blockSelectionMode ) count = right - start + 1;
+
+        const bool appendNewLine = ( y != bottom );
+        int copied = copyLineToStream( y,
+                start,
+                count,
+                decoder, 
+                appendNewLine,
+                preserveLineBreaks );
+
+        // if the selection goes beyond the end of the last line then
+        // append a new line character.
+        //
+        // this makes it possible to 'select' a trailing new line character after
+        // the text on a line.  
+        if ( y == bottom && 
+                copied < count    )
+        {
+            Character newLineChar('\n');
+            decoder->decodeLine(&newLineChar,1,0);
+        }
+    }    
+}
+
+int Screen::copyLineToStream(int line , 
+        int start, 
+        int count,
+        TerminalCharacterDecoder* decoder,
+        bool appendNewLine,
+        bool preserveLineBreaks) const
+{
+    //buffer to hold characters for decoding
+    //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];
+
+    assert( count < MAX_CHARS );
+
+    LineProperty currentLineProperties = 0;
+
+    //determine if the line is in the history buffer or the screen image
+    if (line < history->getLines())
+    {
+        const int lineLength = history->getLineLen(line);
+
+        // ensure that start position is before end of line
+        start = qMin(start,qMax(0,lineLength-1));
+
+        // retrieve line from history buffer.  It is assumed
+        // that the history buffer does not store trailing white space
+        // at the end of the line, so it does not need to be trimmed here 
+        if (count == -1)
+        {
+            count = lineLength-start;
+        }
+        else
+        {
+            count = qMin(start+count,lineLength)-start;
+        }
+
+        // safety checks
+        assert( start >= 0 );
+        assert( count >= 0 );    
+        assert( (start+count) <= history->getLineLen(line) );
+
+        history->getCells(line,start,count,characterBuffer);
+
+        if ( history->isWrappedLine(line) )
+            currentLineProperties |= LINE_WRAPPED;
+    }
+    else
+    {
+        if ( count == -1 )
+            count = columns - start;
+
+        assert( count >= 0 );
+
+        const int screenLine = line-history->getLines();
+
+        Character* data = screenLines[screenLine].data();
+        int length = screenLines[screenLine].count();
+
+        //retrieve line from screen image
+        for (int i=start;i < qMin(start+count,length);i++)
+        {
+            characterBuffer[i-start] = data[i];
+        }
+
+        // count cannot be any greater than length
+        count = qBound(0,count,length-start);
+
+        Q_ASSERT( screenLine < lineProperties.count() );
+        currentLineProperties |= lineProperties[screenLine]; 
+    }
+
+    // add new line character at end
+    const bool omitLineBreak = (currentLineProperties & LINE_WRAPPED) ||
+        !preserveLineBreaks;
+
+    if ( !omitLineBreak && appendNewLine && (count+1 < MAX_CHARS) )
+    {
+        characterBuffer[count] = '\n';
+        count++;
+    }
+
+    //decode line and write to text stream    
+    decoder->decodeLine( (Character*) characterBuffer , 
+            count, currentLineProperties );
+
+    return count;
+}
+
+void Screen::writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, int toLine) const
+{
+    writeToStream(decoder,loc(0,fromLine),loc(columns-1,toLine));
+}
+
+void Screen::addHistLine()
+{
+    // add line to history buffer
+    // we have to take care about scrolling, too...
+
+    if (hasScroll())
+    {
+        int oldHistLines = history->getLines();
+
+        history->addCellsVector(screenLines[0]);
+        history->addLine( lineProperties[0] & LINE_WRAPPED );
+
+        int newHistLines = history->getLines();
+
+        bool beginIsTL = (selBegin == selTopLeft);
+
+        // If the history is full, increment the count
+        // of dropped lines
+        if ( newHistLines == oldHistLines )
+            _droppedLines++;
+
+        // Adjust selection for the new point of reference
+        if (newHistLines > oldHistLines)
+        {
+            if (selBegin != -1)
+            {
+                selTopLeft += columns;
+                selBottomRight += columns;
+            }
+        }
+
+        if (selBegin != -1)
+        {
+            // Scroll selection in history up
+            int top_BR = loc(0, 1+newHistLines);
+
+            if (selTopLeft < top_BR)
+                selTopLeft -= columns;
+
+            if (selBottomRight < top_BR)
+                selBottomRight -= columns;
+
+            if (selBottomRight < 0)
+                clearSelection();
+            else
+            {
+                if (selTopLeft < 0)
+                    selTopLeft = 0;
+            }
+
+            if (beginIsTL)
+                selBegin = selTopLeft;
+            else
+                selBegin = selBottomRight;
+        }
+    }
+
+}
+
+int Screen::getHistLines() const
+{
+    return history->getLines();
+}
+
+void Screen::setScroll(const HistoryType& t , bool copyPreviousScroll)
+{
+    clearSelection();
+
+    if ( copyPreviousScroll )
+        history = t.scroll(history);
+    else
+    {
+        HistoryScroll* oldScroll = history;
+        history = t.scroll(0);
+        delete oldScroll;
+    }
+}
+
+bool Screen::hasScroll() const
+{
+    return history->hasScroll();
+}
+
+const HistoryType& Screen::getScroll() const
+{
+    return history->getType();
+}
+
+void Screen::setLineProperty(LineProperty property , bool enable)
+{
+    if ( enable )
+        lineProperties[cuY] = (LineProperty)(lineProperties[cuY] | property);
+    else
+        lineProperties[cuY] = (LineProperty)(lineProperties[cuY] & ~property);
+}
+void Screen::fillWithDefaultChar(Character* dest, int count)
+{
+    for (int i=0;i<count;i++)
+        dest[i] = defaultChar;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Screen.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,675 @@
+/*
+    This file is part of Konsole, KDE's terminal.
+
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef SCREEN_H
+#define SCREEN_H
+
+// Qt
+#include <QtCore/QRect>
+#include <QtCore/QTextStream>
+#include <QtCore/QVarLengthArray>
+
+// Konsole
+#include "Character.h"
+#include "History.h"
+
+#define MODE_Origin    0
+#define MODE_Wrap      1
+#define MODE_Insert    2
+#define MODE_Screen    3
+#define MODE_Cursor    4
+#define MODE_NewLine   5
+#define MODES_SCREEN   6
+
+namespace Konsole
+{
+
+class TerminalCharacterDecoder;
+
+/**
+    \brief An image of characters with associated attributes.
+
+    The terminal emulation ( Emulation ) receives a serial stream of
+    characters from the program currently running in the terminal.
+    From this stream it creates an image of characters which is ultimately
+    rendered by the display widget ( TerminalDisplay ).  Some types of emulation
+    may have more than one screen image. 
+
+    getImage() is used to retrieve the currently visible image
+    which is then used by the display widget to draw the output from the
+    terminal. 
+
+    The number of lines of output history which are kept in addition to the current
+    screen image depends on the history scroll being used to store the output.  
+    The scroll is specified using setScroll()
+    The output history can be retrieved using writeToStream()
+
+    The screen image has a selection associated with it, specified using 
+    setSelectionStart() and setSelectionEnd().  The selected text can be retrieved
+    using selectedText().  When getImage() is used to retrieve the visible image,
+    characters which are part of the selection have their colours inverted.   
+*/
+class Screen
+{
+public:
+    /** Construct a new screen image of size @p lines by @p columns. */
+    Screen(int lines, int columns);
+    ~Screen();
+
+    // VT100/2 Operations 
+    // Cursor Movement
+    
+    /** 
+     * Move the cursor up by @p n lines.  The cursor will stop at the 
+     * top margin.
+     */
+    void cursorUp(int n);
+    /** 
+     * Move the cursor down by @p n lines.  The cursor will stop at the
+     * bottom margin.
+     */
+    void cursorDown(int n);
+    /** 
+     * Move the cursor to the left by @p n columns.
+     * The cursor will stop at the first column.
+     */
+    void cursorLeft(int n);
+    /** 
+     * Move the cursor to the right by @p n columns.
+     * The cursor will stop at the right-most column.
+     */
+    void cursorRight(int n);
+    /** Position the cursor on line @p y. */
+    void setCursorY(int y);
+    /** Position the cursor at column @p x. */
+    void setCursorX(int x);
+    /** Position the cursor at line @p y, column @p x. */
+    void setCursorYX(int y, int x);
+    /**
+     * Sets the margins for scrolling the screen.
+     *
+     * @param topLine The top line of the new scrolling margin. 
+     * @param bottomLine The bottom line of the new scrolling margin. 
+     */
+    void setMargins(int topLine , int bottomLine);
+    /** Returns the top line of the scrolling region. */ 
+    int topMargin() const;
+    /** Returns the bottom line of the scrolling region. */
+    int bottomMargin() const;
+
+    /** 
+     * Resets the scrolling margins back to the top and bottom lines
+     * of the screen.
+     */
+    void setDefaultMargins();
+    
+    /** 
+     * Moves the cursor down one line, if the MODE_NewLine mode 
+     * flag is enabled then the cursor is returned to the leftmost
+     * column first.
+     *
+     * Equivalent to NextLine() if the MODE_NewLine flag is set
+     * or index() otherwise. 
+     */
+    void newLine();
+    /**
+     * Moves the cursor down one line and positions it at the beginning
+     * of the line.  Equivalent to calling Return() followed by index()
+     */
+    void nextLine();
+
+    /** 
+     * Move the cursor down one line.  If the cursor is on the bottom
+     * line of the scrolling region (as returned by bottomMargin()) the
+     * scrolling region is scrolled up by one line instead.
+     */
+    void index();
+    /**
+     * Move the cursor up one line.  If the cursor is on the top line
+     * of the scrolling region (as returned by topMargin()) the scrolling
+     * region is scrolled down by one line instead.
+     */
+    void reverseIndex();
+    
+    /** 
+     * Scroll the scrolling region of the screen up by @p n lines. 
+     * The scrolling region is initially the whole screen, but can be changed 
+     * using setMargins()
+     */ 
+    void scrollUp(int n);
+    /**
+     * Scroll the scrolling region of the screen down by @p n lines.
+     * The scrolling region is initially the whole screen, but can be changed
+     * using setMargins()
+     */
+    void scrollDown(int n);
+    /** 
+     * Moves the cursor to the beginning of the current line. 
+     * Equivalent to setCursorX(0)
+     */
+    void toStartOfLine();
+    /** 
+     * Moves the cursor one column to the left and erases the character
+     * at the new cursor position.
+     */
+    void backspace();
+    /** Moves the cursor @p n tab-stops to the right. */
+    void tab(int n = 1);
+    /** Moves the cursor @p n tab-stops to the left. */
+    void backtab(int n);
+    
+    // Editing
+    
+    /** 
+     * Erase @p n characters beginning from the current cursor position. 
+     * This is equivalent to over-writing @p n characters starting with the current
+     * cursor position with spaces.
+     * If @p n is 0 then one character is erased. 
+     */
+    void eraseChars(int n);
+    /** 
+     * Delete @p n characters beginning from the current cursor position. 
+     * If @p n is 0 then one character is deleted. 
+     */
+    void deleteChars(int n);
+    /**
+     * Insert @p n blank characters beginning from the current cursor position.
+     * The position of the cursor is not altered.  
+     * If @p n is 0 then one character is inserted.
+     */
+    void insertChars(int n);
+    /** 
+     * Removes @p n lines beginning from the current cursor position.
+     * The position of the cursor is not altered.
+     * If @p n is 0 then one line is removed.
+     */
+    void deleteLines(int n);
+    /**
+     * Inserts @p lines beginning from the current cursor position.
+     * The position of the cursor is not altered.
+     * If @p n is 0 then one line is inserted.
+     */
+    void insertLines(int n);
+    /** Clears all the tab stops. */
+    void clearTabStops();
+    /**  Sets or removes a tab stop at the cursor's current column. */ 
+    void changeTabStop(bool set);
+   
+    /** Resets (clears) the specified screen @p mode. */
+    void resetMode(int mode);
+    /** Sets (enables) the specified screen @p mode. */
+    void setMode(int mode);
+    /** 
+     * Saves the state of the specified screen @p mode.  It can be restored
+     * using restoreMode()
+     */
+    void saveMode(int mode);
+    /** Restores the state of a screen @p mode saved by calling saveMode() */
+    void restoreMode(int mode);
+    /** Returns whether the specified screen @p mode is enabled or not .*/
+    bool getMode(int mode) const;
+   
+    /** 
+     * Saves the current position and appearance (text color and style) of the cursor. 
+     * It can be restored by calling restoreCursor() 
+     */ 
+    void saveCursor();
+    /** Restores the position and appearance of the cursor.  See saveCursor() */
+    void restoreCursor();
+   
+    /** Clear the whole screen, moving the current screen contents into the history first. */ 
+    void clearEntireScreen();
+    /** 
+     * Clear the area of the screen from the current cursor position to the end of 
+     * the screen.
+     */
+    void clearToEndOfScreen();
+    /**
+     * Clear the area of the screen from the current cursor position to the start
+     * of the screen.
+     */
+    void clearToBeginOfScreen();
+    /** Clears the whole of the line on which the cursor is currently positioned. */
+    void clearEntireLine();
+    /** Clears from the current cursor position to the end of the line. */
+    void clearToEndOfLine();
+    /** Clears from the current cursor position to the beginning of the line. */
+    void clearToBeginOfLine();
+    
+    /** Fills the entire screen with the letter 'E' */
+    void helpAlign();
+       
+    /** 
+     * Enables the given @p rendition flag.  Rendition flags control the appearance 
+     * of characters on the screen.
+     *
+     * @see Character::rendition
+     */  
+    void setRendition(int rendition);
+    /**
+     * Disables the given @p rendition flag.  Rendition flags control the appearance
+     * of characters on the screen.
+     *
+     * @see Character::rendition
+     */
+    void resetRendition(int rendition);
+    
+    /** 
+     * Sets the cursor's foreground color.
+     * @param space The color space used by the @p color argument
+     * @param color The new foreground color.  The meaning of this depends on
+     * the color @p space used.
+     *
+     * @see CharacterColor
+     */
+    void setForeColor(int space, int color);
+    /**
+     * Sets the cursor's background color.
+     * @param space The color space used by the @p color argumnet.
+     * @param color The new background color.  The meaning of this depends on
+     * the color @p space used.
+     *
+     * @see CharacterColor
+     */
+    void setBackColor(int space, int color);
+    /** 
+     * Resets the cursor's color back to the default and sets the 
+     * character's rendition flags back to the default settings.
+     */
+    void setDefaultRendition();
+    
+    /** Returns the column which the cursor is positioned at. */
+    int  getCursorX() const;
+    /** Returns the line which the cursor is positioned on. */
+    int  getCursorY() const;
+   
+    /** Clear the entire screen and move the cursor to the home position.
+     * Equivalent to calling clearEntireScreen() followed by home().
+     */
+    void clear();
+    /** 
+     * Sets the position of the cursor to the 'home' position at the top-left
+     * corner of the screen (0,0) 
+     */
+    void home();
+    /**
+     * Resets the state of the screen.  This resets the various screen modes
+     * back to their default states.  The cursor style and colors are reset
+     * (as if setDefaultRendition() had been called)
+     *
+     * <ul>
+     * <li>Line wrapping is enabled.</li>
+     * <li>Origin mode is disabled.</li>
+     * <li>Insert mode is disabled.</li>
+     * <li>Cursor mode is enabled.  TODO Document me</li>
+     * <li>Screen mode is disabled. TODO Document me</li>
+     * <li>New line mode is disabled.  TODO Document me</li>
+     * </ul>
+     *
+     * If @p clearScreen is true then the screen contents are erased entirely, 
+     * otherwise they are unaltered.
+     */
+    void reset(bool clearScreen = true);
+   
+    /** 
+     * Displays a new character at the current cursor position. 
+     * 
+     * If the cursor is currently positioned at the right-edge of the screen and
+     * line wrapping is enabled then the character is added at the start of a new 
+     * line below the current one.
+     *
+     * If the MODE_Insert screen mode is currently enabled then the character 
+     * is inserted at the current cursor position, otherwise it will replace the 
+     * character already at the current cursor position.  
+     */ 
+    void displayCharacter(unsigned short c);
+    
+    // Do composition with last shown character FIXME: Not implemented yet for KDE 4
+    void compose(const QString& compose);
+    
+    /** 
+     * Resizes the image to a new fixed size of @p new_lines by @p new_columns.  
+     * In the case that @p new_columns is smaller than the current number of columns,
+     * existing lines are not truncated.  This prevents characters from being lost
+     * if the terminal display is resized smaller and then larger again.
+     *
+     * The top and bottom margins are reset to the top and bottom of the new 
+     * screen size.  Tab stops are also reset and the current selection is
+     * cleared.
+     */
+    void resizeImage(int new_lines, int new_columns);
+    
+    /**
+     * Returns the current screen image.  
+     * The result is an array of Characters of size [getLines()][getColumns()] which
+     * must be freed by the caller after use.
+     *
+     * @param dest Buffer to copy the characters into
+     * @param size Size of @p dest in Characters
+     * @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;
+
+    /** 
+     * Returns the additional attributes associated with lines in the image.
+     * The most important attribute is LINE_WRAPPED which specifies that the 
+     * line is wrapped,
+     * other attributes control the size of characters in the line.
+     */
+    QVector<LineProperty> getLineProperties( int startLine , int endLine ) const;
+    
+
+    /** Return the number of lines. */
+    int getLines() const   
+    { return lines; }
+    /** Return the number of columns. */
+    int getColumns() const 
+    { return columns; }
+    /** Return the number of lines in the history buffer. */
+    int getHistLines() const;
+    /** 
+     * Sets the type of storage used to keep lines in the history. 
+     * If @p copyPreviousScroll is true then the contents of the previous 
+     * history buffer are copied into the new scroll.
+     */
+    void setScroll(const HistoryType& , bool copyPreviousScroll = true);
+    /** Returns the type of storage used to keep lines in the history. */
+    const HistoryType& getScroll() const;
+    /** 
+     * Returns true if this screen keeps lines that are scrolled off the screen
+     * in a history buffer.
+     */
+    bool hasScroll() const;
+
+    /** 
+     * Sets the start of the selection.
+     *
+     * @param column The column index of the first character in the selection.
+     * @param line The line index of the first character in the selection.
+     * @param blockSelectionMode True if the selection is in column mode.
+     */
+    void setSelectionStart(const int column, const int line, const bool blockSelectionMode);
+    
+    /**
+     * Sets the end of the current selection.
+     *
+     * @param column The column index of the last character in the selection.
+     * @param line The line index of the last character in the selection. 
+     */ 
+    void setSelectionEnd(const int column, const int line);
+   
+    /**
+     * Retrieves the start of the selection or the cursor position if there
+     * is no selection.
+     */
+    void getSelectionStart(int& column , int& line) const;
+    
+    /**
+     * Retrieves the end of the selection or the cursor position if there
+     * is no selection.
+     */
+    void getSelectionEnd(int& column , int& line) const;
+
+    /** Clears the current selection */
+    void clearSelection();
+
+    /** 
+      *  Returns true if the character at (@p column, @p line) is part of the
+      *  current selection. 
+      */ 
+    bool isSelected(const int column,const int line) const;
+
+    /** 
+     * Convenience method.  Returns the currently selected text. 
+     * @param preserveLineBreaks Specifies whether new line characters should 
+     * be inserted into the returned text at the end of each terminal line.
+     */
+    QString selectedText(bool preserveLineBreaks) const;
+        
+    /**
+     * Copies part of the output to a stream.
+     *
+     * @param decoder A decoder which converts terminal characters into text
+     * @param fromLine The first line in the history to retrieve
+     * @param toLine The last line in the history to retrieve
+     */
+    void writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, int toLine) const;
+
+    /**
+     * Copies the selected characters, set using @see setSelBeginXY and @see setSelExtentXY
+     * into a stream.
+     *
+     * @param decoder A decoder which converts terminal characters into text.  
+     * PlainTextDecoder is the most commonly used decoder which converts characters 
+     * into plain text with no formatting.
+     * @param preserveLineBreaks Specifies whether new line characters should 
+     * be inserted into the returned text at the end of each terminal line. 
+     */
+    void writeSelectionToStream(TerminalCharacterDecoder* decoder , bool
+                                preserveLineBreaks = true) const;
+
+    /**
+     * Checks if the text between from and to is inside the current
+     * selection. If this is the case, the selection is cleared. The
+     * from and to are coordinates in the current viewable window.
+     * The loc(x,y) macro can be used to generate these values from a
+     * column,line pair.
+     *
+     * @param from The start of the area to check.
+     * @param to The end of the area to check
+     */
+    void checkSelection(int from, int to);
+
+    /** 
+     * Sets or clears an attribute of the current line.
+     * 
+     * @param property The attribute to set or clear
+     * Possible properties are:
+     * LINE_WRAPPED:     Specifies that the line is wrapped.
+     * LINE_DOUBLEWIDTH: Specifies that the characters in the current line
+     *                   should be double the normal width.
+     * LINE_DOUBLEHEIGHT:Specifies that the characters in the current line 
+     *                   should be double the normal height.
+     *                   Double-height lines are formed of two lines containing the same characters,
+     *                   with both having the LINE_DOUBLEHEIGHT attribute.
+     *                   This allows other parts of the code to work on the
+     *                   assumption that all lines are the same height.
+     *
+     * @param enable true to apply the attribute to the current line or false to remove it
+     */
+    void setLineProperty(LineProperty property , bool enable);
+
+    /** 
+     * Returns the number of lines that the image has been scrolled up or down by,
+     * since the last call to resetScrolledLines().
+     *
+     * a positive return value indicates that the image has been scrolled up,
+     * 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()
+     */
+    void resetScrolledLines();
+
+    /**
+     * Returns the number of lines of output which have been
+     * dropped from the history since the last call
+     * to resetDroppedLines()
+     *
+     * If the history is not unlimited then it will drop
+     * the oldest lines of output if new lines are added when
+     * it is full.  
+     */
+    int droppedLines() const;
+
+    /**
+     * Resets the count of the number of lines dropped from
+     * the history.
+     */
+    void resetDroppedLines();
+
+    /** 
+      * Fills the buffer @p dest with @p count instances of the default (ie. blank)
+      * Character style.
+      */
+    static void fillWithDefaultChar(Character* dest, int count);
+
+private: 
+
+    //copies a line of text from the screen or history into a stream using a 
+    //specified character decoder.  Returns the number of lines actually copied,
+    //which may be less than 'count' if (start+count) is more than the number of characters on
+    //the line 
+    //
+    //line - the line number to copy, from 0 (the earliest line in the history) up to 
+    //         history->getLines() + lines - 1
+    //start - the first column on the line to copy
+    //count - the number of characters on the line to copy
+    //decoder - a decoder which converts terminal characters (an Character array) into text
+    //appendNewLine - if true a new line character (\n) is appended to the end of the line
+    int  copyLineToStream(int line, 
+                          int start, 
+                          int count, 
+                          TerminalCharacterDecoder* decoder,
+                          bool appendNewLine,
+                          bool preserveLineBreaks) const;
+    
+    //fills a section of the screen image with the character 'c'
+    //the parameters are specified as offsets from the start of the screen image.
+    //the loc(x,y) macro can be used to generate these values from a column,line pair.
+    void clearImage(int loca, int loce, char c);
+
+    //move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'.
+    //the parameters are specified as offsets from the start of the screen image.
+    //the loc(x,y) macro can be used to generate these values from a column,line pair.
+    //
+    //NOTE: moveImage() can only move whole lines
+    void moveImage(int dest, int sourceBegin, int sourceEnd);
+    // scroll up 'i' lines in current region, clearing the bottom 'i' lines 
+    void scrollUp(int from, int i);
+    // scroll down 'i' lines in current region, clearing the top 'i' lines
+    void scrollDown(int from, int i);
+
+    void addHistLine();
+
+    void initTabStops();
+
+    void updateEffectiveRendition();
+    void reverseRendition(Character& p) const;
+
+    bool isSelectionValid() const;
+    // copies text from 'startIndex' to 'endIndex' to a stream
+    // startIndex and endIndex are positions generated using the loc(x,y) macro
+    void writeToStream(TerminalCharacterDecoder* decoder, int startIndex, 
+                       int endIndex, bool preserveLineBreaks = true) 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;
+    // 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;
+
+
+    // screen image ----------------
+    int lines;
+    int columns;
+
+    typedef QVector<Character> ImageLine;      // [0..columns]
+    ImageLine*          screenLines;    // [lines]
+
+    int _scrolledLines;
+    QRect _lastScrolledRegion;
+
+    int _droppedLines;
+
+    QVarLengthArray<LineProperty,64> lineProperties;    
+    
+    // history buffer ---------------
+    HistoryScroll* history;
+    
+    // cursor location
+    int cuX;
+    int cuY;
+
+    // cursor color and rendition info
+    CharacterColor currentForeground;
+    CharacterColor currentBackground;
+    quint8 currentRendition; 
+
+    // margins ----------------
+    int _topMargin;
+    int _bottomMargin;
+
+    // states ----------------
+    int currentModes[MODES_SCREEN];
+    int savedModes[MODES_SCREEN];
+
+    // ----------------------------
+
+    QBitArray tabStops;
+
+    // selection -------------------
+    int selBegin; // The first location selected.
+    int selTopLeft;    // TopLeft Location.
+    int selBottomRight;    // Bottom Right Location.
+    bool blockSelectionMode;  // Column selection mode
+
+    // effective colors and rendition ------------
+    CharacterColor effectiveForeground; // These are derived from
+    CharacterColor effectiveBackground; // the cu_* variables above
+    quint8 effectiveRendition;          // to speed up operation
+
+    class SavedState  
+    {
+    public:
+        SavedState()
+        : cursorColumn(0),cursorLine(0),rendition(0) {}
+
+        int cursorColumn;
+        int cursorLine;
+        quint8 rendition;
+        CharacterColor foreground;
+        CharacterColor background;
+    };
+    SavedState savedState;
+        
+    // last position where we added a character
+    int lastPos;
+
+    static Character defaultChar;
+};
+
+}
+
+#endif // SCREEN_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ScreenWindow.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,294 @@
+/*
+    Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
+
+    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 <KDebug>
+
+// 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 "ScreenWindow.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ScreenWindow.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,259 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef SCREENWINDOW_H
+#define SCREENWINDOW_H
+
+// Qt
+#include <QtCore/QObject>
+#include <QtCore/QPoint>
+#include <QtCore/QRect>
+
+// Konsole
+#include "Character.h"
+
+namespace Konsole
+{
+
+class Screen;
+
+/**
+ * Provides a window onto a section of a terminal screen.  A terminal widget can then render
+ * the contents of the window and use the window to change the terminal screen's selection 
+ * in response to mouse or keyboard input.
+ *
+ * A new ScreenWindow for a terminal session can be created by calling Emulation::createWindow()
+ *
+ * Use the scrollTo() method to scroll the window up and down on the screen.
+ * Use the getImage() method to retrieve the character image which is currently visible in the window.
+ *
+ * setTrackOutput() controls whether the window moves to the bottom of the associated screen when new
+ * lines are added to it.
+ *
+ * Whenever the output from the underlying screen is changed, the notifyOutputChanged() slot should
+ * be called.  This in turn will update the window's position and emit the outputChanged() signal
+ * if necessary.
+ */
+class ScreenWindow : public QObject
+{
+Q_OBJECT
+
+public:
+    /** 
+     * Constructs a new screen window with the given parent.
+     * A screen must be specified by calling setScreen() before calling getImage() or getLineProperties().
+     *
+     * You should not call this constructor directly, instead use the Emulation::createWindow() method
+     * to create a window on the emulation which you wish to view.  This allows the emulation
+     * to notify the window when the associated screen has changed and synchronize selection updates
+     * between all views on a session.
+     */
+    ScreenWindow(QObject* parent = 0);
+    virtual ~ScreenWindow();
+
+    /** Sets the screen which this window looks onto */
+    void setScreen(Screen* screen);
+    /** Returns the screen which this window looks onto */
+    Screen* screen() const;
+
+    /** 
+     * Returns the image of characters which are currently visible through this window
+     * onto the screen.
+     *
+     * The returned buffer is managed by the ScreenWindow instance and does not need to be
+     * deleted by the caller.
+     */
+    Character* getImage();
+
+    /**
+     * Returns the line attributes associated with the lines of characters which
+     * are currently visible through this window
+     */
+    QVector<LineProperty> getLineProperties();
+
+    /**
+     * 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 optimize
+     * rendering by reducing the amount of costly text rendering that
+     * needs to be done when the output is scrolled. 
+     */
+    int scrollCount() const;
+
+    /**
+     * Resets the count of scrolled lines returned by scrollCount()
+     */
+    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 optimize rendering.
+     */
+    QRect scrollRegion() const;
+
+    /** 
+     * Sets the start of the selection to the given @p line and @p column within 
+     * the window.
+     */
+    void setSelectionStart( int column , int line , bool columnMode );
+    /**
+     * Sets the end of the selection to the given @p line and @p column within
+     * the window.
+     */
+    void setSelectionEnd( int column , int line ); 
+    /**
+     * Retrieves the start of the selection within the window.
+     */
+    void getSelectionStart( int& column , int& line );
+    /**
+     * Retrieves the end of the selection within the window.
+     */
+    void getSelectionEnd( int& column , int& line );
+    /**
+     * Returns true if the character at @p line , @p column is part of the selection.
+     */
+    bool isSelected( int column , int line );
+    /** 
+     * Clears the current selection
+     */
+    void clearSelection();
+
+    /** Sets the number of lines in the window */
+    void setWindowLines(int lines);
+    /** Returns the number of lines in the window */
+    int windowLines() const;
+    /** Returns the number of columns in the window */
+    int windowColumns() const;
+    
+    /** Returns the total number of lines in the screen */
+    int lineCount() const;
+    /** Returns the total number of columns in the screen */
+    int columnCount() const;
+
+    /** Returns the index of the line which is currently at the top of this window */
+    int currentLine() const;
+
+    /** 
+     * Returns the position of the cursor 
+     * within the window.
+     */
+    QPoint cursorPosition() const;
+
+    /** 
+     * Convenience method. Returns true if the window is currently at the bottom
+     * of the screen.
+     */
+    bool atEndOfOutput() const;
+
+    /** Scrolls the window so that @p line is at the top of the window */
+    void scrollTo( int line );
+
+    /** Describes the units which scrollBy() moves the window by. */
+    enum RelativeScrollMode
+    {
+        /** Scroll the window down by a given number of lines. */
+        ScrollLines,
+        /** 
+         * Scroll the window down by a given number of pages, where
+         * one page is windowLines() lines
+         */
+        ScrollPages
+    };
+
+    /** 
+     * Scrolls the window relative to its current position on the screen.
+     *
+     * @param mode Specifies whether @p amount refers to the number of lines or the number
+     * of pages to scroll.    
+     * @param amount The number of lines or pages ( depending on @p mode ) to scroll by.  If
+     * this number is positive, the view is scrolled down.  If this number is negative, the view
+     * is scrolled up.
+     */
+    void scrollBy( RelativeScrollMode mode , int amount );
+
+    /** 
+     * Specifies whether the window should automatically move to the bottom
+     * of the screen when new output is added.
+     *
+     * If this is set to true, the window will be moved to the bottom of the associated screen ( see 
+     * screen() ) when the notifyOutputChanged() method is called.
+     */
+    void setTrackOutput(bool trackOutput);
+    /** 
+     * Returns whether the window automatically moves to the bottom of the screen as
+     * new output is added.  See setTrackOutput()
+     */
+    bool trackOutput() const;
+
+    /**
+     * Returns the text which is currently selected.
+     *
+     * @param preserveLineBreaks See Screen::selectedText()
+     */
+    QString selectedText( bool preserveLineBreaks ) const;
+
+public slots:
+    /** 
+     * Notifies the window that the contents of the associated terminal screen have changed.
+     * This moves the window to the bottom of the screen if trackOutput() is true and causes
+     * the outputChanged() signal to be emitted.
+     */
+    void notifyOutputChanged();
+
+signals:
+    /**
+     * Emitted when the contents of the associated terminal screen (see screen()) changes. 
+     */
+    void outputChanged();
+
+    /**
+     * Emitted when the screen window is scrolled to a different position.
+     * 
+     * @param line The line which is now at the top of the window.
+     */
+    void scrolled(int line);
+
+    /** Emitted when the selection is changed. */
+    void selectionChanged();
+
+private:
+    int endWindowLine() const;
+    void fillUnusedArea();
+
+    Screen* _screen; // see setScreen() , screen()
+    Character* _windowBuffer;
+    int _windowBufferSize;
+    bool _bufferNeedsUpdate;
+
+    int  _windowLines;
+    int  _currentLine; // see scrollTo() , currentLine()
+    bool _trackOutput; // see setTrackOutput() , trackOutput() 
+    int  _scrollCount; // count of lines which the window has been scrolled by since
+                       // the last call to resetScrollCount()
+};
+
+}
+#endif // SCREENWINDOW_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Session.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,1411 @@
+/*
+    This file is part of Konsole
+
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+    Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
+
+    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 "Session.h"
+
+// Standard
+#include <assert.h>
+#include <stdlib.h>
+#include <signal.h>
+
+// Qt
+#include <QtGui/QApplication>
+#include <QtCore/QByteRef>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QRegExp>
+#include <QtCore/QStringList>
+//#include <QtDBus/QtDBus>
+#include <QtCore/QDate>
+
+
+// KDE
+//#include <KDebug>
+//#include <KLocale>
+//#include <KMessageBox>
+//#include <KNotification>
+//#include <KProcess>
+//#include <KRun>
+//#include <kshell.h>
+//#include <KStandardDirs>
+//#include <KPtyDevice>
+//#include <KUrl>
+#include "kprocess.h"
+#include "kptydevice.h"
+
+// Konsole
+//#include <config-konsole.h>
+//#include <sessionadaptor.h>
+
+#include "ProcessInfo.h"
+#include "Pty.h"
+#include "TerminalDisplay.h"
+#include "ShellCommand.h"
+#include "Vt102Emulation.h"
+//#include "ZModemDialog.h"
+
+using namespace Konsole;
+
+int Session::lastSessionId = 0;
+
+// HACK This is copied out of QUuid::createUuid with reseeding forced.
+// Required because color schemes repeatedly seed the RNG...
+// ...with a constant.
+QUuid createUuid()
+{
+    static const int intbits = sizeof(int)*8;
+    static int randbits = 0;
+    if (!randbits)
+    {
+        int max = RAND_MAX;
+        do { ++randbits; } while ((max=max>>1));
+    }
+
+    qsrand(uint(QDateTime::currentDateTime().toTime_t()));
+    qrand(); // Skip first
+
+    QUuid result;
+    uint *data = &(result.data1);
+    int chunks = 16 / sizeof(uint);
+    while (chunks--) {
+        uint randNumber = 0;
+        for (int filled = 0; filled < intbits; filled += randbits)
+            randNumber |= qrand()<<filled;
+         *(data+chunks) = randNumber;
+    }
+
+    result.data4[0] = (result.data4[0] & 0x3F) | 0x80;        // UV_DCE
+    result.data3 = (result.data3 & 0x0FFF) | 0x4000;        // UV_Random
+
+    return result;
+}
+
+Session::Session(QObject* parent) :
+   QObject(parent)
+   , _shellProcess(0)
+   , _emulation(0)
+   , _monitorActivity(false)
+   , _monitorSilence(false)
+   , _notifiedActivity(false)
+   , _autoClose(true)
+   , _wantedClose(false)
+   , _silenceSeconds(10)
+   , _addToUtmp(true)  
+   , _flowControl(true)
+   , _fullScripting(false)
+   , _sessionId(0)
+   , _sessionProcessInfo(0)
+   , _foregroundProcessInfo(0)
+   , _foregroundPid(0)
+   //, _zmodemBusy(false)
+   //, _zmodemProc(0)
+   //, _zmodemProgress(0)
+   , _hasDarkBackground(false)
+{
+    _uniqueIdentifier = createUuid();
+
+    //prepare DBus communication
+    //new SessionAdaptor(this);
+    _sessionId = ++lastSessionId;
+    
+    // JPS: commented out for lack of DBUS support by default on OSX
+    //QDBusConnection::sessionBus().registerObject(QLatin1String("/Sessions/")+QString::number(_sessionId), this);
+
+    //create emulation backend
+    _emulation = new Vt102Emulation();
+
+    connect( _emulation, SIGNAL( titleChanged( int, const QString & ) ),
+           this, SLOT( setUserTitle( int, const QString & ) ) );
+    connect( _emulation, SIGNAL( stateSet(int) ),
+           this, SLOT( activityStateSet(int) ) );
+    //connect( _emulation, SIGNAL( zmodemDetected() ), this ,
+    //        SLOT( fireZModemDetected() ) );
+    connect( _emulation, SIGNAL( changeTabTextColorRequest( int ) ),
+           this, SIGNAL( changeTabTextColorRequest( int ) ) );
+    connect( _emulation, SIGNAL(profileChangeCommandReceived(const QString&)),
+           this, SIGNAL( profileChangeCommandReceived(const QString&)) );
+    connect( _emulation, SIGNAL(flowControlKeyPressed(bool)) , this, 
+             SLOT(updateFlowControlState(bool)) );
+
+    //create new teletype for I/O with shell process
+    openTeletype(-1);
+
+    //setup timer for monitoring session activity
+    _monitorTimer = new QTimer(this);
+    _monitorTimer->setSingleShot(true);
+    connect(_monitorTimer, SIGNAL(timeout()), this, SLOT(monitorTimerDone()));
+}
+
+void Session::openTeletype(int fd)
+{
+    if (_shellProcess && isRunning())
+    {
+        kWarning() << "Attempted to open teletype in a running session.";
+        return;
+    }
+
+    delete _shellProcess;
+
+    if (fd < 0)
+        _shellProcess = new Pty();
+    else
+        _shellProcess = new Pty(fd);
+
+    _shellProcess->setUtf8Mode(_emulation->utf8());
+
+    //connect teletype to emulation backend
+    connect( _shellProcess,SIGNAL(receivedData(const char*,int)),this,
+            SLOT(onReceiveBlock(const char*,int)) );
+    connect( _emulation,SIGNAL(sendData(const char*,int)),_shellProcess,
+            SLOT(sendData(const char*,int)) );
+    connect( _emulation,SIGNAL(lockPtyRequest(bool)),_shellProcess,SLOT(lockPty(bool)) );
+    connect( _emulation,SIGNAL(useUtf8Request(bool)),_shellProcess,SLOT(setUtf8Mode(bool)) );
+    connect( _shellProcess,SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(done(int)) );
+    connect( _emulation,SIGNAL(imageSizeChanged(int,int)),this,SLOT(updateWindowSize(int,int)) );
+}
+
+WId Session::windowId() const
+{
+    // Returns a window ID for this session which is used
+    // to set the WINDOWID environment variable in the shell
+    // process.
+    //
+    // Sessions can have multiple views or no views, which means
+    // that a single ID is not always going to be accurate.
+    //
+    // If there are no views, the window ID is just 0.  If
+    // there are multiple views, then the window ID for the
+    // top-level window which contains the first view is
+    // returned
+
+    if ( _views.count() == 0 )
+       return 0;
+    else
+    {
+        QWidget* window = _views.first();
+
+        Q_ASSERT( window );
+
+        while ( window->parentWidget() != 0 )
+            window = window->parentWidget();
+
+        return window->winId();
+    }
+}
+
+void Session::setDarkBackground(bool darkBackground)
+{
+    _hasDarkBackground = darkBackground;
+}
+bool Session::hasDarkBackground() const
+{
+    return _hasDarkBackground;
+}
+bool Session::isRunning() const
+{
+    return _shellProcess->state() == QProcess::Running;
+}
+
+void Session::setCodec(QTextCodec* codec)
+{
+    emulation()->setCodec(codec);
+}
+
+bool Session::setCodec(QByteArray name)
+{
+    QTextCodec *codec = QTextCodec::codecForName(name);
+    if (codec) {
+        setCodec(codec);
+        return true;
+    }
+    return false;
+}
+
+QByteArray Session::codec()
+{
+    return _emulation->codec()->name();
+}
+
+void Session::setProgram(const QString& program)
+{
+    _program = ShellCommand::expand(program);
+}
+void Session::setInitialWorkingDirectory(const QString& dir)
+{
+  //_initialWorkingDir = KShell::tildeExpand(ShellCommand::expand(dir));
+  _initialWorkingDir = ShellCommand::expand(dir);
+}
+void Session::setArguments(const QStringList& arguments)
+{
+    _arguments = ShellCommand::expand(arguments);
+}
+
+QString Session::currentWorkingDirectory()
+{
+    // only returned cached value
+    if (_currentWorkingDir.isEmpty()) updateWorkingDirectory();
+    return _currentWorkingDir;
+}
+ProcessInfo* Session::updateWorkingDirectory()
+{
+    ProcessInfo *process = getProcessInfo();
+    _currentWorkingDir = process->validCurrentDir();
+    return process;
+}
+
+QList<TerminalDisplay*> Session::views() const
+{
+    return _views;
+}
+
+void Session::addView(TerminalDisplay* widget)
+{
+     Q_ASSERT( !_views.contains(widget) );
+
+    _views.append(widget);
+
+    if ( _emulation != 0 )
+    {
+        // connect emulation - view signals and slots
+        connect( widget , SIGNAL(keyPressedSignal(QKeyEvent*)) , _emulation ,
+               SLOT(sendKeyEvent(QKeyEvent*)) );
+        connect( widget , SIGNAL(mouseSignal(int,int,int,int)) , _emulation ,
+               SLOT(sendMouseEvent(int,int,int,int)) );
+        connect( widget , SIGNAL(sendStringToEmu(const char*)) , _emulation ,
+               SLOT(sendString(const char*)) );
+
+        // allow emulation to notify view when the foreground process
+        // indicates whether or not it is interested in mouse signals
+        connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
+               SLOT(setUsesMouse(bool)) );
+
+        widget->setUsesMouse( _emulation->programUsesMouse() );
+
+        widget->setScreenWindow(_emulation->createWindow());
+    }
+
+    //connect view signals and slots
+    QObject::connect( widget ,SIGNAL(changedContentSizeSignal(int,int)),this,
+                    SLOT(onViewSizeChange(int,int)));
+
+    QObject::connect( widget ,SIGNAL(destroyed(QObject*)) , this ,
+                    SLOT(viewDestroyed(QObject*)) );
+}
+
+void Session::viewDestroyed(QObject* view)
+{
+    TerminalDisplay* display = (TerminalDisplay*)view;
+
+    Q_ASSERT( _views.contains(display) );
+
+    removeView(display);
+}
+
+void Session::removeView(TerminalDisplay* widget)
+{
+    _views.removeAll(widget);
+
+    disconnect(widget,0,this,0);
+
+    if ( _emulation != 0 )
+    {
+        // disconnect
+        //  - key presses signals from widget
+        //  - mouse activity signals from widget
+        //  - string sending signals from widget
+        //
+        //  ... and any other signals connected in addView()
+        disconnect( widget, 0, _emulation, 0);
+
+        // disconnect state change signals emitted by emulation
+        disconnect( _emulation , 0 , widget , 0);
+    }
+
+    // close the session automatically when the last view is removed
+    if ( _views.count() == 0 )
+    {
+        close();
+    }
+}
+
+QString Session::checkProgram(const QString& program) const
+{
+  // Upon a KPty error, there is no description on what that error was...
+  // Check to see if the given program is executable.
+  QString exec = QFile::encodeName(program);
+
+  if (exec.isEmpty())
+      return QString();
+
+  // if 'exec' is not specified, fall back to default shell.  if that 
+  // is not set then fall back to /bin/sh
+  if ( exec.isEmpty() )
+      exec = qgetenv("SHELL");
+  if ( exec.isEmpty() )
+        exec = "/bin/sh";
+
+  // JPS: commented out to get rid of KShell and KRun
+  /*
+  exec = KRun::binaryName(exec, false);
+  exec = KShell::tildeExpand(exec);
+  QString pexec = KGlobal::dirs()->findExe(exec);
+  if ( pexec.isEmpty() ) 
+  {
+      kError() << i18n("Could not find binary: ") << exec;
+    return QString();
+  }
+
+  return exec;
+  */
+  return program;
+}
+
+void Session::terminalWarning(const QString& message)
+{
+  //static const QByteArray warningText = i18nc("@info:shell Alert the user with red color text", "Warning: ").toLocal8Bit(); 
+  static const QByteArray warningText = i18nc("@info:shell Alert the user with red color text", "Warning: "); 
+    QByteArray messageText = message.toLocal8Bit();
+
+    static const char redPenOn[] = "\033[1m\033[31m";
+    static const char redPenOff[] = "\033[0m";
+
+    _emulation->receiveData(redPenOn,strlen(redPenOn));
+    _emulation->receiveData("\n\r\n\r",4);
+    _emulation->receiveData(warningText.constData(),strlen(warningText.constData()));
+    _emulation->receiveData(messageText.constData(),strlen(messageText.constData()));
+    _emulation->receiveData("\n\r\n\r",4);
+    _emulation->receiveData(redPenOff,strlen(redPenOff));
+}
+
+QString Session::shellSessionId() const
+{
+    QString friendlyUuid(_uniqueIdentifier.toString());
+    friendlyUuid.remove('-').remove('{').remove('}');
+
+    return friendlyUuid;
+}
+
+void Session::run()
+{
+  //check that everything is in place to run the session
+  if (_program.isEmpty())
+  {
+      kWarning() << "Session::run() - program to run not set.";
+  }
+  if (_arguments.isEmpty())
+  {
+      kWarning() << "Session::run() - no command line arguments specified.";
+  }
+  if (_uniqueIdentifier.isNull())
+  {
+      _uniqueIdentifier = createUuid();
+  }
+
+  const int CHOICE_COUNT = 3;
+  QString programs[CHOICE_COUNT] = {_program,qgetenv("SHELL"),"/bin/sh"};
+  QString exec;
+  int choice = 0;
+  while (choice < CHOICE_COUNT)
+  {
+    exec = checkProgram(programs[choice]);
+    if (exec.isEmpty())
+        choice++;
+    else
+        break;
+  }
+
+  // if a program was specified via setProgram(), but it couldn't be found, print a warning
+  if (choice != 0 && choice < CHOICE_COUNT && !_program.isEmpty())
+  {
+    terminalWarning(i18n("Could not find '%1', starting '%2' instead.  Please check your profile settings.",_program.toLatin1().data(),exec.toLatin1().data())); 
+  }
+  // if none of the choices are available, print a warning
+  else if (choice == CHOICE_COUNT)
+  {
+      terminalWarning(i18n("Could not find an interactive shell to start."));
+      return;
+  }
+  
+  // if no arguments are specified, fall back to program name
+  QStringList arguments = _arguments.join(QChar(' ')).isEmpty() ?
+                                                   QStringList() << exec : _arguments;
+
+  // JPS: commented out for lack of DBUS support by default on OSX
+  QString dbusService = ""; //QDBusConnection::sessionBus().baseService();
+  if (!_initialWorkingDir.isEmpty())
+    _shellProcess->setWorkingDirectory(_initialWorkingDir);
+  else
+    _shellProcess->setWorkingDirectory(QDir::homePath());
+
+  _shellProcess->setFlowControlEnabled(_flowControl);
+  _shellProcess->setErase(_emulation->eraseChar());
+
+  // this is not strictly accurate use of the COLORFGBG variable.  This does not
+  // tell the terminal exactly which colors are being used, but instead approximates
+  // the color scheme as "black on white" or "white on black" depending on whether
+  // the background color is deemed dark or not
+  QString backgroundColorHint = _hasDarkBackground ? "COLORFGBG=15;0" : "COLORFGBG=0;15";
+  _environment << backgroundColorHint;
+  _environment << QString("SHELL_SESSION_ID=%1").arg(shellSessionId());
+
+  int result = _shellProcess->start(exec,
+                                  arguments,
+                                  _environment,
+                                  windowId(),
+                                  _addToUtmp,
+                                  dbusService,
+                                  (QLatin1String("/Sessions/") +
+                                   QString::number(_sessionId)));
+
+  if (result < 0)
+  {
+      terminalWarning(i18n("Could not start program '%1' with arguments '%2'.", exec.toLatin1().data(), arguments.join(" ").toLatin1().data()));
+    std::cout << "ERROR: " << exec.toLatin1().data();
+    return;
+  }
+
+  _shellProcess->setWriteable(false);  // We are reachable via kwrited.
+
+  emit started();
+}
+
+void Session::setUserTitle( int what, const QString &caption )
+{
+    //set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle )
+    bool modified = false;
+
+    if ((what == IconNameAndWindowTitle) || (what == WindowTitle)) 
+    {
+           if ( _userTitle != caption ) {
+            _userTitle = caption;
+            modified = true;
+        }
+    }
+
+    if ((what == IconNameAndWindowTitle) || (what == IconName))
+    {
+        if ( _iconText != caption ) {
+               _iconText = caption;
+            modified = true;
+        }
+    }
+
+    if (what == TextColor || what == BackgroundColor) 
+    {
+      QString colorString = caption.section(';',0,0);
+      QColor color = QColor(colorString);
+      if (color.isValid())
+      {
+          if (what == TextColor)
+                  emit changeForegroundColorRequest(color);
+          else
+                  emit changeBackgroundColorRequest(color);
+      }
+    }
+
+    if (what == SessionName) 
+    {
+        if ( _nameTitle != caption ) {
+               setTitle(Session::NameRole,caption);
+            return;
+        }
+    }
+
+    if (what == 31) 
+    {
+       QString cwd=caption;
+       cwd=cwd.replace( QRegExp("^~"), QDir::homePath() );
+       emit openUrlRequest(cwd);
+    }
+
+    // change icon via \033]32;Icon\007
+    if (what == 32) 
+    { 
+        if ( _iconName != caption ) {
+               _iconName = caption;
+
+            modified = true;
+        }
+    }
+
+    if (what == ProfileChange) 
+    {
+        emit profileChangeCommandReceived(caption);
+        return;
+    }
+
+    if ( modified )
+        emit titleChanged();
+}
+
+QString Session::userTitle() const
+{
+    return _userTitle;
+}
+void Session::setTabTitleFormat(TabTitleContext context , const QString& format)
+{
+    if ( context == LocalTabTitle )
+        _localTabTitleFormat = format;
+    else if ( context == RemoteTabTitle )
+        _remoteTabTitleFormat = format;
+}
+QString Session::tabTitleFormat(TabTitleContext context) const
+{
+    if ( context == LocalTabTitle )
+        return _localTabTitleFormat;
+    else if ( context == RemoteTabTitle )
+        return _remoteTabTitleFormat;
+
+    return QString();
+}
+
+void Session::monitorTimerDone()
+{
+  //FIXME: The idea here is that the notification popup will appear to tell the user than output from
+  //the terminal has stopped and the popup will disappear when the user activates the session.
+  //
+  //This breaks with the addition of multiple views of a session.  The popup should disappear
+  //when any of the views of the session becomes active
+  
+
+  //FIXME: Make message text for this notification and the activity notification more descriptive.    
+  if (_monitorSilence) {
+    //KNotification::event("Silence", i18n("Silence in session '%1'", _nameTitle), QPixmap(),
+    //                QApplication::activeWindow(),
+    //                KNotification::CloseWhenWidgetActivated);
+    emit stateChanged(NOTIFYSILENCE);
+  }
+  else
+  {
+    emit stateChanged(NOTIFYNORMAL);
+  }
+
+  _notifiedActivity=false;
+}
+void Session::updateFlowControlState(bool suspended)
+{
+    if (suspended)
+    {
+        if (flowControlEnabled())
+        {
+            foreach(TerminalDisplay* display,_views)
+            {
+                if (display->flowControlWarningEnabled())
+                    display->outputSuspended(true);
+            }
+        }
+    } 
+    else
+    {
+        foreach(TerminalDisplay* display,_views)
+            display->outputSuspended(false);
+    }   
+}
+void Session::activityStateSet(int state)
+{
+  if (state==NOTIFYBELL)
+  {
+      emit bellRequest( i18n("Bell in session '%1'",_nameTitle.toLatin1().data()) );
+  }
+  else if (state==NOTIFYACTIVITY)
+  {
+    if (_monitorSilence) {
+      _monitorTimer->start(_silenceSeconds*1000);
+    }
+
+    if ( _monitorActivity ) {
+      //FIXME:  See comments in Session::monitorTimerDone()
+      if (!_notifiedActivity) {
+        //KNotification::event("Activity", i18n("Activity in session '%1'", _nameTitle), QPixmap(),
+        //                QApplication::activeWindow(),
+        //KNotification::CloseWhenWidgetActivated);
+        _notifiedActivity=true;
+      }
+    }
+  }
+
+  if ( state==NOTIFYACTIVITY && !_monitorActivity )
+          state = NOTIFYNORMAL;
+  if ( state==NOTIFYSILENCE && !_monitorSilence )
+          state = NOTIFYNORMAL;
+
+  emit stateChanged(state);
+}
+
+void Session::onViewSizeChange(int /*height*/, int /*width*/)
+{
+  updateTerminalSize();
+}
+
+void Session::updateTerminalSize()
+{
+    QListIterator<TerminalDisplay*> viewIter(_views);
+
+    int minLines = -1;
+    int minColumns = -1;
+
+    // minimum number of lines and columns that views require for
+    // their size to be taken into consideration ( to avoid problems
+    // with new view widgets which haven't yet been set to their correct size )
+    const int VIEW_LINES_THRESHOLD = 2;
+    const int VIEW_COLUMNS_THRESHOLD = 2;
+
+    //select largest number of lines and columns that will fit in all visible views
+    while ( viewIter.hasNext() )
+    {
+        TerminalDisplay* view = viewIter.next();
+        if ( view->isHidden() == false &&
+             view->lines() >= VIEW_LINES_THRESHOLD &&
+             view->columns() >= VIEW_COLUMNS_THRESHOLD )
+        {
+            minLines = (minLines == -1) ? view->lines() : qMin( minLines , view->lines() );
+            minColumns = (minColumns == -1) ? view->columns() : qMin( minColumns , view->columns() );
+            view->processFilters();
+        }
+    }
+
+    // backend emulation must have a _terminal of at least 1 column x 1 line in size
+    if ( minLines > 0 && minColumns > 0 )
+    {
+        _emulation->setImageSize( minLines , minColumns );
+    }
+}
+void Session::updateWindowSize(int lines, int columns)
+{
+    Q_ASSERT(lines > 0 && columns > 0);
+    _shellProcess->setWindowSize(lines,columns);
+}
+void Session::refresh()
+{
+    // attempt to get the shell process to redraw the display
+    //
+    // this requires the program running in the shell
+    // to cooperate by sending an update in response to
+    // a window size change
+    //
+    // the window size is changed twice, first made slightly larger and then
+    // resized back to its normal size so that there is actually a change
+    // in the window size (some shells do nothing if the
+    // new and old sizes are the same)
+    //
+    // if there is a more 'correct' way to do this, please
+    // send an email with method or patches to konsole-devel@kde.org
+
+    const QSize existingSize = _shellProcess->windowSize();
+    _shellProcess->setWindowSize(existingSize.height(),existingSize.width()+1);
+    _shellProcess->setWindowSize(existingSize.height(),existingSize.width());
+}
+
+bool Session::kill(int signal)
+{
+    int result = ::kill(_shellProcess->pid(),signal);    
+    
+    if ( result == 0 )
+    {
+        _shellProcess->waitForFinished();
+        return true;
+    }
+    else
+        return false;
+}
+
+void Session::close()
+{
+  _autoClose = true;
+  _wantedClose = true;
+
+  if (!isRunning() || !kill(SIGHUP))
+  {
+     if (isRunning())
+     {
+        kWarning() << "Process" << _shellProcess->pid() << "did not respond to SIGHUP";
+
+        // close the pty and wait to see if the process finishes.  If it does,
+        // the done() slot will have been called so we can return.  Otherwise,
+        // emit the finished() signal regardless
+        _shellProcess->pty()->close();
+        if (_shellProcess->waitForFinished(3000))
+            return;
+
+        kWarning() << "Unable to kill process" << _shellProcess->pid();
+     }
+
+     // Forced close.
+     QTimer::singleShot(1, this, SIGNAL(finished()));
+  }
+}
+
+void Session::sendText(const QString &text) const
+{
+  _emulation->sendText(text);
+}
+
+void Session::sendMouseEvent(int buttons, int column, int line, int eventType)
+{
+    _emulation->sendMouseEvent(buttons, column, line, eventType);
+}
+
+Session::~Session()
+{
+  if (_foregroundProcessInfo)
+      delete _foregroundProcessInfo;
+  if (_sessionProcessInfo)
+      delete _sessionProcessInfo;
+  delete _emulation;
+  delete _shellProcess;
+  //delete _zmodemProc;
+}
+
+void Session::done(int exitStatus)
+{
+  if (!_autoClose)
+  {
+    _userTitle = i18n("@info:shell This session is done", "Finished");
+    emit titleChanged();
+    return;
+  }
+
+  QString message;
+  if (!_wantedClose || exitStatus != 0)
+  {
+    if (_shellProcess->exitStatus() == QProcess::NormalExit)
+        message = i18n("Program '%1' exited with status %2.", _program.toLatin1().data(), exitStatus);
+    else
+        message = i18n("Program '%1' crashed.", _program.toLatin1().data());
+
+    //FIXME: See comments in Session::monitorTimerDone()
+    //KNotification::event("Finished", message , QPixmap(),
+    //                     QApplication::activeWindow(),
+    //                     KNotification::CloseWhenWidgetActivated);
+  }
+
+  if ( !_wantedClose && _shellProcess->exitStatus() != QProcess::NormalExit )
+      terminalWarning(message);
+  else
+        emit finished();
+}
+
+Emulation* Session::emulation() const
+{
+  return _emulation;
+}
+
+QString Session::keyBindings() const
+{
+  return _emulation->keyBindings();
+}
+
+QStringList Session::environment() const
+{
+  return _environment;
+}
+
+void Session::setEnvironment(const QStringList& environment)
+{
+    _environment = environment;
+}
+
+int Session::sessionId() const
+{
+  return _sessionId;
+}
+
+void Session::setKeyBindings(const QString &id)
+{
+  _emulation->setKeyBindings(id);
+}
+
+void Session::setTitle(TitleRole role , const QString& newTitle)
+{
+    if ( title(role) != newTitle )
+    {
+        if ( role == NameRole )
+            _nameTitle = newTitle;
+        else if ( role == DisplayedTitleRole )
+            _displayTitle = newTitle;
+
+        emit titleChanged();
+    }
+}
+
+QString Session::title(TitleRole role) const
+{
+    if ( role == NameRole )
+        return _nameTitle;
+    else if ( role == DisplayedTitleRole )
+        return _displayTitle;
+    else
+        return QString();
+}
+
+ProcessInfo* Session::getProcessInfo()
+{
+    ProcessInfo* process;
+
+    if (isForegroundProcessActive())
+        process = _foregroundProcessInfo;
+    else
+    {
+        updateSessionProcessInfo();
+        process = _sessionProcessInfo;
+    }
+
+    return process;
+}
+
+void Session::updateSessionProcessInfo()
+{
+    Q_ASSERT(_shellProcess);
+    if (!_sessionProcessInfo)
+    {
+        _sessionProcessInfo = ProcessInfo::newInstance(processId());
+        _sessionProcessInfo->setUserHomeDir();
+    }
+    _sessionProcessInfo->update();
+}
+
+bool Session::updateForegroundProcessInfo()
+{
+    bool valid = (_foregroundProcessInfo != 0);
+
+    // has foreground process changed?
+    Q_ASSERT(_shellProcess);
+    int pid = _shellProcess->foregroundProcessGroup();
+    if (pid != _foregroundPid)
+    {
+        if (valid)
+            delete _foregroundProcessInfo;
+        _foregroundProcessInfo = ProcessInfo::newInstance(pid);
+        _foregroundPid = pid;
+        valid = true;
+    }
+
+    if (valid)
+    {
+        _foregroundProcessInfo->update();
+        valid = _foregroundProcessInfo->isValid();
+    }
+
+    return valid;
+}
+
+bool Session::isRemote()
+{
+    ProcessInfo* process = getProcessInfo();
+
+    bool ok = false;
+    return ( process->name(&ok) == "ssh" && ok );
+}
+
+QString Session::getDynamicTitle()
+{
+    // update current directory from process
+    ProcessInfo* process = updateWorkingDirectory();
+
+    // format tab titles using process info
+    bool ok = false;
+    QString title;
+    if ( process->name(&ok) == "ssh" && ok )
+    {
+        SSHProcessInfo sshInfo(*process);
+        title = sshInfo.format(tabTitleFormat(Session::RemoteTabTitle));
+    }
+    else
+        title = process->format(tabTitleFormat(Session::LocalTabTitle));
+
+    return title;
+}
+
+/*
+KUrl Session::getUrl()
+{
+    QString path;
+    
+    updateSessionProcessInfo();
+    if (_sessionProcessInfo->isValid())
+    {
+        bool ok = false;
+
+        // check if foreground process is bookmark-able
+        if (isForegroundProcessActive())
+        {
+            // for remote connections, save the user and host
+            // bright ideas to get the directory at the other end are welcome :)
+            if (_foregroundProcessInfo->name(&ok) == "ssh" && ok)
+            {
+                SSHProcessInfo sshInfo(*_foregroundProcessInfo);
+                path = "ssh://" + sshInfo.userName() + '@' + sshInfo.host();
+            }
+            else
+            {
+                path = _foregroundProcessInfo->currentDir(&ok);
+                if (!ok)
+                    path.clear();
+            }
+        }
+        else // otherwise use the current working directory of the shell process
+        {
+            path = _sessionProcessInfo->currentDir(&ok);
+            if (!ok)
+                path.clear();
+        }
+    }
+
+    return KUrl(path);
+}
+*/
+
+void Session::setIconName(const QString& iconName)
+{
+    if ( iconName != _iconName )
+    {
+        _iconName = iconName;
+        emit titleChanged();
+    }
+}
+
+void Session::setIconText(const QString& iconText)
+{
+  _iconText = iconText;
+}
+
+QString Session::iconName() const
+{
+  return _iconName;
+}
+
+QString Session::iconText() const
+{
+  return _iconText;
+}
+
+void Session::setHistoryType(const HistoryType &hType)
+{
+  _emulation->setHistory(hType);
+}
+
+const HistoryType& Session::historyType() const
+{
+  return _emulation->history();
+}
+
+void Session::clearHistory()
+{
+    _emulation->clearHistory();
+}
+
+QStringList Session::arguments() const
+{
+  return _arguments;
+}
+
+QString Session::program() const
+{
+  return _program;
+}
+
+// unused currently
+bool Session::isMonitorActivity() const { return _monitorActivity; }
+// unused currently
+bool Session::isMonitorSilence()  const { return _monitorSilence; }
+
+void Session::setMonitorActivity(bool _monitor)
+{
+  _monitorActivity=_monitor;
+  _notifiedActivity=false;
+
+  activityStateSet(NOTIFYNORMAL);
+}
+
+void Session::setMonitorSilence(bool _monitor)
+{
+  if (_monitorSilence==_monitor)
+    return;
+
+  _monitorSilence=_monitor;
+  if (_monitorSilence)
+  {
+    _monitorTimer->start(_silenceSeconds*1000);
+  }
+  else
+    _monitorTimer->stop();
+
+  activityStateSet(NOTIFYNORMAL);
+}
+
+void Session::setMonitorSilenceSeconds(int seconds)
+{
+  _silenceSeconds=seconds;
+  if (_monitorSilence) {
+    _monitorTimer->start(_silenceSeconds*1000);
+  }
+}
+
+void Session::setAddToUtmp(bool set)
+{
+  _addToUtmp = set;
+}
+
+void Session::setFlowControlEnabled(bool enabled)
+{
+  _flowControl = enabled;
+
+  if (_shellProcess)  
+    _shellProcess->setFlowControlEnabled(_flowControl);
+  emit flowControlEnabledChanged(enabled);
+}
+bool Session::flowControlEnabled() const
+{
+    if (_shellProcess)
+            return _shellProcess->flowControlEnabled();
+    else
+            return _flowControl;
+}
+
+/*
+void Session::fireZModemDetected()
+{
+  if (!_zmodemBusy)
+  {
+    QTimer::singleShot(10, this, SIGNAL(zmodemDetected()));
+    _zmodemBusy = true;
+  }
+}
+
+void Session::cancelZModem()
+{
+  _shellProcess->sendData("\030\030\030\030", 4); // Abort
+  _zmodemBusy = false;
+}
+
+void Session::startZModem(const QString &zmodem, const QString &dir, const QStringList &list)
+{
+  _zmodemBusy = true;
+  _zmodemProc = new KProcess();
+  _zmodemProc->setOutputChannelMode( KProcess::SeparateChannels );
+
+  *_zmodemProc << zmodem << "-v" << list;
+
+  if (!dir.isEmpty())
+     _zmodemProc->setWorkingDirectory(dir);
+
+  connect(_zmodemProc,SIGNAL (readyReadStandardOutput()),
+          this, SLOT(zmodemReadAndSendBlock()));
+  connect(_zmodemProc,SIGNAL (readyReadStandardError()),
+          this, SLOT(zmodemReadStatus()));
+  connect(_zmodemProc,SIGNAL (finished(int,QProcess::ExitStatus)),
+          this, SLOT(zmodemFinished()));
+
+  _zmodemProc->start();
+  
+  disconnect( _shellProcess,SIGNAL(receivedData(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
+  connect( _shellProcess,SIGNAL(receivedData(const char*,int)), this, SLOT(zmodemRcvBlock(const char*,int)) );
+
+  _zmodemProgress = new ZModemDialog(QApplication::activeWindow(), false,
+                                    i18n("ZModem Progress"));
+
+  connect(_zmodemProgress, SIGNAL(user1Clicked()),
+          this, SLOT(zmodemFinished()));
+
+  _zmodemProgress->show();
+}
+
+void Session::zmodemReadAndSendBlock()
+{
+  _zmodemProc->setReadChannel( QProcess::StandardOutput );
+  QByteArray data = _zmodemProc->readAll();
+
+  if ( data.count() == 0 )
+      return;
+
+  _shellProcess->sendData(data.constData(),data.count());
+}
+
+void Session::zmodemReadStatus()
+{
+  _zmodemProc->setReadChannel( QProcess::StandardError );
+  QByteArray msg = _zmodemProc->readAll();
+  while(!msg.isEmpty())
+  {
+     int i = msg.indexOf('\015');
+     int j = msg.indexOf('\012');
+     QByteArray txt;
+     if ((i != -1) && ((j == -1) || (i < j)))
+     {
+       msg = msg.mid(i+1);
+     }
+     else if (j != -1)
+     {
+       txt = msg.left(j);
+       msg = msg.mid(j+1);
+     }
+     else
+     {
+       txt = msg;
+       msg.truncate(0);
+     }
+     if (!txt.isEmpty())
+       _zmodemProgress->addProgressText(QString::fromLocal8Bit(txt));
+  }
+}
+
+void Session::zmodemRcvBlock(const char *data, int len)
+{
+  QByteArray ba( data, len );
+
+  _zmodemProc->write( ba );
+}
+
+void Session::zmodemFinished()
+{
+  // zmodemFinished() is called by QProcess's finished() and
+  //    ZModemDialog's user1Clicked(). Therefore, an invocation by
+  //    user1Clicked() will recursively invoke this function again
+  //    when the KProcess is deleted!
+  if (_zmodemProc) {
+    KProcess* process = _zmodemProc;
+    _zmodemProc = 0;   // Set _zmodemProc to 0 avoid recursive invocations!
+    _zmodemBusy = false;
+    delete process;    // Now, the KProcess may be disposed safely.
+
+    disconnect( _shellProcess,SIGNAL(receivedData(const char*,int)), this ,SLOT(zmodemRcvBlock(const char*,int)) );
+    connect( _shellProcess,SIGNAL(receivedData(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
+
+    _shellProcess->sendData("\030\030\030\030", 4); // Abort
+    _shellProcess->sendData("\001\013\n", 3); // Try to get prompt back
+    _zmodemProgress->transferDone();
+  }
+}
+*/
+
+void Session::onReceiveBlock( const char* buf, int len )
+{
+    _emulation->receiveData( buf, len );
+    emit receivedData( QString::fromLatin1( buf, len ) );
+}
+
+QSize Session::size()
+{
+  return _emulation->imageSize();
+}
+
+void Session::setSize(const QSize& size)
+{
+  if ((size.width() <= 1) || (size.height() <= 1))
+     return;
+
+  emit resizeRequest(size);
+}
+int Session::processId() const
+{
+    return _shellProcess->pid();
+}
+
+void Session::setTitle(int role , const QString& title)
+{
+    switch (role) {
+    case (0):
+        this->setTitle(Session::NameRole, title);
+        break;
+    case (1):
+        this->setTitle(Session::DisplayedTitleRole, title);
+        break;
+    }
+}
+
+QString Session::title(int role) const
+{
+    switch (role) {
+    case (0):
+        return this->title(Session::NameRole);
+    case (1):
+        return this->title(Session::DisplayedTitleRole);
+    default:
+        return QString();
+    }
+}
+
+void Session::setTabTitleFormat(int context , const QString& format)
+{
+    switch (context) {
+    case (0):
+        this->setTabTitleFormat(Session::LocalTabTitle, format);
+        break;
+    case (1):
+        this->setTabTitleFormat(Session::RemoteTabTitle, format);
+        break;
+    }
+}
+
+QString Session::tabTitleFormat(int context) const
+{
+    switch (context) {
+    case (0):
+        return this->tabTitleFormat(Session::LocalTabTitle);
+    case (1):
+        return this->tabTitleFormat(Session::RemoteTabTitle);
+    default:
+        return QString();
+    }
+}
+
+int Session::foregroundProcessId()
+{
+    int pid;
+
+    bool ok = false;
+    pid = getProcessInfo()->pid(&ok);
+    if (!ok)
+        pid = -1;
+
+    return pid;
+}
+
+bool Session::isForegroundProcessActive()
+{
+    // foreground process info is always updated after this
+    return updateForegroundProcessInfo() && (processId() != _foregroundPid);
+}
+
+QString Session::foregroundProcessName()
+{
+    QString name;
+
+    if (updateForegroundProcessInfo()) 
+    {
+        bool ok = false;
+        name = _foregroundProcessInfo->name(&ok);
+        if (!ok)
+            name.clear();
+    }
+
+    return name;
+}
+
+/*
+void Session::saveSession(KConfigGroup& group)
+{
+    group.writePathEntry("WorkingDir", currentWorkingDirectory());
+    group.writeEntry("LocalTab",       tabTitleFormat(LocalTabTitle));
+    group.writeEntry("RemoteTab",      tabTitleFormat(RemoteTabTitle));
+    group.writeEntry("SessionGuid",    _uniqueIdentifier.toString());
+    group.writeEntry("Encoding",       QString(codec()));
+}
+
+void Session::restoreSession(KConfigGroup& group)
+{
+    QString value;
+
+    value = group.readPathEntry("WorkingDir", QString());
+    if (!value.isEmpty()) setInitialWorkingDirectory(value);
+    value = group.readEntry("LocalTab");
+    if (!value.isEmpty()) setTabTitleFormat(LocalTabTitle, value);
+    value = group.readEntry("RemoteTab");
+    if (!value.isEmpty()) setTabTitleFormat(RemoteTabTitle, value);
+    value = group.readEntry("SessionGuid");
+    if (!value.isEmpty()) _uniqueIdentifier = QUuid(value);
+    value = group.readEntry("Encoding");
+    if (!value.isEmpty()) setCodec(value.toUtf8());
+}
+*/
+
+SessionGroup::SessionGroup(QObject* parent)
+    : QObject(parent), _masterMode(0)
+{
+}
+SessionGroup::~SessionGroup()
+{
+}
+int SessionGroup::masterMode() const { return _masterMode; }
+QList<Session*> SessionGroup::sessions() const { return _sessions.keys(); }
+bool SessionGroup::masterStatus(Session* session) const { return _sessions[session]; }
+
+void SessionGroup::addSession(Session* session)
+{
+    connect(session,SIGNAL(finished()),this,SLOT(sessionFinished()));
+    _sessions.insert(session,false);
+}
+void SessionGroup::removeSession(Session* session)
+{
+    disconnect(session,SIGNAL(finished()),this,SLOT(sessionFinished()));
+    setMasterStatus(session,false);
+    _sessions.remove(session);
+}
+void SessionGroup::sessionFinished()
+{
+    Session* session = qobject_cast<Session*>(sender());
+    Q_ASSERT(session);
+    removeSession(session);
+}
+void SessionGroup::setMasterMode(int mode)
+{
+   _masterMode = mode;
+}
+QList<Session*> SessionGroup::masters() const
+{
+    return _sessions.keys(true);
+}
+void SessionGroup::setMasterStatus(Session* session , bool master)
+{
+    const bool wasMaster = _sessions[session];
+
+    if (wasMaster == master) {
+        // No status change -> nothing to do.
+        return;
+    }
+    _sessions[session] = master;
+
+    if(master) {
+        connect( session->emulation() , SIGNAL(sendData(const char*,int)) , this,
+                 SLOT(forwardData(const char*,int)) );
+    }
+    else {
+        disconnect( session->emulation() , SIGNAL(sendData(const char*,int)) , this,
+                    SLOT(forwardData(const char*,int)) );
+    }
+}
+void SessionGroup::forwardData(const char* data, int size)
+{
+    static bool _inForwardData = false;
+    if(_inForwardData) {   // Avoid recursive calls among session groups!
+       // A recursive call happens when a master in group A calls forwardData()
+       // in group B. If one of the destination sessions in group B is also a
+       // master of a group including the master session of group A, this would
+       // again call forwardData() in group A, and so on.
+       return;
+    }
+    
+    _inForwardData = true;
+    QListIterator<Session*> iter(_sessions.keys());
+    while(iter.hasNext()) {
+        Session* other = iter.next();
+        if(!_sessions[other]) {
+           other->emulation()->sendString(data, size);
+        }
+    }
+    _inForwardData = false;
+}
+
+#include "Session.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Session.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,764 @@
+/*
+    This file is part of Konsole, an X terminal.
+
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+    Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
+
+    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.
+*/
+
+#ifndef SESSION_H
+#define SESSION_H
+
+// Qt
+#include <QtCore/QStringList>
+#include <QtCore/QByteRef>
+#include <QtCore/QSize>
+#include <QUuid>
+#include <QWidget>
+
+// KDE
+//#include <KApplication>
+//#include <KMainWindow>
+#include "konsole_export.h"
+
+// Konsole
+#include "History.h"
+
+class KProcess;
+class KUrl;
+
+namespace Konsole
+{
+
+class Emulation;
+class Pty;
+class ProcessInfo;
+class TerminalDisplay;
+  //class ZModemDialog;
+
+/**
+ * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation.
+ * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole.
+ * The terminal emulation ( Emulation and subclasses ) processes the output stream from the
+ * PTY and produces a character image which is then shown on views connected to the session.
+ *
+ * Each Session can be connected to one or more views by using the addView() method.
+ * The attached views can then display output from the program running in the terminal
+ * or send input to the program in the terminal in the form of keypresses and mouse
+ * activity.
+ */
+class KONSOLEPRIVATE_EXPORT Session : public QObject
+{
+Q_OBJECT
+Q_CLASSINFO("D-Bus Interface", "org.kde.konsole.Session")
+
+public:
+  Q_PROPERTY(QString name READ nameTitle)
+  Q_PROPERTY(int processId READ processId)
+  Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings)
+  Q_PROPERTY(QSize size READ size WRITE setSize)
+
+  /**
+   * Constructs a new session.
+   *
+   * To start the terminal process, call the run() method,
+   * after specifying the program and arguments
+   * using setProgram() and setArguments()
+   *
+   * If no program or arguments are specified explicitly, the Session
+   * falls back to using the program specified in the SHELL environment
+   * variable.
+   */
+  explicit Session(QObject* parent = 0);
+  ~Session();
+
+  /** 
+   * Connect to an existing terminal.  When a new Session() is constructed it 
+   * automatically searches for and opens a new teletype.  If you want to 
+   * use an existing teletype (given its file descriptor) call this after
+   * constructing the session.
+   *
+   * Calling openTeletype() while a session is running has no effect.
+   *
+   * @param masterFd The file descriptor of the pseudo-teletype master (See KPtyProcess::KPtyProcess())
+   */
+  void openTeletype(int masterFd);
+
+  /**
+   * Returns true if the session is currently running.  This will be true
+   * after run() has been called successfully.
+   */
+  bool isRunning() const;
+
+  /**
+   * Adds a new view for this session.
+   *
+   * The viewing widget will display the output from the terminal and
+   * input from the viewing widget (key presses, mouse activity etc.)
+   * will be sent to the terminal.
+   *
+   * Views can be removed using removeView().  The session is automatically
+   * closed when the last view is removed.
+   */
+  void addView(TerminalDisplay* widget);
+  /**
+   * Removes a view from this session.  When the last view is removed,
+   * the session will be closed automatically.
+   *
+   * @p widget will no longer display output from or send input
+   * to the terminal
+   */
+  void removeView(TerminalDisplay* widget);
+
+  /**
+   * Returns the views connected to this session
+   */
+  QList<TerminalDisplay*> views() const;
+
+  /**
+   * Returns the terminal emulation instance being used to encode / decode
+   * characters to / from the process.
+   */
+  Emulation*  emulation() const;
+
+  /** Returns the unique ID for this session. */
+  int sessionId() const;
+
+  /**
+   * This enum describes the contexts for which separate
+   * tab title formats may be specified.
+   */
+  enum TabTitleContext
+  {
+    /** Default tab title format */
+    LocalTabTitle,
+    /**
+     * Tab title format used session currently contains
+     * a connection to a remote computer (via SSH)
+     */
+    RemoteTabTitle
+  };
+
+  /**
+   * Returns true if the session currently contains a connection to a 
+   * remote computer.  It currently supports ssh.
+   */
+  bool isRemote();
+
+  /**
+   * Sets the format used by this session for tab titles.
+   *
+   * @param context The context whoose format should be set.
+   * @param format The tab title format.  This may be a mixture
+   * of plain text and dynamic elements denoted by a '%' character
+   * followed by a letter.  (eg. %d for directory).  The dynamic
+   * elements available depend on the @p context
+   */
+  void setTabTitleFormat(TabTitleContext context , const QString& format);
+  /** Returns the format used by this session for tab titles. */
+  QString tabTitleFormat(TabTitleContext context) const;
+
+
+  /** Returns the arguments passed to the shell process when run() is called. */
+  QStringList arguments() const;
+  /** Returns the program name of the shell process started when run() is called. */
+  QString program() const;
+
+  /**
+   * Sets the command line arguments which the session's program will be passed when
+   * run() is called.
+   */
+  void setArguments(const QStringList& arguments);
+  /** Sets the program to be executed when run() is called. */
+  void setProgram(const QString& program);
+
+  /** Returns the session's current working directory. */
+  QString initialWorkingDirectory() { return _initialWorkingDir; }
+
+  /**
+   * Sets the initial working directory for the session when it is run
+   * This has no effect once the session has been started.
+   */
+  void setInitialWorkingDirectory( const QString& dir );
+
+  /**
+   * Returns the current directory of the foreground process in the session
+   */
+  QString currentWorkingDirectory();
+
+  /**
+   * Sets the type of history store used by this session.
+   * Lines of output produced by the terminal are added
+   * to the history store.  The type of history store
+   * used affects the number of lines which can be
+   * remembered before they are lost and the storage
+   * (in memory, on-disk etc.) used.
+   */
+  void setHistoryType(const HistoryType& type);
+  /**
+   * Returns the type of history store used by this session.
+   */
+  const HistoryType& historyType() const;
+  /**
+   * Clears the history store used by this session.
+   */
+  void clearHistory();
+
+  /**
+   * Sets the key bindings used by this session.  The bindings
+   * specify how input key sequences are translated into
+   * the character stream which is sent to the terminal.
+   *
+   * @param id The name of the key bindings to use.  The
+   * names of available key bindings can be determined using the
+   * KeyboardTranslatorManager class.
+   */
+  void setKeyBindings(const QString& id);
+  /** Returns the name of the key bindings used by this session. */
+  QString keyBindings() const;
+
+  /**
+   * This enum describes the available title roles.
+   */
+  enum TitleRole
+  {
+      /** The name of the session. */
+      NameRole,
+      /** The title of the session which is displayed in tabs etc. */
+      DisplayedTitleRole
+  };
+
+  /**
+   * Return the session title set by the user (ie. the program running
+   * in the terminal), or an empty string if the user has not set a custom title
+   */
+  QString userTitle() const;
+
+  /** Convenience method used to read the name property.  Returns title(Session::NameRole). */
+  QString nameTitle() const { return title(Session::NameRole); }
+  /** Returns a title generated from tab format and process information. */
+  QString getDynamicTitle();
+
+  /** Sets the name of the icon associated with this session. */
+  void setIconName(const QString& iconName);
+  /** Returns the name of the icon associated with this session. */
+  QString iconName() const;
+
+  /** Return URL for the session. */
+  //KUrl getUrl();
+
+  /** Sets the text of the icon associated with this session. */
+  void setIconText(const QString& iconText);
+  /** Returns the text of the icon associated with this session. */
+  QString iconText() const;
+
+  /** Sets the session's title for the specified @p role to @p title. */
+  void setTitle(TitleRole role , const QString& title);
+
+  /** Returns the session's title for the specified @p role. */
+  QString title(TitleRole role) const;
+
+  /** 
+   * Specifies whether a utmp entry should be created for the pty used by this session.
+   * If true, KPty::login() is called when the session is started.
+   */
+  void setAddToUtmp(bool);
+
+  /**
+   * Specifies whether to close the session automatically when the terminal
+   * process terminates.
+   */
+  void setAutoClose(bool b) { _autoClose = b; }
+
+  /** Returns true if the user has started a program in the session. */
+  bool isForegroundProcessActive();
+
+  /** Returns the name of the current foreground process. */
+  QString foregroundProcessName();
+
+  /** Returns the terminal session's window size in lines and columns. */
+  QSize size();
+  /**
+   * Emits a request to resize the session to accommodate
+   * the specified window size.
+   *
+   * @param size The size in lines and columns to request.
+   */
+  void setSize(const QSize& size);
+
+  /**
+   * Sets whether the session has a dark background or not.  The session
+   * uses this information to set the COLORFGBG variable in the process's
+   * environment, which allows the programs running in the terminal to determine
+   * whether the background is light or dark and use appropriate colors by default.
+   *
+   * This has no effect once the session is running.
+   */
+  void setDarkBackground(bool darkBackground);
+  /**
+   * Returns true if the session has a dark background.
+   * See setDarkBackground()
+   */
+  bool hasDarkBackground() const;
+
+  /**
+   * Attempts to get the shell program to redraw the current display area.
+   * This can be used after clearing the screen, for example, to get the
+   * shell to redraw the prompt line.
+   */
+  void refresh();
+
+  //  void startZModem(const QString &rz, const QString &dir, const QStringList &list);
+  //  void cancelZModem();
+  //  bool isZModemBusy() { return _zmodemBusy; }
+
+ /** 
+   * Possible values of the @p what parameter for setUserTitle()
+   * See "Operating System Controls" section on http://rtfm.etla.org/xterm/ctlseq.html 
+   */
+  enum UserTitleChange
+  {
+      IconNameAndWindowTitle     = 0,
+    IconName                 = 1,
+    WindowTitle                = 2,
+    TextColor                = 10,
+    BackgroundColor            = 11,
+    SessionName                = 30,
+    ProfileChange            = 50     // this clashes with Xterm's font change command
+  };
+
+  // Sets the text codec used by this sessions terminal emulation.
+  void setCodec(QTextCodec* codec);
+
+  // session management
+  //void saveSession(KConfigGroup& group);
+  //void restoreSession(KConfigGroup& group);
+
+public slots:
+
+  /**
+   * Starts the terminal session.
+   *
+   * This creates the terminal process and connects the teletype to it.
+   */
+  void run();
+
+  /**
+   * Returns the environment of this session as a list of strings like
+   * VARIABLE=VALUE
+   */
+  Q_SCRIPTABLE QStringList environment() const;
+
+  /**
+   * Sets the environment for this session.
+   * @p environment should be a list of strings like
+   * VARIABLE=VALUE
+   */
+  Q_SCRIPTABLE void setEnvironment(const QStringList& environment);
+
+  /**
+   * Closes the terminal session.  This sends a hangup signal
+   * (SIGHUP) to the terminal process and causes the finished()  
+   * signal to be emitted.  If the process does not respond to the SIGHUP signal
+   * then the terminal connection (the pty) is closed and Konsole waits for the 
+   * process to exit.
+   */
+  Q_SCRIPTABLE void close();
+
+  /**
+   * Changes the session title or other customizable aspects of the terminal
+   * emulation display. For a list of what may be changed see the
+   * Emulation::titleChanged() signal.
+   *
+   * @param what The feature being changed.  Value is one of UserTitleChange
+   * @param caption The text part of the terminal command
+   */
+  void setUserTitle( int what , const QString &caption );
+
+  /**
+   * Enables monitoring for activity in the session.
+   * This will cause notifySessionState() to be emitted
+   * with the NOTIFYACTIVITY state flag when output is
+   * received from the terminal.
+   */
+  Q_SCRIPTABLE void setMonitorActivity(bool);
+
+  /** Returns true if monitoring for activity is enabled. */
+  Q_SCRIPTABLE bool isMonitorActivity() const;
+
+  /**
+   * Enables monitoring for silence in the session.
+   * This will cause notifySessionState() to be emitted
+   * with the NOTIFYSILENCE state flag when output is not
+   * received from the terminal for a certain period of
+   * time, specified with setMonitorSilenceSeconds()
+   */
+  Q_SCRIPTABLE void setMonitorSilence(bool);
+
+  /**
+   * Returns true if monitoring for inactivity (silence)
+   * in the session is enabled.
+   */
+  Q_SCRIPTABLE bool isMonitorSilence() const;
+
+  /** See setMonitorSilence() */
+  Q_SCRIPTABLE void setMonitorSilenceSeconds(int seconds);
+
+  /**
+   * Sets whether flow control is enabled for this terminal
+   * session.
+   */
+  Q_SCRIPTABLE void setFlowControlEnabled(bool enabled);
+
+  /** Returns whether flow control is enabled for this terminal session. */
+  Q_SCRIPTABLE bool flowControlEnabled() const;
+
+  /**
+   * Sends @p text to the current foreground terminal program.
+   */
+  Q_SCRIPTABLE void sendText(const QString& text) const;
+
+   /**
+    * Sends a mouse event of type @p eventType emitted by button
+    * @p buttons on @p column/@p line to the current foreground
+    * terminal program
+    */
+   Q_SCRIPTABLE void sendMouseEvent(int buttons, int column, int line, int eventType);
+
+   /**
+   * Returns the process id of the terminal process.
+   * This is the id used by the system API to refer to the process.
+   */
+  Q_SCRIPTABLE int processId() const;
+
+  /**
+   * Returns the process id of the terminal's foreground process.
+   * This is initially the same as processId() but can change
+   * as the user starts other programs inside the terminal.
+   */
+  Q_SCRIPTABLE int foregroundProcessId();
+
+  /** Sets the text codec used by this sessions terminal emulation.
+    * Overloaded to accept a QByteArray for convenience since DBus
+    * does not accept QTextCodec directky.
+    */
+  Q_SCRIPTABLE bool setCodec(QByteArray codec);
+
+  /** Returns the codec used to decode incoming characters in this
+   * terminal emulation
+   */
+  Q_SCRIPTABLE QByteArray codec();
+
+  /** Sets the session's title for the specified @p role to @p title.
+   *  This is an overloaded member function for setTitle(TitleRole, QString)
+   *  provided for convenience since enum data types may not be
+   *  exported directly through DBus
+   */
+  Q_SCRIPTABLE void setTitle(int role, const QString& title);
+
+  /** Returns the session's title for the specified @p role.
+   * This is an overloaded member function for  setTitle(TitleRole)
+   * provided for convenience since enum data types may not be
+   * exported directly through DBus
+   */
+  Q_SCRIPTABLE QString title(int role) const;
+
+  /** Returns the "friendly" version of the QUuid of this session.
+  * This is a QUuid with the braces and dashes removed, so it cannot be
+  * used to construct a new QUuid. The same text appears in the
+  * SHELL_SESSION_ID environment variable.
+  */
+  Q_SCRIPTABLE QString shellSessionId() const;
+
+  /** Sets the session's tab title format for the specified @p context to @p format.
+   *  This is an overloaded member function for setTabTitleFormat(TabTitleContext, QString)
+   *  provided for convenience since enum data types may not be
+   *  exported directly through DBus
+   */
+  Q_SCRIPTABLE void setTabTitleFormat(int context, const QString& format);
+
+  /** Returns the session's tab title format for the specified @p context.
+   * This is an overloaded member function for tabTitleFormat(TitleRole)
+   * provided for convenience since enum data types may not be
+   * exported directly through DBus
+   */
+  Q_SCRIPTABLE QString tabTitleFormat(int context) const;
+
+signals:
+
+  /** Emitted when the terminal process starts. */
+  void started();
+
+  /**
+   * Emitted when the terminal process exits.
+   */
+  void finished();
+
+  /**
+   * Emitted when output is received from the terminal process.
+   */
+  void receivedData( const QString& text );
+
+  /** Emitted when the session's title has changed. */
+  void titleChanged();
+
+  /**
+   * Emitted when the activity state of this session changes.
+   *
+   * @param state The new state of the session.  This may be one
+   * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY
+   */
+  void stateChanged(int state);
+
+  /** Emitted when a bell event occurs in the session. */
+  void bellRequest( const QString& message );
+
+  /**
+   * Requests that the color the text for any tabs associated with
+   * this session should be changed;
+   *
+   * TODO: Document what the parameter does
+   */
+  void changeTabTextColorRequest(int);
+
+  /**
+   * Requests that the background color of views on this session
+   * should be changed.
+   */
+  void changeBackgroundColorRequest(const QColor&);
+  /** 
+   * Requests that the text color of views on this session should
+   * be changed to @p color.
+   */
+  void changeForegroundColorRequest(const QColor&);
+
+  /** TODO: Document me. */
+  void openUrlRequest(const QString& url);
+
+  /** TODO: Document me. */
+  //void zmodemDetected();
+
+  /**
+   * Emitted when the terminal process requests a change
+   * in the size of the terminal window.
+   *
+   * @param size The requested window size in terms of lines and columns.
+   */
+  void resizeRequest(const QSize& size);
+
+  /**
+   * Emitted when a profile change command is received from the terminal.
+   *
+   * @param text The text of the command.  This is a string of the form
+   * "PropertyName=Value;PropertyName=Value ..."
+   */
+  void profileChangeCommandReceived(const QString& text);
+
+ /**
+  * Emitted when the flow control state changes.
+  *
+  * @param enabled True if flow control is enabled or false otherwise.
+  */
+  void flowControlEnabledChanged(bool enabled);
+
+private slots:
+  void done(int);
+
+  //  void fireZModemDetected();
+
+  void onReceiveBlock( const char* buffer, int len );
+  void monitorTimerDone();
+
+  void onViewSizeChange(int height, int width);
+
+  void activityStateSet(int);
+
+  //automatically detach views from sessions when view is destroyed
+  void viewDestroyed(QObject* view);
+
+  //void zmodemReadStatus();
+  //void zmodemReadAndSendBlock();
+  //void zmodemRcvBlock(const char *data, int len);
+  //void zmodemFinished();
+
+  void updateFlowControlState(bool suspended);
+  void updateWindowSize(int lines, int columns);
+private:
+
+  void updateTerminalSize();
+  WId windowId() const;
+  bool kill(int signal);
+  // print a warning message in the terminal.  This is used
+  // if the program fails to start, or if the shell exits in 
+  // an unsuccessful manner
+  void terminalWarning(const QString& message);
+  // checks that the binary 'program' is available and can be executed
+  // returns the binary name if available or an empty string otherwise
+  QString checkProgram(const QString& program) const;
+  ProcessInfo* getProcessInfo();
+  void updateSessionProcessInfo();
+  bool updateForegroundProcessInfo();
+  ProcessInfo* updateWorkingDirectory();
+
+  QUuid            _uniqueIdentifier; // SHELL_SESSION_ID
+
+  Pty*          _shellProcess;
+  Emulation*    _emulation;
+
+  QList<TerminalDisplay*> _views;
+
+  bool           _monitorActivity;
+  bool           _monitorSilence;
+  bool           _notifiedActivity;
+  bool           _masterMode;
+  bool           _autoClose;
+  bool           _wantedClose;
+  QTimer*        _monitorTimer;
+
+  int            _silenceSeconds;
+
+  QString        _nameTitle;
+  QString        _displayTitle;
+  QString        _userTitle;
+
+  QString        _localTabTitleFormat;
+  QString        _remoteTabTitleFormat;
+
+  QString        _iconName;
+  QString        _iconText; // as set by: echo -en '\033]1;IconText\007
+  bool           _addToUtmp;
+  bool           _flowControl;
+  bool           _fullScripting;
+
+  QString        _program;
+  QStringList    _arguments;
+
+  QStringList    _environment;
+  int            _sessionId;
+
+  QString        _initialWorkingDir;
+  QString        _currentWorkingDir;
+
+  ProcessInfo*   _sessionProcessInfo;
+  ProcessInfo*   _foregroundProcessInfo;
+  int            _foregroundPid;
+
+  // ZModem
+  //  bool           _zmodemBusy;
+  //  KProcess*      _zmodemProc;
+  //  ZModemDialog*  _zmodemProgress;
+
+  // Color/Font Changes by ESC Sequences
+
+  QColor         _modifiedBackground; // as set by: echo -en '\033]11;Color\007
+
+  QString        _profileKey;
+
+  bool _hasDarkBackground;
+
+  static int lastSessionId;
+
+};
+
+/**
+ * Provides a group of sessions which is divided into master and slave sessions.
+ * Activity in master sessions can be propagated to all sessions within the group.
+ * The type of activity which is propagated and method of propagation is controlled
+ * by the masterMode() flags.
+ */
+class SessionGroup : public QObject
+{
+Q_OBJECT
+
+public:
+    /** Constructs an empty session group. */
+    SessionGroup(QObject* parent);
+    /** Destroys the session group and removes all connections between master and slave sessions. */
+    ~SessionGroup();
+
+    /** Adds a session to the group. */
+    void addSession( Session* session );
+    /** Removes a session from the group. */
+    void removeSession( Session* session );
+
+    /** Returns the list of sessions currently in the group. */
+    QList<Session*> sessions() const;
+
+    /**
+     * Sets whether a particular session is a master within the group.
+     * Changes or activity in the group's master sessions may be propagated
+     * to all the sessions in the group, depending on the current masterMode()
+     *
+     * @param session The session whoose master status should be changed.
+     * @param master True to make this session a master or false otherwise
+     */
+    void setMasterStatus( Session* session , bool master );
+    /** Returns the master status of a session.  See setMasterStatus() */
+    bool masterStatus( Session* session ) const;
+
+    /**
+     * This enum describes the options for propagating certain activity or
+     * changes in the group's master sessions to all sessions in the group.
+     */
+    enum MasterMode
+    {
+        /**
+         * Any input key presses in the master sessions are sent to all
+         * sessions in the group.
+         */
+        CopyInputToAll = 1
+    };
+
+    /**
+     * Specifies which activity in the group's master sessions is propagated
+     * to all sessions in the group.
+     *
+     * @param mode A bitwise OR of MasterMode flags.
+     */
+    void setMasterMode( int mode );
+    /**
+     * Returns a bitwise OR of the active MasterMode flags for this group.
+     * See setMasterMode()
+     */
+    int masterMode() const;
+
+private slots:
+    void sessionFinished();
+    void forwardData(const char* data, int size);
+
+private:
+    QList<Session*> masters() const;
+
+    // maps sessions to their master status
+    QHash<Session*,bool> _sessions;
+
+    int _masterMode;
+};
+
+}
+
+#endif
+
+/*
+  Local Variables:
+  mode: c++
+  c-file-style: "stroustrup"
+  indent-tabs-mode: nil
+  tab-width: 4
+  End:
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/SessionController.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,1560 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
+
+    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 "SessionController.h"
+
+// Qt
+#include <QtGui/QApplication>
+#include <QMenu>
+
+// KDE
+#include <KAction>
+#include <KDebug>
+#include <KIcon>
+#include <KInputDialog>
+#include <KLocale>
+#include <KMenu>
+#include <KMessageBox>
+#include <KRun>
+#include <kshell.h>
+#include <KStandardDirs>
+#include <KToggleAction>
+#include <KUrl>
+#include <KXmlGuiWindow>
+#include <KXMLGUIFactory>
+#include <KXMLGUIBuilder>
+#include <kdebug.h>
+#include <kcodecaction.h>
+#include <kdeversion.h>
+
+// Konsole
+#include "EditProfileDialog.h"
+#include "CopyInputDialog.h"
+#include "Emulation.h"
+#include "Filter.h"
+#include "History.h"
+#include "IncrementalSearchBar.h"
+#include "RenameTabsDialog.h"
+#include "ScreenWindow.h"
+#include "Session.h"
+#include "ProfileList.h"
+#include "TerminalDisplay.h"
+#include "SessionManager.h"
+
+// for SaveHistoryTask
+#include <KFileDialog>
+#include <KIO/Job>
+#include <KJob>
+#include "TerminalCharacterDecoder.h"
+
+
+using namespace Konsole;
+
+KIcon SessionController::_activityIcon;
+KIcon SessionController::_silenceIcon;
+QSet<SessionController*> SessionController::_allControllers;
+QPointer<SearchHistoryThread> SearchHistoryTask::_thread;
+int SessionController::_lastControllerId;
+
+SessionController::SessionController(Session* session , TerminalDisplay* view, QObject* parent)
+    : ViewProperties(parent)
+    , KXMLGUIClient()
+    , _session(session)
+    , _view(view)
+    , _copyToGroup(0)
+    , _profileList(0)
+    , _previousState(-1)
+    , _viewUrlFilter(0)
+    , _searchFilter(0)
+    , _searchToggleAction(0)
+    , _findNextAction(0)
+    , _findPreviousAction(0)
+    , _urlFilterUpdateRequired(false)
+    , _codecAction(0)
+    , _changeProfileMenu(0)
+    , _listenForScreenWindowUpdates(false)
+    , _preventClose(false)
+{
+    _allControllers.insert(this);
+
+    Q_ASSERT( session );
+    Q_ASSERT( view );
+
+    // handle user interface related to session (menus etc.)
+    if (isKonsolePart())
+        setXMLFile("konsole/partui.rc");
+    else
+        setXMLFile("konsole/sessionui.rc");
+
+    setupActions();
+    actionCollection()->addAssociatedWidget(view);
+    foreach (QAction* action, actionCollection()->actions())
+        action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
+
+    setIdentifier(++_lastControllerId);
+    sessionTitleChanged();
+
+    view->installEventFilter(this);
+
+    // listen for session resize requests
+    connect( _session , SIGNAL(resizeRequest(const QSize&)) , this ,
+            SLOT(sessionResizeRequest(const QSize&)) );
+
+    // listen for popup menu requests
+    connect( _view , SIGNAL(configureRequest(QPoint)) , this,
+            SLOT(showDisplayContextMenu(QPoint)) );
+
+    // move view to newest output when keystrokes occur
+    connect( _view , SIGNAL(keyPressedSignal(QKeyEvent*)) , this ,
+            SLOT(trackOutput(QKeyEvent*)) );
+
+    // listen to activity / silence notifications from session
+    connect( _session , SIGNAL(stateChanged(int)) , this ,
+            SLOT(sessionStateChanged(int) ));
+    // listen to title and icon changes
+    connect( _session , SIGNAL(titleChanged()) , this , SLOT(sessionTitleChanged()) );
+
+    // listen for color changes
+    connect( _session , SIGNAL(changeBackgroundColorRequest(QColor)) , _view , SLOT(setBackgroundColor(QColor)) );
+    connect( _session , SIGNAL(changeForegroundColorRequest(QColor)) , _view , SLOT(setForegroundColor(QColor)) );
+
+    // update the title when the session starts
+    connect( _session , SIGNAL(started()) , this , SLOT(snapshot()) ); 
+
+    // listen for output changes to set activity flag
+    connect( _session->emulation() , SIGNAL(outputChanged()) , this ,
+            SLOT(fireActivity()) );
+
+    // listen for detection of ZModem transfer
+    connect( _session , SIGNAL(zmodemDetected()) , this , SLOT(zmodemDownload()) ); 
+
+    // listen for flow control status changes
+    connect( _session , SIGNAL(flowControlEnabledChanged(bool)) , _view ,
+        SLOT(setFlowControlWarningEnabled(bool)) );
+    _view->setFlowControlWarningEnabled(_session->flowControlEnabled());
+
+    // take a snapshot of the session state every so often when
+    // user activity occurs
+    //
+    // the timer is owned by the session so that it will be destroyed along
+    // with the session
+    QTimer* activityTimer = new QTimer(_session);
+    activityTimer->setSingleShot(true);
+    activityTimer->setInterval(2000);
+    connect( _view , SIGNAL(keyPressedSignal(QKeyEvent*)) , activityTimer , SLOT(start()) );
+    connect( activityTimer , SIGNAL(timeout()) , this , SLOT(snapshot()) );
+}
+
+void SessionController::updateSearchFilter()
+{
+    if ( _searchFilter ) 
+    {
+        Q_ASSERT( searchBar() && searchBar()->isVisible() );
+
+        _view->processFilters();
+    }
+}
+
+SessionController::~SessionController()
+{
+   if ( _view )
+      _view->setScreenWindow(0);
+
+   _allControllers.remove(this);
+}
+void SessionController::trackOutput(QKeyEvent* event)
+{
+    Q_ASSERT( _view->screenWindow() );
+
+    // jump to the end of the history buffer unless the key pressed
+    // is one of the three main modifiers, as these are used to select
+    // the selection mode (eg. Ctrl+Alt+<Left Click> for column/block selection)
+    switch (event->key())
+    {
+        case Qt::Key_Shift:
+        case Qt::Key_Control:
+        case Qt::Key_Alt:
+            break;
+        default:
+            _view->screenWindow()->setTrackOutput(true);
+    }
+}
+void SessionController::requireUrlFilterUpdate()
+{
+    // this method is called every time the screen window's output changes, so do not
+    // do anything expensive here.
+
+    _urlFilterUpdateRequired = true;
+}
+void SessionController::snapshot()
+{
+    Q_ASSERT( _session != 0 );
+
+    QString title = _session->getDynamicTitle();    
+    title         = title.simplified();
+
+    // Visualize that the session is broadcasting to others
+    if (_copyToGroup && _copyToGroup->sessions().count() > 1) {
+        title.append('*');
+    }
+    updateSessionIcon();
+
+    // apply new title
+    if ( !title.isEmpty() )
+        _session->setTitle(Session::DisplayedTitleRole,title);
+    else
+        _session->setTitle(Session::DisplayedTitleRole,_session->title(Session::NameRole));
+}
+
+QString SessionController::currentDir() const
+{
+    return _session->currentWorkingDirectory();
+}
+
+KUrl SessionController::url() const
+{
+    return _session->getUrl();
+}
+
+void SessionController::rename()
+{
+    renameSession();
+}
+
+void SessionController::openUrl( const KUrl& url )
+{
+    // handle local paths
+    if ( url.isLocalFile() )
+    {
+        QString path = url.toLocalFile();
+        _session->emulation()->sendText("cd " + KShell::quoteArg(path) + '\r');
+    }
+    else if ( url.protocol() == "ssh" )
+    {
+        _session->emulation()->sendText("ssh ");
+
+        if ( url.port() > -1 )
+            _session->emulation()->sendText("-p " + QString::number(url.port()) + ' ' );
+        if ( url.hasUser() )
+            _session->emulation()->sendText(url.user() + '@');
+        if ( url.hasHost() )
+            _session->emulation()->sendText(url.host() + '\r');
+    }
+    else if ( url.protocol() == "telnet" )
+    {
+        _session->emulation()->sendText("telnet ");
+
+        if ( url.hasUser() )
+            _session->emulation()->sendText("-l " + url.user() + ' ');
+        if ( url.hasHost() )
+            _session->emulation()->sendText(url.host() + ' ');
+        if ( url.port() > -1 )
+            _session->emulation()->sendText(QString::number(url.port()));
+         _session->emulation()->sendText("\r");
+    }
+    else
+    {
+        //TODO Implement handling for other Url types
+
+        KMessageBox::sorry(_view->window(),
+                           i18n("Konsole does not know how to open the bookmark: ") +
+                           url.prettyUrl());
+
+        kWarning(1211) << "Unable to open bookmark at url" << url << ", I do not know"
+           << " how to handle the protocol " << url.protocol();
+    }
+}
+
+bool SessionController::eventFilter(QObject* watched , QEvent* event)
+{
+    if ( watched == _view )
+    {
+        if ( event->type() == QEvent::FocusIn )
+        {
+            // notify the world that the view associated with this session has been focused
+            // used by the view manager to update the title of the MainWindow widget containing the view
+            emit focused(this);
+
+            // when the view is focused, set bell events from the associated session to be delivered
+            // by the focused view
+
+            // first, disconnect any other views which are listening for bell signals from the session
+            disconnect( _session , SIGNAL(bellRequest(const QString&)) , 0 , 0 );
+            // second, connect the newly focused view to listen for the session's bell signal
+            connect( _session , SIGNAL(bellRequest(const QString&)) ,
+                    _view , SLOT(bell(const QString&)) );
+                    
+            if(_copyToAllTabsAction->isChecked()) {
+                // A session with "Copy To All Tabs" has come into focus:
+                // Ensure that newly created sessions are included in _copyToGroup!
+                copyInputToAllTabs();
+            }
+        }
+        // when a mouse move is received, create the URL filter and listen for output changes if
+        // it has not already been created.  If it already exists, then update only if the output
+        // has changed since the last update ( _urlFilterUpdateRequired == true )
+        //
+        // also check that no mouse buttons are pressed since the URL filter only applies when
+        // the mouse is hovering over the view
+        if ( event->type() == QEvent::MouseMove &&
+            (!_viewUrlFilter || _urlFilterUpdateRequired) &&
+            ((QMouseEvent*)event)->buttons() == Qt::NoButton )
+        {
+            if ( _view->screenWindow() && !_viewUrlFilter )
+            {
+                connect( _view->screenWindow() , SIGNAL(scrolled(int)) , this ,
+                        SLOT(requireUrlFilterUpdate()) );
+                connect( _view->screenWindow() , SIGNAL(outputChanged()) , this ,
+                         SLOT(requireUrlFilterUpdate()) );
+
+                // install filter on the view to highlight URLs
+                _viewUrlFilter = new UrlFilter();
+                _view->filterChain()->addFilter( _viewUrlFilter );
+            }
+
+            _view->processFilters();
+            _urlFilterUpdateRequired = false;
+        }
+    }
+
+    return false;
+}
+
+void SessionController::removeSearchFilter()
+{
+    if (!_searchFilter)
+        return;
+
+    _view->filterChain()->removeFilter(_searchFilter);
+    delete _searchFilter;
+    _searchFilter = 0;
+}
+
+void SessionController::setSearchBar(IncrementalSearchBar* searchBar)
+{
+    // disconnect the existing search bar
+    if ( _searchBar )
+    {
+        disconnect( this , 0 , _searchBar , 0 );
+        disconnect( _searchBar , 0 , this , 0 );
+    }
+
+    // remove any existing search filter
+    removeSearchFilter();
+
+    // connect new search bar
+    _searchBar = searchBar;
+    if ( _searchBar )
+    {
+        connect( _searchBar , SIGNAL(closeClicked()) , this , SLOT(searchClosed()) );
+        connect( _searchBar , SIGNAL(findNextClicked()) , this , SLOT(findNextInHistory()) );
+        connect( _searchBar , SIGNAL(findPreviousClicked()) , this , SLOT(findPreviousInHistory()) );
+        connect( _searchBar , SIGNAL(highlightMatchesToggled(bool)) , this , SLOT(highlightMatches(bool)) );
+
+        // if the search bar was previously active
+        // then re-enter search mode
+        searchHistory( _searchToggleAction->isChecked() );
+    }
+}
+IncrementalSearchBar* SessionController::searchBar() const
+{
+    return _searchBar;
+}
+
+void SessionController::setShowMenuAction(QAction* action)
+{
+    actionCollection()->addAction("show-menubar",action);
+}
+
+void SessionController::setupActions()
+{
+    KAction* action = 0;
+    KToggleAction* toggleAction = 0;
+    KActionCollection* collection = actionCollection();
+
+    // Close Session
+    action = collection->addAction("close-session", this, SLOT(closeSession()));
+    action->setIcon(KIcon("tab-close"));
+    action->setText(i18n("&Close Tab"));
+    action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_W));
+
+    // Open Browser
+    action = collection->addAction("open-browser", this, SLOT(openBrowser()));
+    action->setText(i18n("Open File Manager"));
+    action->setIcon(KIcon("system-file-manager"));
+
+    // Copy and Paste
+    action = KStandardAction::copy(this, SLOT(copy()), collection);
+    action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C));
+
+    action = KStandardAction::paste(this, SLOT(paste()), collection);
+    KShortcut pasteShortcut = action->shortcut();
+    pasteShortcut.setPrimary(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_V));
+    pasteShortcut.setAlternate(QKeySequence(Qt::SHIFT + Qt::Key_Insert));
+    action->setShortcut(pasteShortcut);
+
+    action = collection->addAction("paste-selection", this, SLOT(pasteSelection()));
+    action->setText(i18n("Paste Selection"));
+    action->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Insert));
+
+    // Rename Session
+    action = collection->addAction("rename-session", this, SLOT(renameSession()));
+    action->setText( i18n("&Rename Tab...") );
+    action->setShortcut( QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_S) );
+
+    // Copy Input To -> All Tabs in Current Window
+    _copyToAllTabsAction = collection->addAction("copy-input-to-all-tabs", this, SLOT(copyInputToAllTabs()));
+    _copyToAllTabsAction->setText(i18n("&All Tabs in Current Window"));
+    _copyToAllTabsAction->setCheckable(true);
+
+    // Copy Input To -> Select Tabs
+    _copyToSelectedAction = collection->addAction("copy-input-to-selected-tabs", this, SLOT(copyInputToSelectedTabs()));
+    _copyToSelectedAction->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Period) );
+    _copyToSelectedAction->setText(i18n("&Select Tabs..."));
+    _copyToSelectedAction->setCheckable(true);
+
+    // Copy Input To -> None
+    _copyToNoneAction = collection->addAction("copy-input-to-none", this, SLOT(copyInputToNone()));
+    _copyToNoneAction->setText(i18nc("@action:inmenu Do not select any tabs", "&None"));
+    _copyToNoneAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Slash));
+    _copyToNoneAction->setCheckable(true);
+    _copyToNoneAction->setChecked(true);
+
+    action = collection->addAction("zmodem-upload", this, SLOT(zmodemUpload()));
+    action->setText(i18n("&ZModem Upload..."));
+    action->setIcon(KIcon("document-open"));
+    action->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_U));
+
+    // Monitor
+    toggleAction = new KToggleAction(i18n("Monitor for &Activity"),this);
+    toggleAction->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_A));
+    action = collection->addAction("monitor-activity", toggleAction);
+    connect(action, SIGNAL(toggled(bool)), this, SLOT(monitorActivity(bool)));
+
+    toggleAction = new KToggleAction(i18n("Monitor for &Silence"),this);
+    toggleAction->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_I));
+    action = collection->addAction("monitor-silence", toggleAction);
+    connect(action, SIGNAL(toggled(bool)), this, SLOT(monitorSilence(bool)));
+
+    // Character Encoding
+    _codecAction = new KCodecAction(i18n("Set &Encoding"),this);
+    _codecAction->setIcon(KIcon("character-set"));
+    collection->addAction("set-encoding", _codecAction);
+    connect(_codecAction->menu(), SIGNAL(aboutToShow()), this, SLOT(updateCodecAction()));
+    connect(_codecAction, SIGNAL(triggered(QTextCodec*)), this, SLOT(changeCodec(QTextCodec*)));
+
+    // Text Size
+    action = collection->addAction("enlarge-font", this, SLOT(increaseTextSize()));
+    action->setText(i18n("Enlarge Font"));
+    action->setIcon(KIcon("format-font-size-more"));
+    action->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Plus));
+
+    action = collection->addAction("shrink-font", this, SLOT(decreaseTextSize()));
+    action->setText(i18n("Shrink Font"));
+    action->setIcon(KIcon("format-font-size-less"));
+    action->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Minus));
+
+    // History
+    _searchToggleAction = KStandardAction::find(this, NULL, collection);
+    _searchToggleAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F));
+    _searchToggleAction->setCheckable(true);
+    connect(_searchToggleAction, SIGNAL(toggled(bool)), this, SLOT(searchHistory(bool)));
+
+    _findNextAction = KStandardAction::findNext(this, SLOT(findNextInHistory()), collection);
+    _findNextAction->setEnabled(false);
+
+    _findPreviousAction = KStandardAction::findPrev(this, SLOT(findPreviousInHistory()), collection);
+    _findPreviousAction->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F3));
+    _findPreviousAction->setEnabled(false);
+
+    action = KStandardAction::saveAs(this, SLOT(saveHistory()), collection);
+    action->setText(i18n("Save Output &As..."));
+
+    action = collection->addAction("configure-history", this, SLOT(showHistoryOptions()));
+    action->setText(i18n("Configure Scrollback..."));
+    action->setIcon(KIcon("configure"));
+
+    action = collection->addAction("clear-history", this, SLOT(clearHistory()));
+    action->setText(i18n("Clear Scrollback"));
+    action->setIcon(KIcon("edit-clear-history"));
+
+    action = collection->addAction("clear-history-and-reset", this, SLOT(clearHistoryAndReset()));
+    action->setText(i18n("Clear Scrollback and Reset"));
+    action->setIcon(KIcon("edit-clear-history"));
+    action->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_X));
+
+    // Profile Options
+    action = collection->addAction("edit-current-profile", this, SLOT(editCurrentProfile()));
+    action->setText(i18n("Configure Current Profile..."));
+    action->setIcon(KIcon("document-properties") );
+
+    _changeProfileMenu = new KActionMenu(i18n("Change Profile"), _view);
+    collection->addAction("change-profile", _changeProfileMenu);
+    connect(_changeProfileMenu->menu(), SIGNAL(aboutToShow()), this, SLOT(prepareChangeProfileMenu()));
+}
+
+void SessionController::changeProfile(Profile::Ptr profile)
+{
+    SessionManager::instance()->setSessionProfile(_session,profile);
+}
+
+void SessionController::prepareChangeProfileMenu()
+{
+    if (_changeProfileMenu->menu()->isEmpty()) {
+        _profileList = new ProfileList(false,this);
+        connect(_profileList, SIGNAL(profileSelected(Profile::Ptr)), this, SLOT(changeProfile(Profile::Ptr)));
+    }
+
+    _changeProfileMenu->menu()->clear();
+    _changeProfileMenu->menu()->addActions(_profileList->actions());
+}
+void SessionController::updateCodecAction()
+{
+    _codecAction->setCurrentCodec(QString(_session->emulation()->codec()->name()));
+}
+
+void SessionController::changeCodec(QTextCodec* codec)
+{
+    _session->setCodec(codec);
+}
+
+void SessionController::editCurrentProfile()
+{
+    EditProfileDialog* dialog = new EditProfileDialog( QApplication::activeWindow() );
+
+    dialog->setProfile(SessionManager::instance()->sessionProfile(_session));
+    dialog->show();
+}
+
+void SessionController::renameSession()
+{
+    QScopedPointer<RenameTabsDialog> dialog(new RenameTabsDialog(QApplication::activeWindow()));
+    dialog->setTabTitleText(_session->tabTitleFormat(Session::LocalTabTitle));
+    dialog->setRemoteTabTitleText(_session->tabTitleFormat(Session::RemoteTabTitle));
+
+    if (!_session->isRemote()) {
+        dialog->focusTabTitleText();
+    } else {
+        dialog->focusRemoteTabTitleText();
+    }
+
+    QPointer<Session> guard(_session);
+    int result = dialog->exec();
+    if (!guard)
+        return;
+
+    if (result)
+    {
+        QString tabTitle = dialog->tabTitleText();
+        QString remoteTabTitle = dialog->remoteTabTitleText();
+
+        _session->setTabTitleFormat(Session::LocalTabTitle, tabTitle);
+        _session->setTabTitleFormat(Session::RemoteTabTitle, remoteTabTitle);
+
+        // trigger an update of the tab text
+        snapshot();
+    }
+}
+void SessionController::saveSession()
+{
+    Q_ASSERT(0); // not implemented yet
+
+    //SaveSessionDialog dialog(_view);
+    //int result = dialog.exec();
+}
+bool SessionController::confirmClose() const
+{
+    if (_session->isForegroundProcessActive())
+    {
+        QString title = _session->foregroundProcessName();
+      
+        // hard coded for now.  In future make it possible for the user to specify which programs
+        // are ignored when considering whether to display a confirmation
+        QStringList ignoreList; 
+        ignoreList << QString(qgetenv("SHELL")).section('/',-1);
+        if (ignoreList.contains(title))
+            return true;
+
+        QString question;
+        if (title.isEmpty())
+            question = i18n("A program is currently running in this session."
+                            "  Are you sure you want to close it?");
+        else
+            question = i18n("The program '%1' is currently running in this session."  
+                            "  Are you sure you want to close it?",title);
+
+        int result = KMessageBox::warningYesNo(_view->window(),question,i18n("Confirm Close"));
+        return (result == KMessageBox::Yes) ? true : false; 
+    }
+    return true;
+}
+void SessionController::closeSession()
+{
+    if (_preventClose)
+        return;
+
+    if (confirmClose())
+        _session->close();
+}
+
+void SessionController::openBrowser()
+{
+    new KRun(url(), QApplication::activeWindow());
+}
+
+void SessionController::copy()
+{
+    _view->copyClipboard();
+}
+
+void SessionController::paste()
+{
+    _view->pasteClipboard();
+}
+void SessionController::pasteSelection()
+{
+    _view->pasteSelection();
+}
+static const KXmlGuiWindow* findWindow(const QObject* object)
+{
+    // Walk up the QObject hierarchy to find a KXmlGuiWindow.
+    while(object != NULL) {
+        const KXmlGuiWindow* window = dynamic_cast<const KXmlGuiWindow*>(object);
+        if(window != NULL) {
+            return(window);
+        }
+        object = object->parent();
+    }
+    return(NULL);
+}
+
+static bool hasTerminalDisplayInSameWindow(const Session* session, const KXmlGuiWindow* window)
+{
+    // Iterate all TerminalDisplays of this Session ...
+    QListIterator<TerminalDisplay*> terminalDisplayIterator(session->views());
+    while(terminalDisplayIterator.hasNext()) {
+        const TerminalDisplay* terminalDisplay = terminalDisplayIterator.next();
+        // ... and check whether a TerminalDisplay has the same
+        // window as given in the parameter
+        if(window == findWindow(terminalDisplay)) {
+            return(true);    
+        }
+    }
+    return(false);
+}
+
+void SessionController::copyInputToAllTabs()
+{
+    if(!_copyToGroup) {
+        _copyToGroup = new SessionGroup(this);
+    }
+
+    // Find our window ...
+    const KXmlGuiWindow* myWindow = findWindow(_view);
+
+    QSet<Session*> group =
+       QSet<Session*>::fromList(SessionManager::instance()->sessions());
+    for(QSet<Session*>::iterator iterator = group.begin();
+        iterator != group.end(); ++iterator) {
+        Session* session = *iterator;
+ 
+        // First, ensure that the session is removed
+        // (necessary to avoid duplicates on addSession()!)
+        _copyToGroup->removeSession(session);
+
+        // Add current session if it is displayed our window
+        if(hasTerminalDisplayInSameWindow(session, myWindow)) {
+            _copyToGroup->addSession(session);
+        }
+    }
+    _copyToGroup->setMasterStatus(_session, true);
+    _copyToGroup->setMasterMode(SessionGroup::CopyInputToAll);
+    
+    snapshot();
+    _copyToAllTabsAction->setChecked(true);
+    _copyToSelectedAction->setChecked(false);
+    _copyToNoneAction->setChecked(false);
+}
+
+void SessionController::copyInputToSelectedTabs()
+{
+    if (!_copyToGroup)
+    {
+        _copyToGroup = new SessionGroup(this);
+        _copyToGroup->addSession(_session);
+        _copyToGroup->setMasterStatus(_session,true);
+        _copyToGroup->setMasterMode(SessionGroup::CopyInputToAll);
+    }
+
+    CopyInputDialog* dialog = new CopyInputDialog(_view);
+    dialog->setMasterSession(_session);
+    
+    QSet<Session*> currentGroup = QSet<Session*>::fromList(_copyToGroup->sessions());
+    currentGroup.remove(_session);
+    
+    dialog->setChosenSessions(currentGroup);
+
+    QPointer<Session> guard(_session);
+    int result = dialog->exec();
+    if (!guard)
+        return;
+
+    if (result)
+    {
+        QSet<Session*> newGroup = dialog->chosenSessions();
+        newGroup.remove(_session);
+    
+        QSet<Session*> completeGroup = newGroup | currentGroup;
+        foreach(Session* session, completeGroup)
+        {
+            if (newGroup.contains(session) && !currentGroup.contains(session))
+                _copyToGroup->addSession(session);
+            else if (!newGroup.contains(session) && currentGroup.contains(session))
+                _copyToGroup->removeSession(session);
+        }
+
+        _copyToGroup->setMasterStatus(_session, true);
+        _copyToGroup->setMasterMode(SessionGroup::CopyInputToAll);
+        snapshot();        
+    }
+
+    delete dialog;
+    _copyToAllTabsAction->setChecked(false);
+    _copyToSelectedAction->setChecked(true);
+    _copyToNoneAction->setChecked(false);
+}
+
+void SessionController::copyInputToNone()
+{
+    if (!_copyToGroup)      // No 'Copy To' is active
+        return;
+
+    QSet<Session*> group =
+       QSet<Session*>::fromList(SessionManager::instance()->sessions());
+    for(QSet<Session*>::iterator iterator = group.begin();
+        iterator != group.end(); ++iterator) {
+        Session* session = *iterator;
+ 
+        if(session != _session) {
+            _copyToGroup->removeSession(*iterator);
+        }
+    }
+    delete _copyToGroup;
+    _copyToGroup = NULL;
+    snapshot();
+    
+    _copyToAllTabsAction->setChecked(false);
+    _copyToSelectedAction->setChecked(false);
+    _copyToNoneAction->setChecked(true);
+}
+
+void SessionController::searchClosed()
+{
+    _searchToggleAction->toggle();
+}
+
+#if 0
+void SessionController::searchHistory()
+{
+    searchHistory(true);
+}
+#endif
+
+void SessionController::listenForScreenWindowUpdates()
+{
+    if (_listenForScreenWindowUpdates)
+        return;
+
+    connect( _view->screenWindow() , SIGNAL(outputChanged()) , this , 
+            SLOT(updateSearchFilter()) );
+    connect( _view->screenWindow() , SIGNAL(scrolled(int)) , this , 
+            SLOT(updateSearchFilter()) );
+
+    _listenForScreenWindowUpdates = true;
+}
+
+// searchHistory() may be called either as a result of clicking a menu item or
+// as a result of changing the search bar widget
+void SessionController::searchHistory(bool showSearchBar)
+{
+    if ( _searchBar )
+    {
+        _searchBar->setVisible(showSearchBar);
+
+        if (showSearchBar)
+        {
+            removeSearchFilter();
+
+            listenForScreenWindowUpdates();
+            
+            _searchFilter = new RegExpFilter();
+            _view->filterChain()->addFilter(_searchFilter);
+            connect( _searchBar , SIGNAL(searchChanged(const QString&)) , this ,
+                    SLOT(searchTextChanged(const QString&)) );
+
+            // invoke search for matches for the current search text
+            const QString& currentSearchText = _searchBar->searchText();
+            if (!currentSearchText.isEmpty())
+            {
+                searchTextChanged(currentSearchText);
+            }
+
+            setFindNextPrevEnabled(true);
+        }
+        else
+        {
+            setFindNextPrevEnabled(false);
+
+            disconnect( _searchBar , SIGNAL(searchChanged(const QString&)) , this ,
+                    SLOT(searchTextChanged(const QString&)) );
+
+            removeSearchFilter();
+
+            _view->setFocus( Qt::ActiveWindowFocusReason );
+        }
+    }
+}
+void SessionController::setFindNextPrevEnabled(bool enabled)
+{
+    _findNextAction->setEnabled(enabled);
+    _findPreviousAction->setEnabled(enabled);
+}
+void SessionController::searchTextChanged(const QString& text)
+{
+    Q_ASSERT( _view->screenWindow() );
+
+    if ( text.isEmpty() )
+        _view->screenWindow()->clearSelection();
+
+    // update search.  this is called even when the text is
+    // empty to clear the view's filters
+    beginSearch(text , SearchHistoryTask::ForwardsSearch);
+}
+void SessionController::searchCompleted(bool success)
+{
+    if ( _searchBar )
+        _searchBar->setFoundMatch(success);
+}
+
+void SessionController::beginSearch(const QString& text , int direction)
+{
+    Q_ASSERT( _searchBar );
+    Q_ASSERT( _searchFilter );
+
+    Qt::CaseSensitivity caseHandling = _searchBar->matchCase() ? Qt::CaseSensitive : Qt::CaseInsensitive;
+    QRegExp::PatternSyntax syntax = _searchBar->matchRegExp() ? QRegExp::RegExp : QRegExp::FixedString;
+
+    QRegExp regExp( text.trimmed() ,  caseHandling , syntax );
+    _searchFilter->setRegExp(regExp);
+
+    if ( !regExp.isEmpty() )
+    {
+        SearchHistoryTask* task = new SearchHistoryTask(this);
+
+        connect( task , SIGNAL(completed(bool)) , this , SLOT(searchCompleted(bool)) );
+
+        task->setRegExp(regExp);
+        task->setSearchDirection( (SearchHistoryTask::SearchDirection)direction );
+        task->setAutoDelete(true);
+        task->addScreenWindow( _session , _view->screenWindow() );
+        task->execute();
+    }
+
+    _view->processFilters();
+}
+void SessionController::highlightMatches(bool highlight)
+{
+    if ( highlight )
+    {
+        _view->filterChain()->addFilter(_searchFilter);
+        _view->processFilters();
+    }
+    else
+    {
+        _view->filterChain()->removeFilter(_searchFilter);
+    }
+
+    _view->update();
+}
+void SessionController::findNextInHistory()
+{
+    Q_ASSERT( _searchBar );
+    Q_ASSERT( _searchFilter );
+
+    beginSearch(_searchBar->searchText(),SearchHistoryTask::ForwardsSearch);
+}
+void SessionController::findPreviousInHistory()
+{
+    Q_ASSERT( _searchBar );
+    Q_ASSERT( _searchFilter );
+
+    beginSearch(_searchBar->searchText(),SearchHistoryTask::BackwardsSearch);
+}
+void SessionController::showHistoryOptions()
+{
+    HistorySizeDialog* dialog = new HistorySizeDialog( QApplication::activeWindow() );
+    const HistoryType& currentHistory = _session->historyType();
+
+    if ( currentHistory.isEnabled() )
+    {
+        if ( currentHistory.isUnlimited() )
+            dialog->setMode( HistorySizeDialog::UnlimitedHistory );
+        else
+        {
+            dialog->setMode( HistorySizeDialog::FixedSizeHistory );
+            dialog->setLineCount( currentHistory.maximumLineCount() );
+        }
+    }
+    else
+        dialog->setMode( HistorySizeDialog::NoHistory );
+
+    connect( dialog , SIGNAL(optionsChanged(int,int,bool)) ,
+             this , SLOT(scrollBackOptionsChanged(int,int,bool)) );
+
+    dialog->show();
+}
+void SessionController::sessionResizeRequest(const QSize& size)
+{
+    //kDebug(1211) << "View resize requested to " << size;
+    _view->setSize(size.width(),size.height());
+}
+void SessionController::scrollBackOptionsChanged(int mode, int lines, bool saveToCurrentProfile )
+{
+    switch (mode)
+    {
+        case HistorySizeDialog::NoHistory:
+            _session->setHistoryType( HistoryTypeNone() );
+            break;
+         case HistorySizeDialog::FixedSizeHistory:
+            _session->setHistoryType( CompactHistoryType(lines) );
+            break;
+         case HistorySizeDialog::UnlimitedHistory:
+             _session->setHistoryType( HistoryTypeFile() );
+            break;
+    }
+    if (saveToCurrentProfile)
+    {
+        Profile::Ptr profile = SessionManager::instance()->sessionProfile(_session);
+
+        switch (mode)
+        {
+            case HistorySizeDialog::NoHistory:
+                profile->setProperty(Profile::HistoryMode , Profile::DisableHistory);
+                break;
+            case HistorySizeDialog::FixedSizeHistory:
+                profile->setProperty(Profile::HistoryMode , Profile::FixedSizeHistory);
+                profile->setProperty(Profile::HistorySize , lines);
+                break;
+            case HistorySizeDialog::UnlimitedHistory:
+                profile->setProperty(Profile::HistoryMode , Profile::UnlimitedHistory);
+                break;
+        }
+        SessionManager::instance()->changeProfile(profile, profile->setProperties());
+    }
+}
+
+void SessionController::saveHistory()
+{
+    SessionTask* task = new SaveHistoryTask(this);
+    task->setAutoDelete(true);
+    task->addSession( _session );
+    task->execute();
+}
+
+void SessionController::clearHistory()
+{
+    _session->clearHistory();
+    _view->updateImage();   // To reset view scrollbar
+}
+
+void SessionController::clearHistoryAndReset()
+{
+    Emulation* emulation = _session->emulation();
+    emulation->reset();
+    _session->refresh();
+    clearHistory();
+}
+
+void SessionController::increaseTextSize()
+{
+    QFont font = _view->getVTFont();
+    font.setPointSizeF(font.pointSizeF()+1);
+    _view->setVTFont(font);
+
+    //TODO - Save this setting as a session default
+}
+
+void SessionController::decreaseTextSize()
+{
+    static const qreal MinimumFontSize = 6;
+
+    QFont font = _view->getVTFont();
+    font.setPointSizeF( qMax(font.pointSizeF()-1,MinimumFontSize) );
+    _view->setVTFont(font);
+
+    //TODO - Save this setting as a session default
+}
+
+void SessionController::monitorActivity(bool monitor)
+{
+    _session->setMonitorActivity(monitor);
+}
+void SessionController::monitorSilence(bool monitor)
+{
+    _session->setMonitorSilence(monitor);
+}
+void SessionController::updateSessionIcon()
+{
+    // Visualize that the session is broadcasting to others
+    if (_copyToGroup && _copyToGroup->sessions().count() > 1) {
+        // Master Mode: set different icon, to warn the user to be careful
+        setIcon(KIcon("emblem-important"));
+    }
+    else {
+        // Not in Master Mode: use normal icon
+        setIcon( _sessionIcon );
+    }
+}
+void SessionController::sessionTitleChanged()
+{
+        if ( _sessionIconName != _session->iconName() )
+        {
+            _sessionIconName = _session->iconName();
+            _sessionIcon = KIcon( _sessionIconName );
+            updateSessionIcon();
+        }
+
+        QString title = _session->title(Session::DisplayedTitleRole);
+
+        // special handling for the "%w" marker which is replaced with the
+        // window title set by the shell
+        title.replace("%w",_session->userTitle());
+        // special handling for the "%#" marker which is replaced with the 
+        // number of the shell
+        title.replace("%#",QString::number(_session->sessionId()));
+
+       if ( title.isEmpty() )
+          title = _session->title(Session::NameRole);
+
+       setTitle( title );
+}
+
+void SessionController::showDisplayContextMenu(const QPoint& position)
+{
+    // needed to make sure the popup menu is available, even if a hosting
+    // application did not merge our GUI.
+    if (!factory())
+    {
+        if (!clientBuilder())
+        {
+            setClientBuilder(new KXMLGUIBuilder(_view));
+        }
+
+        KXMLGUIFactory* factory = new KXMLGUIFactory(clientBuilder(), this);
+        factory->addClient(this);
+        //kDebug(1211) << "Created xmlgui factory" << factory;
+    }
+
+    QMenu* popup = qobject_cast<QMenu*>(factory()->container("session-popup-menu",this));
+    if (popup)
+    {
+        // prepend content-specific actions such as "Open Link", "Copy Email Address" etc.
+        QList<QAction*> contentActions = _view->filterActions(position);
+        QAction* contentSeparator = new QAction(popup);
+        contentSeparator->setSeparator(true);
+        contentActions << contentSeparator;
+
+        _preventClose = true;
+
+        popup->insertActions(popup->actions().value(0,0),contentActions);
+        QAction* chosen = popup->exec( _view->mapToGlobal(position) );
+
+        // remove content-specific actions, unless the close action was chosen
+        // in which case the popup menu will be partially destroyed at this point
+           foreach(QAction* action,contentActions)
+            popup->removeAction(action);
+        delete contentSeparator;
+
+        _preventClose = false;
+
+        if (chosen && chosen->objectName() == "close-session")
+            chosen->trigger();
+    }
+    else
+    {
+        kWarning() << "Unable to display popup menu for session"
+                   << _session->title(Session::NameRole)
+                   << ", no GUI factory available to build the popup.";
+    }
+}
+
+void SessionController::sessionStateChanged(int state)
+{
+    if ( state == _previousState )
+        return;
+
+    _previousState = state;
+
+    // TODO - Replace the icon choices below when suitable icons for silence and activity
+    // are available
+    if ( state == NOTIFYACTIVITY )
+    {
+        if (_activityIcon.isNull())
+        {
+            _activityIcon = KIcon("dialog-information");
+        }
+
+        setIcon(_activityIcon);
+    }
+    else if ( state == NOTIFYSILENCE )
+    {
+        if (_silenceIcon.isNull())
+        {
+            _silenceIcon = KIcon("dialog-information");
+        }
+
+        setIcon(_silenceIcon);
+    }
+    else if ( state == NOTIFYNORMAL )
+    {
+        if ( _sessionIconName != _session->iconName() )
+        {
+            _sessionIconName = _session->iconName();
+            _sessionIcon = KIcon( _sessionIconName );
+        }
+
+        updateSessionIcon();
+    }
+}
+
+void SessionController::zmodemDownload()
+{
+    QString zmodem = KGlobal::dirs()->findExe("rz");
+    if(zmodem.isEmpty()) {
+       zmodem = KGlobal::dirs()->findExe("lrz");
+    }
+    if(!zmodem.isEmpty()) {
+        const QString path = KFileDialog::getExistingDirectory(
+                                QString(), _view,
+                                i18n("Save ZModem Download to..."));
+
+        if(!path.isEmpty()) {
+            _session->startZModem(zmodem, path, QStringList());
+            return;
+        }
+    }
+    else {
+        KMessageBox::error(_view,
+          i18n("<p>A ZModem file transfer attempt has been detected, "
+               "but no suitable ZModem software was found on this system.</p>"
+               "<p>You may wish to install the 'rzsz' or 'lrzsz' package.</p>"));
+    }
+    _session->cancelZModem();
+    return;
+}
+
+void SessionController::zmodemUpload()
+{
+    if(_session->isZModemBusy()) {
+      KMessageBox::sorry(_view,
+         i18n("<p>The current session already has a ZModem file transfer in progress.</p>"));
+      return;
+    }
+    QString zmodem = KGlobal::dirs()->findExe("sz");
+    if(zmodem.isEmpty()) {
+       zmodem = KGlobal::dirs()->findExe("lsz");
+    }
+    if(zmodem.isEmpty()) {
+        KMessageBox::sorry(_view,
+           i18n("<p>No suitable ZModem software was found on this system.</p>"
+                "<p>You may wish to install the 'rzsz' or 'lrzsz' package.</p>"));
+        return;
+    }
+
+    QStringList files = KFileDialog::getOpenFileNames(KUrl(), QString(), _view,
+                           i18n("Select Files for ZModem Upload"));
+    if(!files.isEmpty()) {
+        _session->startZModem(zmodem, QString(), files);
+    }
+}
+
+bool SessionController::isKonsolePart() const
+{
+    // Check to see if we are being called from Konsole or a KPart
+    if (QString(qApp->metaObject()->className()) == "Konsole::Application")
+        return false;
+    else
+        return true;
+}
+
+SessionTask::SessionTask(QObject* parent)
+    :  QObject(parent)
+    ,  _autoDelete(false)
+{
+}
+void SessionTask::setAutoDelete(bool enable)
+{
+    _autoDelete = enable;
+}
+bool SessionTask::autoDelete() const
+{
+    return _autoDelete;
+}
+void SessionTask::addSession(Session* session)
+{
+    _sessions << session;
+}
+QList<SessionPtr> SessionTask::sessions() const
+{
+    return _sessions;
+}
+
+SaveHistoryTask::SaveHistoryTask(QObject* parent)
+    : SessionTask(parent)
+{
+}
+SaveHistoryTask::~SaveHistoryTask()
+{
+}
+
+void SaveHistoryTask::execute()
+{
+    QListIterator<SessionPtr> iter(sessions());
+
+    // TODO - think about the UI when saving multiple history sessions, if there are more than two or
+    //        three then providing a URL for each one will be tedious
+
+    // TODO - show a warning ( preferably passive ) if saving the history output fails
+    //
+
+     KFileDialog* dialog = new KFileDialog( QString(":konsole") /* check this */,
+                                               QString(), QApplication::activeWindow() );
+     dialog->setOperationMode(KFileDialog::Saving);
+     dialog->setConfirmOverwrite(true);
+
+     QStringList mimeTypes;
+     mimeTypes << "text/plain";
+     mimeTypes << "text/html";
+     dialog->setMimeFilter(mimeTypes,"text/plain");
+
+     // iterate over each session in the task and display a dialog to allow the user to choose where
+     // to save that session's history.
+     // then start a KIO job to transfer the data from the history to the chosen URL
+    while ( iter.hasNext() )
+    {
+        SessionPtr session = iter.next();
+
+        dialog->setCaption( i18n("Save Output From %1",session->title(Session::NameRole)) );
+
+        int result = dialog->exec();
+
+        if ( result != QDialog::Accepted )
+            continue;
+
+        KUrl url = dialog->selectedUrl();
+
+        if ( !url.isValid() )
+        { // UI:  Can we make this friendlier?
+            KMessageBox::sorry( 0 , i18n("%1 is an invalid URL, the output could not be saved.",url.url()) );
+            continue;
+        }
+
+        KIO::TransferJob* job = KIO::put( url,
+                                          -1,   // no special permissions
+                                          // overwrite existing files
+                                          // do not resume an existing transfer
+                                          // show progress information only for remote
+                                          // URLs
+                                          KIO::Overwrite | (url.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags)
+                                                             // a better solution would be to show progress
+                                                             // information after a certain period of time
+                                                             // instead, since the overall speed of transfer
+                                                             // depends on factors other than just the protocol
+                                                             // used
+                                        );
+
+
+        SaveJob jobInfo;
+        jobInfo.session = session;
+        jobInfo.lastLineFetched = -1;  // when each request for data comes in from the KIO subsystem
+                                       // lastLineFetched is used to keep track of how much of the history
+                                       // has already been sent, and where the next request should continue
+                                       // from.
+                                       // this is set to -1 to indicate the job has just been started
+
+        if ( dialog->currentMimeFilter() == "text/html" )
+           jobInfo.decoder = new HTMLDecoder();
+        else
+           jobInfo.decoder = new PlainTextDecoder();
+
+        _jobSession.insert(job,jobInfo);
+
+        connect( job , SIGNAL(dataReq(KIO::Job*,QByteArray&)),
+                 this, SLOT(jobDataRequested(KIO::Job*,QByteArray&)) );
+        connect( job , SIGNAL(result(KJob*)),
+                 this, SLOT(jobResult(KJob*)) );
+    }
+
+    dialog->deleteLater();
+}
+void SaveHistoryTask::jobDataRequested(KIO::Job* job , QByteArray& data)
+{
+    // TODO - Report progress information for the job
+
+    // PERFORMANCE:  Do some tests and tweak this value to get faster saving
+    const int LINES_PER_REQUEST = 500;
+
+    SaveJob& info = _jobSession[job];
+
+    // transfer LINES_PER_REQUEST lines from the session's history
+    // to the save location
+    if ( info.session )
+    {
+        // note:  when retrieving lines from the emulation,
+        // the first line is at index 0.
+
+        int sessionLines = info.session->emulation()->lineCount();
+
+        if ( sessionLines-1 == info.lastLineFetched )
+            return; // if there is no more data to transfer then stop the job
+
+        int copyUpToLine = qMin( info.lastLineFetched + LINES_PER_REQUEST ,
+                                 sessionLines-1 );
+
+        QTextStream stream(&data,QIODevice::ReadWrite);
+        info.decoder->begin(&stream);
+        info.session->emulation()->writeToStream( info.decoder , info.lastLineFetched+1 , copyUpToLine );
+        info.decoder->end();
+
+        // if there are still more lines to process after this request
+        // then insert a new line character
+        // to ensure that the next block of lines begins on a new line
+        //
+        // FIXME - There is still an extra new-line at the end of the save data.
+        if ( copyUpToLine <= sessionLines-1 )
+        {
+            stream << '\n';
+        }
+
+
+        info.lastLineFetched = copyUpToLine;
+    }
+}
+void SaveHistoryTask::jobResult(KJob* job)
+{
+    if ( job->error() )
+    {
+        KMessageBox::sorry( 0 , i18n("A problem occurred when saving the output.\n%1",job->errorString()) );
+    }
+
+    TerminalCharacterDecoder * decoder = _jobSession[job].decoder;
+
+    _jobSession.remove(job);
+
+    delete decoder;
+
+    // notify the world that the task is done
+    emit completed(true);
+
+    if ( autoDelete() )
+        deleteLater();
+}
+void SearchHistoryTask::addScreenWindow( Session* session , ScreenWindow* searchWindow )
+{
+   _windows.insert(session,searchWindow);
+}
+void SearchHistoryTask::execute()
+{
+    QMapIterator< SessionPtr , ScreenWindowPtr > iter(_windows);
+
+    while ( iter.hasNext() )
+    {
+        iter.next();
+        executeOnScreenWindow( iter.key() , iter.value() );
+    }
+}
+
+void SearchHistoryTask::executeOnScreenWindow( SessionPtr session , ScreenWindowPtr window )
+{
+    Q_ASSERT( session );
+    Q_ASSERT( window );
+
+    Emulation* emulation = session->emulation();
+
+    int selectionColumn = 0;
+    int selectionLine = 0;
+
+    window->getSelectionEnd(selectionColumn , selectionLine);
+
+    if ( !_regExp.isEmpty() )
+    {
+        int pos = -1;
+        const bool forwards = ( _direction == ForwardsSearch );
+        int startLine = selectionLine + window->currentLine() + ( forwards ? 1 : -1 );
+        // Temporary fix for #205495
+        if (startLine < 0) startLine = 0;
+        const int lastLine = window->lineCount() - 1;
+        QString string;
+
+        //text stream to read history into string for pattern or regular expression searching
+        QTextStream searchStream(&string);
+
+        PlainTextDecoder decoder;
+        decoder.setRecordLinePositions(true);
+
+        //setup first and last lines depending on search direction
+        int line = startLine;
+
+        //read through and search history in blocks of 10K lines.
+        //this balances the need to retrieve lots of data from the history each time
+        //(for efficient searching)
+        //without using silly amounts of memory if the history is very large.
+        const int maxDelta = qMin(window->lineCount(),10000);
+        int delta = forwards ? maxDelta : -maxDelta;
+
+        int endLine = line;
+        bool hasWrapped = false;  // set to true when we reach the top/bottom
+                                  // of the output and continue from the other
+                                  // end
+
+        //loop through history in blocks of <delta> lines.
+        do
+        {
+            // ensure that application does not appear to hang
+            // if searching through a lengthy output
+            QApplication::processEvents();
+
+            // calculate lines to search in this iteration
+            if ( hasWrapped )
+            {
+                if ( endLine == lastLine )
+                    line = 0;
+                else if ( endLine == 0 )
+                    line = lastLine;
+
+                endLine += delta;
+
+                if ( forwards )
+                   endLine = qMin( startLine , endLine );
+                else
+                   endLine = qMax( startLine , endLine );
+            }
+            else
+            {
+                endLine += delta;
+
+                if ( endLine > lastLine )
+                {
+                    hasWrapped = true;
+                    endLine = lastLine;
+                } else if ( endLine < 0 )
+                {
+                    hasWrapped = true;
+                    endLine = 0;
+                }
+            }
+
+            decoder.begin(&searchStream);
+            emulation->writeToStream(&decoder, qMin(endLine,line) , qMax(endLine,line) );
+            decoder.end();
+
+            // line number search below assumes that the buffer ends with a new-line 
+            string.append('\n');
+
+            pos = -1;
+            if (forwards)
+                pos = string.indexOf(_regExp);
+            else
+                pos = string.lastIndexOf(_regExp);
+
+            //if a match is found, position the cursor on that line and update the screen
+            if ( pos != -1 )
+            {
+                int newLines = 0;
+                QList<int> linePositions = decoder.linePositions();
+                while (newLines < linePositions.count() && linePositions[newLines] <= pos)
+                    newLines++;
+
+                // ignore the new line at the start of the buffer
+                newLines--;
+
+                int findPos = qMin(line,endLine) + newLines;
+
+                highlightResult(window,findPos);
+
+                emit completed(true);
+
+                return;
+            }
+
+            //clear the current block of text and move to the next one
+            string.clear();
+            line = endLine;
+
+        } while ( startLine != endLine );
+
+        // if no match was found, clear selection to indicate this
+        window->clearSelection();
+        window->notifyOutputChanged();
+    }
+
+    emit completed(false);
+}
+void SearchHistoryTask::highlightResult(ScreenWindowPtr window , int findPos)
+{
+     //work out how many lines into the current block of text the search result was found
+     //- looks a little painful, but it only has to be done once per search.
+
+     //kDebug(1211) << "Found result at line " << findPos;
+
+     //update display to show area of history containing selection
+     window->scrollTo(findPos);
+     window->setSelectionStart( 0 , findPos - window->currentLine() , false );
+     window->setSelectionEnd( window->columnCount() , findPos - window->currentLine() );
+     window->setTrackOutput(false);
+     window->notifyOutputChanged();
+}
+
+SearchHistoryTask::SearchHistoryTask(QObject* parent)
+    : SessionTask(parent)
+    , _direction(ForwardsSearch)
+{
+
+}
+void SearchHistoryTask::setSearchDirection( SearchDirection direction )
+{
+    _direction = direction;
+}
+SearchHistoryTask::SearchDirection SearchHistoryTask::searchDirection() const
+{
+    return _direction;
+}
+void SearchHistoryTask::setRegExp(const QRegExp& expression)
+{
+    _regExp = expression;
+}
+QRegExp SearchHistoryTask::regExp() const
+{
+    return _regExp;
+}
+
+#include "SessionController.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/SessionController.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,452 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
+
+    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.
+*/
+
+#ifndef SESSIONCONTROLLER_H
+#define SESSIONCONTROLLER_H
+
+// Qt
+#include <QtGui/QIcon>
+#include <QtCore/QList>
+#include <QtCore/QPointer>
+#include <QtCore/QString>
+#include <QtCore/QThread>
+#include <QtCore/QHash>
+
+// KDE
+#include <KActionCollection>
+#include <KActionMenu>
+#include <KIcon>
+#include <KXMLGUIClient>
+
+// Konsole
+#include "HistorySizeDialog.h"
+#include "ViewProperties.h"
+#include "Profile.h"
+
+namespace KIO
+{
+    class Job;
+}
+
+class QAction;
+class QTextCodec;
+class KCodecAction;
+class KUrl;
+class KJob;
+
+namespace Konsole
+{
+
+class Session;
+class SessionGroup;
+class ScreenWindow;
+class TerminalDisplay;
+class IncrementalSearchBar;
+class ProfileList;
+class UrlFilter;
+class RegExpFilter;
+
+// SaveHistoryTask
+class TerminalCharacterDecoder;
+
+
+typedef QPointer<Session> SessionPtr;
+
+/**
+ * Provides the menu actions to manipulate a single terminal session and view pair.
+ * The actions provided by this class are defined in the sessionui.rc XML file.
+ *
+ * SessionController monitors the session and provides access to basic information
+ * about the session such as title(), icon() and currentDir().  SessionController 
+ * provides notifications of activity in the session via the activity() signal.
+ *
+ * When the controlled view receives the focus, the focused() signal is emitted
+ * with a pointer to the controller.  This can be used by main application window
+ * which contains the view to plug the controller's actions into the menu when
+ * the view is focused.
+ */
+class KONSOLEPRIVATE_EXPORT SessionController : public ViewProperties , public KXMLGUIClient
+{
+Q_OBJECT
+    
+public:
+    /**
+     * Constructs a new SessionController which operates on @p session and @p view.
+     */
+    SessionController(Session* session , TerminalDisplay* view, QObject* parent);
+    ~SessionController();
+    
+    /** Returns the session associated with this controller */
+    QPointer<Session> session() { return _session; }
+    /** Returns the view associated with this controller */
+    QPointer<TerminalDisplay>  view()    { return _view;    }
+    
+    /** 
+     * Returns true if the controller is valid.
+     * A valid controller is one which has a non-null session() and view().
+     *
+     * Equivalent to "!session().isNull() && !view().isNull()"
+     */
+    bool isValid() const;
+
+    /** 
+     * Sets the widget used for searches through the session's output.
+     *
+     * When the user clicks on the "Search Output" menu action the @p searchBar 's 
+     * show() method will be called.  The SessionController will then connect to the search 
+     * bar's signals to update the search when the widget's controls are pressed.
+     */
+    void setSearchBar( IncrementalSearchBar* searchBar );
+    /** 
+     * see setSearchBar()
+     */
+    IncrementalSearchBar* searchBar() const;
+
+    /**
+     * Sets the action displayed in the session's context menu to hide or
+     * show the menu bar. 
+     */
+    void setShowMenuAction(QAction* action);
+
+    // reimplemented
+    virtual KUrl url() const;
+    virtual QString currentDir() const;
+    virtual void rename();
+    virtual bool confirmClose() const;
+
+    // Reimplemented to watch for events happening to the view
+    virtual bool eventFilter(QObject* watched , QEvent* event);
+
+    /** Returns the set of all controllers that exist. */
+    static QSet<SessionController*> allControllers()
+    { return _allControllers; }
+
+signals:
+    /**
+     * Emitted when the view associated with the controller is focused.  
+     * This can be used by other classes to plug the controller's actions into a window's
+     * menus. 
+     */
+    void focused( SessionController* controller );
+
+public slots:
+    /**
+     * Issues a command to the session to navigate to the specified URL.
+     * This may not succeed if the foreground program does not understand 
+     * the command sent to it ( 'cd path' for local URLs ) or is not 
+     * responding to input.
+     *
+     * openUrl() currently supports urls for local paths and those
+     * using the 'ssh' protocol ( eg. "ssh://joebloggs@hostname" )
+     */
+    void openUrl( const KUrl& url ); 
+
+private slots:
+    // menu item handlers
+    void openBrowser();
+    void copy();
+    void paste();
+    void pasteSelection(); // shortcut only
+    void copyInputToAllTabs();
+    void copyInputToSelectedTabs();
+    void copyInputToNone();
+    void editCurrentProfile();
+    void changeCodec(QTextCodec* codec);
+    void searchHistory(bool showSearchBar);
+    void findNextInHistory();
+    void findPreviousInHistory();
+    void saveHistory();
+    void showHistoryOptions();
+    void clearHistory();
+    void clearHistoryAndReset();
+    void closeSession();
+    void monitorActivity(bool monitor);
+    void monitorSilence(bool monitor);
+    void increaseTextSize();
+    void decreaseTextSize();
+    void renameSession();
+    void saveSession();
+    void changeProfile(Profile::Ptr profile);
+
+    // other
+    void prepareChangeProfileMenu();
+    void updateCodecAction();
+    void showDisplayContextMenu(const QPoint& position);
+    void sessionStateChanged(int state);
+    void sessionTitleChanged();
+    void searchTextChanged(const QString& text);
+    void searchCompleted(bool success);
+    void searchClosed(); // called when the user clicks on the
+                         // history search bar's close button 
+
+    void snapshot(); // called periodically as the user types
+                     // to take a snapshot of the state of the
+                     // foreground process in the terminal
+
+    void requireUrlFilterUpdate();
+    void highlightMatches(bool highlight);
+    void scrollBackOptionsChanged(int mode , int lines, bool saveToCurrentProfile);
+    void sessionResizeRequest(const QSize& size);
+    void trackOutput(QKeyEvent* event);  // move view to end of current output
+                                         // when a key press occurs in the 
+                                         // display area
+
+    void updateSearchFilter();
+    
+    void zmodemDownload();
+    void zmodemUpload();
+
+    /* Returns true if called within a KPart; false if called within Konsole. */
+    bool isKonsolePart() const;
+
+private:
+    // begins the search
+    // text - pattern to search for
+    // direction - value from SearchHistoryTask::SearchDirection enum to specify
+    //             the search direction
+    void beginSearch(const QString& text , int direction);
+    void setupActions();
+    void removeSearchFilter(); // remove and delete the current search filter if set
+    void setFindNextPrevEnabled(bool enabled);
+    void listenForScreenWindowUpdates();
+
+private:
+    void updateSessionIcon();
+  
+    QPointer<Session>         _session;
+    QPointer<TerminalDisplay> _view;
+    SessionGroup*               _copyToGroup;
+    
+    ProfileList* _profileList;
+
+    KIcon      _sessionIcon;
+    QString    _sessionIconName;
+    int        _previousState;
+
+    UrlFilter*      _viewUrlFilter;
+    RegExpFilter*   _searchFilter; 
+
+    KAction* _copyToAllTabsAction;
+    KAction* _copyToSelectedAction;
+    KAction* _copyToNoneAction;
+    
+    KAction* _searchToggleAction;
+    KAction* _findNextAction;
+    KAction* _findPreviousAction;
+    
+    
+    bool _urlFilterUpdateRequired;
+
+    QPointer<IncrementalSearchBar> _searchBar;
+
+    KCodecAction* _codecAction;
+
+    KActionMenu* _changeProfileMenu;
+
+    bool _listenForScreenWindowUpdates;
+    bool _preventClose;
+
+    static QSet<SessionController*> _allControllers;
+    static int _lastControllerId;
+    static KIcon _activityIcon;
+    static KIcon _silenceIcon;
+};
+inline bool SessionController::isValid() const
+{
+    return !_session.isNull() && !_view.isNull();
+}
+
+/** 
+ * Abstract class representing a task which can be performed on a group of sessions.
+ *
+ * Create a new instance of the appropriate sub-class for the task you want to perform and
+ * call the addSession() method to add each session which needs to be processed.
+ *
+ * Finally, call the execute() method to perform the sub-class specific action on each
+ * of the sessions.
+ */
+class SessionTask : public QObject
+{
+Q_OBJECT
+
+public:
+   SessionTask(QObject* parent = 0);
+
+   /** 
+    * Sets whether the task automatically deletes itself when the task has been finished.
+    * Depending on whether the task operates synchronously or asynchronously, the deletion
+    * may be scheduled immediately after execute() returns or it may happen some time later.
+    */
+   void setAutoDelete(bool enable);
+   /** Returns true if the task automatically deletes itself.  See setAutoDelete() */
+   bool autoDelete() const;
+
+   /** Adds a new session to the group */
+   void addSession(Session* session);
+
+   /** 
+    * Executes the task on each of the sessions in the group.
+    * The completed() signal is emitted when the task is finished, depending on the specific sub-class
+    * execute() may be synchronous or asynchronous
+    */
+   virtual void execute() = 0;
+
+signals:
+   /** 
+    * Emitted when the task has completed.  
+    * Depending on the task this may occur just before execute() returns, or it
+    * may occur later
+    *
+    * @param success Indicates whether the task completed successfully or not
+    */
+   void completed(bool success);
+
+protected:
+
+   /** Returns a list of sessions in the group */
+   QList< SessionPtr > sessions() const;
+
+private:
+
+   bool _autoDelete;
+   QList< SessionPtr > _sessions; 
+};
+
+/**
+ * A task which prompts for a URL for each session and saves that session's output
+ * to the given URL
+ */
+class SaveHistoryTask : public SessionTask
+{
+Q_OBJECT
+  
+public:
+    /** Constructs a new task to save session output to URLs */
+    SaveHistoryTask(QObject* parent = 0);
+    virtual ~SaveHistoryTask();
+
+    /**
+     * Opens a save file dialog for each session in the group and begins saving
+     * each session's history to the given URL.
+     *
+     * The data transfer is performed asynchronously and will continue after execute() returns.
+     */
+    virtual void execute();
+
+private slots:
+    void jobDataRequested(KIO::Job* job , QByteArray& data);
+    void jobResult(KJob* job);
+
+private:
+    class SaveJob // structure to keep information needed to process
+                  // incoming data requests from jobs
+    {
+    public:
+        SessionPtr session; // the session associated with a history save job
+        int lastLineFetched; // the last line processed in the previous data request
+                             // set this to -1 at the start of the save job
+        
+        TerminalCharacterDecoder* decoder;  // decoder used to convert terminal characters
+                                            // into output
+
+    };
+
+    QHash<KJob*,SaveJob> _jobSession;
+};
+
+class SearchHistoryThread;
+/**
+ * A task which searches through the output of sessions for matches for a given regular expression.
+ * SearchHistoryTask operates on ScreenWindow instances rather than sessions added by addSession().
+ * A screen window can be added to the list to search using addScreenWindow()
+ *
+ * When execute() is called, the search begins in the direction specified by searchDirection(),
+ * starting at the position of the current selection.
+ *
+ * FIXME - This is not a proper implementation of SessionTask, in that it ignores sessions specified
+ * with addSession()
+ *
+ * TODO - Implementation requirements:
+ *          May provide progress feedback to the user when searching very large output logs.
+ */
+class SearchHistoryTask : public SessionTask
+{
+Q_OBJECT
+
+public:
+    /** 
+     * This enum describes the strategies available for searching through the 
+     * session's output.
+     */
+    enum SearchDirection
+    {
+        /** Searches forwards through the output, starting at the current selection. */
+        ForwardsSearch,
+        /** Searches backwars through the output, starting at the current selection. */
+        BackwardsSearch  
+    };
+
+    /** 
+     * Constructs a new search task. 
+     */
+    explicit SearchHistoryTask(QObject* parent = 0);
+
+    /** Adds a screen window to the list to search when execute() is called. */
+    void addScreenWindow( Session* session , ScreenWindow* searchWindow); 
+
+    /** Sets the regular expression which is searched for when execute() is called */
+    void setRegExp(const QRegExp& regExp);
+    /** Returns the regular expression which is searched for when execute() is called */
+    QRegExp regExp() const;
+   
+    /** Specifies the direction to search in when execute() is called. */ 
+    void setSearchDirection( SearchDirection direction );
+    /** Returns the current search direction.  See setSearchDirection(). */
+    SearchDirection searchDirection() const;
+
+    /** 
+     * Performs a search through the session's history, starting at the position
+     * of the current selection, in the direction specified by setSearchDirection().
+     *
+     * If it finds a match, the ScreenWindow specified in the constructor is 
+     * scrolled to the position where the match occurred and the selection 
+     * is set to the matching text.  execute() then returns immediately.
+     *
+     * To continue the search looking for further matches, call execute() again.
+     */
+    virtual void execute();
+
+private:
+    typedef QPointer<ScreenWindow> ScreenWindowPtr;
+    
+    void executeOnScreenWindow( SessionPtr session , ScreenWindowPtr window );
+    void highlightResult( ScreenWindowPtr window , int position);
+
+    QMap< SessionPtr , ScreenWindowPtr > _windows;
+    QRegExp _regExp;
+    SearchDirection _direction;
+
+    static QPointer<SearchHistoryThread> _thread;
+};
+
+}
+
+#endif //SESSIONCONTROLLER_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/SessionManager.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,978 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "SessionManager.h"
+
+// Qt
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QList>
+#include <QtCore/QSignalMapper>
+#include <QtCore/QString>
+#include <QtCore/QTextCodec>
+
+// KDE
+#include <klocale.h>
+#include <kicon.h>
+#include <krun.h>
+#include <kshell.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <kdebug.h>
+#include <kconfiggroup.h>
+#include <kstandarddirs.h>
+#include <kdesktopfile.h>
+
+// Konsole
+#include "ColorScheme.h"
+#include "Session.h"
+#include "History.h"
+#include "ShellCommand.h"
+
+using namespace Konsole;
+
+#if 0
+
+bool Profile::isAvailable() const
+{
+    //TODO:  Is it necessary to cache the result of the search?
+
+    QString binary = KRun::binaryName( command(true) , false );
+    binary = KShell::tildeExpand(binary);
+
+    QString fullBinaryPath = KGlobal::dirs()->findExe(binary);
+
+    if ( fullBinaryPath.isEmpty() )
+        return false;
+    else
+        return true;
+}
+#endif
+
+bool profileIndexLessThan(const Profile::Ptr &p1, const Profile::Ptr &p2)
+{
+    return p1->menuIndexAsInt() <= p2->menuIndexAsInt();
+}
+
+bool profileNameLessThan(const Profile::Ptr &p1, const Profile::Ptr &p2)
+{
+    return QString::localeAwareCompare(p1->name(), p2->name()) <= 0;
+}
+
+static void sortByIndexProfileList(QList<Profile::Ptr> &list)
+{
+   qStableSort(list.begin(), list.end(), profileIndexLessThan);
+}
+
+static void sortByNameProfileList(QList<Profile::Ptr> &list)
+{
+    qStableSort(list.begin(), list.end(), profileNameLessThan);
+}
+
+SessionManager::SessionManager()
+    : _loadedAllProfiles(false)
+    , _loadedFavorites(false)
+{
+    //map finished() signals from sessions
+    _sessionMapper = new QSignalMapper(this);
+    connect( _sessionMapper , SIGNAL(mapped(QObject*)) , this ,
+            SLOT(sessionTerminated(QObject*)) );
+
+    //load fallback profile
+    _fallbackProfile = Profile::Ptr(new FallbackProfile);
+    addProfile(_fallbackProfile);
+
+    //locate and load default profile
+    KSharedConfigPtr appConfig = KSharedConfig::openConfig("konsolerc");
+    const KConfigGroup group = appConfig->group( "Desktop Entry" );
+    QString defaultSessionFilename = group.readEntry("DefaultProfile","Shell.profile");
+
+    QString path = KGlobal::dirs()->findResource("data","konsole/"+defaultSessionFilename);
+    if (!path.isEmpty())
+    {
+        Profile::Ptr profile = loadProfile(path);
+        if ( profile )
+            _defaultProfile = profile;
+    }
+
+    Q_ASSERT( _types.count() > 0 );
+    Q_ASSERT( _defaultProfile );
+
+    // get shortcuts and paths of profiles associated with
+    // them - this doesn't load the shortcuts themselves,
+    // that is done on-demand.
+    loadShortcuts();
+}
+Profile::Ptr SessionManager::loadProfile(const QString& shortPath)
+{
+    // the fallback profile has a 'special' path name, "FALLBACK/"
+    if (shortPath == _fallbackProfile->property<QString>(Profile::Path))
+        return _fallbackProfile;
+
+    QString path = shortPath;
+
+    // add a suggested suffix and relative prefix if missing
+    QFileInfo fileInfo(path);
+    if ( fileInfo.suffix().isEmpty() )
+        path.append(".profile");
+    if ( fileInfo.path().isEmpty() || fileInfo.path() == "." )
+        path.prepend(QString("konsole")+QDir::separator());
+
+    // if the file is not an absolute path, look it up 
+    if ( !fileInfo.isAbsolute() )
+        path = KStandardDirs::locate("data",path);
+
+    // check that we have not already loaded this profile
+    QSetIterator<Profile::Ptr> iter(_types);
+    while ( iter.hasNext() )
+    {
+        Profile::Ptr profile = iter.next();
+        if ( profile->path() == path )
+            return profile;
+    }
+
+    // guard to prevent problems if a profile specifies itself as its parent
+    // or if there is recursion in the "inheritance" chain
+    // (eg. two profiles, A and B, specifying each other as their parents)
+    static QStack<QString> recursionGuard;
+    PopStackOnExit<QString> popGuardOnExit(recursionGuard);
+
+    if (recursionGuard.contains(path))
+    {
+        kWarning() << "Ignoring attempt to load profile recursively from" << path;
+        return _fallbackProfile;
+    }
+    else
+        recursionGuard.push(path);
+
+    // load the profile
+    ProfileReader* reader = 0;
+    if ( path.endsWith(QLatin1String(".desktop")) )
+        reader = 0; // new KDE3ProfileReader;
+    else
+        reader = new KDE4ProfileReader;
+
+    if (!reader)
+    {
+        kWarning() << "Could not create loader to read profile from" << path;
+        return Profile::Ptr();
+    }
+
+    Profile::Ptr newProfile = Profile::Ptr(new Profile(defaultProfile()));
+    newProfile->setProperty(Profile::Path,path);
+
+    QString parentProfilePath;
+    bool result = reader->readProfile(path,newProfile,parentProfilePath);
+
+    if ( !parentProfilePath.isEmpty() )
+    {
+        Profile::Ptr parentProfile = loadProfile(parentProfilePath);
+        newProfile->setParent(parentProfile);
+    }
+
+    delete reader;
+
+    if (!result)
+    {
+        kWarning() << "Could not load profile from " << path;
+        return Profile::Ptr();
+    }
+    else
+    {
+        addProfile(newProfile);
+        return newProfile;
+    }
+}
+QStringList SessionManager::availableProfilePaths() const
+{
+    KDE3ProfileReader kde3Reader;
+    KDE4ProfileReader kde4Reader;
+
+    QStringList profiles;
+    profiles += kde3Reader.findProfiles();
+    profiles += kde4Reader.findProfiles();
+
+    return profiles;
+}
+
+void SessionManager::loadAllProfiles()
+{
+    if ( _loadedAllProfiles )
+        return;
+
+    QStringList profiles = availableProfilePaths();
+    
+    QListIterator<QString> iter(profiles);
+    while (iter.hasNext())
+        loadProfile(iter.next());
+
+    _loadedAllProfiles = true;
+}
+
+void SessionManager::sortProfiles(QList<Profile::Ptr> &list)
+{
+
+    QList<Profile::Ptr> lackingIndices;
+    QList<Profile::Ptr> havingIndices;
+
+    for (int i = 0; i < list.size(); ++i)
+    {
+        // dis-regard the fallback profile
+        if (list.at(i)->path() == _fallbackProfile->property<QString>(Profile::Path))
+            continue;
+
+        if (list.at(i)->menuIndexAsInt() == 0)
+            lackingIndices.append(list.at(i));
+        else
+            havingIndices.append(list.at(i));
+    }
+
+    // sort by index
+    sortByIndexProfileList(havingIndices);
+
+    // sort alphabetically those w/o an index
+    sortByNameProfileList(lackingIndices);
+
+    // Put those with indices in sequential order w/o any gaps
+    int i = 0;
+    for (i = 0; i < havingIndices.size(); ++i)
+    {
+        Profile::Ptr tempProfile = havingIndices.at(i);
+        tempProfile->setProperty(Profile::MenuIndex, QString::number(i+1));
+        havingIndices.replace(i, tempProfile);
+    }
+    // Put those w/o indices in sequential order
+    for (int j = 0; j < lackingIndices.size(); ++j)
+    {
+        Profile::Ptr tempProfile = lackingIndices.at(j);
+        tempProfile->setProperty(Profile::MenuIndex, QString::number(j+1+i));
+        lackingIndices.replace(j, tempProfile);
+    }
+
+    // combine the 2 list: first those who had indices
+    list.clear();
+    list.append(havingIndices);
+    list.append(lackingIndices);
+}
+
+void SessionManager::saveState()
+{
+    // save default profile
+    setDefaultProfile( _defaultProfile );
+
+    // save shortcuts
+    saveShortcuts();
+
+    // save favorites
+    saveFavorites();
+}
+void SessionManager::closeAll()
+{
+    // close remaining sessions
+    foreach( Session* session , _sessions )
+    {
+        session->close();
+    }
+    _sessions.clear();    
+}
+SessionManager::~SessionManager()
+{
+    if (_sessions.count() > 0)
+    {
+        kWarning() << "Konsole SessionManager destroyed with sessions still alive";
+        // ensure that the Session doesn't later try to call back and do things to the 
+        // SessionManager
+        foreach(Session* session , _sessions)
+            disconnect(session , 0 , this , 0);
+    }
+}
+
+const QList<Session*> SessionManager::sessions()
+{
+    return _sessions;
+}
+
+void SessionManager::updateSession(Session* session)
+{
+    Profile::Ptr info = _sessionProfiles[session]; 
+
+    // Temp fix for crashes when changing profiles 256357, 246054
+    if (!info)
+        info = defaultProfile();
+
+    Q_ASSERT( info );
+
+    applyProfile(session,info,false);
+
+    // FIXME - This may update a lot more than just the session
+    // of interest. 
+    emit sessionUpdated(session);
+}
+
+Session* SessionManager::createSession(Profile::Ptr info)
+{
+    Session* session = 0;
+    
+    if (!info)
+        info = defaultProfile();
+   
+    if (!_types.contains(info))
+        addProfile(info);
+
+    //configuration information found, create a new session based on this
+    session = new Session();
+    applyProfile(session,info,false);
+
+    connect( session , SIGNAL(profileChangeCommandReceived(QString)) , this ,
+            SLOT(sessionProfileCommandReceived(QString)) );
+
+    //ask for notification when session dies
+    _sessionMapper->setMapping(session,session);
+    connect( session , SIGNAL(finished()) , _sessionMapper , 
+             SLOT(map()) );
+
+    //add session to active list
+    _sessions << session;
+    _sessionProfiles.insert(session,info);
+
+    Q_ASSERT( session );
+
+    return session;
+}
+
+void SessionManager::sessionTerminated(QObject* sessionObject)
+{
+    Session* session = qobject_cast<Session*>(sessionObject);
+
+    Q_ASSERT( session );
+
+    _sessions.removeAll(session);
+    session->deleteLater();
+}
+
+QList<Profile::Ptr> SessionManager::sortedFavorites()
+{
+    QList<Profile::Ptr> favorites = findFavorites().toList();
+
+    sortProfiles(favorites);
+    return favorites;
+}
+
+QList<Profile::Ptr> SessionManager::loadedProfiles() const
+{
+    return _types.toList();
+}
+
+Profile::Ptr SessionManager::defaultProfile() const
+{
+    return _defaultProfile;
+}
+Profile::Ptr SessionManager::fallbackProfile() const
+{ return _fallbackProfile; }
+
+QString SessionManager::saveProfile(Profile::Ptr info)
+{
+    ProfileWriter* writer = new KDE4ProfileWriter;
+
+    QString newPath = writer->getPath(info);
+
+    writer->writeProfile(newPath,info);
+
+    delete writer;
+
+    return newPath;
+}
+
+void SessionManager::changeProfile(Profile::Ptr info , 
+                                   QHash<Profile::Property,QVariant> propertyMap, bool persistant)
+{
+    Q_ASSERT(info); 
+
+    // insert the changes into the existing Profile instance
+    QListIterator<Profile::Property> iter(propertyMap.keys());
+    while ( iter.hasNext() )
+    {
+        const Profile::Property property = iter.next();
+        info->setProperty(property,propertyMap[property]);
+    }
+    
+    // when changing a group, iterate through the profiles
+    // in the group and call changeProfile() on each of them
+    //
+    // this is so that each profile in the group, the profile is 
+    // applied, a change notification is emitted and the profile
+    // is saved to disk
+    ProfileGroup::Ptr group = info->asGroup();
+    if (group)
+    {
+        foreach(const Profile::Ptr &profile, group->profiles())
+            changeProfile(profile,propertyMap,persistant);
+        return;
+    }
+    
+    // apply the changes to existing sessions
+    applyProfile(info,true);
+
+    // notify the world about the change
+    emit profileChanged(info);
+
+    // save changes to disk, unless the profile is hidden, in which case
+    // it has no file on disk 
+    if ( persistant && !info->isHidden() )
+    {
+        info->setProperty(Profile::Path,saveProfile(info));
+    }
+}
+void SessionManager::applyProfile(Profile::Ptr info , bool modifiedPropertiesOnly)
+{
+    QListIterator<Session*> iter(_sessions);
+    while ( iter.hasNext() )
+    {
+        Session* next = iter.next();
+        if ( _sessionProfiles[next] == info )
+            applyProfile(next,info,modifiedPropertiesOnly);        
+    }
+}
+Profile::Ptr SessionManager::sessionProfile(Session* session) const
+{
+    return _sessionProfiles[session];
+}
+void SessionManager::setSessionProfile(Session* session, Profile::Ptr profile)
+{
+    _sessionProfiles[session] = profile;
+    updateSession(session);
+}
+void SessionManager::applyProfile(Session* session, const Profile::Ptr info , bool modifiedPropertiesOnly)
+{
+    Q_ASSERT(info);
+
+    _sessionProfiles[session] = info;
+
+    ShouldApplyProperty apply(info,modifiedPropertiesOnly);
+
+    // Basic session settings
+    if ( apply.shouldApply(Profile::Name) )
+        session->setTitle(Session::NameRole,info->name());
+
+    if ( apply.shouldApply(Profile::Command) )
+        session->setProgram(info->command());
+
+    if ( apply.shouldApply(Profile::Arguments) )
+        session->setArguments(info->arguments());
+
+    if ( apply.shouldApply(Profile::Directory) )
+        session->setInitialWorkingDirectory(info->defaultWorkingDirectory());
+
+    if ( apply.shouldApply(Profile::Environment) )
+    {
+        // add environment variable containing home directory of current profile
+        // (if specified)
+        QStringList environment = info->property<QStringList>(Profile::Environment);
+        environment << QString("PROFILEHOME=%1").arg(info->defaultWorkingDirectory());
+
+        session->setEnvironment(environment);
+    }
+
+    if ( apply.shouldApply(Profile::Icon) )
+        session->setIconName(info->icon());
+
+    // Key bindings
+    if ( apply.shouldApply(Profile::KeyBindings) )
+        session->setKeyBindings(info->property<QString>(Profile::KeyBindings));
+
+    // Tab formats
+    if ( apply.shouldApply(Profile::LocalTabTitleFormat) )
+        session->setTabTitleFormat( Session::LocalTabTitle ,
+                                    info->property<QString>(Profile::LocalTabTitleFormat));
+    if ( apply.shouldApply(Profile::RemoteTabTitleFormat) )
+        session->setTabTitleFormat( Session::RemoteTabTitle ,
+                                    info->property<QString>(Profile::RemoteTabTitleFormat));
+
+    // History
+    if ( apply.shouldApply(Profile::HistoryMode) || apply.shouldApply(Profile::HistorySize) ) 
+    {
+        int mode = info->property<int>(Profile::HistoryMode);
+        switch ((Profile::HistoryModeEnum)mode)
+        {
+            case Profile::DisableHistory:
+                    session->setHistoryType( HistoryTypeNone() );
+                break;
+            case Profile::FixedSizeHistory:
+                {
+                    int lines = info->property<int>(Profile::HistorySize);
+                    session->setHistoryType( CompactHistoryType(lines) );
+                }
+                break;
+            case Profile::UnlimitedHistory:
+                    session->setHistoryType( HistoryTypeFile() );
+                break;
+        }
+    }
+
+    // Terminal features
+    if ( apply.shouldApply(Profile::FlowControlEnabled) )
+        session->setFlowControlEnabled( info->property<bool>(Profile::FlowControlEnabled) );
+
+    // Encoding
+    if ( apply.shouldApply(Profile::DefaultEncoding) )
+    {
+        QByteArray name = info->property<QString>(Profile::DefaultEncoding).toUtf8();
+        session->setCodec( QTextCodec::codecForName(name) );
+    } 
+}
+
+void SessionManager::addProfile(Profile::Ptr type)
+{
+    if ( _types.isEmpty() )
+        _defaultProfile = type;
+ 
+    _types.insert(type);
+
+    emit profileAdded(type);
+}
+
+bool SessionManager::deleteProfile(Profile::Ptr type)
+{
+    bool wasDefault = ( type == defaultProfile() );
+
+    if ( type )
+    {
+        // try to delete the config file
+        if ( type->isPropertySet(Profile::Path) && QFile::exists(type->path()) )
+        {
+            if (!QFile::remove(type->path()))
+            {
+                kWarning() << "Could not delete profile: " << type->path()
+                    << "The file is most likely in a directory which is read-only.";
+
+                return false;
+            }
+        }
+
+        // remove from favorites, profile list, shortcut list etc.
+        setFavorite(type,false);
+        setShortcut(type,QKeySequence());
+        _types.remove(type);
+
+        // mark the profile as hidden so that it does not show up in the 
+        // Manage Profiles dialog and is not saved to disk
+        type->setHidden(true);
+    }
+
+    // if we just deleted the default session type,
+    // replace it with a random type from the list
+    if ( wasDefault )
+    {
+        setDefaultProfile( _types.toList().first() );
+    }
+
+    emit profileRemoved(type);
+
+    return true; 
+}
+void SessionManager::setDefaultProfile(Profile::Ptr info)
+{
+   Q_ASSERT ( _types.contains(info) );
+
+   _defaultProfile = info;
+
+   QString path = info->path();  
+   
+   if ( path.isEmpty() )
+       path = KDE4ProfileWriter().getPath(info);
+
+   QFileInfo fileInfo(path);
+
+   KSharedConfigPtr config = KGlobal::config();
+   KConfigGroup group = config->group("Desktop Entry");
+   group.writeEntry("DefaultProfile",fileInfo.fileName());
+}
+QSet<Profile::Ptr> SessionManager::findFavorites() 
+{
+    if (!_loadedFavorites)
+        loadFavorites();
+
+    return _favorites;
+}
+void SessionManager::setFavorite(Profile::Ptr info , bool favorite)
+{
+    if (!_types.contains(info))
+        addProfile(info);
+
+    if ( favorite && !_favorites.contains(info) )
+    {
+        _favorites.insert(info);
+        emit favoriteStatusChanged(info,favorite);
+    }
+    else if ( !favorite && _favorites.contains(info) )
+    {
+        _favorites.remove(info);
+        emit favoriteStatusChanged(info,favorite);
+    }
+}
+void SessionManager::loadShortcuts()
+{
+    KSharedConfigPtr appConfig = KGlobal::config();
+    KConfigGroup shortcutGroup = appConfig->group("Profile Shortcuts");
+
+    QMap<QString,QString> entries = shortcutGroup.entryMap();
+
+    QMapIterator<QString,QString> iter(entries);
+    while ( iter.hasNext() )
+    {
+        iter.next();
+
+        QKeySequence shortcut = QKeySequence::fromString(iter.key());
+        QString profilePath = iter.value();
+
+        ShortcutData data;
+        data.profilePath = profilePath;
+
+        _shortcuts.insert(shortcut,data);
+    }
+}
+void SessionManager::saveShortcuts()
+{
+    KSharedConfigPtr appConfig = KGlobal::config();
+    KConfigGroup shortcutGroup = appConfig->group("Profile Shortcuts");
+    shortcutGroup.deleteGroup();
+
+    QMapIterator<QKeySequence,ShortcutData> iter(_shortcuts);
+    while ( iter.hasNext() )
+    {
+        iter.next();
+
+        QString shortcutString = iter.key().toString();
+
+        shortcutGroup.writeEntry(shortcutString,
+                iter.value().profilePath);
+    }    
+}
+void SessionManager::setShortcut(Profile::Ptr info , 
+                                 const QKeySequence& keySequence )
+{
+    QKeySequence existingShortcut = shortcut(info);
+    _shortcuts.remove(existingShortcut);
+
+    if (keySequence.isEmpty())
+        return;
+
+    ShortcutData data;
+    data.profileKey = info;
+    data.profilePath = info->path();
+    // TODO - This won't work if the profile doesn't 
+    // have a path yet
+    _shortcuts.insert(keySequence,data);
+
+    emit shortcutChanged(info,keySequence);
+}
+void SessionManager::loadFavorites()
+{
+    KSharedConfigPtr appConfig = KGlobal::config();
+    KConfigGroup favoriteGroup = appConfig->group("Favorite Profiles");
+
+    QSet<QString> favoriteSet;
+
+    if ( favoriteGroup.hasKey("Favorites") )
+    {
+       QStringList list = favoriteGroup.readEntry("Favorites", QStringList());
+       favoriteSet = QSet<QString>::fromList(list);
+    }
+    else
+    {
+       // if there is no favorites key at all, mark the 
+       // supplied 'Shell.profile' as the only favorite
+       favoriteSet << "Shell.profile";
+    }
+
+    // look for favorites amongst those already loaded
+    QSetIterator<Profile::Ptr> iter(_types);
+    while ( iter.hasNext() )
+    {
+         Profile::Ptr profile = iter.next();
+         const QString& path = profile->path();
+         if ( favoriteSet.contains( path ) )
+         {
+             _favorites.insert( profile );
+             favoriteSet.remove(path);
+         }
+    }
+    // load any remaining favorites
+    QSetIterator<QString> unloadedFavoriteIter(favoriteSet);
+    while ( unloadedFavoriteIter.hasNext() )
+    {
+          Profile::Ptr profile = loadProfile(unloadedFavoriteIter.next());
+          if (profile)
+              _favorites.insert(profile);
+    }
+
+    _loadedFavorites = true;
+}
+void SessionManager::saveFavorites()
+{
+    KSharedConfigPtr appConfig = KGlobal::config();
+    KConfigGroup favoriteGroup = appConfig->group("Favorite Profiles");
+
+    QStringList paths;
+    QSetIterator<Profile::Ptr> keyIter(_favorites);
+    while ( keyIter.hasNext() )
+    {
+        Profile::Ptr profile = keyIter.next();
+
+        Q_ASSERT( _types.contains(profile) && profile );
+
+        paths << profile->path();
+    }
+
+    favoriteGroup.writeEntry("Favorites",paths);
+}
+
+QList<QKeySequence> SessionManager::shortcuts() 
+{
+    return _shortcuts.keys();
+}
+
+Profile::Ptr SessionManager::findByShortcut(const QKeySequence& shortcut)
+{
+    Q_ASSERT( _shortcuts.contains(shortcut) );
+
+    if ( !_shortcuts[shortcut].profileKey )
+    {
+        Profile::Ptr key = loadProfile(_shortcuts[shortcut].profilePath);
+        if (!key)
+        {
+            _shortcuts.remove(shortcut);
+            return Profile::Ptr();
+        }
+        _shortcuts[shortcut].profileKey = key;
+    }
+
+    return _shortcuts[shortcut].profileKey;
+}
+
+void SessionManager::sessionProfileCommandReceived(const QString& text)
+{
+    // FIXME: This is inefficient, it creates a new profile instance for
+    // each set of changes applied.  Instead a new profile should be created
+    // only the first time changes are applied to a session
+
+    Session* session = qobject_cast<Session*>(sender());
+    Q_ASSERT( session );
+
+    ProfileCommandParser parser;
+    QHash<Profile::Property,QVariant> changes = parser.parse(text);
+
+    Profile::Ptr newProfile = Profile::Ptr(new Profile(_sessionProfiles[session]));
+    
+    QHashIterator<Profile::Property,QVariant> iter(changes);
+    while ( iter.hasNext() )
+    {
+        iter.next();
+        newProfile->setProperty(iter.key(),iter.value());
+    } 
+
+    _sessionProfiles[session] = newProfile;
+    applyProfile(newProfile,true);
+    emit sessionUpdated(session);
+}
+
+QKeySequence SessionManager::shortcut(Profile::Ptr info) const
+{
+    QMapIterator<QKeySequence,ShortcutData> iter(_shortcuts);
+    while (iter.hasNext())
+    {
+        iter.next();
+        if ( iter.value().profileKey == info 
+             || iter.value().profilePath == info->path() )
+            return iter.key();
+    }
+    
+    return QKeySequence();
+}
+
+void SessionManager::saveSessions(KConfig* config)
+{
+    // The session IDs can't be restored.
+    // So we need to map the old ID to the future new ID.
+    int n = 1;
+    _restoreMapping.clear();
+
+    foreach(Session* session, _sessions)
+    {
+        QString name = QLatin1String("Session") + QString::number(n);
+        KConfigGroup group(config, name);
+
+        group.writePathEntry("Profile",
+                             _sessionProfiles.value(session)->path());
+        session->saveSession(group);
+        _restoreMapping.insert(session, n);
+        n++;
+    }
+
+    KConfigGroup group(config, "Number");
+    group.writeEntry("NumberOfSessions", _sessions.count());
+}
+
+int SessionManager::getRestoreId(Session* session)
+{
+    return _restoreMapping.value(session);
+}
+
+void SessionManager::restoreSessions(KConfig* config)
+{
+    KConfigGroup group(config, "Number");
+    int sessions;
+
+    // Any sessions saved?
+    if ((sessions = group.readEntry("NumberOfSessions", 0)) > 0)
+    {
+        for (int n = 1; n <= sessions; n++)
+        {
+            QString name = QLatin1String("Session") + QString::number(n);
+            KConfigGroup sessionGroup(config, name);
+
+            QString profile = sessionGroup.readPathEntry("Profile", QString());
+            Profile::Ptr ptr = defaultProfile();
+            if (!profile.isEmpty()) ptr = loadProfile(profile);
+
+            Session* session = createSession(ptr);
+            session->restoreSession(sessionGroup);
+        }
+    }
+}
+
+Session* SessionManager::idToSession(int id)
+{
+    Q_ASSERT(id); 
+    foreach(Session* session, _sessions)
+        if (session->sessionId() == id)
+            return session;
+
+    // this should not happen
+    Q_ASSERT(0);
+    return 0;
+}
+
+K_GLOBAL_STATIC( SessionManager , theSessionManager )
+SessionManager* SessionManager::instance()
+{
+    return theSessionManager;
+}
+
+SessionListModel::SessionListModel(QObject* parent)
+: QAbstractListModel(parent)
+{
+}
+
+void SessionListModel::setSessions(const QList<Session*>& sessions)
+{
+    _sessions = sessions;
+
+    foreach(Session* session, sessions)
+        connect(session,SIGNAL(finished()),this,SLOT(sessionFinished()));
+
+    reset();
+}
+QVariant SessionListModel::data(const QModelIndex& index, int role) const
+{
+    Q_ASSERT(index.isValid());
+    
+    int row = index.row();
+    int column = index.column();
+
+    Q_ASSERT( row >= 0 && row < _sessions.count() );
+    Q_ASSERT( column >= 0 && column < 2 );
+
+    switch (role)
+    {
+        case Qt::DisplayRole:
+            if (column == 1)
+                return _sessions[row]->title(Session::DisplayedTitleRole);
+            else if (column == 0)
+                return _sessions[row]->sessionId();
+            break;
+        case Qt::DecorationRole:
+            if (column == 1)
+                return KIcon(_sessions[row]->iconName());
+            else
+                return QVariant();
+    }
+
+    return QVariant();
+}
+QVariant SessionListModel::headerData(int section, Qt::Orientation orientation, 
+                        int role) const
+{
+    if (role != Qt::DisplayRole)
+        return QVariant();
+
+    if (orientation == Qt::Vertical)
+        return QVariant();
+    else
+    {
+        switch (section)
+        {
+            case 0:
+                return i18n("Number");
+            case 1:
+                return i18n("Title");
+            default:
+                return QVariant();
+        }    
+    }
+}
+
+int SessionListModel::columnCount(const QModelIndex&) const
+{
+    return 2;
+}
+int SessionListModel::rowCount(const QModelIndex&) const
+{
+    return _sessions.count();
+}
+QModelIndex SessionListModel::parent(const QModelIndex&) const
+{
+    return QModelIndex();
+}
+void SessionListModel::sessionFinished()
+{
+    Session* session = qobject_cast<Session*>(sender());
+    int row = _sessions.indexOf(session);
+    
+    if (row != -1)
+    {
+        beginRemoveRows(QModelIndex(),row,row);
+        sessionRemoved(session);
+        _sessions.removeAt(row);
+        endRemoveRows();
+    }
+}
+QModelIndex SessionListModel::index(int row, int column, const QModelIndex& parent) const
+{
+    if (hasIndex(row,column,parent))
+        return createIndex(row,column,_sessions[row]);
+    else
+        return QModelIndex();
+}
+
+#include "SessionManager.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/SessionManager.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,448 @@
+/*
+    This source file is part of Konsole, a terminal emulator.
+
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef SESSIONMANAGER_H
+#define SESSIONMANAGER_H
+
+// Qt
+#include <QtGui/QFont>
+#include <QtGui/QKeySequence>
+
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QHash>
+#include <QtCore/QList>
+#include <QtCore/QSet>
+#include <QtCore/QStringList>
+#include <QtCore/QPair>
+#include <QtCore/QPointer>
+#include <QtCore/QVariant>
+#include <QtCore/QStack>
+
+// Konsole
+#include "Profile.h"
+
+class QSignalMapper;
+
+
+namespace Konsole
+{
+
+class Session;
+
+/**
+ * Manages running terminal sessions and the profiles which specify various
+ * settings for terminal sessions and their displays.
+ *
+ * Profiles in the manager have a concept of favorite status, which can be used
+ * by widgets and dialogs in the application decide which sessions to list and
+ * how to display them.  The favorite status of a profile can be altered using
+ * setFavorite() and retrieved using isFavorite() 
+ */
+class KONSOLEPRIVATE_EXPORT SessionManager : public QObject
+{
+Q_OBJECT
+
+public:
+    /** 
+     * Constructs a new session manager and loads information about the available 
+     * profiles.
+     */
+    SessionManager();
+    void setMenuOrder();
+ 
+    /** 
+     * Destroys the SessionManager.  All running sessions should be closed (via closeAll()) and the 
+     * SessionManager's state should be saved via saveState() before the SessionManager is destroyed.
+     */
+    virtual ~SessionManager();
+
+    /** Kill all running sessions. */
+    void closeAll();
+
+    /** Saves state information (favorites, shortcuts, default profile etc.) to disk. */
+    void saveState();
+
+    /**
+     * Returns a list of profiles which have been loaded.
+     * Initially only the profile currently set as the default is loaded.
+     *
+     * Favorite profiles are loaded automatically when findFavorites() is called.
+     *
+     * All other profiles can be loaded by calling loadAllProfiles().  This may
+     * involves opening, reading and parsing all profiles from disk, and
+     * should only be done when necessary.
+     */
+    QList<Profile::Ptr> loadedProfiles() const;
+
+    QList<Profile::Ptr> sortedFavorites();
+
+    /*
+     * Sorts the profile list by menuindex; those without an menuindex, sort by name.
+     *  The menuindex list is first and then the non-menuindex list.
+     *
+     * @param list The profile list to sort
+     */
+    void sortProfiles(QList<Profile::Ptr> &list);
+
+    /**
+     * Searches for available profiles on-disk and returns a list
+     * of paths of profiles which can be loaded.
+     */
+    QStringList availableProfilePaths() const;
+
+    
+    /**
+     * Loads a profile from the specified path and registers 
+     * it with the SessionManager.
+     *
+     * @p path may be relative or absolute.  The path may just be the 
+     * base name of the profile to load (eg. if the profile's full path
+     * is "<konsole data dir>/My Profile.profile" then both
+     * "konsole/My Profile.profile" , "My Profile.profile" and 
+     * "My Profile" will be accepted)
+     *
+     * @return Pointer to a profile which can be passed to createSession()
+     * to create a new session using this profile.
+     */
+    Profile::Ptr loadProfile(const QString& path);
+
+    /**
+     * Updates a @p profile with the changes specified in @p propertyMap.
+     *
+     * All sessions currently using the profile will be updated to reflect the new settings.
+     *
+     * After the profile is updated, the profileChanged() signal will be emitted.
+     *
+     * @param profile The profile to change
+     * @param propertyMap A map between profile properties and values describing the changes
+     * @param persistant If true, the changes are saved to the profile's configuration file,
+     * set this to false if you want to preview possible changes to a profile but do not
+     * wish to make them permanent.
+     */
+    void changeProfile(Profile::Ptr profile , QHash<Profile::Property,QVariant> propertyMap, 
+            bool persistant = true);
+
+    /**
+     * Returns a Profile object describing the default type of session, which is used
+     * if createSession() is called with an empty configPath argument.
+     */
+    Profile::Ptr defaultProfile() const;
+    /**
+     * Returns a Profile object with hard-coded settings which is always available.
+     * This can be used as a parent for new profiles which provides suitable default settings
+     * for all properties.
+     */
+    Profile::Ptr fallbackProfile() const;
+
+    /**
+     * Creates a new session using the settings specified by the specified
+     * profile.
+     *
+     * The new session has no views associated with it.  A new TerminalDisplay view
+     * must be created in order to display the output from the terminal session and
+     * send keyboard or mouse input to it.
+     *
+     * @param profile A profile containing the settings for the new session.  If @p profile 
+     * is null the default profile (see defaultProfile()) will be used.
+     */
+    Session* createSession(Profile::Ptr profile = Profile::Ptr());
+
+    /** Returns the profile associated with a session. */
+    Profile::Ptr sessionProfile(Session* session) const;
+    /** Sets the profile associated with a session. */
+    void setSessionProfile(Session* session, Profile::Ptr profile);
+
+    /**
+     * Updates a session's properties to match its current profile.
+     */
+    void updateSession(Session* session);
+
+    /**
+     * Returns a list of active sessions.
+     */
+    const QList<Session*> sessions();
+
+    /**
+     * Deletes the configuration file used to store a profile.
+     * The profile will continue to exist while sessions are still using it.  The profile
+     * will be marked as hidden (see Profile::setHidden() ) so that it does not show
+     * up in profile lists and future changes to the profile are not stored to disk.
+     *
+     * Returns true if the profile was successfully deleted or false otherwise.
+     */
+    bool deleteProfile(Profile::Ptr profile);
+
+    /**
+     * Sets the @p profile as the default profile for new sessions created
+     * with createSession()
+     */
+    void setDefaultProfile(Profile::Ptr profile);
+
+    /**
+     * Returns the set of the user's favorite profiles.
+     */
+    QSet<Profile::Ptr> findFavorites();
+
+    /**
+     * Returns the list of shortcut key sequences which
+     * can be used to create new sessions based on
+     * existing profiles
+     *
+     * When one of the shortcuts is activated, 
+     * use findByShortcut() to load the profile associated
+     * with the shortcut. 
+     */
+    QList<QKeySequence> shortcuts();
+
+    /**
+     * Finds and loads the profile associated with 
+     * the specified @p shortcut key sequence and returns a pointer to it.
+     */
+    Profile::Ptr findByShortcut(const QKeySequence& shortcut);
+
+    /**
+     * Associates a shortcut with a particular profile.
+     */
+    void setShortcut(Profile::Ptr profile , const QKeySequence& shortcut);
+
+    /** Returns the shortcut associated with a particular profile. */
+    QKeySequence shortcut(Profile::Ptr profile) const;
+
+    /** 
+     * Registers a new type of session. 
+     * The favorite status of the session ( as returned by isFavorite() ) is set to false by default.
+     */
+    void addProfile(Profile::Ptr type);
+
+    /**
+     * Specifies whether a profile should be included in the user's
+     * list of favorite sessions.
+     */
+    void setFavorite(Profile::Ptr profile , bool favorite);
+
+    /** 
+     * Loads all available profiles.  This involves reading each
+     * profile configuration file from disk and parsing it.  
+     * Therefore it should only be done when necessary.
+     */
+    void loadAllProfiles();
+
+    /**
+     * Sets the global session manager instance.
+     */
+    static void setInstance(SessionManager* instance);
+    /**
+     * Returns the session manager instance.
+     */
+    static SessionManager* instance();
+
+    // session management
+    void saveSessions(KConfig* config);
+    int  getRestoreId(Session* session);
+    void restoreSessions(KConfig* config);
+    Session *idToSession(int id);
+
+signals:
+    /** Emitted when a profile is added to the manager. */
+    void profileAdded(Profile::Ptr ptr);
+    /** Emitted when a profile is removed from the manager. */
+    void profileRemoved(Profile::Ptr ptr);
+    /** Emitted when a profile's properties are modified. */
+    void profileChanged(Profile::Ptr ptr);
+
+    /** 
+     * Emitted when a session's settings are updated to match 
+     * its current profile. 
+     */
+    void sessionUpdated(Session* session);
+
+    /** 
+     * Emitted when the favorite status of a profile changes. 
+     * 
+     * @param profile The profile to change 
+     * @param favorite Specifies whether the session is a favorite or not 
+     */
+    void favoriteStatusChanged(Profile::Ptr profile , bool favorite);
+
+    /** 
+     * Emitted when the shortcut for a profile is changed. 
+     *
+     * @param profile The profile whoose status was changed
+     * @param newShortcut The new shortcut key sequence for the profile
+     */
+    void shortcutChanged(Profile::Ptr profile , const QKeySequence& newShortcut);
+
+protected Q_SLOTS:
+
+    /**
+     * Called to inform the manager that a session has finished executing.
+     *
+     * @param session The Session which has finished executing.
+     */
+    void sessionTerminated( QObject* session );
+
+private slots:
+    void sessionProfileCommandReceived(const QString& text);
+
+private:
+    
+    
+    // loads the mappings between shortcut key sequences and 
+    // profile paths
+    void loadShortcuts();
+    // saves the mappings between shortcut key sequences and
+    // profile paths
+    void saveShortcuts();
+
+    //loads the set of favorite sessions
+    void loadFavorites();
+    //saves the set of favorite sessions
+    void saveFavorites();
+    // saves a profile to a file
+    // returns the path to which the profile was saved, which will
+    // be the same as the path property of profile if valid or a newly generated path
+    // otherwise
+    QString saveProfile(Profile::Ptr profile);
+
+    // applies updates to a profile
+    // to all sessions currently using that profile
+    // if modifiedPropertiesOnly is true, only properties which
+    // are set in the profile @p key are updated
+    void applyProfile(Profile::Ptr ptr , bool modifiedPropertiesOnly);
+    // apples updates to the profile @p info to the session @p session
+    // if modifiedPropertiesOnly is true, only properties which
+    // are set in @p info are update ( ie. properties for which info->isPropertySet(<property>) 
+    // returns true )
+    void applyProfile(Session* session , const Profile::Ptr info , bool modifiedPropertiesOnly); 
+
+    QSet<Profile::Ptr> _types;
+    QHash<Session*,Profile::Ptr> _sessionProfiles;
+    QHash<Session*,int> _restoreMapping;
+
+    struct ShortcutData
+    {
+        Profile::Ptr profileKey;
+        QString profilePath;
+    };
+    QMap<QKeySequence,ShortcutData> _shortcuts; // shortcut keys -> profile path
+
+    QList<Session*> _sessions; // list of running sessions
+
+    Profile::Ptr _defaultProfile; 
+    Profile::Ptr _fallbackProfile;
+
+    QSet<Profile::Ptr> _favorites; // list of favorite profiles
+
+    bool _loadedAllProfiles; // set to true after loadAllProfiles has been called
+    bool _loadedFavorites; // set to true after loadFavorites has been called
+    QSignalMapper* _sessionMapper;
+};
+
+/** Utility class to simplify code in SessionManager::applyProfile(). */
+class ShouldApplyProperty 
+{
+public:
+    ShouldApplyProperty(const Profile::Ptr profile , bool modifiedOnly) : 
+    _profile(profile) , _modifiedPropertiesOnly(modifiedOnly) {}
+
+    bool shouldApply(Profile::Property property) const
+    {
+        return !_modifiedPropertiesOnly || _profile->isPropertySet(property); 
+    }
+private:
+    const Profile::Ptr _profile;
+    bool _modifiedPropertiesOnly;
+};
+
+/**
+ * PopStackOnExit is a utility to remove all values from a QStack which are added during
+ * the lifetime of a PopStackOnExit instance.
+ *
+ * When a PopStackOnExit instance is destroyed, elements are removed from the stack
+ * until the stack count is reduced the value when the PopStackOnExit instance was created.
+ */
+template <class T>
+class PopStackOnExit
+{
+public:
+    PopStackOnExit(QStack<T>& stack) : _stack(stack) , _count(stack.count()) {} 
+    ~PopStackOnExit() 
+    { 
+        while (_stack.count() > _count) 
+            _stack.pop(); 
+    }
+private:
+    QStack<T>& _stack;
+    int _count;
+};
+/** 
+ * Item-view model which contains a flat list of sessions.
+ * After constructing the model, call setSessions() to set the sessions displayed
+ * in the list.  When a session ends (after emitting the finished() signal) it is
+ * automatically removed from the list.
+ *
+ * The internal pointer for each item in the model (index.internalPointer()) is the
+ * associated Session*
+ */
+class SessionListModel : public QAbstractListModel
+{
+Q_OBJECT
+
+public:
+    SessionListModel(QObject* parent = 0);
+
+    /** 
+     * Sets the list of sessions displayed in the model.  
+     * To display all sessions that are currently running in the list,
+     * call setSessions(SessionManager::instance()->sessions())
+     */
+    void setSessions(const QList<Session*>& sessions);
+
+    // reimplemented from QAbstractItemModel
+    virtual QModelIndex index(int row, int column, const QModelIndex& parent) const;
+    virtual QVariant data(const QModelIndex& index, int role) const;
+    virtual QVariant headerData(int section, Qt::Orientation orientation, 
+                        int role) const;
+    virtual int columnCount(const QModelIndex& parent) const;
+    virtual int rowCount(const QModelIndex& parent) const;
+    virtual QModelIndex parent(const QModelIndex& index) const;
+
+protected:
+    virtual void sessionRemoved(Session*) {}
+
+private slots:
+    void sessionFinished();
+
+private:
+    QList<Session*> _sessions;    
+};
+
+}
+#endif //SESSIONMANAGER_H
+
+/*
+  Local Variables:
+  mode: c++
+  c-file-style: "stroustrup"
+  indent-tabs-mode: nil
+  tab-width: 4
+  End:
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ShellCommand.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,179 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ShellCommand.h"
+
+// Qt
+//#include <KShell>
+//#include <KDebug>
+
+using namespace Konsole;
+
+// expands environment variables in 'text'
+// function copied from kdelibs/kio/kio/kurlcompletion.cpp
+static bool expandEnv(QString& text);
+
+ShellCommand::ShellCommand(const QString& fullCommand)
+{
+  //_arguments = KShell::splitArgs(fullCommand);
+  bool inQuotes = false;
+
+    QString builder;
+
+    for ( int i = 0 ; i < fullCommand.count() ; i++ )
+    {
+        QChar ch = fullCommand[i];
+
+        const bool isLastChar = ( i == fullCommand.count() - 1 );
+        const bool isQuote = ( ch == '\'' || ch == '\"' );
+
+        if ( !isLastChar && isQuote )
+            inQuotes = !inQuotes;
+        else
+        {
+            if ( (!ch.isSpace() || inQuotes) && !isQuote )
+                builder.append(ch);
+
+            if ( (ch.isSpace() && !inQuotes) || ( i == fullCommand.count()-1 ) )
+            {
+                _arguments << builder;
+                builder.clear();
+            }
+        }
+    }
+
+}
+ShellCommand::ShellCommand(const QString& command , const QStringList& arguments)
+{
+    _arguments = arguments;
+    
+    if ( !_arguments.isEmpty() )
+        _arguments[0] == command;
+}
+QString ShellCommand::fullCommand() const
+{
+    QStringList quotedArgs(_arguments);
+    for (int i=0;i<quotedArgs.count();i++)
+    {
+        QString arg = quotedArgs.at(i);
+        bool hasSpace = false;
+        for (int j=0;j<arg.count();j++)
+            if (arg[j].isSpace())
+                hasSpace = true;
+        if (hasSpace)
+            quotedArgs[i] = '\"' + arg + '\"';
+    }
+    return quotedArgs.join(QChar(' '));
+}
+QString ShellCommand::command() const
+{
+    if ( !_arguments.isEmpty() )
+        return _arguments[0];
+    else
+        return QString();
+}
+QStringList ShellCommand::arguments() const
+{
+    return _arguments;
+}
+bool ShellCommand::isRootCommand() const
+{
+    Q_ASSERT(0); // not implemented yet
+    return false;
+}
+bool ShellCommand::isAvailable() const
+{
+    Q_ASSERT(0); // not implemented yet
+    return false; 
+}
+QStringList ShellCommand::expand(const QStringList& items)
+{
+    QStringList result;
+
+    foreach( const QString &item , items )
+        result << expand(item);
+
+    return result;
+}
+QString ShellCommand::expand(const QString& text)
+{
+    QString result = text;
+    expandEnv(result);
+    return result;
+}
+
+/*
+ * expandEnv
+ *
+ * Expand environment variables in text. Escaped '$' characters are ignored.
+ * Return true if any variables were expanded
+ */
+static bool expandEnv( QString &text )
+{
+    // Find all environment variables beginning with '$'
+    //
+    int pos = 0;
+
+    bool expanded = false;
+
+    while ( (pos = text.indexOf(QLatin1Char('$'), pos)) != -1 ) {
+
+        // Skip escaped '$'
+        //
+        if ( pos > 0 && text.at(pos-1) == QLatin1Char('\\') ) {
+            pos++;
+        }
+        // Variable found => expand
+        //
+        else {
+            // Find the end of the variable = next '/' or ' '
+            //
+            int pos2 = text.indexOf( QLatin1Char(' '), pos+1 );
+            int pos_tmp = text.indexOf( QLatin1Char('/'), pos+1 );
+
+            if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) )
+                pos2 = pos_tmp;
+
+            if ( pos2 == -1 )
+                pos2 = text.length();
+
+            // Replace if the variable is terminated by '/' or ' '
+            // and defined
+            //
+            if ( pos2 >= 0 ) {
+                int len    = pos2 - pos;
+                QString key    = text.mid( pos+1, len-1);
+                QString value =
+                    QString::fromLocal8Bit( qgetenv(key.toLocal8Bit()) );
+
+                if ( !value.isEmpty() ) {
+                    expanded = true;
+                    text.replace( pos, len, value );
+                    pos = pos + value.length();
+                }
+                else {
+                    pos = pos2;
+                }
+            }
+        }
+    }
+
+    return expanded;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ShellCommand.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,92 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef SHELLCOMMAND_H
+#define SHELLCOMMAND_H
+
+// Qt
+#include <QtCore/QStringList>
+
+namespace Konsole
+{
+
+/** 
+ * A class to parse and extract information about shell commands. 
+ *
+ * ShellCommand can be used to:
+ *
+ * <ul>
+ *      <li>Take a command-line (eg "/bin/sh -c /path/to/my/script") and split it
+ *          into its component parts (eg. the command "/bin/sh" and the arguments
+ *          "-c","/path/to/my/script")
+ *      </li>
+ *      <li>Take a command and a list of arguments and combine them to 
+ *          form a complete command line.
+ *      </li>
+ *      <li>Determine whether the binary specified by a command exists in the
+ *          user's PATH.
+ *      </li>
+ *      <li>Determine whether a command-line specifies the execution of
+ *          another command as the root user using su/sudo etc.
+ *      </li>
+ * </ul> 
+ */
+class ShellCommand
+{
+public:
+    /**
+     * Constructs a ShellCommand from a command line.
+     *
+     * @param fullCommand The command line to parse.  
+     */
+    ShellCommand(const QString& fullCommand);
+    /**
+     * Constructs a ShellCommand with the specified @p command and @p arguments.
+     */
+    ShellCommand(const QString& command , const QStringList& arguments);
+
+    /** Returns the command. */
+    QString command() const;
+    /** Returns the arguments. */
+    QStringList arguments() const;
+
+    /** 
+     * Returns the full command line. 
+     */
+    QString fullCommand() const;
+
+    /** Returns true if this is a root command. */
+    bool isRootCommand() const;
+    /** Returns true if the program specified by @p command() exists. */
+    bool isAvailable() const;
+
+    /** Expands environment variables in @p text .*/
+    static QString expand(const QString& text);
+
+    /** Expands environment variables in each string in @p list. */
+    static QStringList expand(const QStringList& items);
+
+private:
+    QStringList _arguments;    
+};
+
+}
+
+#endif // SHELLCOMMAND_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/TabTitleFormatAction.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,104 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "TabTitleFormatAction.h"
+
+// Qt
+#include <QList>
+#include <QMenu>
+
+// KDE
+#include <KLocale>
+
+using namespace Konsole;
+
+const TabTitleFormatAction::Element TabTitleFormatAction::_localElements[] = 
+{
+    { "%n" , I18N_NOOP("Program Name") },
+    { "%d" , I18N_NOOP("Current Directory (Short)") },
+    { "%D" , I18N_NOOP("Current Directory (Long)") },
+    { "%w" , I18N_NOOP("Window Title Set by Shell") },
+    { "%#" , I18N_NOOP("Session Number") },
+    { "%u" , I18N_NOOP("User Name") }
+};
+const int TabTitleFormatAction::_localElementCount = 6;
+const TabTitleFormatAction::Element TabTitleFormatAction::_remoteElements[] =
+{
+    { "%u" , I18N_NOOP("User Name") },
+    { "%h" , I18N_NOOP("Remote Host (Short)") },
+    { "%H" , I18N_NOOP("Remote Host (Long)") },
+    { "%w" , I18N_NOOP("Window Title Set by Shell") },
+    { "%#" , I18N_NOOP("Session Number") }
+};
+const int TabTitleFormatAction::_remoteElementCount = 5;
+
+TabTitleFormatAction::TabTitleFormatAction(QObject* parent)
+    : QAction(parent)
+    , _context(Session::LocalTabTitle)
+{
+    setMenu( new QMenu() );
+    connect( menu() , SIGNAL(triggered(QAction*)) , this , SLOT(fireElementSelected(QAction*)) );
+}
+TabTitleFormatAction::~TabTitleFormatAction()
+{
+    menu()->deleteLater();
+}
+void TabTitleFormatAction::fireElementSelected(QAction* action)
+{
+    emit dynamicElementSelected(action->data().value<QString>());
+}
+void TabTitleFormatAction::setContext(Session::TabTitleContext context)
+{
+    _context = context;
+
+    menu()->clear();
+
+    QList<QAction*> list;
+    
+    int count = 0;
+    const Element* array = 0;
+
+    if ( context == Session::LocalTabTitle )
+    {
+        count = _localElementCount;
+        array = _localElements;    
+    }
+    else if ( context == Session::RemoteTabTitle )
+    {
+        count = _remoteElementCount;
+        array = _remoteElements;
+    }
+     
+    for ( int i = 0 ; i < count ; i++ )
+    {
+        QAction* action = new QAction(i18n(array[i].description),this);
+        action->setData(array[i].element);
+        list << action;
+    }
+
+    menu()->addActions(list);
+}
+Session::TabTitleContext TabTitleFormatAction::context() const
+{
+    return _context;
+}
+
+#include "TabTitleFormatAction.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/TabTitleFormatAction.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,66 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef TABTITLEFORMATACTION_H
+#define TABTITLEFORMATACTION_H
+
+// Qt
+#include <QAction>
+
+// Konsole
+#include "Session.h"
+
+namespace Konsole
+{
+
+class TabTitleFormatAction : public QAction
+{
+Q_OBJECT
+
+public:
+    TabTitleFormatAction(QObject* parent);
+    ~TabTitleFormatAction();
+
+    void setContext(Session::TabTitleContext context);
+    Session::TabTitleContext context() const;
+
+signals:
+    void dynamicElementSelected(const QString&);
+  
+private slots:
+    void fireElementSelected(QAction*);
+
+private:
+    Session::TabTitleContext _context;
+    
+    struct Element
+    {
+        QString element;
+        const char *description;
+    };
+    static const Element _localElements[];
+    static const int _localElementCount;
+    static const Element _remoteElements[];
+    static const int _remoteElementCount;
+
+};
+
+}
+
+#endif // TABTITLEFORMATACTION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/TerminalCharacterDecoder.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,251 @@
+/*
+    This file is part of Konsole, an X terminal.
+    
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+    
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser 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 Lesser 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 "TerminalCharacterDecoder.h"
+
+// Qt
+#include <QtCore/QTextStream>
+
+// KDE
+//#include <kdebug.h>
+
+// Konsole
+#include "konsole_wcwidth.h"
+
+using namespace Konsole;
+PlainTextDecoder::PlainTextDecoder()
+ : _output(0)
+ , _includeTrailingWhitespace(true)
+ , _recordLinePositions(false)
+{
+
+}
+void PlainTextDecoder::setTrailingWhitespace(bool enable)
+{
+    _includeTrailingWhitespace = enable;
+}
+bool PlainTextDecoder::trailingWhitespace() const
+{
+    return _includeTrailingWhitespace;
+}
+void PlainTextDecoder::begin(QTextStream* output)
+{
+   _output = output;
+   if (!_linePositions.isEmpty())
+       _linePositions.clear();
+}
+void PlainTextDecoder::end()
+{
+    _output = 0;
+}
+
+void PlainTextDecoder::setRecordLinePositions(bool record)
+{
+    _recordLinePositions = record;
+}
+QList<int> PlainTextDecoder::linePositions() const
+{
+    return _linePositions;
+}
+void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
+                             )
+{
+    Q_ASSERT( _output );
+
+    if (_recordLinePositions && _output->string())
+    {
+        int pos = _output->string()->count();
+        _linePositions << pos;
+    }
+
+    //TODO should we ignore or respect the LINE_WRAPPED line property?
+
+    //note:  we build up a QString and send it to the text stream rather writing into the text
+    //stream a character at a time because it is more efficient.
+    //(since QTextStream always deals with QStrings internally anyway)
+    QString plainText;
+    plainText.reserve(count);
+   
+    int outputCount = count;
+
+    // if inclusion of trailing whitespace is disabled then find the end of the
+    // line
+    if ( !_includeTrailingWhitespace )
+    {
+        for (int i = count-1 ; i >= 0 ; i--)
+        {
+            if ( characters[i].character != ' '  )
+                break;
+            else
+                outputCount--;
+        }
+    }
+    
+    for (int i=0;i<outputCount;)
+    {
+        plainText.append( QChar(characters[i].character) );
+        i += qMax(1,konsole_wcwidth(characters[i].character));
+    }
+    *_output << plainText;
+}
+
+HTMLDecoder::HTMLDecoder() :
+        _output(0)
+    ,_colorTable(base_color_table)
+       ,_innerSpanOpen(false)
+       ,_lastRendition(DEFAULT_RENDITION)
+{
+    
+}
+
+void HTMLDecoder::begin(QTextStream* output)
+{
+    _output = output;
+
+    QString text;
+
+    //open monospace span
+    openSpan(text,"font-family:monospace");
+
+    *output << text;
+}
+
+void HTMLDecoder::end()
+{
+    Q_ASSERT( _output );
+
+    QString text;
+
+    closeSpan(text);
+
+    *_output << text;
+
+    _output = 0;
+
+}
+
+//TODO: Support for LineProperty (mainly double width , double height)
+void HTMLDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
+                            )
+{
+    Q_ASSERT( _output );
+
+    QString text;
+
+    int spaceCount = 0;
+        
+    for (int i=0;i<count;i++)
+    {
+        QChar ch(characters[i].character);
+
+        //check if appearance of character is different from previous char
+        if ( characters[i].rendition != _lastRendition  ||
+             characters[i].foregroundColor != _lastForeColor  ||
+             characters[i].backgroundColor != _lastBackColor )
+        {
+            if ( _innerSpanOpen )
+                    closeSpan(text);
+
+            _lastRendition = characters[i].rendition;
+            _lastForeColor = characters[i].foregroundColor;
+            _lastBackColor = characters[i].backgroundColor;
+            
+            //build up style string
+            QString style;
+
+            bool useBold;
+            ColorEntry::FontWeight weight = characters[i].fontWeight(_colorTable);
+            if (weight == ColorEntry::UseCurrentFormat)
+                useBold = _lastRendition & RE_BOLD;
+            else
+                useBold = weight == ColorEntry::Bold;
+            
+            if (useBold)
+                style.append("font-weight:bold;");
+
+            if ( _lastRendition & RE_UNDERLINE )
+                    style.append("font-decoration:underline;");
+        
+            //colours - a colour table must have been defined first
+            if ( _colorTable )    
+            {
+                style.append( QString("color:%1;").arg(_lastForeColor.color(_colorTable).name() ) );
+
+                if (!characters[i].isTransparent(_colorTable))
+                {
+                    style.append( QString("background-color:%1;").arg(_lastBackColor.color(_colorTable).name() ) );
+                }
+            }
+        
+            //open the span with the current style    
+            openSpan(text,style);
+            _innerSpanOpen = true;
+        }
+
+        //handle whitespace
+        if (ch.isSpace())
+            spaceCount++;
+        else
+            spaceCount = 0;
+        
+
+        //output current character
+        if (spaceCount < 2)
+        {
+            //escape HTML tag characters and just display others as they are
+            if ( ch == '<' )
+                text.append("&lt;");
+            else if (ch == '>')
+                    text.append("&gt;");
+            else    
+                    text.append(ch);
+        }
+        else
+        {
+            text.append("&nbsp;"); //HTML truncates multiple spaces, so use a space marker instead
+        }
+        
+    }
+
+    //close any remaining open inner spans
+    if ( _innerSpanOpen )
+        closeSpan(text);
+
+    //start new line
+    text.append("<br>");
+    
+    *_output << text;
+}
+void HTMLDecoder::openSpan(QString& text , const QString& style)
+{
+    text.append( QString("<span style=\"%1\">").arg(style) );
+}
+
+void HTMLDecoder::closeSpan(QString& text)
+{
+    text.append("</span>");
+}
+
+void HTMLDecoder::setColorTable(const ColorEntry* table)
+{
+    _colorTable = table;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/TerminalCharacterDecoder.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,150 @@
+/*
+    This file is part of Konsole, an X terminal.
+    
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+    
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser 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 Lesser 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.
+*/
+
+#ifndef TERMINAL_CHARACTER_DECODER_H
+#define TERMINAL_CHARACTER_DECODER_H
+
+#include "Character.h"
+
+#include <QList>
+
+class QTextStream;
+
+namespace Konsole
+{
+
+/**
+ * Base class for terminal character decoders
+ *
+ * The decoder converts lines of terminal characters which consist of a unicode character, foreground
+ * and background colours and other appearance-related properties into text strings.
+ *
+ * Derived classes may produce either plain text with no other colour or appearance information, or
+ * they may produce text which incorporates these additional properties. 
+ */
+class TerminalCharacterDecoder
+{
+public:
+    virtual ~TerminalCharacterDecoder() {}
+
+    /** Begin decoding characters.  The resulting text is appended to @p output. */
+    virtual void begin(QTextStream* output) = 0;
+    /** End decoding. */
+    virtual void end() = 0;
+
+    /**
+     * Converts a line of terminal characters with associated properties into a text string
+     * and writes the string into an output QTextStream.
+     *
+     * @param characters An array of characters of length @p count.
+     * @param count The number of characters
+     * @param properties Additional properties which affect all characters in the line
+     */
+    virtual void decodeLine(const Character* const characters, 
+                            int count,
+                            LineProperty properties) = 0; 
+};
+
+/**
+ * A terminal character decoder which produces plain text, ignoring colours and other appearance-related
+ * properties of the original characters.
+ */
+class PlainTextDecoder : public TerminalCharacterDecoder
+{
+public:
+    PlainTextDecoder(); 
+
+    /** 
+     * Set whether trailing whitespace at the end of lines should be included 
+     * in the output.
+     * Defaults to true.
+     */
+    void setTrailingWhitespace(bool enable);
+    /**
+     * Returns whether trailing whitespace at the end of lines is included
+     * in the output.
+     */
+    bool trailingWhitespace() const;
+    /** 
+     * Returns of character positions in the output stream
+     * at which new lines where added.  Returns an empty if setTrackLinePositions() is false or if 
+     * the output device is not a string.
+     */
+    QList<int> linePositions() const;
+    /** Enables recording of character positions at which new lines are added.  See linePositions() */
+    void setRecordLinePositions(bool record);
+
+    virtual void begin(QTextStream* output);
+    virtual void end();
+
+    virtual void decodeLine(const Character* const characters,
+                            int count,
+                            LineProperty properties);    
+
+    
+private:
+    QTextStream* _output;
+    bool _includeTrailingWhitespace;
+
+    bool _recordLinePositions;
+    QList<int> _linePositions;
+};
+
+/**
+ * A terminal character decoder which produces pretty HTML markup
+ */
+class HTMLDecoder : public TerminalCharacterDecoder
+{
+public:
+    /** 
+     * Constructs an HTML decoder using a default black-on-white color scheme.
+     */
+    HTMLDecoder();
+
+    /**
+     * Sets the colour table which the decoder uses to produce the HTML colour codes in its
+     * output
+     */
+    void setColorTable( const ColorEntry* table );
+        
+    virtual void decodeLine(const Character* const characters,
+                            int count,
+                            LineProperty properties);
+
+    virtual void begin(QTextStream* output);
+    virtual void end();
+
+private:
+    void openSpan(QString& text , const QString& style);
+    void closeSpan(QString& text);
+
+    QTextStream* _output;
+    const ColorEntry* _colorTable;
+    bool _innerSpanOpen; 
+    quint8 _lastRendition;
+    CharacterColor _lastForeColor;
+    CharacterColor _lastBackColor;
+
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/TerminalDisplay.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,2987 @@
+/*
+    This file is part of Konsole, a terminal emulator for KDE.
+    
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+    
+    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 "TerminalDisplay.h"
+
+// Qt
+#include <QtGui/QApplication>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QClipboard>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QEvent>
+#include <QtCore/QTime>
+#include <QtCore/QFile>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QPainter>
+#include <QtGui/QPixmap>
+#include <QtGui/QScrollBar>
+#include <QtGui/QStyle>
+#include <QtCore/QTimer>
+#include <QtGui/QToolTip>
+#include <QtCore/QTextStream>
+
+// KDE
+//#include <kshell.h>
+//#include <KColorScheme>
+//#include <KCursor>
+//#include <kdebug.h>
+//#include <KLocale>
+//#include <KMenu>
+//#include <KNotification>
+//#include <KGlobalSettings>
+//#include <KShortcut>
+//#include <KIO/NetAccess>
+
+// Konsole
+//#include <config-apps.h>
+#include "Filter.h"
+#include "konsole_wcwidth.h"
+#include "ScreenWindow.h"
+#include "TerminalCharacterDecoder.h"
+
+using namespace Konsole;
+
+#ifndef loc
+#define loc(X,Y) ((Y)*_columns+(X))
+#endif
+
+#define yMouseScroll 1
+
+#define REPCHAR   "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+                  "abcdefgjijklmnopqrstuvwxyz" \
+                  "0123456789./+@"
+
+const ColorEntry Konsole::base_color_table[TABLE_COLORS] =
+// The following are almost IBM standard color codes, with some slight
+// gamma correction for the dim colors to compensate for bright X screens.
+// It contains the 8 ansiterm/xterm colors in 2 intensities.
+{
+  // Fixme: could add faint colors here, also.
+  // normal
+  ColorEntry(QColor(0x00,0x00,0x00), 0), ColorEntry( QColor(0xB2,0xB2,0xB2), 1), // Dfore, Dback
+  ColorEntry(QColor(0x00,0x00,0x00), 0), ColorEntry( QColor(0xB2,0x18,0x18), 0), // Black, Red
+  ColorEntry(QColor(0x18,0xB2,0x18), 0), ColorEntry( QColor(0xB2,0x68,0x18), 0), // Green, Yellow
+  ColorEntry(QColor(0x18,0x18,0xB2), 0), ColorEntry( QColor(0xB2,0x18,0xB2), 0), // Blue, Magenta
+  ColorEntry(QColor(0x18,0xB2,0xB2), 0), ColorEntry( QColor(0xB2,0xB2,0xB2), 0), // Cyan, White
+  // intensiv
+  ColorEntry(QColor(0x00,0x00,0x00), 0), ColorEntry( QColor(0xFF,0xFF,0xFF), 1),
+  ColorEntry(QColor(0x68,0x68,0x68), 0), ColorEntry( QColor(0xFF,0x54,0x54), 0),
+  ColorEntry(QColor(0x54,0xFF,0x54), 0), ColorEntry( QColor(0xFF,0xFF,0x54), 0),
+  ColorEntry(QColor(0x54,0x54,0xFF), 0), ColorEntry( QColor(0xFF,0x54,0xFF), 0),
+  ColorEntry(QColor(0x54,0xFF,0xFF), 0), ColorEntry( QColor(0xFF,0xFF,0xFF), 0)
+};
+
+// scroll increment used when dragging selection at top/bottom of window.
+
+// static
+bool TerminalDisplay::_antialiasText = true;
+bool TerminalDisplay::HAVE_TRANSPARENCY = false;
+
+// we use this to force QPainter to display text in LTR mode
+// more information can be found in: http://unicode.org/reports/tr9/ 
+const QChar LTR_OVERRIDE_CHAR( 0x202D );
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                                Colors                                     */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
+
+   Code        0       1       2       3       4       5       6       7
+   ----------- ------- ------- ------- ------- ------- ------- ------- -------
+   ANSI  (bgr) Black   Red     Green   Yellow  Blue    Magenta Cyan    White
+   IBMPC (rgb) Black   Blue    Green   Cyan    Red     Magenta Yellow  White
+*/
+
+ScreenWindow* TerminalDisplay::screenWindow() const
+{
+    return _screenWindow;
+}
+void TerminalDisplay::setScreenWindow(ScreenWindow* window)
+{
+    // disconnect existing screen window if any
+    if ( _screenWindow )
+    {
+        disconnect( _screenWindow , 0 , this , 0 );
+    }
+
+    _screenWindow = window;
+
+    if ( window )
+    {
+
+// TODO: Determine if this is an issue.
+//#warning "The order here is not specified - does it matter whether updateImage or updateLineProperties comes first?"
+        connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateLineProperties()) );
+        connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateImage()) );
+        window->setWindowLines(_lines);
+    }
+}
+
+const ColorEntry* TerminalDisplay::colorTable() const
+{
+  return _colorTable;
+}
+void TerminalDisplay::setBackgroundColor(const QColor& color)
+{
+    _colorTable[DEFAULT_BACK_COLOR].color = color;
+    QPalette p = palette();
+      p.setColor( backgroundRole(), color ); 
+      setPalette( p );
+
+      // Avoid propagating the palette change to the scroll bar 
+      _scrollBar->setPalette( QApplication::palette() );  
+
+    update();
+}
+void TerminalDisplay::setForegroundColor(const QColor& color)
+{
+    _colorTable[DEFAULT_FORE_COLOR].color = color;
+
+    update();
+}
+void TerminalDisplay::setColorTable(const ColorEntry table[])
+{
+  for (int i = 0; i < TABLE_COLORS; i++)
+      _colorTable[i] = table[i];
+
+  setBackgroundColor(_colorTable[DEFAULT_BACK_COLOR].color);
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                                   Font                                    */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+/*
+   The VT100 has 32 special graphical characters. The usual vt100 extended
+   xterm fonts have these at 0x00..0x1f.
+
+   QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
+   come in here as proper unicode characters.
+
+   We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
+   from unicode to 0x00..0x1f. The remaining translation is then left to the
+   QCodec.
+*/
+
+static inline bool isLineChar(quint16 c) { return ((c & 0xFF80) == 0x2500);}
+static inline bool isLineCharString(const QString& string)
+{
+        return (string.length() > 0) && (isLineChar(string.at(0).unicode()));
+}
+                        
+
+// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
+
+unsigned short Konsole::vt100_graphics[32] =
+{ // 0/8     1/9    2/10    3/11    4/12    5/13    6/14    7/15
+  0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
+  0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
+  0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
+  0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
+};
+
+void TerminalDisplay::fontChange(const QFont&)
+{
+  QFontMetrics fm(font());
+  _fontHeight = fm.height() + _lineSpacing;
+
+  // waba TerminalDisplay 1.123:
+  // "Base character width on widest ASCII character. This prevents too wide
+  //  characters in the presence of double wide (e.g. Japanese) characters."
+  // Get the width from representative normal width characters
+  _fontWidth = qRound((double)fm.width(REPCHAR)/(double)strlen(REPCHAR));
+
+  _fixedFont = true;
+
+  int fw = fm.width(REPCHAR[0]);
+  for(unsigned int i=1; i< strlen(REPCHAR); i++)
+  {
+    if (fw != fm.width(REPCHAR[i]))
+    {
+      _fixedFont = false;
+      break;
+    }
+  }
+
+  if (_fontWidth < 1)
+    _fontWidth=1;
+
+  _fontAscent = fm.ascent();
+
+  emit changedFontMetricSignal( _fontHeight, _fontWidth );
+  propagateSize();
+  update();
+}
+
+void TerminalDisplay::setVTFont(const QFont& f)
+{
+  QFont font = f;
+
+  QFontMetrics metrics(font);
+
+  if ( !QFontInfo(font).fixedPitch() )
+  {
+      kWarning() << "Using an unsupported variable-width font in the terminal.  This may produce display errors.";
+  }
+
+  if ( metrics.height() < height() && metrics.maxWidth() < width() )
+  {
+    // hint that text should be drawn without anti-aliasing.  
+    // depending on the user's font configuration, this may not be respected
+    if (!_antialiasText)
+        font.setStyleStrategy( QFont::NoAntialias );
+ 
+    // experimental optimization.  Konsole assumes that the terminal is using a 
+    // mono-spaced font, in which case kerning information should have an effect.
+    // Disabling kerning saves some computation when rendering text. 
+    font.setKerning(false);
+
+    QWidget::setFont(font);
+    fontChange(font);
+  }
+}
+
+void TerminalDisplay::setFont(const QFont &)
+{
+  // ignore font change request if not coming from konsole itself
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                         Constructor / Destructor                          */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+TerminalDisplay::TerminalDisplay(QWidget *parent)
+:QWidget(parent)
+,_screenWindow(0)
+,_allowBell(true)
+,_gridLayout(0)
+,_fontHeight(1)
+,_fontWidth(1)
+,_fontAscent(1)
+,_boldIntense(true)
+,_lines(1)
+,_columns(1)
+,_usedLines(1)
+,_usedColumns(1)
+,_contentHeight(1)
+,_contentWidth(1)
+,_image(0)
+,_randomSeed(0)
+,_resizing(false)
+,_terminalSizeHint(false)
+,_terminalSizeStartup(true)
+,_bidiEnabled(false)
+,_actSel(0)
+,_wordSelectionMode(false)
+,_lineSelectionMode(false)
+,_preserveLineBreaks(false)
+,_columnSelectionMode(false)
+,_scrollbarLocation(NoScrollBar)
+,_wordCharacters(":@-./_~")
+,_bellMode(SystemBeepBell)
+,_blinking(false)
+,_hasBlinker(false)
+,_cursorBlinking(false)
+,_hasBlinkingCursor(false)
+,_allowBlinkingText(true)
+,_ctrlDrag(true)
+,_tripleClickMode(SelectWholeLine)
+,_isFixedSize(false)
+,_possibleTripleClick(false)
+,_resizeWidget(0)
+,_resizeTimer(0)
+,_flowControlWarningEnabled(false)
+,_outputSuspendedLabel(0)
+,_lineSpacing(0)
+,_colorsInverted(false)
+,_blendColor(qRgba(0,0,0,0xff))
+,_filterChain(new TerminalImageFilterChain())
+,_cursorShape(BlockCursor)
+{
+  // terminal applications are not designed with Right-To-Left in mind,
+  // so the layout is forced to Left-To-Right
+  setLayoutDirection(Qt::LeftToRight);
+
+  // The offsets are not yet calculated.
+  // Do not calculate these too often to be more smoothly when resizing
+  // konsole in opaque mode.
+  _topMargin = DEFAULT_TOP_MARGIN;
+  _leftMargin = DEFAULT_LEFT_MARGIN;
+
+  // create scroll bar for scrolling output up and down
+  // set the scroll bar's slider to occupy the whole area of the scroll bar initially
+  _scrollBar = new QScrollBar(this);
+  setScroll(0,0); 
+  _scrollBar->setCursor( Qt::ArrowCursor );
+  connect(_scrollBar, SIGNAL(valueChanged(int)), this, 
+                        SLOT(scrollBarPositionChanged(int)));
+
+  // setup timers for blinking cursor and text
+  _blinkTimer   = new QTimer(this);
+  connect(_blinkTimer, SIGNAL(timeout()), this, SLOT(blinkEvent()));
+  _blinkCursorTimer   = new QTimer(this);
+  connect(_blinkCursorTimer, SIGNAL(timeout()), this, SLOT(blinkCursorEvent()));
+
+  //KCursor::setAutoHideCursor( this, true );
+  
+  setUsesMouse(true);
+  setColorTable(base_color_table);
+  setMouseTracking(true);
+
+  // Enable drag and drop 
+  setAcceptDrops(true); // attempt
+  dragInfo.state = diNone;
+
+  setFocusPolicy( Qt::WheelFocus );
+
+  // enable input method support
+  setAttribute(Qt::WA_InputMethodEnabled, true);
+
+  // this is an important optimization, it tells Qt
+  // that TerminalDisplay will handle repainting its entire area.
+  setAttribute(Qt::WA_OpaquePaintEvent);
+
+  _gridLayout = new QGridLayout(this);
+  _gridLayout->setContentsMargins(0, 0, 0, 0);
+
+  setLayout( _gridLayout ); 
+
+  new AutoScrollHandler(this);
+}
+
+TerminalDisplay::~TerminalDisplay()
+{
+  disconnect(_blinkTimer);
+  disconnect(_blinkCursorTimer);
+  qApp->removeEventFilter( this );
+  
+  delete[] _image;
+
+  delete _gridLayout;
+  delete _outputSuspendedLabel;
+  delete _filterChain;
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                             Display Operations                            */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+/**
+ A table for emulating the simple (single width) unicode drawing chars.
+ It represents the 250x - 257x glyphs. If it's zero, we can't use it.
+ if it's not, it's encoded as follows: imagine a 5x5 grid where the points are numbered
+ 0 to 24 left to top, top to bottom. Each point is represented by the corresponding bit.
+
+ Then, the pixels basically have the following interpretation:
+ _|||_
+ -...-
+ -...-
+ -...-
+ _|||_
+
+where _ = none
+      | = vertical line.
+      - = horizontal line.
+ */
+
+
+enum LineEncode
+{
+    TopL  = (1<<1),
+    TopC  = (1<<2),
+    TopR  = (1<<3),
+
+    LeftT = (1<<5),
+    Int11 = (1<<6),
+    Int12 = (1<<7),
+    Int13 = (1<<8),
+    RightT = (1<<9),
+
+    LeftC = (1<<10),
+    Int21 = (1<<11),
+    Int22 = (1<<12),
+    Int23 = (1<<13),
+    RightC = (1<<14),
+
+    LeftB = (1<<15),
+    Int31 = (1<<16),
+    Int32 = (1<<17),
+    Int33 = (1<<18),
+    RightB = (1<<19),
+
+    BotL  = (1<<21),
+    BotC  = (1<<22),
+    BotR  = (1<<23)
+};
+
+#include "LineFont.h"
+
+static void drawLineChar(QPainter& paint, int x, int y, int w, int h, uchar code)
+{
+    //Calculate cell midpoints, end points.
+    int cx = x + w/2;
+    int cy = y + h/2;
+    int ex = x + w - 1;
+    int ey = y + h - 1;
+
+    quint32 toDraw = LineChars[code];
+
+    //Top _lines:
+    if (toDraw & TopL)
+        paint.drawLine(cx-1, y, cx-1, cy-2);
+    if (toDraw & TopC)
+        paint.drawLine(cx, y, cx, cy-2);
+    if (toDraw & TopR)
+        paint.drawLine(cx+1, y, cx+1, cy-2);
+
+    //Bot _lines:
+    if (toDraw & BotL)
+        paint.drawLine(cx-1, cy+2, cx-1, ey);
+    if (toDraw & BotC)
+        paint.drawLine(cx, cy+2, cx, ey);
+    if (toDraw & BotR)
+        paint.drawLine(cx+1, cy+2, cx+1, ey);
+
+    //Left _lines:
+    if (toDraw & LeftT)
+        paint.drawLine(x, cy-1, cx-2, cy-1);
+    if (toDraw & LeftC)
+        paint.drawLine(x, cy, cx-2, cy);
+    if (toDraw & LeftB)
+        paint.drawLine(x, cy+1, cx-2, cy+1);
+
+    //Right _lines:
+    if (toDraw & RightT)
+        paint.drawLine(cx+2, cy-1, ex, cy-1);
+    if (toDraw & RightC)
+        paint.drawLine(cx+2, cy, ex, cy);
+    if (toDraw & RightB)
+        paint.drawLine(cx+2, cy+1, ex, cy+1);
+
+    //Intersection points.
+    if (toDraw & Int11)
+        paint.drawPoint(cx-1, cy-1);
+    if (toDraw & Int12)
+        paint.drawPoint(cx, cy-1);
+    if (toDraw & Int13)
+        paint.drawPoint(cx+1, cy-1);
+
+    if (toDraw & Int21)
+        paint.drawPoint(cx-1, cy);
+    if (toDraw & Int22)
+        paint.drawPoint(cx, cy);
+    if (toDraw & Int23)
+        paint.drawPoint(cx+1, cy);
+
+    if (toDraw & Int31)
+        paint.drawPoint(cx-1, cy+1);
+    if (toDraw & Int32)
+        paint.drawPoint(cx, cy+1);
+    if (toDraw & Int33)
+        paint.drawPoint(cx+1, cy+1);
+
+}
+
+void TerminalDisplay::drawLineCharString(    QPainter& painter, int x, int y, const QString& str, 
+                                    const Character* attributes)
+{
+        const QPen& currentPen = painter.pen();
+        
+        if ( (attributes->rendition & RE_BOLD) && _boldIntense )
+        {
+            QPen boldPen(currentPen);
+            boldPen.setWidth(3);
+            painter.setPen( boldPen );
+        }    
+        
+        for (int i=0 ; i < str.length(); i++)
+        {
+            uchar code = str[i].cell();
+            if (LineChars[code])
+                drawLineChar(painter, x + (_fontWidth*i), y, _fontWidth, _fontHeight, code);
+        }
+
+        painter.setPen( currentPen );
+}
+
+void TerminalDisplay::setKeyboardCursorShape(KeyboardCursorShape shape)
+{
+    _cursorShape = shape;
+}
+TerminalDisplay::KeyboardCursorShape TerminalDisplay::keyboardCursorShape() const
+{
+    return _cursorShape;
+}
+void TerminalDisplay::setKeyboardCursorColor(bool useForegroundColor, const QColor& color)
+{
+    if (useForegroundColor)
+        _cursorColor = QColor(); // an invalid color means that
+                                 // the foreground color of the
+                                 // current character should
+                                 // be used
+
+    else
+        _cursorColor = color;
+}
+QColor TerminalDisplay::keyboardCursorColor() const
+{
+    return _cursorColor;
+}
+
+void TerminalDisplay::setOpacity(qreal opacity)
+{
+    QColor color(_blendColor);
+    color.setAlphaF(opacity);
+
+    // enable automatic background filling to prevent the display
+    // flickering if there is no transparency
+    /*if ( color.alpha() == 255 ) 
+    {
+        setAutoFillBackground(true);
+    }
+    else
+    {
+        setAutoFillBackground(false);
+    }*/
+
+    _blendColor = color.rgba();
+}
+
+void TerminalDisplay::drawBackground(QPainter& painter, const QRect& rect, const QColor& backgroundColor, bool useOpacitySetting )
+{
+        // the area of the widget showing the contents of the terminal display is drawn
+        // using the background color from the color scheme set with setColorTable()
+        //
+        // the area of the widget behind the scroll-bar is drawn using the background
+        // brush from the scroll-bar's palette, to give the effect of the scroll-bar
+        // being outside of the terminal display and visual consistency with other KDE
+        // applications.  
+        //
+        QRect scrollBarArea = _scrollBar->isVisible() ? 
+                                    rect.intersected(_scrollBar->geometry()) :
+                                    QRect();
+        QRegion contentsRegion = QRegion(rect).subtracted(scrollBarArea);
+        QRect contentsRect = contentsRegion.boundingRect();
+
+        if ( HAVE_TRANSPARENCY && qAlpha(_blendColor) < 0xff && useOpacitySetting ) 
+        {
+            QColor color(backgroundColor);
+            color.setAlpha(qAlpha(_blendColor));
+
+            painter.save();
+            painter.setCompositionMode(QPainter::CompositionMode_Source);
+            painter.fillRect(contentsRect, color);
+            painter.restore();
+        } 
+        else
+            painter.fillRect(contentsRect, backgroundColor);
+
+        painter.fillRect(scrollBarArea,_scrollBar->palette().background());
+}
+
+void TerminalDisplay::drawCursor(QPainter& painter, 
+                                 const QRect& rect,
+                                 const QColor& foregroundColor,
+                                 const QColor& /*backgroundColor*/,
+                                 bool& invertCharacterColor)
+{
+    QRect cursorRect = rect;
+    cursorRect.setHeight(_fontHeight - _lineSpacing - 1);
+    
+    if (!_cursorBlinking)
+    {
+       if ( _cursorColor.isValid() )
+           painter.setPen(_cursorColor);
+       else
+           painter.setPen(foregroundColor);
+
+       if ( _cursorShape == BlockCursor )
+       {
+            // draw the cursor outline, adjusting the area so that
+            // it is draw entirely inside 'rect'
+            int penWidth = qMax(1,painter.pen().width());
+
+            painter.drawRect(cursorRect.adjusted(penWidth/2,
+                                                 penWidth/2,
+                                                 - penWidth/2 - penWidth%2,
+                                                 - penWidth/2 - penWidth%2));
+            if ( hasFocus() )
+            {
+                painter.fillRect(cursorRect, _cursorColor.isValid() ? _cursorColor : foregroundColor);
+            
+                if ( !_cursorColor.isValid() )
+                {
+                    // invert the colour used to draw the text to ensure that the character at
+                    // the cursor position is readable
+                    invertCharacterColor = true;
+                }
+            }
+       }
+       else if ( _cursorShape == UnderlineCursor )
+            painter.drawLine(cursorRect.left(),
+                             cursorRect.bottom(),
+                             cursorRect.right(),
+                             cursorRect.bottom());
+       else if ( _cursorShape == IBeamCursor )
+            painter.drawLine(cursorRect.left(),
+                             cursorRect.top(),
+                             cursorRect.left(),
+                             cursorRect.bottom());
+    
+    }
+}
+
+void TerminalDisplay::drawCharacters(QPainter& painter,
+                                     const QRect& rect,
+                                     const QString& text,
+                                     const Character* style,
+                                     bool invertCharacterColor)
+{
+    // don't draw text which is currently blinking
+    if ( _blinking && (style->rendition & RE_BLINK) )
+            return;
+   
+    // setup bold and underline
+    bool useBold;
+    ColorEntry::FontWeight weight = style->fontWeight(_colorTable);    
+    if (weight == ColorEntry::UseCurrentFormat)
+        useBold = ((style->rendition & RE_BOLD) && _boldIntense) || font().bold();
+    else
+        useBold = (weight == ColorEntry::Bold) ? true : false;
+    bool useUnderline = style->rendition & RE_UNDERLINE || font().underline();
+
+    QFont font = painter.font();
+    if (    font.bold() != useBold 
+         || font.underline() != useUnderline )
+    {
+       font.setBold(useBold);
+       font.setUnderline(useUnderline);
+       painter.setFont(font);
+    }
+
+    // setup pen
+    const CharacterColor& textColor = ( invertCharacterColor ? style->backgroundColor : style->foregroundColor );
+    const QColor color = textColor.color(_colorTable);
+    QPen pen = painter.pen();
+    if ( pen.color() != color )
+    {
+        pen.setColor(color);
+        painter.setPen(color);
+    }
+
+    // draw text
+    if ( isLineCharString(text) )
+        drawLineCharString(painter,rect.x(),rect.y(),text,style);
+    else
+    {
+        // the drawText(rect,flags,string) overload is used here with null flags
+        // instead of drawText(rect,string) because the (rect,string) overload causes 
+        // the application's default layout direction to be used instead of 
+        // the widget-specific layout direction, which should always be
+        // Qt::LeftToRight for this widget
+    // This was discussed in: http://lists.kde.org/?t=120552223600002&r=1&w=2
+        if (_bidiEnabled)
+            painter.drawText(rect,0,text);
+        else
+            painter.drawText(rect,0,LTR_OVERRIDE_CHAR+text);
+    }
+}
+
+void TerminalDisplay::drawTextFragment(QPainter& painter , 
+                                       const QRect& rect,
+                                       const QString& text, 
+                                       const Character* style)
+{
+    painter.save();
+
+    // setup painter 
+    const QColor foregroundColor = style->foregroundColor.color(_colorTable);
+    const QColor backgroundColor = style->backgroundColor.color(_colorTable);
+    
+    // draw background if different from the display's background color
+    if ( backgroundColor != palette().background().color() )
+        drawBackground(painter,rect,backgroundColor,
+                       false /* do not use transparency */);
+
+    // draw cursor shape if the current character is the cursor
+    // this may alter the foreground and background colors
+    bool invertCharacterColor = false;
+    if ( style->rendition & RE_CURSOR )
+        drawCursor(painter,rect,foregroundColor,backgroundColor,invertCharacterColor);
+
+    // draw text
+    drawCharacters(painter,rect,text,style,invertCharacterColor);
+
+    painter.restore();
+}
+
+void TerminalDisplay::setRandomSeed(uint randomSeed) { _randomSeed = randomSeed; }
+uint TerminalDisplay::randomSeed() const { return _randomSeed; }
+
+#if 0
+/*!
+    Set XIM Position
+*/
+void TerminalDisplay::setCursorPos(const int curx, const int cury)
+{
+    QPoint tL  = contentsRect().topLeft();
+    int    tLx = tL.x();
+    int    tLy = tL.y();
+
+    int xpos, ypos;
+    ypos = _topMargin + tLy + _fontHeight*(cury-1) + _fontAscent;
+    xpos = _leftMargin + tLx + _fontWidth*curx;
+    //setMicroFocusHint(xpos, ypos, 0, _fontHeight); //### ???
+    // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos);
+    _cursorLine = cury;
+    _cursorCol = curx;
+}
+#endif
+
+// 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() 
+// 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
+void TerminalDisplay::scrollImage(int lines , const QRect& screenWindowRegion)
+{
+    // if the flow control warning is enabled this will interfere with the 
+    // scrolling optimizations and cause artifacts.  the simple solution here
+    // is to just disable the optimization whilst it is visible
+    if ( _outputSuspendedLabel && _outputSuspendedLabel->isVisible() )
+        return;
+
+    // constrain the region to the display
+    // the bottom of the region is capped to the number of lines in the display's
+    // internal image - 2, so that the height of 'region' is strictly less
+    // than the height of the internal image.
+    QRect region = screenWindowRegion;
+    region.setBottom( qMin(region.bottom(),this->_lines-2) ); 
+
+    // return if there is nothing to do
+    if (    lines == 0 
+         || _image == 0
+         || !region.isValid() 
+         || (region.top() + abs(lines)) >= region.bottom() 
+         || this->_lines <= region.height() ) return;
+
+    // hide terminal size label to prevent it being scrolled
+    if (_resizeWidget && _resizeWidget->isVisible())
+        _resizeWidget->hide();
+
+    // Note:  With Qt 4.4 the left edge of the scrolled area must be at 0
+    // to get the correct (newly exposed) part of the widget repainted.
+    //
+    // The right edge must be before the left edge of the scroll bar to 
+    // avoid triggering a repaint of the entire widget, the distance is 
+    // given by SCROLLBAR_CONTENT_GAP
+    //
+    // Set the QT_FLUSH_PAINT environment variable to '1' before starting the
+    // application to monitor repainting.
+    //
+    int scrollBarWidth = _scrollBar->isHidden() ? 0 : _scrollBar->width();
+    const int SCROLLBAR_CONTENT_GAP = 1;
+    QRect scrollRect;
+    if ( _scrollbarLocation == ScrollBarLeft )
+    {
+        scrollRect.setLeft(scrollBarWidth+SCROLLBAR_CONTENT_GAP);
+        scrollRect.setRight(width());
+    }
+    else
+    {
+        scrollRect.setLeft(0);
+        scrollRect.setRight(width() - scrollBarWidth - SCROLLBAR_CONTENT_GAP);
+    }
+    void* firstCharPos = &_image[ region.top() * this->_columns ];
+    void* lastCharPos = &_image[ (region.top() + abs(lines)) * this->_columns ];
+
+    int top = _topMargin + (region.top() * _fontHeight);
+    int linesToMove = region.height() - abs(lines);
+    int bytesToMove = linesToMove * 
+                      this->_columns *
+                      sizeof(Character);
+
+    Q_ASSERT( linesToMove > 0 );
+    Q_ASSERT( bytesToMove > 0 );
+
+    //scroll internal image
+    if ( lines > 0 )
+    {
+        // check that the memory areas that we are going to move are valid
+        Q_ASSERT( (char*)lastCharPos + bytesToMove < 
+                  (char*)(_image + (this->_lines * this->_columns)) );
+        
+        Q_ASSERT( (lines*this->_columns) < _imageSize ); 
+
+        //scroll internal image down
+        memmove( firstCharPos , lastCharPos , bytesToMove ); 
+      
+        //set region of display to scroll
+        scrollRect.setTop(top);
+    }
+    else
+    {
+        // check that the memory areas that we are going to move are valid
+        Q_ASSERT( (char*)firstCharPos + bytesToMove < 
+                  (char*)(_image + (this->_lines * this->_columns)) );
+
+        //scroll internal image up
+        memmove( lastCharPos , firstCharPos , bytesToMove ); 
+     
+        //set region of the display to scroll
+        scrollRect.setTop(top + abs(lines) * _fontHeight); 
+    }
+    scrollRect.setHeight(linesToMove * _fontHeight );
+
+    Q_ASSERT(scrollRect.isValid() && !scrollRect.isEmpty());
+
+    //scroll the display vertically to match internal _image
+    scroll( 0 , _fontHeight * (-lines) , scrollRect );
+}
+
+QRegion TerminalDisplay::hotSpotRegion() const 
+{
+    QRegion region;
+    foreach( Filter::HotSpot* hotSpot , _filterChain->hotSpots() )
+    {
+        QRect r;
+        if (hotSpot->startLine()==hotSpot->endLine()) {
+            r.setLeft(hotSpot->startColumn());
+            r.setTop(hotSpot->startLine());
+            r.setRight(hotSpot->endColumn());
+            r.setBottom(hotSpot->endLine());
+            region |= imageToWidget(r);;
+        } else {
+            r.setLeft(hotSpot->startColumn());
+            r.setTop(hotSpot->startLine());
+            r.setRight(_columns);
+            r.setBottom(hotSpot->startLine());
+            region |= imageToWidget(r);;
+            for ( int line = hotSpot->startLine()+1 ; line < hotSpot->endLine() ; line++ ) {
+                r.setLeft(0);
+                r.setTop(line);
+                r.setRight(_columns);
+                r.setBottom(line);
+                region |= imageToWidget(r);;
+            }
+            r.setLeft(0);
+            r.setTop(hotSpot->endLine());
+            r.setRight(hotSpot->endColumn());
+            r.setBottom(hotSpot->endLine());
+            region |= imageToWidget(r);;
+        }
+    }
+    return region;
+}
+
+void TerminalDisplay::processFilters() 
+{
+    if (!_screenWindow)
+        return;
+
+    QRegion preUpdateHotSpots = hotSpotRegion();
+
+    // use _screenWindow->getImage() here rather than _image because
+    // other classes may call processFilters() when this display's
+    // ScreenWindow emits a scrolled() signal - which will happen before
+    // updateImage() is called on the display and therefore _image is 
+    // out of date at this point
+    _filterChain->setImage( _screenWindow->getImage(),
+                            _screenWindow->windowLines(),
+                            _screenWindow->windowColumns(),
+                            _screenWindow->getLineProperties() );
+    _filterChain->process();
+
+    QRegion postUpdateHotSpots = hotSpotRegion();
+
+    update( preUpdateHotSpots | postUpdateHotSpots );
+}
+
+void TerminalDisplay::updateImage() 
+{
+  if ( !_screenWindow )
+      return;
+
+  // 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() ,
+               _screenWindow->scrollRegion() );
+  _screenWindow->resetScrollCount();
+
+  if (!_image) {
+     // Create _image.
+     // The emitted changedContentSizeSignal also leads to getImage being recreated, so do this first.
+     updateImageSize();
+  }
+
+  Character* const newimg = _screenWindow->getImage();
+  int lines = _screenWindow->windowLines();
+  int columns = _screenWindow->windowColumns();
+
+  setScroll( _screenWindow->currentLine() , _screenWindow->lineCount() );
+
+  Q_ASSERT( this->_usedLines <= this->_lines );
+  Q_ASSERT( this->_usedColumns <= this->_columns );
+
+  int y,x,len;
+
+  QPoint tL  = contentsRect().topLeft();
+  int    tLx = tL.x();
+  int    tLy = tL.y();
+  _hasBlinker = false;
+
+  CharacterColor cf;       // undefined
+  CharacterColor _clipboard;       // undefined
+  int cr  = -1;   // undefined
+
+  const int linesToUpdate = qMin(this->_lines, qMax(0,lines  ));
+  const int columnsToUpdate = qMin(this->_columns,qMax(0,columns));
+
+  QChar *disstrU = new QChar[columnsToUpdate];
+  char *dirtyMask = new char[columnsToUpdate+2]; 
+  QRegion dirtyRegion;
+
+  // debugging variable, this records the number of lines that are found to
+  // be 'dirty' ( ie. have changed from the old _image to the new _image ) and
+  // which therefore need to be repainted
+  int dirtyLineCount = 0;
+
+  for (y = 0; y < linesToUpdate; ++y)
+  {
+    const Character*       currentLine = &_image[y*this->_columns];
+    const Character* const newLine = &newimg[y*columns];
+
+    bool updateLine = false;
+    
+    // The dirty mask indicates which characters need repainting. We also
+    // mark surrounding neighbours dirty, in case the character exceeds
+    // its cell boundaries
+    memset(dirtyMask, 0, columnsToUpdate+2);
+   
+    for( x = 0 ; x < columnsToUpdate ; ++x)
+    {
+        if ( newLine[x] != currentLine[x] ) 
+        {
+            dirtyMask[x] = true;
+        }
+    }
+
+    if (!_resizing) // not while _resizing, we're expecting a paintEvent
+    for (x = 0; x < columnsToUpdate; ++x)
+    {
+      _hasBlinker |= (newLine[x].rendition & RE_BLINK);
+    
+      // Start drawing if this character or the next one differs.
+      // We also take the next one into account to handle the situation
+      // where characters exceed their cell width.
+      if (dirtyMask[x])
+      {
+        quint16 c = newLine[x+0].character;
+        if ( !c )
+            continue;
+        int p = 0;
+        disstrU[p++] = c; //fontMap(c);
+        bool lineDraw = isLineChar(c);
+        bool doubleWidth = (x+1 == columnsToUpdate) ? false : (newLine[x+1].character == 0);
+        cr = newLine[x].rendition;
+        _clipboard = newLine[x].backgroundColor;
+        if (newLine[x].foregroundColor != cf) cf = newLine[x].foregroundColor;
+        int lln = columnsToUpdate - x;
+        for (len = 1; len < lln; ++len)
+        {
+            const Character& ch = newLine[x+len];
+
+            if (!ch.character)
+                continue; // Skip trailing part of multi-col chars.
+
+            bool nextIsDoubleWidth = (x+len+1 == columnsToUpdate) ? false : (newLine[x+len+1].character == 0);
+
+            if (  ch.foregroundColor != cf || 
+                  ch.backgroundColor != _clipboard || 
+                  ch.rendition != cr ||
+                  !dirtyMask[x+len] || 
+                  isLineChar(c) != lineDraw || 
+                  nextIsDoubleWidth != doubleWidth )
+            break;
+
+          disstrU[p++] = c; //fontMap(c);
+        }
+
+        QString unistr(disstrU, p);
+
+        bool saveFixedFont = _fixedFont;
+        if (lineDraw)
+           _fixedFont = false;
+        if (doubleWidth)
+           _fixedFont = false;
+
+        updateLine = true;
+
+        _fixedFont = saveFixedFont;
+        x += len - 1;
+      }
+      
+    }
+
+    //both the top and bottom halves of double height _lines must always be redrawn
+    //although both top and bottom halves contain the same characters, only 
+    //the top one is actually 
+    //drawn.
+    if (_lineProperties.count() > y)
+        updateLine |= (_lineProperties[y] & LINE_DOUBLEHEIGHT);
+
+    // if the characters on the line are different in the old and the new _image
+    // then this line must be repainted.    
+    if (updateLine)
+    {
+        dirtyLineCount++;
+
+        // add the area occupied by this line to the region which needs to be
+        // repainted
+        QRect dirtyRect = QRect( _leftMargin+tLx , 
+                                 _topMargin+tLy+_fontHeight*y , 
+                                 _fontWidth * columnsToUpdate , 
+                                 _fontHeight );     
+
+        dirtyRegion |= dirtyRect;
+    }
+
+    // replace the line of characters in the old _image with the 
+    // current line of the new _image 
+    memcpy((void*)currentLine,(const void*)newLine,columnsToUpdate*sizeof(Character));
+  }
+
+  // if the new _image is smaller than the previous _image, then ensure that the area
+  // outside the new _image is cleared 
+  if ( linesToUpdate < _usedLines )
+  {
+    dirtyRegion |= QRect(   _leftMargin+tLx , 
+                            _topMargin+tLy+_fontHeight*linesToUpdate , 
+                            _fontWidth * this->_columns , 
+                            _fontHeight * (_usedLines-linesToUpdate) );
+  }
+  _usedLines = linesToUpdate;
+  
+  if ( columnsToUpdate < _usedColumns )
+  {
+    dirtyRegion |= QRect(   _leftMargin+tLx+columnsToUpdate*_fontWidth , 
+                            _topMargin+tLy , 
+                            _fontWidth * (_usedColumns-columnsToUpdate) , 
+                            _fontHeight * this->_lines );
+  }
+  _usedColumns = columnsToUpdate;
+
+  dirtyRegion |= _inputMethodData.previousPreeditRect;
+
+  // update the parts of the display which have changed
+  update(dirtyRegion);
+
+  if ( _hasBlinker && !_blinkTimer->isActive()) _blinkTimer->start( TEXT_BLINK_DELAY ); 
+  if (!_hasBlinker && _blinkTimer->isActive()) { _blinkTimer->stop(); _blinking = false; }
+  delete[] dirtyMask;
+  delete[] disstrU;
+
+}
+
+void TerminalDisplay::showResizeNotification()
+{
+  if (_terminalSizeHint && isVisible())
+  {
+     if (_terminalSizeStartup) {
+               _terminalSizeStartup=false;
+       return;
+     }
+     if (!_resizeWidget)
+     {
+        _resizeWidget = new QLabel(i18n("Size: XXX x XXX"), this);
+        _resizeWidget->setMinimumWidth(_resizeWidget->fontMetrics().width(i18n("Size: XXX x XXX")));
+        _resizeWidget->setMinimumHeight(_resizeWidget->sizeHint().height());
+        _resizeWidget->setAlignment(Qt::AlignCenter);
+
+        _resizeWidget->setStyleSheet("background-color:palette(window);border-style:solid;border-width:1px;border-color:palette(dark)");
+
+        _resizeTimer = new QTimer(this);
+        _resizeTimer->setSingleShot(true);
+        connect(_resizeTimer, SIGNAL(timeout()), _resizeWidget, SLOT(hide()));
+     }
+     QString sizeStr = i18n("Size: %1 x %2", _columns, _lines);
+     _resizeWidget->setText(sizeStr);
+     _resizeWidget->move((width()-_resizeWidget->width())/2,
+                         (height()-_resizeWidget->height())/2+20);
+     _resizeWidget->show();
+     _resizeTimer->start(1000);
+  }
+}
+
+void TerminalDisplay::setBlinkingCursor(bool blink)
+{
+  _hasBlinkingCursor=blink;
+  
+  if (blink && !_blinkCursorTimer->isActive()) 
+      _blinkCursorTimer->start(QApplication::cursorFlashTime() / 2);
+  
+  if (!blink && _blinkCursorTimer->isActive()) 
+  {
+    _blinkCursorTimer->stop();
+    if (_cursorBlinking)
+      blinkCursorEvent();
+    else
+      _cursorBlinking = false;
+  }
+}
+
+void TerminalDisplay::setBlinkingTextEnabled(bool blink)
+{
+    _allowBlinkingText = blink;
+
+    if (blink && !_blinkTimer->isActive()) 
+        _blinkTimer->start(TEXT_BLINK_DELAY);
+  
+    if (!blink && _blinkTimer->isActive()) 
+    {
+        _blinkTimer->stop();
+        _blinking = false;
+    }
+}
+
+void TerminalDisplay::focusOutEvent(QFocusEvent*)
+{
+    // trigger a repaint of the cursor so that it is both visible (in case
+    // it was hidden during blinking)
+    // and drawn in a focused out state
+    _cursorBlinking = false;
+    updateCursor();
+
+    _blinkCursorTimer->stop();
+    if (_blinking)
+        blinkEvent();
+
+    _blinkTimer->stop();
+}
+void TerminalDisplay::focusInEvent(QFocusEvent*)
+{
+    if (_hasBlinkingCursor)
+    {
+        _blinkCursorTimer->start();
+    }
+    updateCursor();
+
+    if (_hasBlinker)
+        _blinkTimer->start();
+}
+
+void TerminalDisplay::paintEvent( QPaintEvent* pe )
+{
+  QPainter paint(this);
+
+  foreach (const QRect &rect, (pe->region() & contentsRect()).rects())
+  {
+    drawBackground(paint,rect,palette().background().color(),
+                    true /* use opacity setting */);
+    drawContents(paint, rect);
+  }
+  drawInputMethodPreeditString(paint,preeditRect());
+  paintFilters(paint);
+}
+
+QPoint TerminalDisplay::cursorPosition() const
+{
+    if (_screenWindow)
+        return _screenWindow->cursorPosition();
+    else
+        return QPoint(0,0);
+}
+
+QRect TerminalDisplay::preeditRect() const
+{
+    const int preeditLength = string_width(_inputMethodData.preeditString);
+
+    if ( preeditLength == 0 )
+        return QRect();
+
+    return QRect(_leftMargin + _fontWidth*cursorPosition().x(),
+                 _topMargin + _fontHeight*cursorPosition().y(),
+                 _fontWidth*preeditLength,
+                 _fontHeight);
+}   
+
+void TerminalDisplay::drawInputMethodPreeditString(QPainter& painter , const QRect& rect)
+{
+    if ( _inputMethodData.preeditString.isEmpty() )
+        return;
+
+    const QPoint cursorPos = cursorPosition(); 
+
+    bool invertColors = false;
+    const QColor background = _colorTable[DEFAULT_BACK_COLOR].color;
+    const QColor foreground = _colorTable[DEFAULT_FORE_COLOR].color;
+    const Character* style = &_image[loc(cursorPos.x(),cursorPos.y())];
+
+    drawBackground(painter,rect,background,true);
+    drawCursor(painter,rect,foreground,background,invertColors);
+    drawCharacters(painter,rect,_inputMethodData.preeditString,style,invertColors);
+
+    _inputMethodData.previousPreeditRect = rect; 
+}
+
+FilterChain* TerminalDisplay::filterChain() const
+{
+    return _filterChain;
+}
+
+void TerminalDisplay::paintFilters(QPainter& painter)
+{
+    // get color of character under mouse and use it to draw
+    // lines for filters
+    QPoint cursorPos = mapFromGlobal(QCursor::pos());
+    int cursorLine;
+    int cursorColumn;
+    int scrollBarWidth = (_scrollbarLocation == ScrollBarLeft) ? _scrollBar->width() : 0;
+
+    getCharacterPosition( cursorPos , cursorLine , cursorColumn );
+    Character cursorCharacter = _image[loc(cursorColumn,cursorLine)];
+
+    painter.setPen( QPen(cursorCharacter.foregroundColor.color(colorTable())) );
+
+    // iterate over hotspots identified by the display's currently active filters 
+    // and draw appropriate visuals to indicate the presence of the hotspot
+
+    QList<Filter::HotSpot*> spots = _filterChain->hotSpots();
+    QListIterator<Filter::HotSpot*> iter(spots);
+    while (iter.hasNext())
+    {
+        Filter::HotSpot* spot = iter.next();
+
+        QRegion region;
+        if ( spot->type() == Filter::HotSpot::Link ) {
+            QRect r;
+            if (spot->startLine()==spot->endLine()) {
+                r.setCoords( spot->startColumn()*_fontWidth + 1 + scrollBarWidth, 
+                             spot->startLine()*_fontHeight + 1,
+                             (spot->endColumn()-1)*_fontWidth - 1 + scrollBarWidth, 
+                             (spot->endLine()+1)*_fontHeight - 1 ); 
+                region |= r;
+            } else {
+                r.setCoords( spot->startColumn()*_fontWidth + 1 + scrollBarWidth, 
+                             spot->startLine()*_fontHeight + 1,
+                             (_columns-1)*_fontWidth - 1 + scrollBarWidth, 
+                             (spot->startLine()+1)*_fontHeight - 1 ); 
+                region |= r;
+                for ( int line = spot->startLine()+1 ; line < spot->endLine() ; line++ ) {
+                    r.setCoords( 0*_fontWidth + 1 + scrollBarWidth, 
+                                 line*_fontHeight + 1,
+                                 (_columns-1)*_fontWidth - 1 + scrollBarWidth,
+                                 (line+1)*_fontHeight - 1 ); 
+                    region |= r;
+                }
+                r.setCoords( 0*_fontWidth + 1 + scrollBarWidth,
+                             spot->endLine()*_fontHeight + 1,
+                             (spot->endColumn()-1)*_fontWidth - 1 + scrollBarWidth,
+                             (spot->endLine()+1)*_fontHeight - 1 ); 
+                region |= r;
+            }
+        }
+
+        for ( int line = spot->startLine() ; line <= spot->endLine() ; line++ )
+        {
+            int startColumn = 0;
+            int endColumn = _columns-1; // TODO use number of _columns which are actually 
+                                        // occupied on this line rather than the width of the 
+                                        // display in _columns
+
+            // ignore whitespace at the end of the lines
+            while ( QChar(_image[loc(endColumn,line)].character).isSpace() && endColumn > 0 )
+                endColumn--;
+              
+            // increment here because the column which we want to set 'endColumn' to
+            // is the first whitespace character at the end of the line
+            endColumn++;
+
+            if ( line == spot->startLine() )
+                startColumn = spot->startColumn();
+            if ( line == spot->endLine() )
+                endColumn = spot->endColumn();
+
+            // subtract one pixel from
+            // the right and bottom so that
+            // we do not overdraw adjacent
+            // hotspots
+            //
+            // subtracting one pixel from all sides also prevents an edge case where
+            // moving the mouse outside a link could still leave it underlined 
+            // because the check below for the position of the cursor
+            // finds it on the border of the target area
+            QRect r;
+            r.setCoords( startColumn*_fontWidth + 1 + scrollBarWidth,
+                         line*_fontHeight + 1,
+                         endColumn*_fontWidth - 1 + scrollBarWidth,
+                         (line+1)*_fontHeight - 1 ); 
+            // Underline link hotspots 
+            if ( spot->type() == Filter::HotSpot::Link )
+            {
+                QFontMetrics metrics(font());
+        
+                // find the baseline (which is the invisible line that the characters in the font sit on,
+                // with some having tails dangling below)
+                int baseline = r.bottom() - metrics.descent();
+                // find the position of the underline below that
+                int underlinePos = baseline + metrics.underlinePos();
+                if ( region.contains( mapFromGlobal(QCursor::pos()) ) ){
+                    painter.drawLine( r.left() , underlinePos , 
+                                      r.right() , underlinePos );
+                }
+            }
+            // Marker hotspots simply have a transparent rectanglular shape
+            // drawn on top of them
+            else if ( spot->type() == Filter::HotSpot::Marker )
+            {
+            //TODO - Do not use a hardcoded colour for this
+                painter.fillRect(r,QBrush(QColor(255,0,0,120)));
+            }
+        }
+    }
+}
+void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect)
+{
+  QPoint tL  = contentsRect().topLeft();
+  int    tLx = tL.x();
+  int    tLy = tL.y();
+
+  int lux = qMin(_usedColumns-1, qMax(0,(rect.left()   - tLx - _leftMargin ) / _fontWidth));
+  int luy = qMin(_usedLines-1,  qMax(0,(rect.top()    - tLy - _topMargin  ) / _fontHeight));
+  int rlx = qMin(_usedColumns-1, qMax(0,(rect.right()  - tLx - _leftMargin ) / _fontWidth));
+  int rly = qMin(_usedLines-1,  qMax(0,(rect.bottom() - tLy - _topMargin  ) / _fontHeight));
+
+  const int bufferSize = _usedColumns;
+  QString unistr;
+  unistr.reserve(bufferSize);
+  for (int y = luy; y <= rly; y++)
+  {
+    quint16 c = _image[loc(lux,y)].character;
+    int x = lux;
+    if(!c && x)
+      x--; // Search for start of multi-column character
+    for (; x <= rlx; x++)
+    {
+      int len = 1;
+      int p = 0;
+
+      // reset our buffer to the maximal size
+      unistr.resize(bufferSize);
+      QChar *disstrU = unistr.data();
+
+      // is this a single character or a sequence of characters ?
+      if ( _image[loc(x,y)].rendition & RE_EXTENDED_CHAR )
+      {
+        // sequence of characters
+        ushort extendedCharLength = 0;
+        ushort* chars = ExtendedCharTable::instance
+                            .lookupExtendedChar(_image[loc(x,y)].charSequence,extendedCharLength);
+        for ( int index = 0 ; index < extendedCharLength ; index++ ) 
+        {
+            Q_ASSERT( p < bufferSize );
+            disstrU[p++] = chars[index];
+        }
+      }
+      else
+      {
+        // single character
+        c = _image[loc(x,y)].character;
+        if (c)
+        {
+             Q_ASSERT( p < bufferSize );
+             disstrU[p++] = c; //fontMap(c);
+        }
+      }
+
+      bool lineDraw = isLineChar(c);
+      bool doubleWidth = (_image[ qMin(loc(x,y)+1,_imageSize) ].character == 0);
+      CharacterColor currentForeground = _image[loc(x,y)].foregroundColor;
+      CharacterColor currentBackground = _image[loc(x,y)].backgroundColor;
+      quint8 currentRendition = _image[loc(x,y)].rendition;
+      
+      while (x+len <= rlx &&
+             _image[loc(x+len,y)].foregroundColor == currentForeground &&
+             _image[loc(x+len,y)].backgroundColor == currentBackground &&
+             _image[loc(x+len,y)].rendition == currentRendition &&
+             (_image[ qMin(loc(x+len,y)+1,_imageSize) ].character == 0) == doubleWidth &&
+             isLineChar( c = _image[loc(x+len,y)].character) == lineDraw) // Assignment!
+      {
+        if (c)
+          disstrU[p++] = c; //fontMap(c);
+        if (doubleWidth) // assert((_image[loc(x+len,y)+1].character == 0)), see above if condition
+          len++; // Skip trailing part of multi-column character
+        len++;
+      }
+      if ((x+len < _usedColumns) && (!_image[loc(x+len,y)].character))
+        len++; // Adjust for trailing part of multi-column character
+
+            bool save__fixedFont = _fixedFont;
+         if (lineDraw)
+            _fixedFont = false;
+         if (doubleWidth)
+            _fixedFont = false;
+         unistr.resize(p);
+
+         // Create a text scaling matrix for double width and double height lines.
+         QMatrix textScale;
+
+         if (y < _lineProperties.size())
+         {
+            if (_lineProperties[y] & LINE_DOUBLEWIDTH)
+                textScale.scale(2,1);
+
+            if (_lineProperties[y] & LINE_DOUBLEHEIGHT)
+                textScale.scale(1,2);
+         }
+
+         //Apply text scaling matrix.
+         paint.setWorldMatrix(textScale, true);
+
+         //calculate the area in which the text will be drawn
+         QRect textArea = QRect( _leftMargin+tLx+_fontWidth*x , _topMargin+tLy+_fontHeight*y , _fontWidth*len , _fontHeight);
+        
+         //move the calculated area to take account of scaling applied to the painter.
+         //the position of the area from the origin (0,0) is scaled 
+         //by the opposite of whatever
+         //transformation has been applied to the painter.  this ensures that 
+         //painting does actually start from textArea.topLeft() 
+         //(instead of textArea.topLeft() * painter-scale)    
+         textArea.moveTopLeft( textScale.inverted().map(textArea.topLeft()) );
+         
+         //paint text fragment
+         drawTextFragment(    paint,
+                            textArea,
+                            unistr, 
+                            &_image[loc(x,y)] ); //, 
+                            //0, 
+                            //!_isPrinting );
+         
+         _fixedFont = save__fixedFont;
+     
+         //reset back to single-width, single-height _lines 
+         paint.setWorldMatrix(textScale.inverted(), true);
+
+         if (y < _lineProperties.size()-1)
+         {
+            //double-height _lines are represented by two adjacent _lines 
+            //containing the same characters
+            //both _lines will have the LINE_DOUBLEHEIGHT attribute.  
+            //If the current line has the LINE_DOUBLEHEIGHT attribute, 
+            //we can therefore skip the next line
+            if (_lineProperties[y] & LINE_DOUBLEHEIGHT)
+                y++;
+         }
+         
+        x += len - 1;
+    }
+  }
+}
+
+void TerminalDisplay::blinkEvent()
+{
+  if (!_allowBlinkingText) return;
+
+  _blinking = !_blinking;
+
+  //TODO:  Optimize to only repaint the areas of the widget 
+  // where there is blinking text
+  // rather than repainting the whole widget.
+  update();
+}
+
+QRect TerminalDisplay::imageToWidget(const QRect& imageArea) const
+{
+    QRect result;
+    result.setLeft( _leftMargin + _fontWidth * imageArea.left() );
+    result.setTop( _topMargin + _fontHeight * imageArea.top() );
+    result.setWidth( _fontWidth * imageArea.width() );
+    result.setHeight( _fontHeight * imageArea.height() );
+
+    return result;
+}
+
+void TerminalDisplay::updateCursor()
+{
+  QRect cursorRect = imageToWidget( QRect(cursorPosition(),QSize(1,1)) ); 
+  update(cursorRect);
+}
+
+void TerminalDisplay::blinkCursorEvent()
+{
+  _cursorBlinking = !_cursorBlinking;
+  updateCursor();
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                                  Resizing                                 */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+void TerminalDisplay::resizeEvent(QResizeEvent*)
+{
+  updateImageSize();
+}
+
+void TerminalDisplay::propagateSize()
+{
+  if (_isFixedSize)
+  {
+     setSize(_columns, _lines);
+     QWidget::setFixedSize(sizeHint());
+     parentWidget()->adjustSize();
+     parentWidget()->setFixedSize(parentWidget()->sizeHint());
+     return;
+  }
+  if (_image)
+     updateImageSize();
+}
+
+void TerminalDisplay::updateImageSize()
+{
+  Character* oldimg = _image;
+  int oldlin = _lines;
+  int oldcol = _columns;
+
+  makeImage();
+  
+  // copy the old image to reduce flicker
+  int lines = qMin(oldlin,_lines);
+  int columns = qMin(oldcol,_columns);
+
+  if (oldimg)
+  {
+    for (int line = 0; line < lines; line++) 
+    {
+      memcpy((void*)&_image[_columns*line],
+             (void*)&oldimg[oldcol*line],columns*sizeof(Character));
+    }
+    delete[] oldimg;
+  }
+
+  if (_screenWindow)
+      _screenWindow->setWindowLines(_lines);
+
+  _resizing = (oldlin!=_lines) || (oldcol!=_columns);
+
+  if ( _resizing )
+  {
+      showResizeNotification();
+    emit changedContentSizeSignal(_contentHeight, _contentWidth); // expose resizeEvent
+  }
+  
+  _resizing = false;
+}
+
+//showEvent and hideEvent are reimplemented here so that it appears to other classes that the 
+//display has been resized when the display is hidden or shown.
+//
+//TODO: Perhaps it would be better to have separate signals for show and hide instead of using
+//the same signal as the one for a content size change 
+void TerminalDisplay::showEvent(QShowEvent*)
+{
+    emit changedContentSizeSignal(_contentHeight,_contentWidth);
+}
+void TerminalDisplay::hideEvent(QHideEvent*)
+{
+    emit changedContentSizeSignal(_contentHeight,_contentWidth);
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                                Scrollbar                                  */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+void TerminalDisplay::scrollBarPositionChanged(int)
+{
+  if ( !_screenWindow ) 
+      return;
+
+  _screenWindow->scrollTo( _scrollBar->value() );
+
+  // if the thumb has been moved to the bottom of the _scrollBar then set
+  // the display to automatically track new output, 
+  // that is, scroll down automatically
+  // to how new _lines as they are added
+  const bool atEndOfOutput = (_scrollBar->value() == _scrollBar->maximum());
+  _screenWindow->setTrackOutput( atEndOfOutput );
+
+  updateImage();
+}
+
+void TerminalDisplay::setScroll(int cursor, int slines)
+{
+  // update _scrollBar if the range or value has changed,
+  // otherwise return
+  //
+  // setting the range or value of a _scrollBar will always trigger
+  // a repaint, so it should be avoided if it is not necessary
+  if ( _scrollBar->minimum() == 0                 &&
+       _scrollBar->maximum() == (slines - _lines) &&
+       _scrollBar->value()   == cursor )
+  {
+        return;
+  }
+
+  disconnect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int)));
+  _scrollBar->setRange(0,slines - _lines);
+  _scrollBar->setSingleStep(1);
+  _scrollBar->setPageStep(_lines);
+  _scrollBar->setValue(cursor);
+  connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int)));
+}
+
+void TerminalDisplay::setScrollBarPosition(ScrollBarPosition position)
+{
+  if (_scrollbarLocation == position) 
+      return; 
+ 
+  if ( position == NoScrollBar )
+     _scrollBar->hide();
+  else 
+     _scrollBar->show(); 
+
+  _topMargin = _leftMargin = 1;
+  _scrollbarLocation = position;
+  
+  propagateSize();
+  update();
+}
+
+void TerminalDisplay::mousePressEvent(QMouseEvent* ev)
+{
+  if ( _possibleTripleClick && (ev->button()==Qt::LeftButton) ) {
+    mouseTripleClickEvent(ev);
+    return;
+  }
+
+  if ( !contentsRect().contains(ev->pos()) ) return;
+  
+  if ( !_screenWindow ) return;
+
+  int charLine;
+  int charColumn;
+  getCharacterPosition(ev->pos(),charLine,charColumn);
+  QPoint pos = QPoint(charColumn,charLine);
+
+  if ( ev->button() == Qt::LeftButton)
+  {
+    _lineSelectionMode = false;
+    _wordSelectionMode = false;
+
+    emit isBusySelecting(true); // Keep it steady...
+    // Drag only when the Control key is hold
+    bool selected = false;
+    
+    // The receiver of the testIsSelected() signal will adjust
+    // 'selected' accordingly.
+    //emit testIsSelected(pos.x(), pos.y(), selected);
+    
+    selected =  _screenWindow->isSelected(pos.x(),pos.y());
+
+    if ((!_ctrlDrag || ev->modifiers() & Qt::ControlModifier) && selected ) {
+      // The user clicked inside selected text
+      dragInfo.state = diPending;
+      dragInfo.start = ev->pos();
+    }
+    else {
+      // No reason to ever start a drag event
+      dragInfo.state = diNone;
+
+      _preserveLineBreaks = !( ( ev->modifiers() & Qt::ControlModifier ) && !(ev->modifiers() & Qt::AltModifier) );
+      _columnSelectionMode = (ev->modifiers() & Qt::AltModifier) && (ev->modifiers() & Qt::ControlModifier);
+
+      if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier))
+      {
+         _screenWindow->clearSelection();
+
+        //emit clearSelectionSignal();
+        pos.ry() += _scrollBar->value();
+        _iPntSel = _pntSel = pos;
+        _actSel = 1; // left mouse button pressed but nothing selected yet.
+        
+      }
+      else
+      {
+        emit mouseSignal( 0, charColumn + 1, charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 0);
+      }
+    }
+  }
+  else if ( ev->button() == Qt::MidButton )
+  {
+    if ( _mouseMarks || (!_mouseMarks && (ev->modifiers() & Qt::ShiftModifier)) )
+      emitSelection(true,ev->modifiers() & Qt::ControlModifier);
+    else
+      emit mouseSignal( 1, charColumn +1, charLine +1 +_scrollBar->value() -_scrollBar->maximum() , 0);
+  }
+  else if ( ev->button() == Qt::RightButton )
+  {
+    if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier)) 
+        emit configureRequest(ev->pos());
+    else
+        emit mouseSignal( 2, charColumn +1, charLine +1 +_scrollBar->value() -_scrollBar->maximum() , 0);
+  }
+}
+
+QList<QAction*> TerminalDisplay::filterActions(const QPoint& position)
+{
+  int charLine, charColumn;
+  getCharacterPosition(position,charLine,charColumn);
+
+  Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn);
+
+  return spot ? spot->actions() : QList<QAction*>();
+}
+
+void TerminalDisplay::mouseMoveEvent(QMouseEvent* ev)
+{
+  int charLine = 0;
+  int charColumn = 0;
+  int scrollBarWidth = (_scrollbarLocation == ScrollBarLeft) ? _scrollBar->width() : 0;
+
+  getCharacterPosition(ev->pos(),charLine,charColumn); 
+
+  // handle filters
+  // change link hot-spot appearance on mouse-over
+  Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn);
+  if ( spot && spot->type() == Filter::HotSpot::Link)
+  {
+    QRegion previousHotspotArea = _mouseOverHotspotArea;
+    _mouseOverHotspotArea = QRegion();
+    QRect r;
+    if (spot->startLine()==spot->endLine()) {
+        r.setCoords( spot->startColumn()*_fontWidth + scrollBarWidth, 
+                     spot->startLine()*_fontHeight,
+                     spot->endColumn()*_fontWidth + scrollBarWidth, 
+                     (spot->endLine()+1)*_fontHeight - 1 ); 
+        _mouseOverHotspotArea |= r;
+    } else {
+        r.setCoords( spot->startColumn()*_fontWidth + scrollBarWidth,
+                     spot->startLine()*_fontHeight,
+                     _columns*_fontWidth - 1 + scrollBarWidth,
+                     (spot->startLine()+1)*_fontHeight ); 
+        _mouseOverHotspotArea |= r;
+        for ( int line = spot->startLine()+1 ; line < spot->endLine() ; line++ ) {
+            r.setCoords( 0*_fontWidth + scrollBarWidth, 
+                         line*_fontHeight,
+                         _columns*_fontWidth + scrollBarWidth,
+                         (line+1)*_fontHeight ); 
+            _mouseOverHotspotArea |= r;
+        }
+        r.setCoords( 0*_fontWidth + scrollBarWidth, 
+                     spot->endLine()*_fontHeight,
+                     spot->endColumn()*_fontWidth + scrollBarWidth, 
+                     (spot->endLine()+1)*_fontHeight ); 
+        _mouseOverHotspotArea |= r;
+    }
+    // display tooltips when mousing over links
+    // TODO: Extend this to work with filter types other than links
+    const QString& tooltip = spot->tooltip();
+    if ( !tooltip.isEmpty() )
+    {
+        QToolTip::showText( mapToGlobal(ev->pos()) , tooltip , this , _mouseOverHotspotArea.boundingRect() );
+    }
+
+    update( _mouseOverHotspotArea | previousHotspotArea );
+  }
+  else if ( !_mouseOverHotspotArea.isEmpty() )
+  {
+        update( _mouseOverHotspotArea );
+        // set hotspot area to an invalid rectangle
+        _mouseOverHotspotArea = QRegion();
+  }
+  
+  // for auto-hiding the cursor, we need mouseTracking
+  if (ev->buttons() == Qt::NoButton ) return;
+
+  // if the terminal is interested in mouse movements 
+  // then emit a mouse movement signal, unless the shift
+  // key is being held down, which overrides this.
+  if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier))
+  {
+    int button = 3;
+    if (ev->buttons() & Qt::LeftButton)
+        button = 0;
+    if (ev->buttons() & Qt::MidButton)
+        button = 1;
+    if (ev->buttons() & Qt::RightButton)
+        button = 2;
+
+        
+        emit mouseSignal( button, 
+                        charColumn + 1,
+                        charLine + 1 +_scrollBar->value() -_scrollBar->maximum(),
+             1 );
+      
+    return;
+  }
+      
+  if (dragInfo.state == diPending) 
+  {
+    // we had a mouse down, but haven't confirmed a drag yet
+    // if the mouse has moved sufficiently, we will confirm
+
+   int distance = 10; //KGlobalSettings::dndEventDelay();
+   if ( ev->x() > dragInfo.start.x() + distance || ev->x() < dragInfo.start.x() - distance ||
+        ev->y() > dragInfo.start.y() + distance || ev->y() < dragInfo.start.y() - distance) 
+   {
+      // we've left the drag square, we can start a real drag operation now
+      emit isBusySelecting(false); // Ok.. we can breath again.
+      
+       _screenWindow->clearSelection();
+      doDrag();
+    }
+    return;
+  } 
+  else if (dragInfo.state == diDragging) 
+  {
+    // this isn't technically needed because mouseMoveEvent is suppressed during
+    // Qt drag operations, replaced by dragMoveEvent
+    return;
+  }
+
+  if (_actSel == 0) return;
+
+ // don't extend selection while pasting
+  if (ev->buttons() & Qt::MidButton) return;
+
+  extendSelection( ev->pos() );
+}
+
+void TerminalDisplay::extendSelection( const QPoint& position )
+{
+  QPoint pos = position;
+
+  if ( !_screenWindow )
+      return;
+
+  //if ( !contentsRect().contains(ev->pos()) ) return;
+  QPoint tL  = contentsRect().topLeft();
+  int    tLx = tL.x();
+  int    tLy = tL.y();
+  int    scroll = _scrollBar->value();
+
+  // we're in the process of moving the mouse with the left button pressed
+  // the mouse cursor will kept caught within the bounds of the text in
+  // this widget.
+
+  int linesBeyondWidget = 0;
+
+  QRect textBounds(tLx + _leftMargin,
+                     tLy + _topMargin,
+                   _usedColumns*_fontWidth-1,
+                   _usedLines*_fontHeight-1);
+
+  // Adjust position within text area bounds.
+  QPoint oldpos = pos;
+ 
+  pos.setX( qBound(textBounds.left(),pos.x(),textBounds.right()) );
+  pos.setY( qBound(textBounds.top(),pos.y(),textBounds.bottom()) );
+
+  if ( oldpos.y() > textBounds.bottom() ) 
+  {
+      linesBeyondWidget = (oldpos.y()-textBounds.bottom()) / _fontHeight;
+    _scrollBar->setValue(_scrollBar->value()+linesBeyondWidget+1); // scrollforward
+  }
+  if ( oldpos.y() < textBounds.top() )
+  {
+      linesBeyondWidget = (textBounds.top()-oldpos.y()) / _fontHeight;
+    _scrollBar->setValue(_scrollBar->value()-linesBeyondWidget-1); // history
+  }
+
+  int charColumn = 0;
+  int charLine = 0;
+  getCharacterPosition(pos,charLine,charColumn);
+
+  QPoint here = QPoint(charColumn,charLine); //QPoint((pos.x()-tLx-_leftMargin+(_fontWidth/2))/_fontWidth,(pos.y()-tLy-_topMargin)/_fontHeight);
+  QPoint ohere;
+  QPoint _iPntSelCorr = _iPntSel;
+  _iPntSelCorr.ry() -= _scrollBar->value();
+  QPoint _pntSelCorr = _pntSel;
+  _pntSelCorr.ry() -= _scrollBar->value();
+  bool swapping = false;
+
+  if ( _wordSelectionMode )
+  {
+    // Extend to word boundaries
+    int i;
+    QChar selClass;
+
+    bool left_not_right = ( here.y() < _iPntSelCorr.y() ||
+       ( here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x() ) );
+    bool old_left_not_right = ( _pntSelCorr.y() < _iPntSelCorr.y() ||
+       ( _pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x() ) );
+    swapping = left_not_right != old_left_not_right;
+
+    // Find left (left_not_right ? from here : from start)
+    QPoint left = left_not_right ? here : _iPntSelCorr;
+    i = loc(left.x(),left.y());
+    if (i>=0 && i<=_imageSize) {
+      selClass = charClass(_image[i].character);
+      while ( ((left.x()>0) || (left.y()>0 && (_lineProperties[left.y()-1] & LINE_WRAPPED) )) 
+                      && charClass(_image[i-1].character) == selClass )
+      { i--; if (left.x()>0) left.rx()--; else {left.rx()=_usedColumns-1; left.ry()--;} }
+    }
+
+    // Find left (left_not_right ? from start : from here)
+    QPoint right = left_not_right ? _iPntSelCorr : here;
+    i = loc(right.x(),right.y());
+    if (i>=0 && i<=_imageSize) {
+      selClass = charClass(_image[i].character);
+      while( ((right.x()<_usedColumns-1) || (right.y()<_usedLines-1 && (_lineProperties[right.y()] & LINE_WRAPPED) )) 
+                      && charClass(_image[i+1].character) == selClass )
+      { i++; if (right.x()<_usedColumns-1) right.rx()++; else {right.rx()=0; right.ry()++; } }
+    }
+
+    // Pick which is start (ohere) and which is extension (here)
+    if ( left_not_right )
+    {
+      here = left; ohere = right;
+    }
+    else
+    {
+      here = right; ohere = left;
+    }
+    ohere.rx()++;
+  }
+
+  if ( _lineSelectionMode )
+  {
+    // Extend to complete line
+    bool above_not_below = ( here.y() < _iPntSelCorr.y() );
+
+    QPoint above = above_not_below ? here : _iPntSelCorr;
+    QPoint below = above_not_below ? _iPntSelCorr : here;
+
+    while (above.y()>0 && (_lineProperties[above.y()-1] & LINE_WRAPPED) )
+      above.ry()--;
+    while (below.y()<_usedLines-1 && (_lineProperties[below.y()] & LINE_WRAPPED) )
+      below.ry()++;
+
+    above.setX(0);
+    below.setX(_usedColumns-1);
+
+    // Pick which is start (ohere) and which is extension (here)
+    if ( above_not_below )
+    {
+      here = above; ohere = below;
+    }
+    else
+    {
+      here = below; ohere = above;
+    }
+
+    QPoint newSelBegin = QPoint( ohere.x(), ohere.y() );
+    swapping = !(_tripleSelBegin==newSelBegin);
+    _tripleSelBegin = newSelBegin;
+
+    ohere.rx()++;
+  }
+
+  int offset = 0;
+  if ( !_wordSelectionMode && !_lineSelectionMode )
+  {
+    int i;
+    QChar selClass;
+
+    bool left_not_right = ( here.y() < _iPntSelCorr.y() ||
+       ( here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x() ) );
+    bool old_left_not_right = ( _pntSelCorr.y() < _iPntSelCorr.y() ||
+       ( _pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x() ) );
+    swapping = left_not_right != old_left_not_right;
+
+    // Find left (left_not_right ? from here : from start)
+    QPoint left = left_not_right ? here : _iPntSelCorr;
+
+    // Find left (left_not_right ? from start : from here)
+    QPoint right = left_not_right ? _iPntSelCorr : here;
+    if ( right.x() > 0 && !_columnSelectionMode )
+    {
+      i = loc(right.x(),right.y());
+      if (i>=0 && i<=_imageSize) {
+        selClass = charClass(_image[i-1].character);
+       /* if (selClass == ' ')
+        {
+          while ( right.x() < _usedColumns-1 && charClass(_image[i+1].character) == selClass && (right.y()<_usedLines-1) && 
+                          !(_lineProperties[right.y()] & LINE_WRAPPED))
+          { i++; right.rx()++; }
+          if (right.x() < _usedColumns-1)
+            right = left_not_right ? _iPntSelCorr : here;
+          else
+            right.rx()++;  // will be balanced later because of offset=-1;
+        }*/
+      }
+    }
+
+    // Pick which is start (ohere) and which is extension (here)
+    if ( left_not_right )
+    {
+      here = left; ohere = right; offset = 0;
+    }
+    else
+    {
+      here = right; ohere = left; offset = -1;
+    }
+  }
+
+  if ((here == _pntSelCorr) && (scroll == _scrollBar->value())) return; // not moved
+
+  if (here == ohere) return; // It's not left, it's not right.
+
+  if ( _actSel < 2 || swapping )
+  {
+    if ( _columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode )
+    {
+        _screenWindow->setSelectionStart( ohere.x() , ohere.y() , true );
+    }
+    else
+    {
+        _screenWindow->setSelectionStart( ohere.x()-1-offset , ohere.y() , false );
+    }
+
+  }
+
+  _actSel = 2; // within selection
+  _pntSel = here;
+  _pntSel.ry() += _scrollBar->value();
+
+  if ( _columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode )
+  {
+     _screenWindow->setSelectionEnd( here.x() , here.y() );
+  }
+  else
+  {
+     _screenWindow->setSelectionEnd( here.x()+offset , here.y() );
+  }
+
+}
+
+void TerminalDisplay::mouseReleaseEvent(QMouseEvent* ev)
+{
+    if ( !_screenWindow )
+        return;
+
+    int charLine;
+    int charColumn;
+    getCharacterPosition(ev->pos(),charLine,charColumn);
+
+  if ( ev->button() == Qt::LeftButton)
+  {
+    emit isBusySelecting(false); 
+    if(dragInfo.state == diPending)
+    {
+      // We had a drag event pending but never confirmed.  Kill selection
+       _screenWindow->clearSelection();
+      //emit clearSelectionSignal();
+    }
+    else
+    {
+      if ( _actSel > 1 )
+      {
+          setSelection(  _screenWindow->selectedText(_preserveLineBreaks)  );
+      }
+
+      _actSel = 0;
+
+      //FIXME: emits a release event even if the mouse is
+      //       outside the range. The procedure used in `mouseMoveEvent'
+      //       applies here, too.
+
+      if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier))
+        emit mouseSignal( 3, // release
+                        charColumn + 1,
+                        charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 0);
+    }
+    dragInfo.state = diNone;
+  }
+  
+  
+  if ( !_mouseMarks && 
+       ((ev->button() == Qt::RightButton && !(ev->modifiers() & Qt::ShiftModifier))
+                        || ev->button() == Qt::MidButton) ) 
+  {
+    emit mouseSignal( 3, 
+                      charColumn + 1, 
+                      charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 
+                      0);
+  }
+}
+
+void TerminalDisplay::getCharacterPosition(const QPoint& widgetPoint,int& line,int& column) const
+{
+    column = (widgetPoint.x() + _fontWidth/2 -contentsRect().left()-_leftMargin) / _fontWidth;
+    line = (widgetPoint.y()-contentsRect().top()-_topMargin) / _fontHeight;
+
+    if ( line < 0 )
+        line = 0;
+    if ( column < 0 )
+        column = 0;
+
+    if ( line >= _usedLines )
+        line = _usedLines-1;
+
+    // the column value returned can be equal to _usedColumns, which
+    // is the position just after the last character displayed in a line.
+    //
+    // this is required so that the user can select characters in the right-most
+    // column (or left-most for right-to-left input)
+    if ( column > _usedColumns )
+        column = _usedColumns;
+}
+
+void TerminalDisplay::updateLineProperties()
+{
+    if ( !_screenWindow ) 
+        return;
+
+    _lineProperties = _screenWindow->getLineProperties();    
+}
+
+void TerminalDisplay::mouseDoubleClickEvent(QMouseEvent* ev)
+{
+  if ( ev->button() != Qt::LeftButton) return;
+  if ( !_screenWindow ) return;
+
+  int charLine = 0;
+  int charColumn = 0;
+
+  getCharacterPosition(ev->pos(),charLine,charColumn);
+
+  QPoint pos(charColumn,charLine);
+
+  // pass on double click as two clicks.
+  if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier))
+  {
+    // Send just _ONE_ click event, since the first click of the double click
+    // was already sent by the click handler
+    emit mouseSignal( 0, 
+                      pos.x()+1, 
+                      pos.y()+1 +_scrollBar->value() -_scrollBar->maximum(),
+                      0 ); // left button
+    return;
+  }
+
+  _screenWindow->clearSelection();
+  QPoint bgnSel = pos;
+  QPoint endSel = pos;
+  int i = loc(bgnSel.x(),bgnSel.y());
+  _iPntSel = bgnSel;
+  _iPntSel.ry() += _scrollBar->value();
+
+  _wordSelectionMode = true;
+
+  // find word boundaries...
+  QChar selClass = charClass(_image[i].character);
+  {
+     // find the start of the word
+     int x = bgnSel.x();
+     while ( ((x>0) || (bgnSel.y()>0 && (_lineProperties[bgnSel.y()-1] & LINE_WRAPPED) )) 
+                     && charClass(_image[i-1].character) == selClass )
+     {  
+       i--; 
+       if (x>0) 
+           x--; 
+       else 
+       {
+           x=_usedColumns-1; 
+           bgnSel.ry()--;
+       } 
+     }
+
+     bgnSel.setX(x);
+     _screenWindow->setSelectionStart( bgnSel.x() , bgnSel.y() , false );
+
+     // find the end of the word
+     i = loc( endSel.x(), endSel.y() );
+     x = endSel.x();
+     while( ((x<_usedColumns-1) || (endSel.y()<_usedLines-1 && (_lineProperties[endSel.y()] & LINE_WRAPPED) )) 
+                     && charClass(_image[i+1].character) == selClass )
+     { 
+         i++; 
+         if (x<_usedColumns-1) 
+             x++; 
+         else 
+         {  
+             x=0; 
+             endSel.ry()++; 
+         } 
+     }
+
+     endSel.setX(x);
+
+     // In word selection mode don't select @ (64) if at end of word.
+     if ( ( QChar( _image[i].character ) == '@' ) && ( ( endSel.x() - bgnSel.x() ) > 0 ) )
+       endSel.setX( x - 1 );
+
+
+     _actSel = 2; // within selection
+     
+     _screenWindow->setSelectionEnd( endSel.x() , endSel.y() );
+    
+     setSelection( _screenWindow->selectedText(_preserveLineBreaks) ); 
+   }
+
+  _possibleTripleClick=true;
+
+  QTimer::singleShot(QApplication::doubleClickInterval(),this,
+                     SLOT(tripleClickTimeout()));
+}
+
+void TerminalDisplay::wheelEvent( QWheelEvent* ev )
+{
+  if (ev->orientation() != Qt::Vertical)
+    return;
+
+  // if the terminal program is not interested mouse events
+  // then send the event to the scrollbar if the slider has room to move
+  // or otherwise send simulated up / down key presses to the terminal program
+  // for the benefit of programs such as 'less'
+  if ( _mouseMarks )
+  {
+    bool canScroll = _scrollBar->maximum() > 0;
+      if (canScroll)
+        _scrollBar->event(ev);
+    else
+    {
+        // assume that each Up / Down key event will cause the terminal application
+        // to scroll by one line.  
+        //
+        // to get a reasonable scrolling speed, scroll by one line for every 5 degrees
+        // of mouse wheel rotation.  Mouse wheels typically move in steps of 15 degrees,
+        // giving a scroll of 3 lines
+        int key = ev->delta() > 0 ? Qt::Key_Up : Qt::Key_Down;
+
+        // QWheelEvent::delta() gives rotation in eighths of a degree
+        int wheelDegrees = ev->delta() / 8;
+        int linesToScroll = abs(wheelDegrees) / 5;
+
+        QKeyEvent keyScrollEvent(QEvent::KeyPress,key,Qt::NoModifier);
+
+        for (int i=0;i<linesToScroll;i++)
+            emit keyPressedSignal(&keyScrollEvent);
+    }
+  }
+  else
+  {
+    // terminal program wants notification of mouse activity
+    
+    int charLine;
+    int charColumn;
+    getCharacterPosition( ev->pos() , charLine , charColumn );
+    
+    emit mouseSignal( ev->delta() > 0 ? 4 : 5, 
+                      charColumn + 1, 
+                      charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 
+                      0);
+  }
+}
+
+void TerminalDisplay::tripleClickTimeout()
+{
+  _possibleTripleClick=false;
+}
+
+void TerminalDisplay::mouseTripleClickEvent(QMouseEvent* ev)
+{
+  if ( !_screenWindow ) return;
+
+  int charLine;
+  int charColumn;
+  getCharacterPosition(ev->pos(),charLine,charColumn);
+  _iPntSel = QPoint(charColumn,charLine);
+
+  _screenWindow->clearSelection();
+
+  _lineSelectionMode = true;
+  _wordSelectionMode = false;
+
+  _actSel = 2; // within selection
+  emit isBusySelecting(true); // Keep it steady...
+
+  while (_iPntSel.y()>0 && (_lineProperties[_iPntSel.y()-1] & LINE_WRAPPED) )
+    _iPntSel.ry()--;
+  
+  if (_tripleClickMode == SelectForwardsFromCursor) {
+    // find word boundary start
+    int i = loc(_iPntSel.x(),_iPntSel.y());
+    QChar selClass = charClass(_image[i].character);
+    int x = _iPntSel.x();
+    
+    while ( ((x>0) || 
+             (_iPntSel.y()>0 && (_lineProperties[_iPntSel.y()-1] & LINE_WRAPPED) )
+            ) 
+            && charClass(_image[i-1].character) == selClass )
+    {
+        i--; 
+        if (x>0) 
+            x--; 
+        else 
+        {
+            x=_columns-1; 
+            _iPntSel.ry()--;
+        } 
+    }
+
+    _screenWindow->setSelectionStart( x , _iPntSel.y() , false );
+    _tripleSelBegin = QPoint( x, _iPntSel.y() );
+  }
+  else if (_tripleClickMode == SelectWholeLine) {
+    _screenWindow->setSelectionStart( 0 , _iPntSel.y() , false );
+    _tripleSelBegin = QPoint( 0, _iPntSel.y() );
+  }
+
+  while (_iPntSel.y()<_lines-1 && (_lineProperties[_iPntSel.y()] & LINE_WRAPPED) )
+    _iPntSel.ry()++;
+  
+  _screenWindow->setSelectionEnd( _columns - 1 , _iPntSel.y() );
+
+  setSelection(_screenWindow->selectedText(_preserveLineBreaks));
+
+  _iPntSel.ry() += _scrollBar->value();
+}
+
+
+bool TerminalDisplay::focusNextPrevChild( bool next )
+{
+  if (next)
+    return false; // This disables changing the active part in konqueror
+                  // when pressing Tab
+  return QWidget::focusNextPrevChild( next );
+}
+
+
+QChar TerminalDisplay::charClass(QChar qch) const
+{
+    if ( qch.isSpace() ) return ' ';
+
+    if ( qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive ) )
+    return 'a';
+
+    return qch;
+}
+
+void TerminalDisplay::setWordCharacters(const QString& wc)
+{
+    _wordCharacters = wc;
+}
+
+void TerminalDisplay::setUsesMouse(bool on)
+{
+  _mouseMarks = on;
+  setCursor( _mouseMarks ? Qt::IBeamCursor : Qt::ArrowCursor );
+}
+bool TerminalDisplay::usesMouse() const
+{
+    return _mouseMarks;
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                               Clipboard                                   */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+#undef KeyPress
+
+void TerminalDisplay::emitSelection(bool useXselection,bool appendReturn)
+{
+  if ( !_screenWindow ) 
+      return;
+
+  // Paste Clipboard by simulating keypress events
+  QString text = QApplication::clipboard()->text(useXselection ? QClipboard::Selection :
+                                                                 QClipboard::Clipboard);
+  if(appendReturn)
+    text.append("\r");
+  if ( ! text.isEmpty() )
+  {
+    text.replace('\n', '\r');
+    QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text);
+    emit keyPressedSignal(&e); // expose as a big fat keypress event
+    
+    _screenWindow->clearSelection();
+  }
+}
+
+void TerminalDisplay::setSelection(const QString& t)
+{
+  QApplication::clipboard()->setText(t, QClipboard::Selection);
+}
+
+void TerminalDisplay::copyClipboard()
+{
+  if ( !_screenWindow )
+      return;
+
+  QString text = _screenWindow->selectedText(_preserveLineBreaks);
+  if (!text.isEmpty())
+    QApplication::clipboard()->setText(text);
+}
+
+void TerminalDisplay::pasteClipboard()
+{
+  emitSelection(false,false);
+}
+
+void TerminalDisplay::pasteSelection()
+{
+  emitSelection(true,false);
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                                Keyboard                                   */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+void TerminalDisplay::setFlowControlWarningEnabled( bool enable )
+{
+    _flowControlWarningEnabled = enable;
+    
+    // if the dialog is currently visible and the flow control warning has 
+    // been disabled then hide the dialog
+    if (!enable)
+        outputSuspended(false);
+}
+
+void TerminalDisplay::keyPressEvent( QKeyEvent* event )
+{
+    bool emitKeyPressSignal = true;
+
+    // Keyboard-based navigation
+    if ( event->modifiers() == Qt::ShiftModifier )
+    {
+        bool update = true;
+
+        if ( event->key() == Qt::Key_PageUp )
+        {
+            _screenWindow->scrollBy( ScreenWindow::ScrollPages , -1 );
+        }
+        else if ( event->key() == Qt::Key_PageDown )
+        {
+            _screenWindow->scrollBy( ScreenWindow::ScrollPages , 1 );
+        }
+        else if ( event->key() == Qt::Key_Up )
+        {
+            _screenWindow->scrollBy( ScreenWindow::ScrollLines , -1 );
+        }
+        else if ( event->key() == Qt::Key_Down )
+        {
+            _screenWindow->scrollBy( ScreenWindow::ScrollLines , 1 );
+        }
+        else
+            update = false;
+
+        if ( update )
+        {
+            _screenWindow->setTrackOutput( _screenWindow->atEndOfOutput() );
+            
+            updateLineProperties();
+            updateImage();
+
+            // do not send key press to terminal
+            emitKeyPressSignal = false;
+        }
+    }
+
+    _actSel=0; // Key stroke implies a screen update, so TerminalDisplay won't
+              // know where the current selection is.
+
+    if (_hasBlinkingCursor) 
+    {
+      _blinkCursorTimer->start(QApplication::cursorFlashTime() / 2);
+      if (_cursorBlinking)
+        blinkCursorEvent();
+      else
+        _cursorBlinking = false;
+    }
+
+    if ( emitKeyPressSignal )
+        emit keyPressedSignal(event);
+
+    event->accept();
+}
+
+void TerminalDisplay::inputMethodEvent( QInputMethodEvent* event )
+{
+    QKeyEvent keyEvent(QEvent::KeyPress,0,Qt::NoModifier,event->commitString());
+    emit keyPressedSignal(&keyEvent);
+
+    _inputMethodData.preeditString = event->preeditString();
+    update(preeditRect() | _inputMethodData.previousPreeditRect);
+    
+    event->accept();
+}
+QVariant TerminalDisplay::inputMethodQuery( Qt::InputMethodQuery query ) const
+{
+    const QPoint cursorPos = _screenWindow ? _screenWindow->cursorPosition() : QPoint(0,0);
+    switch ( query ) 
+    {
+        case Qt::ImMicroFocus:
+                return imageToWidget(QRect(cursorPos.x(),cursorPos.y(),1,1));
+            break;
+        case Qt::ImFont:
+                return font();
+            break;
+        case Qt::ImCursorPosition:
+                // return the cursor position within the current line
+                return cursorPos.x();
+            break;
+        case Qt::ImSurroundingText:
+            {
+                // return the text from the current line
+                QString lineText;
+                QTextStream stream(&lineText);
+                PlainTextDecoder decoder;
+                decoder.begin(&stream);
+                decoder.decodeLine(&_image[loc(0,cursorPos.y())],_usedColumns,_lineProperties[cursorPos.y()]);
+                decoder.end();
+                return lineText;
+            }
+            break;
+        case Qt::ImCurrentSelection:
+                return QString();
+            break;
+        default:
+            break;
+    }
+
+    return QVariant();
+}
+
+bool TerminalDisplay::handleShortcutOverrideEvent(QKeyEvent* keyEvent)
+{
+    int modifiers = keyEvent->modifiers();
+
+    //  When a possible shortcut combination is pressed, 
+    //  emit the overrideShortcutCheck() signal to allow the host
+    //  to decide whether the terminal should override it or not.
+    if (modifiers != Qt::NoModifier) 
+    {
+        int modifierCount = 0;
+        unsigned int currentModifier = Qt::ShiftModifier;
+
+        while (currentModifier <= Qt::KeypadModifier)
+        {
+            if (modifiers & currentModifier)
+                modifierCount++;
+            currentModifier <<= 1;
+        }
+        if (modifierCount < 2) 
+        {
+            bool override = false;
+            emit overrideShortcutCheck(keyEvent,override);
+            if (override)
+            {
+                keyEvent->accept();
+                return true;
+            }
+        }
+    }
+
+    // Override any of the following shortcuts because
+    // they are needed by the terminal
+    int keyCode = keyEvent->key() | modifiers;
+    switch ( keyCode )
+    {
+      // list is taken from the QLineEdit::event() code
+      case Qt::Key_Tab:
+      case Qt::Key_Delete:
+      case Qt::Key_Home:
+      case Qt::Key_End:
+      case Qt::Key_Backspace:
+      case Qt::Key_Left:
+      case Qt::Key_Right:
+        keyEvent->accept();
+        return true;
+    }
+    return false;
+}
+
+bool TerminalDisplay::event(QEvent* event)
+{
+  bool eventHandled = false;
+  switch (event->type())
+  {
+    case QEvent::ShortcutOverride:
+        eventHandled = handleShortcutOverrideEvent((QKeyEvent*)event);
+        break;
+    case QEvent::PaletteChange:
+    case QEvent::ApplicationPaletteChange:
+        _scrollBar->setPalette( QApplication::palette() );
+        break;
+    default:
+        break;
+  }
+  return eventHandled ? true : QWidget::event(event); 
+}
+
+void TerminalDisplay::setBellMode(int mode)
+{
+  _bellMode=mode;
+}
+
+void TerminalDisplay::enableBell()
+{
+    _allowBell = true;
+}
+
+void TerminalDisplay::bell(const QString& message)
+{
+  if (_bellMode==NoBell) return;
+
+  //limit the rate at which bells can occur 
+  //...mainly for sound effects where rapid bells in sequence 
+  //produce a horrible noise
+  if ( _allowBell )
+  {
+    _allowBell = false;
+    QTimer::singleShot(500,this,SLOT(enableBell()));
+ 
+    if (_bellMode==SystemBeepBell) 
+    {
+      // TODO: This will need added back in at some point
+      //KNotification::beep();
+    } 
+    else if (_bellMode==NotifyBell) 
+    {
+      // TODO: This will need added back in at some point
+      //KNotification::event("BellVisible", message,QPixmap(),this);
+    } 
+    else if (_bellMode==VisualBell) 
+    {
+        swapColorTable();
+        QTimer::singleShot(200,this,SLOT(swapColorTable()));
+    }
+  }
+}
+
+void TerminalDisplay::swapColorTable()
+{
+  ColorEntry color = _colorTable[1];
+  _colorTable[1]=_colorTable[0];
+  _colorTable[0]= color;
+  _colorsInverted = !_colorsInverted;
+  update();
+}
+
+void TerminalDisplay::clearImage()
+{
+  // We initialize _image[_imageSize] too. See makeImage()
+  for (int i = 0; i <= _imageSize; i++)
+  {
+    _image[i].character = ' ';
+    _image[i].foregroundColor = CharacterColor(COLOR_SPACE_DEFAULT,
+                                               DEFAULT_FORE_COLOR);
+    _image[i].backgroundColor = CharacterColor(COLOR_SPACE_DEFAULT,
+                                               DEFAULT_BACK_COLOR);
+    _image[i].rendition = DEFAULT_RENDITION;
+  }
+}
+
+void TerminalDisplay::calcGeometry()
+{
+  _scrollBar->resize(_scrollBar->sizeHint().width(), contentsRect().height());
+  switch(_scrollbarLocation)
+  {
+    case NoScrollBar :
+     _leftMargin = DEFAULT_LEFT_MARGIN;
+     _contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN;
+     break;
+    case ScrollBarLeft :
+     _leftMargin = DEFAULT_LEFT_MARGIN + _scrollBar->width();
+     _contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN - _scrollBar->width();
+     _scrollBar->move(contentsRect().topLeft());
+     break;
+    case ScrollBarRight:
+     _leftMargin = DEFAULT_LEFT_MARGIN;
+     _contentWidth = contentsRect().width()  - 2 * DEFAULT_LEFT_MARGIN - _scrollBar->width();
+     _scrollBar->move(contentsRect().topRight() - QPoint(_scrollBar->width()-1,0));
+     break;
+  }
+
+  _topMargin = DEFAULT_TOP_MARGIN;
+  _contentHeight = contentsRect().height() - 2 * DEFAULT_TOP_MARGIN + /* mysterious */ 1;
+   
+  if (!_isFixedSize)
+  {
+     // ensure that display is always at least one column wide
+     _columns = qMax(1,_contentWidth / _fontWidth);
+     _usedColumns = qMin(_usedColumns,_columns);
+     
+     // ensure that display is always at least one line high
+     _lines = qMax(1,_contentHeight / _fontHeight);
+     _usedLines = qMin(_usedLines,_lines);
+  }
+}
+
+void TerminalDisplay::makeImage()
+{
+  calcGeometry();
+
+  // confirm that array will be of non-zero size, since the painting code 
+  // assumes a non-zero array length
+  Q_ASSERT( _lines > 0 && _columns > 0 );
+  Q_ASSERT( _usedLines <= _lines && _usedColumns <= _columns );
+
+  _imageSize=_lines*_columns;
+  
+  // We over-commit one character so that we can be more relaxed in dealing with
+  // certain boundary conditions: _image[_imageSize] is a valid but unused position
+  _image = new Character[_imageSize+1];
+
+  clearImage();
+}
+
+// calculate the needed size, this must be synced with calcGeometry()
+void TerminalDisplay::setSize(int columns, int lines)
+{
+  int scrollBarWidth = _scrollBar->isHidden() ? 0 : _scrollBar->sizeHint().width();
+  int horizontalMargin = 2 * DEFAULT_LEFT_MARGIN;
+  int verticalMargin = 2 * DEFAULT_TOP_MARGIN;
+
+  QSize newSize = QSize( horizontalMargin + scrollBarWidth + (columns * _fontWidth)  ,
+                 verticalMargin + (lines * _fontHeight)   );
+
+  if ( newSize != size() )
+  {
+    _size = newSize;
+    updateGeometry();
+  }
+}
+
+void TerminalDisplay::setFixedSize(int cols, int lins)
+{
+  _isFixedSize = true;
+  
+  //ensure that display is at least one line by one column in size
+  _columns = qMax(1,cols);
+  _lines = qMax(1,lins);
+  _usedColumns = qMin(_usedColumns,_columns);
+  _usedLines = qMin(_usedLines,_lines);
+
+  if (_image)
+  {
+     delete[] _image;
+     makeImage();
+  }
+  setSize(cols, lins);
+  QWidget::setFixedSize(_size);
+}
+
+QSize TerminalDisplay::sizeHint() const
+{
+  return _size;
+}
+
+
+/* --------------------------------------------------------------------- */
+/*                                                                       */
+/* Drag & Drop                                                           */
+/*                                                                       */
+/* --------------------------------------------------------------------- */
+
+void TerminalDisplay::dragEnterEvent(QDragEnterEvent* event)
+{
+  if (event->mimeData()->hasFormat("text/plain"))
+      event->acceptProposedAction();
+}
+
+void TerminalDisplay::dropEvent(QDropEvent* event)
+{
+  //KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
+
+  QString dropText;
+  /*
+  if (!urls.isEmpty()) 
+  {
+    for ( int i = 0 ; i < urls.count() ; i++ ) 
+    {
+        KUrl url = KIO::NetAccess::mostLocalUrl( urls[i] , 0 );
+        QString urlText;
+
+        if (url.isLocalFile())
+            urlText = url.path(); 
+        else
+            urlText = url.url();
+    
+        // in future it may be useful to be able to insert file names with drag-and-drop
+        // without quoting them (this only affects paths with spaces in) 
+        urlText = KShell::quoteArg(urlText);
+      
+        dropText += urlText;
+
+        if ( i != urls.count()-1 ) 
+            dropText += ' ';
+    }
+  }
+  else 
+  {
+    dropText = event->mimeData()->text();
+  }
+  */
+
+  if(event->mimeData()->hasFormat("text/plain")) 
+  {
+    emit sendStringToEmu(dropText.toLocal8Bit());
+  }
+}
+
+void TerminalDisplay::doDrag()
+{
+  dragInfo.state = diDragging;
+  dragInfo.dragObject = new QDrag(this);
+  QMimeData *mimeData = new QMimeData;
+  mimeData->setText(QApplication::clipboard()->text(QClipboard::Selection));
+  dragInfo.dragObject->setMimeData(mimeData);
+  dragInfo.dragObject->start(Qt::CopyAction);
+  // Don't delete the QTextDrag object.  Qt will delete it when it's done with it.
+}
+
+void TerminalDisplay::outputSuspended(bool suspended)
+{
+    //create the label when this function is first called
+    if (!_outputSuspendedLabel)
+    {
+            //This label includes a link to an English language website
+            //describing the 'flow control' (Xon/Xoff) feature found in almost 
+            //all terminal emulators.
+            //If there isn't a suitable article available in the target language the link
+            //can simply be removed.
+            _outputSuspendedLabel = new QLabel( i18n("<qt>Output has been "
+                                                "<a href=\"http://en.wikipedia.org/wiki/Flow_control\">suspended</a>"
+                                                " by pressing Ctrl+S."
+                                               "  Press <b>Ctrl+Q</b> to resume.</qt>"),
+                                               this );
+
+            QPalette palette(_outputSuspendedLabel->palette());
+            //KColorScheme::adjustBackground(palette,KColorScheme::NeutralBackground);
+            _outputSuspendedLabel->setPalette(palette);
+            _outputSuspendedLabel->setAutoFillBackground(true);
+            _outputSuspendedLabel->setBackgroundRole(QPalette::Base);
+            _outputSuspendedLabel->setFont(QApplication::font());
+            _outputSuspendedLabel->setContentsMargins(5, 5, 5, 5);
+
+            //enable activation of "Xon/Xoff" link in label
+            _outputSuspendedLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | 
+                                                          Qt::LinksAccessibleByKeyboard);
+            _outputSuspendedLabel->setOpenExternalLinks(true);
+            _outputSuspendedLabel->setVisible(false);
+
+            _gridLayout->addWidget(_outputSuspendedLabel);       
+            _gridLayout->addItem( new QSpacerItem(0,0,QSizePolicy::Expanding,
+                                                      QSizePolicy::Expanding),
+                                 1,0);
+
+    }
+
+    _outputSuspendedLabel->setVisible(suspended);
+}
+
+uint TerminalDisplay::lineSpacing() const
+{
+  return _lineSpacing;
+}
+
+void TerminalDisplay::setLineSpacing(uint i)
+{
+  _lineSpacing = i;
+  setVTFont(font()); // Trigger an update.
+}
+
+AutoScrollHandler::AutoScrollHandler(QWidget* parent)
+: QObject(parent)
+, _timerId(0)
+{
+    parent->installEventFilter(this);
+}
+void AutoScrollHandler::timerEvent(QTimerEvent* event)
+{
+    if (event->timerId() != _timerId)
+        return;
+
+    QMouseEvent mouseEvent(    QEvent::MouseMove,
+                              widget()->mapFromGlobal(QCursor::pos()),
+                              Qt::NoButton,
+                              Qt::LeftButton,
+                              Qt::NoModifier);
+
+    QApplication::sendEvent(widget(),&mouseEvent);    
+}
+bool AutoScrollHandler::eventFilter(QObject* watched,QEvent* event)
+{
+    Q_ASSERT( watched == parent() );
+    Q_UNUSED( watched );
+
+    QMouseEvent* mouseEvent = (QMouseEvent*)event;
+    switch (event->type())
+    {
+        case QEvent::MouseMove:
+        {
+            bool mouseInWidget = widget()->rect().contains(mouseEvent->pos());
+
+            if (mouseInWidget)
+            {
+                if (_timerId)
+                    killTimer(_timerId);
+                _timerId = 0;
+            }
+            else
+            {
+                if (!_timerId && (mouseEvent->buttons() & Qt::LeftButton))
+                    _timerId = startTimer(100);
+            }
+                break;
+        }
+        case QEvent::MouseButtonRelease:
+            if (_timerId && (mouseEvent->buttons() & ~Qt::LeftButton))
+            {
+                killTimer(_timerId);
+                _timerId = 0;
+            }
+        break;
+        default:
+        break;
+    };
+
+    return false;
+}
+
+#include "TerminalDisplay.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/TerminalDisplay.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,821 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef TERMINALDISPLAY_H
+#define TERMINALDISPLAY_H
+
+// Qt
+#include <QtGui/QColor>
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+// Konsole
+#include "Filter.h"
+#include "Character.h"
+#include "konsole_export.h"
+
+class QDrag;
+class QDragEnterEvent;
+class QDropEvent;
+class QLabel;
+class QTimer;
+class QEvent;
+class QGridLayout;
+class QKeyEvent;
+class QScrollBar;
+class QShowEvent;
+class QHideEvent;
+class QTimerEvent;
+class QWidget;
+
+class KMenu;
+
+namespace Konsole
+{
+
+extern unsigned short vt100_graphics[32];
+
+class ScreenWindow;
+
+/**
+ * A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
+ * to the terminal.
+ *
+ * When the terminal emulation receives new output from the program running in the terminal, 
+ * it will update the display by calling updateImage().
+ *
+ * TODO More documentation
+ */
+class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget
+{
+   Q_OBJECT
+
+public:
+    /** Constructs a new terminal display widget with the specified parent. */
+    TerminalDisplay(QWidget *parent=0);
+    virtual ~TerminalDisplay();
+
+    /** Returns the terminal color palette used by the display. */
+    const ColorEntry* colorTable() const;
+    /** Sets the terminal color palette used by the display. */
+    void setColorTable(const ColorEntry table[]);
+    /**
+     * Sets the seed used to generate random colors for the display
+     * (in color schemes that support them).
+     */
+    void setRandomSeed(uint seed);
+    /**
+     * Returns the seed used to generate random colors for the display
+     * (in color schemes that support them).
+     */
+    uint randomSeed() const;
+
+    /** Sets the opacity of the terminal display. */
+    void setOpacity(qreal opacity);
+
+    /** 
+     * This enum describes the location where the scroll bar is positioned in the display widget.
+     */
+    enum ScrollBarPosition 
+    { 
+        /** Do not show the scroll bar. */
+        NoScrollBar=0, 
+        /** Show the scroll bar on the left side of the display. */
+        ScrollBarLeft=1, 
+        /** Show the scroll bar on the right side of the display. */
+        ScrollBarRight=2 
+    };
+    /** 
+     * Specifies whether the terminal display has a vertical scroll bar, and if so whether it
+     * is shown on the left or right side of the display.
+     */
+    void setScrollBarPosition(ScrollBarPosition position);
+
+    /** 
+     * Sets the current position and range of the display's scroll bar.
+     *
+     * @param cursor The position of the scroll bar's thumb.
+     * @param lines The maximum value of the scroll bar.
+     */
+    void setScroll(int cursor, int lines);
+
+    /** 
+     * 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).
+     * Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
+     * the view will draw visual cues such as underlines on mouse-over for links or translucent
+     * rectangles for markers.
+     *
+     * To add a new filter to the view, call:
+     *      viewWidget->filterChain()->addFilter( filterObject );
+     */
+    FilterChain* filterChain() const;
+
+    /** 
+     * Updates the filters in the display's filter chain.  This will cause
+     * the hotspots to be updated to match the current image.
+     *
+     * WARNING:  This function can be expensive depending on the 
+     * image size and number of filters in the filterChain()
+     *
+     * TODO - This API does not really allow efficient usage.  Revise it so
+     * that the processing can be done in a better way.
+     *
+     * eg:
+     *      - Area of interest may be known ( eg. mouse cursor hovering
+     *      over an area )
+     */  
+    void processFilters();
+
+    /** 
+     * Returns a list of menu actions created by the filters for the content
+     * at the given @p position.
+     */
+    QList<QAction*> filterActions(const QPoint& position);
+
+    /** Returns true if the cursor is set to blink or false otherwise. */
+    bool blinkingCursor() { return _hasBlinkingCursor; }
+    /** Specifies whether or not the cursor blinks. */
+    void setBlinkingCursor(bool blink);
+
+    /** Specifies whether or not text can blink. */
+    void setBlinkingTextEnabled(bool blink);
+
+    void setCtrlDrag(bool enable) { _ctrlDrag=enable; }
+    bool ctrlDrag() { return _ctrlDrag; }
+
+    /** 
+     *  This enum describes the methods for selecting text when
+      *  the user triple-clicks within the display. 
+      */
+    enum TripleClickMode
+    {
+        /** Select the whole line underneath the cursor. */
+        SelectWholeLine,
+        /** Select from the current cursor position to the end of the line. */
+        SelectForwardsFromCursor
+    };
+    /** Sets how the text is selected when the user triple clicks within the display. */    
+    void setTripleClickMode(TripleClickMode mode) { _tripleClickMode = mode; }
+    /** See setTripleClickSelectionMode() */
+    TripleClickMode tripleClickMode() { return _tripleClickMode; }
+
+    void setLineSpacing(uint);
+    uint lineSpacing() const;
+
+    void emitSelection(bool useXselection,bool appendReturn);
+
+    /**
+     * This enum describes the available shapes for the keyboard cursor.
+     * See setKeyboardCursorShape()
+     */
+    enum KeyboardCursorShape
+    {
+        /** A rectangular block which covers the entire area of the cursor character. */
+        BlockCursor,
+        /** 
+         * A single flat line which occupies the space at the bottom of the cursor
+         * character's area.
+         */
+        UnderlineCursor,
+        /** 
+         * An cursor shaped like the capital letter 'I', similar to the IBeam 
+         * cursor used in Qt/KDE text editors.
+         */
+        IBeamCursor
+    };
+    /** 
+     * Sets the shape of the keyboard cursor.  This is the cursor drawn   
+     * at the position in the terminal where keyboard input will appear.
+     *
+     * In addition the terminal display widget also has a cursor for 
+     * the mouse pointer, which can be set using the QWidget::setCursor()
+     * method.
+     *
+     * Defaults to BlockCursor
+     */
+    void setKeyboardCursorShape(KeyboardCursorShape shape);
+    /**
+     * Returns the shape of the keyboard cursor.  See setKeyboardCursorShape()
+     */
+    KeyboardCursorShape keyboardCursorShape() const;
+
+    /**
+     * Sets the color used to draw the keyboard cursor.  
+     *
+     * The keyboard cursor defaults to using the foreground color of the character
+     * underneath it.
+     *
+     * @param useForegroundColor If true, the cursor color will change to match
+     * the foreground color of the character underneath it as it is moved, in this
+     * case, the @p color parameter is ignored and the color of the character
+     * under the cursor is inverted to ensure that it is still readable.
+     * @param color The color to use to draw the cursor.  This is only taken into
+     * account if @p useForegroundColor is false.
+     */
+    void setKeyboardCursorColor(bool useForegroundColor , const QColor& color);
+
+    /** 
+     * Returns the color of the keyboard cursor, or an invalid color if the keyboard
+     * cursor color is set to change according to the foreground color of the character
+     * underneath it. 
+     */
+    QColor keyboardCursorColor() const;
+
+    /**
+     * Returns the number of lines of text which can be displayed in the widget.
+     *
+     * This will depend upon the height of the widget and the current font.
+     * See fontHeight()
+     */
+    int  lines()   { return _lines;   }
+    /**
+     * Returns the number of characters of text which can be displayed on
+     * each line in the widget.
+     *
+     * This will depend upon the width of the widget and the current font.
+     * See fontWidth()
+     */
+    int  columns() { return _columns; }
+
+    /**
+     * Returns the height of the characters in the font used to draw the text in the display.
+     */
+    int  fontHeight()   { return _fontHeight;   }
+    /**
+     * Returns the width of the characters in the display.  
+     * This assumes the use of a fixed-width font.
+     */
+    int  fontWidth()    { return _fontWidth; }
+
+    void setSize(int cols, int lins);
+    void setFixedSize(int cols, int lins);
+    
+    // reimplemented
+    QSize sizeHint() const;
+
+    /**
+     * Sets which characters, in addition to letters and numbers, 
+     * are regarded as being part of a word for the purposes
+     * of selecting words in the display by double clicking on them.
+     *
+     * The word boundaries occur at the first and last characters which
+     * are either a letter, number, or a character in @p wc
+     *
+     * @param wc An array of characters which are to be considered parts
+     * of a word ( in addition to letters and numbers ).
+     */
+    void setWordCharacters(const QString& wc);
+    /** 
+     * Returns the characters which are considered part of a word for the 
+     * purpose of selecting words in the display with the mouse.
+     *
+     * @see setWordCharacters()
+     */
+    QString wordCharacters() { return _wordCharacters; }
+
+    /** 
+     * Sets the type of effect used to alert the user when a 'bell' occurs in the 
+     * terminal session.
+     *
+     * The terminal session can trigger the bell effect by calling bell() with
+     * the alert message.
+     */
+    void setBellMode(int mode);
+    /** 
+     * Returns the type of effect used to alert the user when a 'bell' occurs in
+     * the terminal session.
+     * 
+     * See setBellMode()
+     */
+    int bellMode() { return _bellMode; }
+
+    /**
+     * This enum describes the different types of sounds and visual effects which
+     * can be used to alert the user when a 'bell' occurs in the terminal
+     * session.
+     */
+    enum BellMode
+    { 
+        /** A system beep. */
+        SystemBeepBell=0, 
+        /** 
+         * KDE notification.  This may play a sound, show a passive popup
+         * or perform some other action depending on the user's settings.
+         */
+        NotifyBell=1, 
+        /** A silent, visual bell (eg. inverting the display's colors briefly) */
+        VisualBell=2, 
+        /** No bell effects */
+        NoBell=3 
+    };
+
+    void setSelection(const QString &t);
+
+    /** 
+     * Reimplemented.  Has no effect.  Use setVTFont() to change the font
+     * used to draw characters in the display.
+     */
+    virtual void setFont(const QFont &);
+
+    /** Returns the font used to draw characters in the display */
+    QFont getVTFont() { return font(); }
+
+    /** 
+     * Sets the font used to draw the display.  Has no effect if @p font
+     * is larger than the size of the display itself.    
+     */
+    void setVTFont(const QFont& font);
+
+    /**
+     * Specified whether anti-aliasing of text in the terminal display
+     * is enabled or not.  Defaults to enabled.
+     */
+    static void setAntialias( bool antialias ) { _antialiasText = antialias; }
+    /** 
+     * Returns true if anti-aliasing of text in the terminal is enabled.
+     */
+    static bool antialias()                 { return _antialiasText;   }
+
+    /**
+     * Specifies whether characters with intense colors should be rendered
+     * as bold. Defaults to true.
+     */
+    void setBoldIntense(bool value) { _boldIntense = value; }
+    /**
+     * Returns true if characters with intense colors are rendered in bold.
+     */
+    bool getBoldIntense() { return _boldIntense; }
+    
+    /**
+     * Sets whether or not the current height and width of the 
+     * terminal in lines and columns is displayed whilst the widget
+     * is being resized.
+     */
+    void setTerminalSizeHint(bool on) { _terminalSizeHint=on; }
+    /** 
+     * Returns whether or not the current height and width of
+     * the terminal in lines and columns is displayed whilst the widget
+     * is being resized.
+     */
+    bool terminalSizeHint() { return _terminalSizeHint; }
+    /** 
+     * Sets whether the terminal size display is shown briefly
+     * after the widget is first shown.
+     *
+     * See setTerminalSizeHint() , isTerminalSizeHint()
+     */
+    void setTerminalSizeStartup(bool on) { _terminalSizeStartup=on; }
+
+    /**
+     * Sets the status of the BiDi rendering inside the terminal display.
+     * Defaults to disabled.
+     */
+    void setBidiEnabled(bool set) { _bidiEnabled=set; }
+    /**
+     * Returns the status of the BiDi rendering in this widget.
+     */
+    bool isBidiEnabled() { return _bidiEnabled; }
+
+    /**
+     * Sets the terminal screen section which is displayed in this widget.
+     * When updateImage() is called, the display fetches the latest character image from the
+     * the associated terminal screen window.
+     *
+     * In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
+     * by the TerminalDisplay.
+     */
+    void setScreenWindow( ScreenWindow* window );
+    /** Returns the terminal screen section which is displayed in this widget.  See setScreenWindow() */
+    ScreenWindow* screenWindow() const;
+
+    static bool HAVE_TRANSPARENCY;
+
+public slots:
+
+    /** 
+     * Causes the terminal display to fetch the latest character image from the associated
+     * terminal screen ( see setScreenWindow() ) and redraw the display.
+     */
+    void updateImage(); 
+    /**
+     * Causes the terminal display to fetch the latest line status flags from the 
+     * associated terminal screen ( see setScreenWindow() ).  
+     */ 
+    void updateLineProperties();
+
+    /** Copies the selected text to the clipboard. */
+    void copyClipboard();
+    /** 
+     * Pastes the content of the clipboard into the 
+     * display.
+     */
+    void pasteClipboard();
+    /**
+     * Pastes the content of the selection into the
+     * display.
+     */
+    void pasteSelection();
+
+    /** 
+       * Changes whether the flow control warning box should be shown when the flow control
+       * stop key (Ctrl+S) are pressed.
+       */
+    void setFlowControlWarningEnabled(bool enabled);
+    /** 
+     * Returns true if the flow control warning box is enabled. 
+     * See outputSuspended() and setFlowControlWarningEnabled()
+     */
+    bool flowControlWarningEnabled() const
+    { return _flowControlWarningEnabled; }
+
+    /** 
+     * Causes the widget to display or hide a message informing the user that terminal
+     * output has been suspended (by using the flow control key combination Ctrl+S)
+     *
+     * @param suspended True if terminal output has been suspended and the warning message should
+     *                     be shown or false to indicate that terminal output has been resumed and that
+     *                     the warning message should disappear.
+     */ 
+    void outputSuspended(bool suspended);
+
+    /**
+     * Sets whether the program whoose output is being displayed in the view
+     * is interested in mouse events.
+     *
+     * If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
+     * or otherwise moves the mouse inside the view.
+     * The user interaction needed to create selections will also change, and the user will be required
+     * to hold down the shift key to create a selection or perform other mouse activities inside the 
+     * view area - since the program running in the terminal is being allowed to handle normal mouse
+     * events itself.
+     *
+     * @param usesMouse Set to true if the program running in the terminal is interested in mouse events
+     * or false otherwise.
+     */
+    void setUsesMouse(bool usesMouse);
+  
+    /** See setUsesMouse() */
+    bool usesMouse() const;
+
+    /** 
+     * Shows a notification that a bell event has occurred in the terminal.
+     * TODO: More documentation here
+     */
+    void bell(const QString& message);
+
+    /** 
+     * Sets the background of the display to the specified color. 
+     * @see setColorTable(), setForegroundColor() 
+     */
+    void setBackgroundColor(const QColor& color);
+
+    /** 
+     * Sets the text of the display to the specified color. 
+     * @see setColorTable(), setBackgroundColor()
+     */
+    void setForegroundColor(const QColor& color);
+
+signals:
+
+    /**
+     * Emitted when the user presses a key whilst the terminal widget has focus.
+     */
+    void keyPressedSignal(QKeyEvent *e);
+
+    /** 
+     * A mouse event occurred.
+     * @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
+     * @param column The character column where the event occurred
+     * @param line The character row where the event occurred
+     * @param eventType The type of event.  0 for a mouse press / release or 1 for mouse motion
+     */
+    void mouseSignal(int button, int column, int line, int eventType);
+    void changedFontMetricSignal(int height, int width);
+    void changedContentSizeSignal(int height, int width);
+
+    /** 
+     * Emitted when the user right clicks on the display, or right-clicks with the Shift
+     * key held down if usesMouse() is true.
+     *
+     * This can be used to display a context menu.
+     */
+    void configureRequest(const QPoint& position);
+
+    /**
+     * When a shortcut which is also a valid terminal key sequence is pressed while 
+     * the terminal widget  has focus, this signal is emitted to allow the host to decide 
+     * whether the shortcut should be overridden.  
+     * When the shortcut is overridden, the key sequence will be sent to the terminal emulation instead
+     * and the action associated with the shortcut will not be triggered.
+     *
+     * @p override is set to false by default and the shortcut will be triggered as normal.
+     */
+    void overrideShortcutCheck(QKeyEvent* keyEvent,bool& override);
+
+   void isBusySelecting(bool);
+   void sendStringToEmu(const char*);
+
+protected:
+    virtual bool event( QEvent * );
+
+    virtual void paintEvent( QPaintEvent * );
+
+    virtual void showEvent(QShowEvent*);
+    virtual void hideEvent(QHideEvent*);
+    virtual void resizeEvent(QResizeEvent*);
+
+    virtual void fontChange(const QFont &font);
+    virtual void focusInEvent(QFocusEvent* event);
+    virtual void focusOutEvent(QFocusEvent* event);
+    virtual void keyPressEvent(QKeyEvent* event);
+    virtual void mouseDoubleClickEvent(QMouseEvent* ev);
+    virtual void mousePressEvent( QMouseEvent* );
+    virtual void mouseReleaseEvent( QMouseEvent* );
+    virtual void mouseMoveEvent( QMouseEvent* );
+    virtual void extendSelection( const QPoint& pos );
+    virtual void wheelEvent( QWheelEvent* );
+
+    virtual bool focusNextPrevChild( bool next );
+    
+    // drag and drop
+    virtual void dragEnterEvent(QDragEnterEvent* event);
+    virtual void dropEvent(QDropEvent* event);
+    void doDrag();
+    enum DragState { diNone, diPending, diDragging };
+
+    struct _dragInfo {
+      DragState       state;
+      QPoint          start;
+      QDrag           *dragObject;
+    } dragInfo;
+
+    // classifies the 'ch' into one of three categories
+    // and returns a character to indicate which category it is in
+    //
+    //     - A space (returns ' ') 
+    //     - Part of a word (returns 'a')
+    //     - Other characters (returns the input character)
+    QChar charClass(QChar ch) const;
+
+    void clearImage();
+
+    void mouseTripleClickEvent(QMouseEvent* ev);
+
+    // reimplemented
+    virtual void inputMethodEvent ( QInputMethodEvent* event );
+    virtual QVariant inputMethodQuery( Qt::InputMethodQuery query ) const;
+
+protected slots:
+
+    void scrollBarPositionChanged(int value);
+    void blinkEvent();
+    void blinkCursorEvent();
+    
+    //Renables bell noises and visuals.  Used to disable further bells for a short period of time
+    //after emitting the first in a sequence of bell events.
+    void enableBell();
+
+private slots:
+
+    void swapColorTable();
+    void tripleClickTimeout();  // resets possibleTripleClick
+
+private:
+
+    // -- Drawing helpers --
+
+    // divides the part of the display specified by 'rect' into
+    // fragments according to their colors and styles and calls
+    // drawTextFragment() to draw the fragments 
+    void drawContents(QPainter &paint, const QRect &rect);
+    // draws a section of text, all the text in this section
+    // has a common color and style
+    void drawTextFragment(QPainter& painter, const QRect& rect, 
+                          const QString& text, const Character* style); 
+    // draws the background for a text fragment
+    // if useOpacitySetting is true then the color's alpha value will be set to
+    // the display's transparency (set with setOpacity()), otherwise the background
+    // will be drawn fully opaque
+    void drawBackground(QPainter& painter, const QRect& rect, const QColor& color,
+                        bool useOpacitySetting);
+    // draws the cursor character
+    void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor, 
+                                       const QColor& backgroundColor , bool& invertColors);
+    // draws the characters or line graphics in a text fragment
+    void drawCharacters(QPainter& painter, const QRect& rect,  const QString& text, 
+                                           const Character* style, bool invertCharacterColor);
+    // draws a string of line graphics
+    void drawLineCharString(QPainter& painter, int x, int y, 
+                            const QString& str, const Character* attributes);
+
+    // draws the preedit string for input methods
+    void drawInputMethodPreeditString(QPainter& painter , const QRect& rect);
+
+    // --
+
+    // maps an area in the character image to an area on the widget 
+    QRect imageToWidget(const QRect& imageArea) const;
+
+    // maps a point on the widget to the position ( ie. line and column ) 
+    // of the character at that point.
+    void getCharacterPosition(const QPoint& widgetPoint,int& line,int& column) const;
+
+    // the area where the preedit string for input methods will be draw
+    QRect preeditRect() const;
+
+    // shows a notification window in the middle of the widget indicating the terminal's
+    // current size in columns and lines
+    void showResizeNotification();
+
+    // scrolls the image by a number of lines.  
+    // 'lines' may be positive ( to scroll the image down ) 
+    // or negative ( to scroll the image up )
+    // '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();
+    void updateImageSize();
+    void makeImage();
+    
+    void paintFilters(QPainter& painter);
+
+    // returns a region covering all of the areas of the widget which contain
+    // a hotspot
+    QRegion hotSpotRegion() const;
+
+    // returns the position of the cursor in columns and lines
+    QPoint cursorPosition() const;
+
+    // redraws the cursor
+    void updateCursor();
+
+    bool handleShortcutOverrideEvent(QKeyEvent* event);
+
+    // the window onto the terminal screen which this display
+    // is currently showing.  
+    QPointer<ScreenWindow> _screenWindow;
+
+    bool _allowBell;
+
+    QGridLayout* _gridLayout;
+
+    bool _fixedFont; // has fixed pitch
+    int  _fontHeight;     // height
+    int  _fontWidth;     // width
+    int  _fontAscent;     // ascend
+    bool _boldIntense;   // Whether intense colors should be rendered with bold font
+
+    int _leftMargin;    // offset
+    int _topMargin;    // offset
+
+    int _lines;      // the number of lines that can be displayed in the widget
+    int _columns;    // the number of columns that can be displayed in the widget
+    
+    int _usedLines;  // the number of lines that are actually being used, this will be less
+                    // than 'lines' if the character image provided with setImage() is smaller
+                    // than the maximum image size which can be displayed
+
+    int _usedColumns; // the number of columns that are actually being used, this will be less
+                     // than 'columns' if the character image provided with setImage() is smaller
+                     // than the maximum image size which can be displayed
+    
+    int _contentHeight;
+    int _contentWidth;
+    Character* _image; // [lines][columns]
+               // only the area [usedLines][usedColumns] in the image contains valid data
+
+    int _imageSize;
+    QVector<LineProperty> _lineProperties;
+
+    ColorEntry _colorTable[TABLE_COLORS];
+    uint _randomSeed;
+
+    bool _resizing;
+    bool _terminalSizeHint;
+    bool _terminalSizeStartup;
+    bool _bidiEnabled;
+    bool _mouseMarks;
+
+    QPoint  _iPntSel; // initial selection point
+    QPoint  _pntSel; // current selection point
+    QPoint  _tripleSelBegin; // help avoid flicker
+    int     _actSel; // selection state
+    bool    _wordSelectionMode;
+    bool    _lineSelectionMode;
+    bool    _preserveLineBreaks;
+    bool    _columnSelectionMode;
+
+    QClipboard*  _clipboard;
+    QScrollBar* _scrollBar;
+    ScrollBarPosition _scrollbarLocation;
+    QString     _wordCharacters;
+    int         _bellMode;
+
+    bool _blinking;   // hide text in paintEvent
+    bool _hasBlinker; // has characters to blink
+    bool _cursorBlinking;     // hide cursor in paintEvent
+    bool _hasBlinkingCursor;  // has blinking cursor enabled
+    bool _allowBlinkingText;  // allow text to blink
+    bool _ctrlDrag;           // require Ctrl key for drag
+    TripleClickMode _tripleClickMode;
+    bool _isFixedSize; //Columns / lines are locked.
+    QTimer* _blinkTimer;  // active when hasBlinker
+    QTimer* _blinkCursorTimer;  // active when hasBlinkingCursor
+
+    KMenu* _drop;
+    QString _dropText;
+    int _dndFileCount;
+
+    bool _possibleTripleClick;  // is set in mouseDoubleClickEvent and deleted
+                               // after QApplication::doubleClickInterval() delay
+
+
+    QLabel* _resizeWidget;
+    QTimer* _resizeTimer;
+
+    bool _flowControlWarningEnabled;
+
+    //widgets related to the warning message that appears when the user presses Ctrl+S to suspend
+    //terminal output - informing them what has happened and how to resume output
+    QLabel* _outputSuspendedLabel; 
+        
+    uint _lineSpacing;
+
+    bool _colorsInverted; // true during visual bell
+
+    QSize _size;
+    
+    QRgb _blendColor;
+
+    // list of filters currently applied to the display.  used for links and
+    // search highlight
+    TerminalImageFilterChain* _filterChain;
+    QRegion _mouseOverHotspotArea;
+
+    KeyboardCursorShape _cursorShape;
+
+    // custom cursor color.  if this is invalid then the foreground
+    // color of the character under the cursor is used
+    QColor _cursorColor;  
+
+
+    struct InputMethodData
+    {
+        QString preeditString;
+        QRect previousPreeditRect;
+    };
+    InputMethodData _inputMethodData;
+
+    static bool _antialiasText;   // do we antialias or not
+
+    //the delay in milliseconds between redrawing blinking text
+    static const int TEXT_BLINK_DELAY = 500;
+    static const int DEFAULT_LEFT_MARGIN = 1;
+    static const int DEFAULT_TOP_MARGIN = 1;
+
+public:
+    static void setTransparencyEnabled(bool enable)
+    {
+        HAVE_TRANSPARENCY = enable;
+    }
+};
+
+class AutoScrollHandler : public QObject
+{
+Q_OBJECT
+
+public:
+    AutoScrollHandler(QWidget* parent);
+protected:
+    virtual void timerEvent(QTimerEvent* event);
+    virtual bool eventFilter(QObject* watched,QEvent* event);
+private:
+    QWidget* widget() const { return static_cast<QWidget*>(parent()); }
+    int _timerId;
+};
+
+}
+
+#endif // TERMINALDISPLAY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewContainer.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,851 @@
+/*
+    This file is part of the Konsole Terminal.
+    
+    Copyright 2006-2008 Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+//krazy:excludeall=qclasses
+
+// Own
+#include "ViewContainer.h"
+
+// Qt
+#include <QtCore/QHash>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QBrush>
+#include <QtGui/QListWidget>
+#include <QtGui/QSplitter>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QTabBar>
+#include <QtGui/QToolButton>
+#include <QtGui/QWidgetAction>
+
+#include <QtGui/QDrag>
+#include <QtGui/QDragMoveEvent>
+#include <QMimeData>
+
+// KDE 
+#include <KColorDialog>
+#include <kcolorscheme.h>
+#include <kcolorutils.h>
+#include <kdebug.h>
+#include <kconfiggroup.h>
+#include <KLocale>
+#include <KMenu>
+#include <KColorCollection>
+#include <KTabWidget>
+
+// Konsole
+#include "IncrementalSearchBar.h"
+#include "ViewProperties.h"
+
+// TODO Perhaps move everything which is Konsole-specific into different files
+#include "ProfileListWidget.h"
+
+using namespace Konsole;
+
+ViewContainer::ViewContainer(NavigationPosition position , QObject* parent)
+    : QObject(parent)
+    , _navigationDisplayMode(AlwaysShowNavigation)
+    , _navigationPosition(position)
+    , _searchBar(0)
+{
+}
+
+ViewContainer::~ViewContainer()
+{
+    foreach( QWidget* view , _views ) 
+    {
+        disconnect(view,SIGNAL(destroyed(QObject*)),this,SLOT(viewDestroyed(QObject*)));
+    }
+
+    if (_searchBar) {
+        _searchBar->deleteLater();
+    }
+
+    emit destroyed(this);
+}
+void ViewContainer::moveViewWidget( int , int ) {}
+void ViewContainer::setFeatures(Features features)
+{ _features = features; }
+ViewContainer::Features ViewContainer::features() const
+{ return _features; }
+void ViewContainer::moveActiveView( MoveDirection direction )
+{
+    const int currentIndex = _views.indexOf( activeView() ) ;
+    int newIndex = -1; 
+
+    switch ( direction )
+    {
+        case MoveViewLeft:
+            newIndex = qMax( currentIndex-1 , 0 );
+            break;
+        case MoveViewRight:
+            newIndex = qMin( currentIndex+1 , _views.count() -1 );
+            break;
+    }
+
+    Q_ASSERT( newIndex != -1 );
+
+    moveViewWidget( currentIndex , newIndex );   
+
+    _views.swap(currentIndex,newIndex);
+
+    setActiveView( _views[newIndex] );
+}
+
+void ViewContainer::setNavigationDisplayMode(NavigationDisplayMode mode)
+{
+    _navigationDisplayMode = mode;
+    navigationDisplayModeChanged(mode);
+}
+ViewContainer::NavigationPosition ViewContainer::navigationPosition() const
+{
+    return _navigationPosition;
+}
+void ViewContainer::setNavigationPosition(NavigationPosition position)
+{
+    // assert that this position is supported
+    Q_ASSERT( supportedNavigationPositions().contains(position) );
+
+    _navigationPosition = position;
+
+    navigationPositionChanged(position);
+}
+QList<ViewContainer::NavigationPosition> ViewContainer::supportedNavigationPositions() const
+{
+    return QList<NavigationPosition>() << NavigationPositionTop;
+}
+ViewContainer::NavigationDisplayMode ViewContainer::navigationDisplayMode() const
+{
+    return _navigationDisplayMode;
+}
+void ViewContainer::addView(QWidget* view , ViewProperties* item, int index)
+{
+    if (index == -1)
+        _views.append(view);
+    else
+        _views.insert(index,view);
+
+    _navigation[view] = item;
+
+    connect( view , SIGNAL(destroyed(QObject*)) , this , SLOT( viewDestroyed(QObject*) ) );
+
+    addViewWidget(view,index);
+
+    emit viewAdded(view,item);
+}
+void ViewContainer::viewDestroyed(QObject* object)
+{
+    QWidget* widget = static_cast<QWidget*>(object);
+
+    _views.removeAll(widget);
+    _navigation.remove(widget);
+
+    // FIXME This can result in ViewContainerSubClass::removeViewWidget() being 
+    // called after the widget's parent has been deleted or partially deleted
+    // in the ViewContainerSubClass instance's destructor.
+    //
+    // Currently deleteLater() is used to remove child widgets in the subclass 
+    // constructors to get around the problem, but this is a hack and needs
+    // to be fixed. 
+    removeViewWidget(widget);
+    
+    emit viewRemoved(widget);
+
+    if (_views.count() == 0)
+        emit empty(this);
+}
+void ViewContainer::removeView(QWidget* view)
+{
+    _views.removeAll(view);
+    _navigation.remove(view);
+
+    disconnect( view , SIGNAL(destroyed(QObject*)) , this , SLOT( viewDestroyed(QObject*) ) );
+
+    removeViewWidget(view);
+    
+    emit viewRemoved(view);
+
+    if (_views.count() == 0)
+        emit empty(this);
+
+}
+
+const QList<QWidget*> ViewContainer::views()
+{
+    return _views;
+}
+
+IncrementalSearchBar* ViewContainer::searchBar()
+{
+    if (!_searchBar) {
+        _searchBar = new IncrementalSearchBar( IncrementalSearchBar::AllFeatures , 0);
+        _searchBar->setVisible(false);
+        connect(_searchBar, SIGNAL(destroyed(QObject*)), this, SLOT(searchBarDestroyed()));
+    }
+    return _searchBar;
+}
+
+void ViewContainer::searchBarDestroyed()
+{
+    _searchBar = 0;
+}
+
+void ViewContainer::activateNextView()
+{
+    QWidget* active = activeView();
+
+    int index = _views.indexOf(active);
+
+    if ( index == -1 )
+        return;
+
+    if ( index == _views.count() - 1 )
+        index = 0;
+    else
+        index++;
+
+    setActiveView( _views.at(index) );
+}
+
+void ViewContainer::activatePreviousView()
+{
+    QWidget* active = activeView();
+
+    int index = _views.indexOf(active);
+
+    if ( index == -1 ) 
+        return;
+
+    if ( index == 0 )
+        index = _views.count() - 1;
+    else
+        index--;
+
+    setActiveView( _views.at(index) );
+}
+
+ViewProperties* ViewContainer::viewProperties( QWidget* widget )
+{
+    Q_ASSERT( _navigation.contains(widget) );
+
+    return _navigation[widget];    
+}
+
+QList<QWidget*> ViewContainer::widgetsForItem(ViewProperties* item) const
+{
+    return _navigation.keys(item);
+}
+
+ViewContainerTabBar::ViewContainerTabBar(QWidget* parent,TabbedViewContainer* container)
+    : KTabBar(parent)
+    , _container(container)
+    , _dropIndicator(0)
+    , _dropIndicatorIndex(-1)
+    , _drawIndicatorDisabled(false)
+{
+    setStyleSheet("QTabBar::tab { min-width: 2em; max-width: 25em }");
+    setElideMode(Qt::ElideLeft);
+}
+void ViewContainerTabBar::setDropIndicator(int index, bool drawDisabled)
+{
+    if (!parentWidget() || _dropIndicatorIndex == index)
+        return;
+
+    _dropIndicatorIndex = index;
+    const int ARROW_SIZE = 32;
+    bool north = shape() == QTabBar::RoundedNorth || shape() == QTabBar::TriangularNorth;
+
+    if (!_dropIndicator || _drawIndicatorDisabled != drawDisabled)
+    {
+        if (!_dropIndicator)
+        {
+            _dropIndicator = new QLabel(parentWidget());
+            _dropIndicator->resize(ARROW_SIZE,ARROW_SIZE);
+        }
+
+        QIcon::Mode drawMode = drawDisabled ? QIcon::Disabled : QIcon::Normal;
+        const QString iconName = north ? "arrow-up" : "arrow-down";
+        _dropIndicator->setPixmap(KIcon(iconName).pixmap(ARROW_SIZE,ARROW_SIZE,drawMode));
+        _drawIndicatorDisabled = drawDisabled;
+    }
+
+    if (index < 0)
+    {
+        _dropIndicator->hide();
+        return;
+    }
+
+    const QRect rect = tabRect(index < count() ? index : index-1);
+
+    QPoint pos;
+    if (index < count())
+        pos = rect.topLeft();
+    else
+        pos = rect.topRight();
+
+    if (north)
+        pos.ry() += ARROW_SIZE;
+    else
+        pos.ry() -= ARROW_SIZE; 
+
+    pos.rx() -= ARROW_SIZE/2; 
+
+    _dropIndicator->move(mapTo(parentWidget(),pos));
+    _dropIndicator->show();
+
+}
+void ViewContainerTabBar::dragLeaveEvent(QDragLeaveEvent*)
+{
+    setDropIndicator(-1);
+}
+void ViewContainerTabBar::dragEnterEvent(QDragEnterEvent* event)
+{
+    if (event->mimeData()->hasFormat(ViewProperties::mimeType()) &&
+        event->source() != 0)
+        event->acceptProposedAction();    
+}
+void ViewContainerTabBar::dragMoveEvent(QDragMoveEvent* event)
+{
+    if (event->mimeData()->hasFormat(ViewProperties::mimeType())
+        && event->source() != 0)
+    {
+        int index = dropIndex(event->pos());
+        if (index == -1)
+            index = count();
+
+        setDropIndicator(index,proposedDropIsSameTab(event));
+
+        event->acceptProposedAction();
+    }
+}
+int ViewContainerTabBar::dropIndex(const QPoint& pos) const
+{
+    int tab = tabAt(pos);
+    if (tab < 0)
+        return tab;
+
+    // pick the closest tab boundary 
+    QRect rect = tabRect(tab);
+    if ( (pos.x()-rect.left()) > (rect.width()/2) )
+        tab++;
+
+    if (tab == count())
+        return -1;
+
+    return tab;
+}
+bool ViewContainerTabBar::proposedDropIsSameTab(const QDropEvent* event) const
+{
+    int index = dropIndex(event->pos());
+    int droppedId = ViewProperties::decodeMimeData(event->mimeData());
+    bool sameTabBar = event->source() == this;
+
+    if (!sameTabBar)
+        return false;
+
+    const QList<QWidget*> viewList = _container->views();
+    int sourceIndex = -1;
+    for (int i=0;i<count();i++)
+    {
+        int idAtIndex = _container->viewProperties(viewList[i])->identifier();
+        if (idAtIndex == droppedId)
+            sourceIndex = i;
+    }
+
+    bool sourceAndDropAreLast = sourceIndex == count()-1 && index == -1;
+    if (sourceIndex == index || sourceIndex == index-1 || sourceAndDropAreLast)
+        return true;
+    else
+        return false;
+}
+void ViewContainerTabBar::dropEvent(QDropEvent* event)
+{
+    setDropIndicator(-1);
+
+    if (    !event->mimeData()->hasFormat(ViewProperties::mimeType())
+        ||  proposedDropIsSameTab(event) )
+    {
+        event->ignore();
+        return;
+    }
+
+    int index = dropIndex(event->pos());
+    int droppedId = ViewProperties::decodeMimeData(event->mimeData());
+    bool result = false;
+    emit _container->moveViewRequest(index,droppedId,result);
+    
+    if (result)
+        event->accept();
+    else
+        event->ignore();
+}
+
+QPixmap ViewContainerTabBar::dragDropPixmap(int tab) 
+{
+    Q_ASSERT(tab >= 0 && tab < count());
+
+    // TODO - grabWidget() works except that it includes part
+    // of the tab bar outside the tab itself if the tab has 
+    // curved corners
+    const QRect rect = tabRect(tab);
+    const int borderWidth = 1;
+
+    QPixmap tabPixmap(rect.width()+borderWidth,
+                      rect.height()+borderWidth);
+    QPainter painter(&tabPixmap);
+    painter.drawPixmap(0,0,QPixmap::grabWidget(this,rect));
+    QPen borderPen;
+    borderPen.setBrush(palette().dark());
+    borderPen.setWidth(borderWidth);
+    painter.setPen(borderPen);
+    painter.drawRect(0,0,rect.width(),rect.height());
+    painter.end();
+
+    return tabPixmap;
+}
+TabbedViewContainer::TabbedViewContainer(NavigationPosition position , QObject* parent) 
+: ViewContainer(position,parent)
+   , _contextMenuTabIndex(0)
+{
+    _containerWidget = new QWidget;
+    _stackWidget = new QStackedWidget();
+    _tabBar = new ViewContainerTabBar(_containerWidget,this);
+    _tabBar->setDrawBase(true);
+    _tabBar->setDocumentMode(true);
+    _tabBar->setFocusPolicy(Qt::NoFocus);
+    _tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
+
+    _newTabButton = new QToolButton(_containerWidget);
+    _newTabButton->setIcon(KIcon("tab-new"));
+    _newTabButton->adjustSize();
+    // new tab button is initially hidden, it will be shown when setFeatures() is called
+    // with the QuickNewView flag enabled
+    _newTabButton->setHidden(true);
+
+    _closeTabButton = new QToolButton(_containerWidget);
+    _closeTabButton->setIcon(KIcon("tab-close"));
+    _closeTabButton->adjustSize();
+    _closeTabButton->setHidden(true);
+    _closeTabButton->setEnabled(false);
+
+    connect( _tabBar , SIGNAL(currentChanged(int)) , this , SLOT(currentTabChanged(int)) );
+    connect( _tabBar , SIGNAL(tabDoubleClicked(int)) , this , SLOT(tabDoubleClicked(int)) );
+    connect( _tabBar , SIGNAL(newTabRequest()) , this , SIGNAL(newViewRequest()) );
+    connect( _tabBar , SIGNAL(wheelDelta(int)) , this , SLOT(wheelScrolled(int)) );
+    connect( _tabBar , SIGNAL(tabCloseRequested(int)) , this , SLOT(closeTab(int)) );
+    connect( _tabBar , SIGNAL(initiateDrag(int)) , this , SLOT(startTabDrag(int)) );
+    connect( _tabBar, SIGNAL(contextMenu(int, const QPoint&)), this,
+            SLOT(openTabContextMenu(int, const QPoint&)) );
+
+    connect( _newTabButton , SIGNAL(clicked()) , this , SIGNAL(newViewRequest()) );
+    connect( _closeTabButton , SIGNAL(clicked()) , this , SLOT(closeCurrentTab()) );
+
+    _layout = new TabbedViewContainerLayout;
+    _layout->setSpacing(0);
+    _layout->setContentsMargins(0, 0, 0, 0);
+    _tabBarLayout = new QHBoxLayout;
+    _tabBarLayout->setSpacing(0);
+    _tabBarLayout->setContentsMargins(0, 0, 0, 0);
+    _tabBarLayout->addWidget(_newTabButton);
+    _tabBarLayout->addWidget(_tabBar);
+    _tabBarLayout->addWidget(_closeTabButton); 
+
+    _layout->addWidget(_stackWidget);
+    searchBar()->setParent(_containerWidget);
+    if ( position == NavigationPositionTop )
+    {
+        _layout->insertLayout(0,_tabBarLayout);
+        _layout->insertWidget(-1,searchBar());
+        _tabBar->setShape(QTabBar::RoundedNorth);
+    }
+    else if ( position == NavigationPositionBottom )
+    {
+        _layout->insertWidget(-1,searchBar());
+        _layout->insertLayout(-1,_tabBarLayout);
+        _tabBar->setShape(QTabBar::RoundedSouth);
+    }
+    else
+        Q_ASSERT(false); // position not supported
+
+    _containerWidget->setLayout(_layout);
+ 
+    _contextPopupMenu = new KMenu(_tabBar);
+
+    _contextPopupMenu->addAction(KIcon("tab-detach"),
+        i18nc("@action:inmenu", "&Detach Tab"), this,
+        SLOT(tabContextMenuDetachTab()));
+
+    _contextPopupMenu->addAction(KIcon(),
+        i18nc("@action:inmenu", "&Rename Tab..."), this,
+        SLOT(tabContextMenuRenameTab()));
+
+//    _contextPopupMenu->addAction(KIcon("tab-close"),
+//        i18nc("@action:inmenu", "&Close Tab"), this,
+//        SLOT(tabContextMenuCloseTab()));
+
+}
+void TabbedViewContainer::setNewViewMenu(QMenu* menu)
+{
+  _newTabButton->setMenu(menu);
+}
+ViewContainer::Features TabbedViewContainer::supportedFeatures() const
+{ 
+  return QuickNewView|QuickCloseView;
+}
+void TabbedViewContainer::setFeatures(Features features)
+{
+    ViewContainer::setFeatures(features);
+
+    const bool tabBarHidden = _tabBar->isHidden();
+    _newTabButton->setVisible(!tabBarHidden && (features & QuickNewView));
+    _closeTabButton->setVisible(!tabBarHidden && (features & QuickCloseView));
+}
+void TabbedViewContainer::closeCurrentTab()
+{
+    if (_stackWidget->currentIndex() != -1)
+    {
+        closeTab(_stackWidget->currentIndex());
+    }
+}
+void TabbedViewContainer::closeTab(int tab)
+{
+    Q_ASSERT(tab >= 0 && tab < _stackWidget->count());
+    
+    if (viewProperties(_stackWidget->widget(tab))->confirmClose())
+        removeView(_stackWidget->widget(tab));
+}
+void TabbedViewContainer::setTabBarVisible(bool visible)
+{
+    _tabBar->setVisible(visible);
+    _newTabButton->setVisible(visible && (features() & QuickNewView));
+    _closeTabButton->setVisible(visible && (features() & QuickCloseView));
+}
+QList<ViewContainer::NavigationPosition> TabbedViewContainer::supportedNavigationPositions() const
+{
+    return QList<NavigationPosition>() << NavigationPositionTop << NavigationPositionBottom;
+}
+void TabbedViewContainer::navigationPositionChanged(NavigationPosition position)
+{
+    // this method assumes that there are only two items
+    // in the layout
+    Q_ASSERT( _layout->count() == 3 );
+
+    // index of stack widget in the layout when tab bar is at the bottom
+    const int StackIndexWithTabBottom = 0;
+
+    if ( position == NavigationPositionTop 
+            && _layout->indexOf(_stackWidget) == StackIndexWithTabBottom )
+    {
+        _layout->removeItem(_tabBarLayout);
+        _layout->removeWidget(searchBar());
+
+        _layout->insertLayout(0,_tabBarLayout);
+        _layout->insertWidget(-1,searchBar());
+        _tabBar->setShape(QTabBar::RoundedNorth);
+    }
+    else if ( position == NavigationPositionBottom 
+            && _layout->indexOf(_stackWidget) != StackIndexWithTabBottom )
+    {
+        _layout->removeItem(_tabBarLayout);
+        _layout->removeWidget(searchBar());
+
+        _layout->insertWidget(-1,searchBar());
+        _layout->insertLayout(-1,_tabBarLayout);
+        _tabBar->setShape(QTabBar::RoundedSouth);
+    }
+}
+void TabbedViewContainer::navigationDisplayModeChanged(NavigationDisplayMode mode)
+{
+    if ( mode == AlwaysShowNavigation && _tabBar->isHidden() )
+        setTabBarVisible(true);
+
+    if ( mode == AlwaysHideNavigation && !_tabBar->isHidden() )
+        setTabBarVisible(false);
+
+    if ( mode == ShowNavigationAsNeeded )
+        dynamicTabBarVisibility();
+}
+void TabbedViewContainer::dynamicTabBarVisibility()
+{
+    if ( _tabBar->count() > 1 && _tabBar->isHidden() )
+        setTabBarVisible(true);
+
+    if ( _tabBar->count() < 2 && !_tabBar->isHidden() )
+        setTabBarVisible(false);    
+}
+TabbedViewContainer::~TabbedViewContainer()
+{
+    if (!_containerWidget.isNull())
+        _containerWidget->deleteLater();
+}
+
+void TabbedViewContainer::startTabDrag(int tab)
+{
+    QDrag* drag = new QDrag(_tabBar);
+    const QRect tabRect = _tabBar->tabRect(tab);
+    QPixmap tabPixmap = _tabBar->dragDropPixmap(tab); 
+
+    drag->setPixmap(tabPixmap);
+
+    // offset the tab position so the tab will follow the cursor exactly
+    // where it was clicked (as opposed to centering on the origin of the pixmap)
+    QPoint mappedPos = _tabBar->mapFromGlobal(QCursor::pos());
+    mappedPos.rx() -= tabRect.x();
+
+    drag->setHotSpot(mappedPos);
+
+    int id = viewProperties(views()[tab])->identifier();
+    QWidget* view = views()[tab];
+    drag->setMimeData(ViewProperties::createMimeData(id));
+
+    // start drag, if drag-and-drop is successful the view at 'tab' will be
+    // deleted
+    //
+    // if the tab was dragged onto another application
+    // which blindly accepted the drop then ignore it
+    if (drag->exec() == Qt::MoveAction && drag->target() != 0)
+    {
+        // Deleting the view may cause the view container to be deleted, which
+        // will also delete the QDrag object.
+        // This can cause a crash if Qt's internal drag-and-drop handling
+        // tries to delete it later.  
+        //
+        // For now set the QDrag's parent to 0 so that it won't be deleted if 
+        // this view container is destroyed.
+        //
+        // FIXME: Resolve this properly
+        drag->setParent(0);
+        removeView(view);
+    }
+}
+
+void TabbedViewContainer::tabDoubleClicked(int index)
+{
+    renameTab(index);
+}
+
+void TabbedViewContainer::renameTab(int index)
+{
+    viewProperties(views()[index])->rename();
+}
+
+void TabbedViewContainer::openTabContextMenu(int index, const QPoint& pos)
+{
+    _contextMenuTabIndex = index;
+
+    _contextPopupMenu->exec(pos);
+}
+
+void TabbedViewContainer::tabContextMenuCloseTab()
+{
+    closeTab(_contextMenuTabIndex);
+}
+
+void TabbedViewContainer::tabContextMenuDetachTab()
+{
+    emit detachTab(this, _stackWidget->widget(_contextMenuTabIndex));
+}
+
+void TabbedViewContainer::tabContextMenuRenameTab()
+{
+    renameTab(_contextMenuTabIndex);
+}
+
+void TabbedViewContainer::moveViewWidget( int fromIndex , int toIndex )
+{
+    QString text = _tabBar->tabText(fromIndex);
+    QIcon icon = _tabBar->tabIcon(fromIndex);
+   
+    // FIXME - This will lose properties of the tab other than
+    // their text and icon when moving them
+    
+    _tabBar->removeTab(fromIndex);
+    _tabBar->insertTab(toIndex,icon,text);
+
+    QWidget* widget = _stackWidget->widget(fromIndex);
+    _stackWidget->removeWidget(widget);
+    _stackWidget->insertWidget(toIndex,widget);
+}
+void TabbedViewContainer::currentTabChanged(int index)
+{
+    _stackWidget->setCurrentIndex(index);
+    if (_stackWidget->widget(index))
+        emit activeViewChanged(_stackWidget->widget(index));
+
+    // clear activity indicators
+    setTabActivity(index,false);
+}
+
+void TabbedViewContainer::wheelScrolled(int delta)
+{
+    if ( delta < 0 )
+    activateNextView();
+    else
+    activatePreviousView();
+}
+
+QWidget* TabbedViewContainer::containerWidget() const
+{
+    return _containerWidget;
+}
+QWidget* TabbedViewContainer::activeView() const
+{
+    return _stackWidget->currentWidget();
+}
+void TabbedViewContainer::setActiveView(QWidget* view)
+{
+    const int index = _stackWidget->indexOf(view);
+
+    Q_ASSERT( index != -1 );
+
+   _stackWidget->setCurrentWidget(view);
+   _tabBar->setCurrentIndex(index); 
+}
+void TabbedViewContainer::addViewWidget( QWidget* view , int index)
+{
+    _stackWidget->insertWidget(index,view);
+    _stackWidget->updateGeometry();
+
+    ViewProperties* item = viewProperties(view);
+    connect( item , SIGNAL(titleChanged(ViewProperties*)) , this , 
+                    SLOT(updateTitle(ViewProperties*))); 
+    connect( item , SIGNAL(iconChanged(ViewProperties*) ) , this , 
+                    SLOT(updateIcon(ViewProperties*)));
+    connect( item , SIGNAL(activity(ViewProperties*)) , this ,
+                    SLOT(updateActivity(ViewProperties*)));
+
+    _tabBar->insertTab( index , item->icon() , item->title() );
+
+    if ( navigationDisplayMode() == ShowNavigationAsNeeded )
+        dynamicTabBarVisibility();
+}
+void TabbedViewContainer::removeViewWidget( QWidget* view )
+{
+    if (!_stackWidget)
+        return;
+    const int index = _stackWidget->indexOf(view);
+
+    Q_ASSERT( index != -1 );
+
+    _stackWidget->removeWidget(view);
+    _tabBar->removeTab(index);
+
+    if ( navigationDisplayMode() == ShowNavigationAsNeeded )
+        dynamicTabBarVisibility();
+}
+
+void TabbedViewContainer::setTabActivity(int index , bool activity)
+{
+    const QPalette& palette = _tabBar->palette();
+    KColorScheme colorScheme(palette.currentColorGroup());
+    const QColor colorSchemeActive = colorScheme.foreground(KColorScheme::ActiveText).color();    
+    
+    const QColor normalColor = palette.text().color();
+    const QColor activityColor = KColorUtils::mix(normalColor,colorSchemeActive); 
+    
+    QColor color = activity ? activityColor : QColor();
+
+    if ( color != _tabBar->tabTextColor(index) )
+        _tabBar->setTabTextColor(index,color);
+}
+
+void TabbedViewContainer::updateActivity(ViewProperties* item)
+{
+    QListIterator<QWidget*> iter(widgetsForItem(item));
+    while ( iter.hasNext() )
+    {
+        const int index = _stackWidget->indexOf(iter.next());
+
+        if ( index != _stackWidget->currentIndex() )
+        {
+            setTabActivity(index,true);
+        } 
+    }
+}
+
+void TabbedViewContainer::updateTitle(ViewProperties* item)
+{
+    QListIterator<QWidget*> iter(widgetsForItem(item));
+    while ( iter.hasNext() )
+    {
+        const int index = _stackWidget->indexOf( iter.next() );
+        QString tabText = item->title();
+
+        _tabBar->setTabText( index , tabText );
+        _tabBar->setTabToolTip( index , tabText );
+    }
+}
+void TabbedViewContainer::updateIcon(ViewProperties* item)
+{
+    QListIterator<QWidget*> iter(widgetsForItem(item));
+    while ( iter.hasNext() )
+    {
+        const int index = _stackWidget->indexOf( iter.next() );
+        _tabBar->setTabIcon( index , item->icon() );
+    }
+}
+
+StackedViewContainer::StackedViewContainer(QObject* parent) 
+: ViewContainer(NavigationPositionTop,parent)
+{
+    _containerWidget = new QWidget;
+    QVBoxLayout *layout = new QVBoxLayout(_containerWidget);
+
+    _stackWidget = new QStackedWidget(_containerWidget);
+
+    searchBar()->setParent(_containerWidget);
+    layout->addWidget(searchBar());
+    layout->addWidget(_stackWidget);
+    layout->setContentsMargins(0, 0, 0, 0);
+}
+StackedViewContainer::~StackedViewContainer()
+{
+    if (!_containerWidget.isNull())
+        _containerWidget->deleteLater();
+}
+QWidget* StackedViewContainer::containerWidget() const
+{
+    return _containerWidget;
+}
+QWidget* StackedViewContainer::activeView() const
+{
+    return _stackWidget->currentWidget();
+}
+void StackedViewContainer::setActiveView(QWidget* view)
+{
+   _stackWidget->setCurrentWidget(view); 
+}
+void StackedViewContainer::addViewWidget( QWidget* view , int )
+{
+    _stackWidget->addWidget(view);
+}
+void StackedViewContainer::removeViewWidget( QWidget* view )
+{
+    if (!_stackWidget)
+        return;
+    const int index = _stackWidget->indexOf(view);
+
+    Q_ASSERT( index != -1);
+    Q_UNUSED(index);
+
+    _stackWidget->removeWidget(view);
+}
+
+#include "ViewContainer.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewContainer.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,483 @@
+/*
+    This file is part of the Konsole Terminal.
+    
+    Copyright 2006-2008 Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef VIEWCONTAINER_H
+#define VIEWCONTAINER_H
+
+// Qt
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtCore/QHash>
+#include <QtCore/QList>
+#include <QtGui/QBoxLayout>
+
+// KDE
+#include <KTabBar>
+
+class QStackedWidget;
+class QWidget;
+class QLabel;
+
+// TabbedViewContainer
+    // Qt
+    class QPoint;
+    class QToolButton;
+    class QMenu;
+
+    // KDE
+    class KMenu;
+
+// ListViewContainer
+
+namespace Konsole
+{
+    class IncrementalSearchBar;
+    class ViewProperties;
+/**
+ * An interface for container widgets which can hold one or more views.
+ *
+ * The container widget typically displays a list of the views which
+ * it has and provides a means of switching between them.  
+ *
+ * Subclasses should reimplement the addViewWidget() and removeViewWidget() functions
+ * to actually add or remove view widgets from the container widget, as well
+ * as updating any navigation aids.
+ */
+class ViewContainer : public QObject
+{
+Q_OBJECT
+    
+public:
+
+    /**
+     * This enum describes the options for positioning the 
+     * container's navigation widget.
+     */
+    enum NavigationPosition
+    {
+        /** Position the navigation widget above the views. */
+        NavigationPositionTop,
+        /** Position the navigation widget below the views. */
+        NavigationPositionBottom,
+        /** Position the navigation widget to the left of the views. */
+        NavigationPositionLeft,
+        /** Position the navigation widget to the right of the views. */
+        NavigationPositionRight
+    };
+
+    /** 
+     * Constructs a new view container with the specified parent. 
+     * 
+     * @param position The initial position of the navigation widget
+     * @param parent The parent object of the container 
+     */
+    ViewContainer(NavigationPosition position , QObject* parent);
+
+    /** 
+     * Called when the ViewContainer is destroyed.  When reimplementing this in 
+     * subclasses, use object->deleteLater() to delete any widgets or other objects
+     * instead of 'delete object'.
+     */
+    virtual ~ViewContainer();
+
+    /** Returns the widget which contains the view widgets */
+    virtual QWidget* containerWidget() const = 0;
+
+    /** 
+     * This enum describes the options for showing or hiding the
+     * container's navigation widget.
+     */
+    enum NavigationDisplayMode
+    {
+        /** Always show the navigation widget. */
+        AlwaysShowNavigation,
+        /** Always hide the navigation widget. */
+        AlwaysHideNavigation,
+        /** Show the navigation widget only when the container has more than one view. */
+        ShowNavigationAsNeeded
+    };
+    /*
+     * Sets the visibility of the view container's navigation widget.
+     *
+     * The ViewContainer sub-class is responsible for ensuring that this
+     * setting is respected as views are added or removed from the 
+     * container.
+     *
+     * ViewContainer sub-classes should reimplement the 
+     * navigationDisplayModeChanged() method to respond to changes 
+     * of this property.
+     */
+    void setNavigationDisplayMode(NavigationDisplayMode mode);
+    /** 
+     * Returns the current mode for controlling the visibility of the 
+     * the view container's navigation widget. 
+     */
+    NavigationDisplayMode navigationDisplayMode() const;
+    
+    /**
+     * Sets the position of the navigation widget with
+     * respect to the main content area.
+     *
+     * Depending on the ViewContainer subclass, not all
+     * positions from the NavigationPosition enum may be
+     * supported.  A list of supported positions can be 
+     * obtained by calling supportedNavigationPositions()
+     *
+     * ViewContainer sub-classes should re-implement the 
+     * navigationPositionChanged() method to respond
+     * to changes of this property.
+     */
+    void setNavigationPosition(NavigationPosition position);
+
+    /**
+     * Returns the position of the navigation widget with
+     * respect to the main content area.
+     */
+    NavigationPosition navigationPosition() const;
+
+    /**
+     * Returns the list of supported navigation positions.
+     * The supported positions will depend upon the type of the 
+     * navigation widget used by the ViewContainer subclass.
+     *
+     * The base implementation returns one item, NavigationPositionTop 
+     */
+    virtual QList<NavigationPosition> supportedNavigationPositions() const;
+
+    /** Adds a new view to the container widget */
+    void addView(QWidget* view , ViewProperties* navigationItem, int index = -1);
+ 
+    /** Removes a view from the container */
+    void removeView(QWidget* view);
+
+    /** Returns the ViewProperties instance associated with a particular view in the container */
+    ViewProperties* viewProperties(  QWidget* view );   
+    
+    /** Returns a list of the contained views */
+    const QList<QWidget*> views();
+   
+    /** 
+     * Returns the view which currently has the focus or 0 if none
+     * of the child views have the focus.
+     */ 
+    virtual QWidget* activeView() const = 0;
+
+    /**
+     * Changes the focus to the specified view and updates
+     * navigation aids to reflect the change.
+     */
+    virtual void setActiveView(QWidget* widget) = 0;
+
+    /**
+     * @return the search widget for this view
+     */
+    IncrementalSearchBar* searchBar();
+
+    /** Changes the active view to the next view */
+    void activateNextView();
+
+    /** Changes the active view to the previous view */
+    void activatePreviousView();
+
+    /** 
+     * This enum describes the directions 
+     * in which views can be re-arranged within the container
+     * using the moveActiveView() method.
+     */
+    enum MoveDirection
+    {
+        /** Moves the view to the left. */
+        MoveViewLeft,
+        /** Moves the view to the right. */
+        MoveViewRight
+    };
+
+    /** 
+     * Moves the active view within the container and 
+     * updates the order in which the views are shown
+     * in the container's navigation widget.
+     *
+     * The default implementation does nothing.
+     */
+    void moveActiveView( MoveDirection direction );
+
+    /** Enum describing extra UI features which can be 
+     * provided by the container. */
+    enum Feature
+    {
+        /** Provides a button which can be clicked to create new views quickly.
+         * When the button is clicked, a newViewRequest() signal is emitted. */
+        QuickNewView = 1,
+        /** Provides a button which can be clicked to close views quickly. */
+        QuickCloseView = 2
+    };
+    Q_DECLARE_FLAGS(Features,Feature)
+    /** 
+     * Sets which additional features are enabled in this container. 
+     * The default implementation does thing.  Sub-classes should re-implement this
+     * to hide or show the relevant parts of their UI
+     */
+    virtual void setFeatures(Features features);
+    /** Returns a bitwise-OR of enabled extra UI features.  See setFeatures() */
+    Features features() const;
+    /** Returns a bitwise-OR of supported extra UI features.  The default
+     * implementation returns 0 (no extra features) */
+    virtual Features supportedFeatures() const
+    { return 0; }
+    /** Sets the menu to be shown when the new view button is clicked.  
+     * Only valid if the QuickNewView feature is enabled.
+     * The default implementation does nothing. */
+    virtual void setNewViewMenu(QMenu* menu) { Q_UNUSED(menu); }
+
+signals:
+    /** Emitted when the container is deleted */
+    void destroyed(ViewContainer* container);
+
+    /** Emitted when the container has no more children */
+    void empty(ViewContainer* container);
+
+    /** Emitted when the user requests to duplicate a view */
+    void duplicateRequest( ViewProperties* properties );
+
+    /** Emitted when the user requests to close a view */
+    void closeRequest(QWidget* activeView);
+
+    /** Emitted when the user requests to open a new view */
+    void newViewRequest();
+
+    /** 
+     * Emitted when the user requests to move a view from another container
+     * into this container.  If 'success' is set to true by a connected slot
+     * then the original view will be removed.
+     *
+     * @param index Index at which to insert the new view in the container or -1
+     * to append it.  This index should be passed to addView() when the new view
+     * has been created.
+     * @param id The identifier of the view.
+     * @param success The slot handling this signal should set this to true if the 
+     * new view was successfully created.  
+     */
+    void moveViewRequest(int index,int id,bool& success);
+
+    /** Emitted when the active view changes */
+    void activeViewChanged( QWidget* view );
+
+    /** Emitted when a view is added to the container. */
+    void viewAdded(QWidget* view , ViewProperties* properties);
+
+    /** Emitted when a view is removed from the container. */
+    void viewRemoved(QWidget* view);
+
+protected:
+    /** 
+     * Performs the task of adding the view widget
+     * to the container widget.
+     */
+    virtual void addViewWidget(QWidget* view,int index) = 0;
+    /**
+     * Performs the task of removing the view widget
+     * from the container widget.
+     */
+    virtual void removeViewWidget(QWidget* view) = 0;
+   
+    /** 
+     * Called when the navigation display mode changes.
+     * See setNavigationDisplayMode
+     */
+    virtual void navigationDisplayModeChanged(NavigationDisplayMode) {}
+
+    /**
+     * Called when the navigation position changes to re-layout 
+     * the container and place the navigation widget in the 
+     * specified position.
+     */
+    virtual void navigationPositionChanged(NavigationPosition) {}
+
+    /** Returns the widgets which are associated with a particular navigation item */
+    QList<QWidget*> widgetsForItem( ViewProperties* item ) const;
+
+    /** 
+     * Rearranges the order of widgets in the container.
+     *
+     * @param fromIndex Current index of the widget to move
+     * @param toIndex New index for the widget
+     */
+    virtual void moveViewWidget( int fromIndex , int toIndex );
+
+private slots:
+    void viewDestroyed(QObject* view);
+    void searchBarDestroyed();
+
+private:
+    NavigationDisplayMode _navigationDisplayMode;
+    NavigationPosition _navigationPosition;
+    QList<QWidget*> _views;
+    QHash<QWidget*,ViewProperties*> _navigation;
+    Features _features;
+    IncrementalSearchBar* _searchBar;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(ViewContainer::Features)
+
+class TabbedViewContainer;
+
+// internal class,
+// to allow for tweaks to the tab bar required by TabbedViewContainer.
+class ViewContainerTabBar : public KTabBar
+{
+Q_OBJECT
+
+public:
+    ViewContainerTabBar(QWidget* parent,TabbedViewContainer* container);
+
+    // returns a pixmap image of a tab for use with QDrag 
+    QPixmap dragDropPixmap(int tab);
+
+protected:
+    virtual void dragEnterEvent(QDragEnterEvent* event);
+    virtual void dragLeaveEvent(QDragLeaveEvent* event);
+    virtual void dragMoveEvent(QDragMoveEvent* event);
+    virtual void dropEvent(QDropEvent* event);
+
+private:
+    // show the indicator arrow which shows where a dropped tab will
+    // be inserted at 'index'
+    void setDropIndicator(int index, bool drawDisabled = false);
+    // returns the index at which a tab will be inserted if the mouse
+    // in a drag-drop operation is released at 'pos'
+    int dropIndex(const QPoint& pos) const;
+    // returns true if the tab to be dropped in a drag-drop operation
+    // is the same as the tab at the drop location
+    bool proposedDropIsSameTab(const QDropEvent* event) const;
+
+    TabbedViewContainer* _container;
+    QLabel* _dropIndicator;
+    int _dropIndicatorIndex;
+    bool _drawIndicatorDisabled;
+};
+
+// internal
+// this class provides a work-around for a problem in Qt 4.x
+// where the insertItem() method only has protected access - 
+// and the TabbedViewContainer class needs to call it.
+//
+// and presumably for binary compatibility reasons will
+// not be fixed until Qt 5. 
+class TabbedViewContainerLayout : public QVBoxLayout
+{
+public:
+    void insertItemAt( int index , QLayoutItem* item )
+    {
+        insertItem(index,item);
+    }
+};
+
+/** 
+ * An alternative tabbed view container which uses a QTabBar and QStackedWidget
+ * combination for navigation instead of QTabWidget
+ */
+class TabbedViewContainer : public ViewContainer
+{
+    Q_OBJECT
+
+friend class ViewContainerTabBar;
+
+public:
+    /**
+     * Constructs a new tabbed view container.  Supported positions
+     * are NavigationPositionTop and NavigationPositionBottom.
+     */
+    TabbedViewContainer(NavigationPosition position , QObject* parent);
+    virtual ~TabbedViewContainer();
+
+    virtual QWidget* containerWidget() const;
+    virtual QWidget* activeView() const;
+    virtual void setActiveView(QWidget* view);
+    virtual QList<NavigationPosition> supportedNavigationPositions() const;
+    virtual void setFeatures(Features features);
+    virtual Features supportedFeatures() const;
+    virtual void setNewViewMenu(QMenu* menu);
+
+protected:
+    virtual void addViewWidget(QWidget* view , int index);
+    virtual void removeViewWidget(QWidget* view);
+    virtual void navigationDisplayModeChanged(NavigationDisplayMode mode);
+    virtual void navigationPositionChanged(NavigationPosition position);
+    virtual void moveViewWidget( int fromIndex , int toIndex );
+
+private slots:
+    void updateTitle(ViewProperties* item);
+    void updateIcon(ViewProperties* item);
+    void updateActivity(ViewProperties* item);
+    void currentTabChanged(int index);
+    void closeTab(int index);
+    void closeCurrentTab();
+    void wheelScrolled(int delta);
+   
+    void tabDoubleClicked(int index);
+    void openTabContextMenu(int index, const QPoint& point);
+    void tabContextMenuCloseTab();
+    void tabContextMenuRenameTab();
+    void tabContextMenuDetachTab();
+    void startTabDrag(int index);
+
+signals:
+    void detachTab(ViewContainer * self, QWidget * activeView);
+
+private:
+    void dynamicTabBarVisibility();
+    void setTabBarVisible(bool visible);
+    void setTabActivity(int index,bool activity);
+    void renameTab(int index);
+
+    ViewContainerTabBar* _tabBar;
+    QPointer<QStackedWidget> _stackWidget;
+    QPointer<QWidget> _containerWidget;
+    TabbedViewContainerLayout* _layout;
+    QHBoxLayout* _tabBarLayout;
+    QToolButton* _newTabButton;
+    QToolButton* _closeTabButton;
+    int _contextMenuTabIndex;
+    KMenu* _contextPopupMenu;
+
+};
+
+/** A plain view container with no navigation display */
+class StackedViewContainer : public ViewContainer
+{
+public:
+    StackedViewContainer(QObject* parent);
+    virtual ~StackedViewContainer();
+
+    virtual QWidget* containerWidget() const;
+    virtual QWidget* activeView() const;
+    virtual void setActiveView(QWidget* view);
+
+protected:
+    virtual void addViewWidget( QWidget* view , int index);
+    virtual void removeViewWidget( QWidget* view );
+
+private:
+    QPointer<QWidget> _containerWidget;
+    QPointer<QStackedWidget> _stackWidget;
+};
+
+}
+#endif //VIEWCONTAINER_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewManager.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,1092 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ViewManager.h"
+
+// System
+#include <assert.h>
+
+// Qt
+#include <QtCore/QDateTime>
+#include <QtCore/QSignalMapper>
+#include <QtGui/QMenu>
+
+// KDE
+#include <kdebug.h>
+#include <KAcceleratorManager>
+#include <KGlobal>
+#include <KLocale>
+#include <KToggleAction>
+#include <KXMLGUIFactory>
+#include <QStringList>
+#include <KConfigGroup>
+
+// Konsole
+#include "ColorScheme.h"
+#include "ProfileList.h"
+#include "Session.h"
+#include "TerminalDisplay.h"
+#include "SessionController.h"
+#include "SessionManager.h"
+#include "ViewContainer.h"
+#include "ViewSplitter.h"
+#include "konsoleadaptor.h"
+#include "Profile.h"
+
+using namespace Konsole;
+
+ViewManager::ViewManager(QObject* parent , KActionCollection* collection)
+    : QObject(parent)
+    , _viewSplitter(0)
+    , _actionCollection(collection)
+    , _containerSignalMapper(new QSignalMapper(this))
+    , _navigationMethod(TabbedNavigation)
+    , _newViewMenu(0)
+{
+    // create main view area
+    _viewSplitter = new ViewSplitter(0);  
+    KAcceleratorManager::setNoAccel(_viewSplitter);
+
+    // the ViewSplitter class supports both recursive and non-recursive splitting,
+    // in non-recursive mode, all containers are inserted into the same top-level splitter
+    // widget, and all the divider lines between the containers have the same orientation
+    //
+    // the ViewManager class is not currently able to handle a ViewSplitter in recursive-splitting
+    // mode 
+    _viewSplitter->setRecursiveSplitting(false);
+    _viewSplitter->setFocusPolicy(Qt::NoFocus);
+
+    // setup actions which relating to the view
+    setupActions();
+
+    // emit a signal when all of the views held by this view manager are destroyed
+    connect( _viewSplitter , SIGNAL(allContainersEmpty()) , this , SIGNAL(empty()) );
+    connect( _viewSplitter , SIGNAL(empty(ViewSplitter*)) , this , SIGNAL(empty()) );
+
+    // listen for addition or removal of views from associated containers
+    connect( _containerSignalMapper , SIGNAL(mapped(QObject*)) , this , 
+            SLOT(containerViewsChanged(QObject*)) ); 
+
+    // listen for profile changes
+    connect( SessionManager::instance() , SIGNAL(profileChanged(Profile::Ptr)) , this,
+            SLOT(profileChanged(Profile::Ptr)) );
+    connect( SessionManager::instance() , SIGNAL(sessionUpdated(Session*)) , this,
+            SLOT(updateViewsForSession(Session*)) );
+
+    //prepare DBus communication
+    new KonsoleAdaptor(this);
+    QDBusConnection::sessionBus().registerObject(QLatin1String("/Konsole"), this);
+
+}
+
+ViewManager::~ViewManager()
+{
+    delete _newViewMenu;
+}
+QMenu* ViewManager::createNewViewMenu() 
+{
+    if (_newViewMenu)
+        return _newViewMenu;
+
+    _newViewMenu = new QMenu(0);
+    ProfileList* newViewProfiles = new ProfileList(false,_newViewMenu);
+    newViewProfiles->syncWidgetActions(_newViewMenu,true);
+    connect(newViewProfiles,SIGNAL(profileSelected(Profile::Ptr)),this,
+        SIGNAL(newViewRequest(Profile::Ptr)));
+
+    return _newViewMenu;
+}
+QWidget* ViewManager::activeView() const
+{
+    ViewContainer* container = _viewSplitter->activeContainer();
+    if ( container )
+    {
+        return container->activeView();
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+QWidget* ViewManager::widget() const
+{
+    return _viewSplitter;
+}
+
+void ViewManager::setupActions()
+{
+    KActionCollection* collection = _actionCollection;
+
+    KAction* nextViewAction = new KAction( i18n("Next View") , this );
+    KAction* previousViewAction = new KAction( i18n("Previous View") , this );
+    KAction* nextContainerAction = new KAction( i18n("Next View Container") , this);
+  
+    KAction* moveViewLeftAction = new KAction( i18n("Move View Left") , this );
+    KAction* moveViewRightAction = new KAction( i18n("Move View Right") , this );
+
+    // list of actions that should only be enabled when there are multiple view
+    // containers open
+    QList<QAction*> multiViewOnlyActions;
+    multiViewOnlyActions << nextContainerAction;
+
+    if ( collection )
+    {
+        KAction* splitLeftRightAction = new KAction( KIcon("view-split-left-right"),
+                                                      i18nc("@action:inmenu", "Split View Left/Right"),
+                                                      this );
+        splitLeftRightAction->setShortcut( QKeySequence(Qt::CTRL+Qt::Key_ParenLeft) );
+        collection->addAction("split-view-left-right",splitLeftRightAction);
+        connect( splitLeftRightAction , SIGNAL(triggered()) , this , SLOT(splitLeftRight()) );
+
+        KAction* splitTopBottomAction = new KAction( KIcon("view-split-top-bottom") , 
+                                             i18nc("@action:inmenu", "Split View Top/Bottom"),this);
+        splitTopBottomAction->setShortcut( QKeySequence(Qt::CTRL+Qt::Key_ParenRight) );
+        collection->addAction("split-view-top-bottom",splitTopBottomAction);
+        connect( splitTopBottomAction , SIGNAL(triggered()) , this , SLOT(splitTopBottom()));
+
+        KAction* closeActiveAction = new KAction( i18nc("@action:inmenu Close Active View", "Close Active") , this );
+        closeActiveAction->setIcon(KIcon("view-close"));
+        closeActiveAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_S) );
+        closeActiveAction->setEnabled(false);
+        collection->addAction("close-active-view",closeActiveAction);
+        connect( closeActiveAction , SIGNAL(triggered()) , this , SLOT(closeActiveView()) );
+
+        multiViewOnlyActions << closeActiveAction;
+
+        KAction* closeOtherAction = new KAction( i18nc("@action:inmenu Close Other Views", "Close Others") , this );
+        closeOtherAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_O) );
+        closeOtherAction->setEnabled(false);
+        collection->addAction("close-other-views",closeOtherAction);
+        connect( closeOtherAction , SIGNAL(triggered()) , this , SLOT(closeOtherViews()) );
+
+        multiViewOnlyActions << closeOtherAction;
+
+        KAction* detachViewAction = collection->addAction("detach-view");
+        detachViewAction->setIcon(KIcon("tab-detach"));
+        detachViewAction->setText(i18n("D&etach Current Tab"));
+        // Ctrl+Shift+D is not used as a shortcut by default because it is too close
+        // to Ctrl+D - which will terminate the session in many cases
+        detachViewAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_H));
+
+        connect( this , SIGNAL(splitViewToggle(bool)) , this , SLOT(updateDetachViewState()) );
+        connect( detachViewAction , SIGNAL(triggered()) , this , SLOT(detachActiveView()) );
+
+        // Expand & Shrink Active View
+        KAction* expandActiveAction = new KAction( i18nc("@action:inmenu", "Expand View") , this );
+        expandActiveAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_BracketRight) );
+        collection->addAction("expand-active-view",expandActiveAction);
+        connect( expandActiveAction , SIGNAL(triggered()) , this , SLOT(expandActiveView()) );
+
+        multiViewOnlyActions << expandActiveAction;
+
+        KAction* shrinkActiveAction = new KAction( i18nc("@action:inmenu", "Shrink View") , this );
+        shrinkActiveAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_BracketLeft) );
+        collection->addAction("shrink-active-view",shrinkActiveAction);
+        connect( shrinkActiveAction , SIGNAL(triggered()) , this , SLOT(shrinkActiveView()) );
+
+        multiViewOnlyActions << shrinkActiveAction;
+
+        // Next / Previous View , Next Container
+        collection->addAction("next-view",nextViewAction);
+        collection->addAction("previous-view",previousViewAction);
+        collection->addAction("next-container",nextContainerAction);
+        collection->addAction("move-view-left",moveViewLeftAction);
+        collection->addAction("move-view-right",moveViewRightAction);
+
+        // Switch to tab N shortcuts
+        const int SWITCH_TO_TAB_COUNT = 10;
+        QSignalMapper* switchToTabMapper = new QSignalMapper(this);
+        connect(switchToTabMapper,SIGNAL(mapped(int)),this,SLOT(switchToView(int)));
+        for (int i=0;i < SWITCH_TO_TAB_COUNT;i++)
+        {
+            KAction* switchToTabAction = new KAction(i18n("Switch to Tab %1",i+1),this);
+            switchToTabMapper->setMapping(switchToTabAction,i);
+            connect(switchToTabAction,SIGNAL(triggered()),switchToTabMapper,
+                    SLOT(map()));
+            collection->addAction(QString("switch-to-tab-%1").arg(i),switchToTabAction);
+        }
+    }
+
+    QListIterator<QAction*> iter(multiViewOnlyActions);
+    while ( iter.hasNext() )
+    {
+        connect( this , SIGNAL(splitViewToggle(bool)) , iter.next() , SLOT(setEnabled(bool)) );
+    }
+
+    // keyboard shortcut only actions
+    KShortcut nextViewShortcut = nextViewAction->shortcut();
+    nextViewShortcut.setPrimary( QKeySequence(Qt::SHIFT+Qt::Key_Right) );
+    nextViewShortcut.setAlternate( QKeySequence(Qt::CTRL+Qt::Key_PageDown) );
+    nextViewAction->setShortcut(nextViewShortcut); 
+    connect( nextViewAction, SIGNAL(triggered()) , this , SLOT(nextView()) );
+    _viewSplitter->addAction(nextViewAction);
+
+    KShortcut previousViewShortcut = previousViewAction->shortcut();
+    previousViewShortcut.setPrimary( QKeySequence(Qt::SHIFT+Qt::Key_Left) );
+    previousViewShortcut.setAlternate( QKeySequence(Qt::CTRL+Qt::Key_PageUp) );
+    previousViewAction->setShortcut(previousViewShortcut);
+    connect( previousViewAction, SIGNAL(triggered()) , this , SLOT(previousView()) );
+    _viewSplitter->addAction(previousViewAction);
+
+    nextContainerAction->setShortcut( QKeySequence(Qt::SHIFT+Qt::Key_Tab) );
+    connect( nextContainerAction , SIGNAL(triggered()) , this , SLOT(nextContainer()) );
+    _viewSplitter->addAction(nextContainerAction);
+
+    moveViewLeftAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Left) );
+    connect( moveViewLeftAction , SIGNAL(triggered()) , this , SLOT(moveActiveViewLeft()) );
+    _viewSplitter->addAction(moveViewLeftAction);
+    moveViewRightAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Right) );
+    connect( moveViewRightAction , SIGNAL(triggered()) , this , SLOT(moveActiveViewRight()) );
+    _viewSplitter->addAction(moveViewRightAction);
+}
+void ViewManager::switchToView(int index)
+{
+    Q_ASSERT(index >= 0);
+    ViewContainer* container = _viewSplitter->activeContainer();
+    Q_ASSERT( container );
+    QList<QWidget*> containerViews = container->views();
+    if (index >= containerViews.count())
+        return;
+    container->setActiveView(containerViews.at(index));
+}
+void ViewManager::updateDetachViewState()
+{
+    if (!_actionCollection)
+        return;
+
+
+    bool splitView = _viewSplitter->containers().count() >= 2;
+    bool shouldEnable = splitView || _viewSplitter->activeContainer()->views().count() >= 2;
+
+    QAction* detachAction = _actionCollection->action("detach-view");
+
+    if ( detachAction && shouldEnable != detachAction->isEnabled() )
+        detachAction->setEnabled(shouldEnable);
+}
+void ViewManager::moveActiveViewLeft()
+{
+    ViewContainer* container = _viewSplitter->activeContainer();
+    Q_ASSERT( container );
+    container->moveActiveView( ViewContainer::MoveViewLeft );
+}
+void ViewManager::moveActiveViewRight()
+{
+    ViewContainer* container = _viewSplitter->activeContainer();
+    Q_ASSERT( container );
+    container->moveActiveView( ViewContainer::MoveViewRight );
+}
+void ViewManager::nextContainer()
+{
+    _viewSplitter->activateNextContainer();
+}
+
+void ViewManager::nextView()
+{
+    ViewContainer* container = _viewSplitter->activeContainer();
+
+    Q_ASSERT( container );
+
+    container->activateNextView();
+}
+
+void ViewManager::previousView()
+{
+    ViewContainer* container = _viewSplitter->activeContainer();
+
+    Q_ASSERT( container );
+
+    container->activatePreviousView();
+}
+
+void ViewManager::detachActiveView()
+{
+    // find the currently active view and remove it from its container 
+    ViewContainer* container = _viewSplitter->activeContainer();
+
+    detachView(container, container->activeView());
+}
+
+void ViewManager::detachView(ViewContainer* container, QWidget* widgetView)
+{
+    TerminalDisplay * viewToDetach = 
+        dynamic_cast<TerminalDisplay*>(widgetView);
+
+    if (!viewToDetach)
+        return;
+
+    emit viewDetached(_sessionMap[viewToDetach]);
+    
+    _sessionMap.remove(viewToDetach);
+
+    // remove the view from this window
+    container->removeView(viewToDetach);
+    viewToDetach->deleteLater();
+
+    // if the container from which the view was removed is now empty then it can be deleted,
+    // unless it is the only container in the window, in which case it is left empty
+    // so that there is always an active container
+    if ( _viewSplitter->containers().count() > 1 && 
+         container->views().count() == 0 )
+    {
+        removeContainer(container);
+    }
+
+}
+
+void ViewManager::sessionFinished()
+{
+    // if this slot is called after the view manager's main widget
+    // has been destroyed, do nothing
+    if (!_viewSplitter)
+        return;
+
+    Session* session = qobject_cast<Session*>(sender());
+
+    // We're using setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab)
+    // so no need to manually select next tab.
+
+    Q_ASSERT(session);
+
+    // close attached views
+    QList<TerminalDisplay*> children = _viewSplitter->findChildren<TerminalDisplay*>();
+
+    foreach ( TerminalDisplay* view , children )
+    {
+        if ( _sessionMap[view] == session )
+        {
+            _sessionMap.remove(view);
+            view->deleteLater();
+        }
+    }
+
+    // This is needed to remove this controller from factory() in 
+    // order to prevent BUG: 185466 - disappearing menu popup
+    if (_pluggedController)
+        emit unplugController(_pluggedController);
+}
+
+void ViewManager::focusActiveView()
+{
+    // give the active view in a container the focus.  this ensures 
+    // that controller associated with that view is activated and the session-specific
+    // menu items are replaced with the ones for the newly focused view
+
+    // see the viewFocused() method
+
+    ViewContainer* container = _viewSplitter->activeContainer(); 
+    if ( container )
+    {
+        QWidget* activeView = container->activeView();
+        if ( activeView )
+        {
+            activeView->setFocus(Qt::MouseFocusReason);
+        }
+    }
+}
+
+
+void ViewManager::viewActivated( QWidget* view )
+{
+    Q_ASSERT( view != 0 );
+
+    // focus the activated view, this will cause the SessionController
+    // to notify the world that the view has been focused and the appropriate UI
+    // actions will be plugged in.
+    view->setFocus(Qt::OtherFocusReason);
+}
+
+void ViewManager::splitLeftRight()
+{
+    splitView(Qt::Horizontal);
+}
+void ViewManager::splitTopBottom()
+{
+    splitView(Qt::Vertical);
+}
+
+void ViewManager::splitView(Qt::Orientation orientation)
+{
+    // iterate over each session which has a view in the current active
+    // container and create a new view for that session in a new container 
+    QListIterator<QWidget*> existingViewIter(_viewSplitter->activeContainer()->views());
+    
+    ViewContainer* container = 0; 
+
+    while (existingViewIter.hasNext())
+    {
+        Session* session = _sessionMap[(TerminalDisplay*)existingViewIter.next()];
+        TerminalDisplay* display = createTerminalDisplay(session);
+        const Profile::Ptr info = SessionManager::instance()->sessionProfile(session);
+        applyProfile(display, info, false);
+        ViewProperties* properties = createController(session,display);
+
+        _sessionMap[display] = session;
+
+        // create a container using settings from the first 
+        // session in the previous container
+        if ( !container )
+            container = createContainer(info);
+
+        int tabBarMode = info->property<int>(Profile::TabBarMode);
+        if ( tabBarMode == Profile::AlwaysHideTabBar )
+            container->setNavigationDisplayMode(ViewContainer::AlwaysHideNavigation);
+        else if ( tabBarMode == Profile::AlwaysShowTabBar )
+            container->setNavigationDisplayMode(ViewContainer::AlwaysShowNavigation);
+        else if ( tabBarMode == Profile::ShowTabBarAsNeeded )
+            container->setNavigationDisplayMode(ViewContainer::ShowNavigationAsNeeded);
+        container->addView(display,properties);
+        session->addView( display );
+    }
+
+    _viewSplitter->addContainer(container,orientation);
+    emit splitViewToggle(_viewSplitter->containers().count() > 0);
+
+    // focus the new container
+    container->containerWidget()->setFocus();
+
+    // ensure that the active view is focused after the split / unsplit
+    ViewContainer* activeContainer = _viewSplitter->activeContainer();
+    QWidget* activeView = activeContainer ? activeContainer->activeView() : 0;
+
+    if ( activeView )
+        activeView->setFocus(Qt::OtherFocusReason);
+}
+void ViewManager::removeContainer(ViewContainer* container)
+{
+    // remove session map entries for views in this container
+    foreach( QWidget* view , container->views() )
+    {
+        TerminalDisplay* display = qobject_cast<TerminalDisplay*>(view);
+        Q_ASSERT(display);
+        _sessionMap.remove(display);
+    } 
+
+    _viewSplitter->removeContainer(container);
+    container->deleteLater();
+
+    emit splitViewToggle( _viewSplitter->containers().count() > 1 );
+}
+void ViewManager::expandActiveView()
+{
+    _viewSplitter->adjustContainerSize(_viewSplitter->activeContainer(),10);
+}
+void ViewManager::shrinkActiveView()
+{
+    _viewSplitter->adjustContainerSize(_viewSplitter->activeContainer(),-10);
+}
+void ViewManager::closeActiveView()
+{
+    // only do something if there is more than one container active
+    if ( _viewSplitter->containers().count() > 1 )
+    {
+        ViewContainer* container = _viewSplitter->activeContainer();
+
+        removeContainer(container);
+
+        // focus next container so that user can continue typing 
+        // without having to manually focus it themselves
+        nextContainer();
+    }
+}
+void ViewManager::closeOtherViews()
+{
+    ViewContainer* active = _viewSplitter->activeContainer();
+
+    QListIterator<ViewContainer*> iter(_viewSplitter->containers());
+    while ( iter.hasNext() )
+    {
+        ViewContainer* next = iter.next();
+        if ( next != active )
+            removeContainer(next);
+    }
+}
+
+SessionController* ViewManager::createController(Session* session , TerminalDisplay* view)
+{
+    // create a new controller for the session, and ensure that this view manager
+    // is notified when the view gains the focus
+    SessionController* controller = new SessionController(session,view,this);
+    connect( controller , SIGNAL(focused(SessionController*)) , this , SLOT(controllerChanged(SessionController*)) );
+    connect( session , SIGNAL(destroyed()) , controller , SLOT(deleteLater()) );
+    connect( view , SIGNAL(destroyed()) , controller , SLOT(deleteLater()) );
+
+    // if this is the first controller created then set it as the active controller
+    if (!_pluggedController)
+        controllerChanged(controller);
+
+    return controller;
+}
+
+void ViewManager::controllerChanged(SessionController* controller)
+{
+    if ( controller == _pluggedController )
+        return;
+
+    _viewSplitter->setFocusProxy(controller->view());
+
+    _pluggedController = controller;
+    emit activeViewChanged(controller);
+}
+
+SessionController* ViewManager::activeViewController() const
+{
+    return _pluggedController;
+}
+
+IncrementalSearchBar* ViewManager::searchBar() const
+{
+    return _viewSplitter->activeSplitter()->activeContainer()->searchBar();
+}
+
+void ViewManager::createView(Session* session, ViewContainer* container, int index)
+{
+    // notify this view manager when the session finishes so that its view
+    // can be deleted
+    //
+    // TODO - Find a more efficient a way to avoid multiple connections
+    disconnect( session , SIGNAL(finished()) , this , SLOT(sessionFinished()) );
+    connect( session , SIGNAL(finished()) , this , SLOT(sessionFinished()) );
+
+     bool isFirst = _sessionMap.isEmpty();
+     TerminalDisplay* display = createTerminalDisplay(session);
+     applyProfile(display,SessionManager::instance()->sessionProfile(session),isFirst);
+     
+     // set initial size
+     display->setSize(80,40);
+
+     ViewProperties* properties = createController(session,display);
+
+     _sessionMap[display] = session; 
+     container->addView(display,properties,index);
+     session->addView(display);
+
+     // tell the session whether it has a light or dark background
+     const Profile::Ptr profile = SessionManager::instance()->sessionProfile(session);
+     session->setDarkBackground( colorSchemeForProfile(profile)->hasDarkBackground() );
+
+     if ( container == _viewSplitter->activeContainer() ) 
+     {
+         container->setActiveView(display);
+         display->setFocus( Qt::OtherFocusReason );
+     }
+    
+     updateDetachViewState();
+}
+
+void ViewManager::createView(Session* session)
+{
+    // create the default container
+    if (_viewSplitter->containers().count() == 0)
+    {
+        _viewSplitter->addContainer( createContainer(SessionManager::instance()->sessionProfile(session)) , 
+                                     Qt::Vertical );
+        emit splitViewToggle(false);
+    }
+
+       
+    // iterate over the view containers owned by this view manager
+    // and create a new terminal display for the session in each of them, along with
+    // a controller for the session/display pair 
+    QListIterator<ViewContainer*> containerIter(_viewSplitter->containers());
+
+    while ( containerIter.hasNext() )
+    {
+        ViewContainer* container = containerIter.next();
+        createView(session,container,-1);
+    }
+
+}
+
+ViewContainer* ViewManager::createContainer(const Profile::Ptr info)
+{
+    Q_ASSERT( info );
+
+    const int tabPosition = info->property<int>(Profile::TabBarPosition);
+
+    ViewContainer::NavigationPosition position = ( tabPosition == Profile::TabBarTop ) ?
+                                                   ViewContainer::NavigationPositionTop :
+                                                   ViewContainer::NavigationPositionBottom;
+
+    ViewContainer* container = 0;
+
+    switch ( _navigationMethod )
+    {
+        case TabbedNavigation:    
+            {
+                container =
+                    new TabbedViewContainer(position,_viewSplitter);
+
+                connect(container,
+                    SIGNAL(detachTab(ViewContainer*, QWidget*)),
+                    this,
+                    SLOT(detachView(ViewContainer*, QWidget*))
+                    );
+            }
+            break;
+        case NoNavigation:
+        default:
+            container = new StackedViewContainer(_viewSplitter);
+    }
+
+    // connect signals and slots
+    connect( container , SIGNAL(viewAdded(QWidget*,ViewProperties*)) , _containerSignalMapper ,
+           SLOT(map()) );
+    connect( container , SIGNAL(viewRemoved(QWidget*)) , _containerSignalMapper ,
+           SLOT(map()) ); 
+    _containerSignalMapper->setMapping(container,container);
+
+    connect( container, SIGNAL(newViewRequest()), this, SIGNAL(newViewRequest()) );
+    connect( container, SIGNAL(moveViewRequest(int,int,bool&)), 
+    this , SLOT(containerMoveViewRequest(int,int,bool&)) );
+    connect( container , SIGNAL(viewRemoved(QWidget*)) , this , SLOT(viewCloseRequest(QWidget*)) );
+    connect( container , SIGNAL(closeRequest(QWidget*)) , this , SLOT(viewCloseRequest(QWidget*)) );
+    connect( container , SIGNAL(activeViewChanged(QWidget*)) , this , SLOT(viewActivated(QWidget*)));
+    
+    return container;
+}
+void ViewManager::containerMoveViewRequest(int index, int id, bool& moved)
+{
+    ViewContainer* container = qobject_cast<ViewContainer*>(sender());
+    SessionController* controller = qobject_cast<SessionController*>(ViewProperties::propertiesById(id));
+
+    if (!controller)
+        return;
+
+    createView(controller->session(),container,index);
+    controller->session()->refresh();
+    moved = true;
+}
+void ViewManager::setNavigationMethod(NavigationMethod method)
+{
+    _navigationMethod = method;
+
+    KActionCollection* collection = _actionCollection;
+
+    if ( collection )
+    {
+        // FIXME: The following disables certain actions for the KPart that it
+        // doesn't actually have a use for, to avoid polluting the action/shortcut
+        // namespace of an application using the KPart (otherwise, a shortcut may
+        // be in use twice, and the user gets to see an "ambiguous shortcut over-
+        // load" error dialog). However, this approach sucks - it's the inverse of
+        // what it should be. Rather than disabling actions not used by the KPart,
+        // a method should be devised to only enable those that are used, perhaps
+        // by using a separate action collection.
+
+        QAction* action;
+
+        action = collection->action( "next-view" );
+        if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
+
+        action = collection->action( "previous-view" );
+        if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
+
+        action = collection->action( "split-view-left-right" );
+        if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
+
+        action = collection->action( "split-view-top-bottom" );
+        if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
+
+        action = collection->action( "rename-session" );
+        if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
+
+        action = collection->action( "move-view-left" );
+        if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
+
+        action = collection->action( "move-view-right" );
+        if ( action ) action->setEnabled( _navigationMethod != NoNavigation );
+    }
+}
+
+ViewManager::NavigationMethod ViewManager::navigationMethod() const { return _navigationMethod; }
+
+void ViewManager::containerViewsChanged(QObject* container)
+{
+    if (_viewSplitter && container == _viewSplitter->activeContainer() )
+    {
+        emit viewPropertiesChanged( viewProperties() );
+    } 
+}
+
+void ViewManager::viewCloseRequest(QWidget* view)
+{
+    //FIXME Check that this cast is actually legal
+    TerminalDisplay* display = (TerminalDisplay*)view;
+  
+    Q_ASSERT(display);
+
+    // 1. detach view from session
+    // 2. if the session has no views left, close it
+    Session* session = _sessionMap[ display ];
+    _sessionMap.remove(display);
+    if ( session )
+    {
+        display->deleteLater();
+
+        if ( session->views().count() == 0 )
+            session->close();
+    }
+    //we only update the focus if the splitter is still alive
+    if (_viewSplitter) {
+        focusActiveView();
+        updateDetachViewState();
+    }
+    // The below causes the menus  to be messed up
+    // Only happenss when using the tab bar close button
+//    if (_pluggedController)
+//        emit unplugController(_pluggedController);
+}
+
+TerminalDisplay* ViewManager::createTerminalDisplay(Session* session)
+{
+   TerminalDisplay* display = new TerminalDisplay(0);
+
+   //TODO Temporary settings used here
+   display->setBellMode(TerminalDisplay::NotifyBell);
+   display->setTerminalSizeHint(true);
+   display->setTripleClickMode(TerminalDisplay::SelectWholeLine);
+   display->setTerminalSizeStartup(true);
+   display->setScrollBarPosition(TerminalDisplay::ScrollBarRight);
+   display->setRandomSeed(session->sessionId() * 31);
+
+   return display;
+}
+
+const ColorScheme* ViewManager::colorSchemeForProfile(const Profile::Ptr info) const
+{
+    const ColorScheme* colorScheme = ColorSchemeManager::instance()->
+                                            findColorScheme(info->colorScheme());
+    if ( !colorScheme )
+       colorScheme = ColorSchemeManager::instance()->defaultColorScheme(); 
+    Q_ASSERT( colorScheme );
+
+    return colorScheme;
+}
+
+void ViewManager::applyProfile(TerminalDisplay* view , const Profile::Ptr info, 
+                               bool applyContainerSettings) 
+{
+    Q_ASSERT( info );
+    
+    const ColorScheme* colorScheme = colorSchemeForProfile(info);
+
+    // menu bar visibility
+    emit setMenuBarVisibleRequest( info->property<bool>(Profile::ShowMenuBar) );
+
+    emit setSaveGeometryOnExitRequest( info->property<bool>(Profile::SaveGeometryOnExit) );
+
+    // tab bar visibility
+    if (applyContainerSettings)
+    {
+        ViewContainer* container = _viewSplitter->activeContainer();
+        int tabBarMode = info->property<int>(Profile::TabBarMode);
+        int tabBarPosition = info->property<int>(Profile::TabBarPosition);
+        bool showNewCloseButtons = info->property<bool>(Profile::ShowNewAndCloseTabButtons);
+
+        if ( tabBarMode == Profile::AlwaysHideTabBar )
+            container->setNavigationDisplayMode(ViewContainer::AlwaysHideNavigation);
+        else if ( tabBarMode == Profile::AlwaysShowTabBar )
+            container->setNavigationDisplayMode(ViewContainer::AlwaysShowNavigation);
+        else if ( tabBarMode == Profile::ShowTabBarAsNeeded )
+            container->setNavigationDisplayMode(ViewContainer::ShowNavigationAsNeeded);
+
+        ViewContainer::NavigationPosition position = container->navigationPosition();
+
+        if ( tabBarPosition == Profile::TabBarTop )
+            position = ViewContainer::NavigationPositionTop;
+        else if ( tabBarPosition == Profile::TabBarBottom )
+            position = ViewContainer::NavigationPositionBottom; 
+
+        if ( container->supportedNavigationPositions().contains(position) )
+            container->setNavigationPosition(position);
+       
+        if (showNewCloseButtons)
+        {
+            container->setFeatures(container->features() 
+                               | ViewContainer::QuickNewView | ViewContainer::QuickCloseView);
+            container->setNewViewMenu(createNewViewMenu());
+        }
+        else
+            container->setFeatures(container->features() 
+                            & ~ViewContainer::QuickNewView & ~ViewContainer::QuickCloseView);
+    }
+
+    // load colour scheme
+    ColorEntry table[TABLE_COLORS];
+    
+    colorScheme->getColorTable(table , view->randomSeed() );
+    view->setColorTable(table);
+    view->setOpacity(colorScheme->opacity());
+  
+    // load font 
+    view->setAntialias(info->property<bool>(Profile::AntiAliasFonts));
+    view->setBoldIntense(info->property<bool>(Profile::BoldIntense));
+    view->setVTFont(info->font());
+
+    // set scroll-bar position
+    int scrollBarPosition = info->property<int>(Profile::ScrollBarPosition);
+
+    if ( scrollBarPosition == Profile::ScrollBarHidden )
+       view->setScrollBarPosition(TerminalDisplay::NoScrollBar);
+    else if ( scrollBarPosition == Profile::ScrollBarLeft )
+       view->setScrollBarPosition(TerminalDisplay::ScrollBarLeft);
+    else if ( scrollBarPosition == Profile::ScrollBarRight )
+       view->setScrollBarPosition(TerminalDisplay::ScrollBarRight);
+
+    // terminal features
+    bool blinkingCursor = info->property<bool>(Profile::BlinkingCursorEnabled);
+    view->setBlinkingCursor(blinkingCursor);  
+
+    bool blinkingText = info->property<bool>(Profile::BlinkingTextEnabled);
+    view->setBlinkingTextEnabled(blinkingText);
+
+    bool tripleClickMode = info->property<bool>(Profile::TripleClickMode);
+    view->setTripleClickMode(tripleClickMode ? TerminalDisplay::SelectForwardsFromCursor : TerminalDisplay::SelectWholeLine);
+
+    bool bidiEnabled = info->property<bool>(Profile::BidiRenderingEnabled);
+    view->setBidiEnabled(bidiEnabled);
+
+    // cursor shape
+    int cursorShape = info->property<int>(Profile::CursorShape);
+
+    if ( cursorShape == Profile::BlockCursor )
+        view->setKeyboardCursorShape(TerminalDisplay::BlockCursor);  
+    else if ( cursorShape == Profile::IBeamCursor )
+        view->setKeyboardCursorShape(TerminalDisplay::IBeamCursor);
+    else if ( cursorShape == Profile::UnderlineCursor )
+        view->setKeyboardCursorShape(TerminalDisplay::UnderlineCursor);
+
+    // cursor color
+    bool useCustomColor = info->property<bool>(Profile::UseCustomCursorColor);
+    const QColor& cursorColor = info->property<QColor>(Profile::CustomCursorColor);
+        
+    view->setKeyboardCursorColor(!useCustomColor,cursorColor);
+
+    // word characters
+    view->setWordCharacters( info->property<QString>(Profile::WordCharacters) );
+}
+
+void ViewManager::updateViewsForSession(Session* session)
+{
+    QListIterator<TerminalDisplay*> iter(_sessionMap.keys(session));
+    while ( iter.hasNext() )
+    {
+        applyProfile(iter.next(),SessionManager::instance()->sessionProfile(session),false);
+    }
+}
+
+void ViewManager::profileChanged(Profile::Ptr profile)
+{
+    QHashIterator<TerminalDisplay*,Session*> iter(_sessionMap);
+
+    while ( iter.hasNext() )
+    {
+        iter.next();
+
+        // if session uses this profile, update the display
+        if ( iter.key() != 0 && 
+             iter.value() != 0 && 
+             SessionManager::instance()->sessionProfile(iter.value()) == profile ) 
+        {
+            applyProfile(iter.key(),profile,true);
+        }
+    }
+}
+
+QList<ViewProperties*> ViewManager::viewProperties() const
+{
+    QList<ViewProperties*> list;
+
+    ViewContainer* container = _viewSplitter->activeContainer();
+
+    Q_ASSERT( container );
+
+    QListIterator<QWidget*> viewIter(container->views());
+    while ( viewIter.hasNext() )
+    {
+        ViewProperties* properties = container->viewProperties(viewIter.next()); 
+        Q_ASSERT( properties );
+        list << properties; 
+    } 
+
+    return list;
+}
+
+void ViewManager::saveSessions(KConfigGroup& group)
+{
+    // find all unique session restore IDs
+    QList<int> ids;
+    QHash<Session*,int> unique;
+
+    // first: sessions in the active container, preserving the order
+    ViewContainer* container = _viewSplitter->activeContainer();
+    Q_ASSERT(container);
+    TerminalDisplay* activeview = dynamic_cast<TerminalDisplay*>(container->activeView());
+
+    QListIterator<QWidget*> viewIter(container->views());
+    int tab = 1;
+    while (viewIter.hasNext())
+    {
+        TerminalDisplay *view = dynamic_cast<TerminalDisplay*>(viewIter.next());
+        Q_ASSERT(view);
+        Session *session = _sessionMap[view];
+        ids << SessionManager::instance()->getRestoreId(session);
+        if (view == activeview) group.writeEntry("Active", tab);
+        unique.insert(session, 1);
+        tab++;
+    }
+
+    // second: all other sessions, in random order
+    // we don't want to have sessions restored that are not connected
+    foreach(Session* session, _sessionMap)
+        if (!unique.contains(session))
+        {
+            ids << SessionManager::instance()->getRestoreId(session);
+            unique.insert(session, 1);
+        }
+
+    group.writeEntry("Sessions", ids);
+}
+
+void ViewManager::restoreSessions(const KConfigGroup& group)
+{
+    QList<int> ids = group.readEntry("Sessions", QList<int>());
+    int activeTab  = group.readEntry("Active", 0);
+    TerminalDisplay *display = 0;
+
+    int tab = 1;
+    foreach(int id, ids)
+    {
+        Session *session = SessionManager::instance()->idToSession(id);
+        createView(session);
+        if (!session->isRunning())
+            session->run();
+        if (tab++ == activeTab)
+            display = dynamic_cast<TerminalDisplay*>(activeView());
+    }
+
+    if (display)
+    {
+        _viewSplitter->activeContainer()->setActiveView(display);
+        display->setFocus(Qt::OtherFocusReason);
+    }
+
+    if (ids.isEmpty()) // Session file is unusable, start default Profile
+    {
+        Profile::Ptr profile = SessionManager::instance()->defaultProfile();
+        Session* session = SessionManager::instance()->createSession(profile);
+        createView(session);
+        if (!session->isRunning())
+            session->run();
+    }
+}
+
+uint qHash(QPointer<TerminalDisplay> display)
+{
+    return qHash((TerminalDisplay*)display);
+}
+
+int ViewManager::sessionCount()
+{
+    return this->_sessionMap.size();
+}
+
+int ViewManager::currentSession()
+{
+    QHash<TerminalDisplay*,Session*>::iterator i;
+    for (i = this->_sessionMap.begin(); i != this->_sessionMap.end(); ++i)
+        if (i.key()->isVisible())
+            return i.value()->sessionId();
+    return -1;
+}
+
+int ViewManager::newSession()
+{
+    Profile::Ptr profile = SessionManager::instance()->defaultProfile();
+    Session* session = SessionManager::instance()->createSession(profile);
+
+    this->createView(session);
+    session->run();
+
+    return session->sessionId();
+}
+
+int ViewManager::newSession(QString profile, QString directory)
+{
+    QList<Profile::Ptr> profilelist = SessionManager::instance()->loadedProfiles();
+    QList<Profile::Ptr>::iterator i = profilelist.begin();
+
+    Profile::Ptr profileptr = SessionManager::instance()->defaultProfile();
+
+    while (i != profilelist.end() )
+    {
+        Profile::Ptr ptr = *i;
+        if ( ptr->name().compare(profile) == 0)
+            profileptr = ptr;
+        i++;
+    }
+
+    Session* session = SessionManager::instance()->createSession(profileptr);
+    session->setInitialWorkingDirectory(directory);
+
+    this->createView(session);
+    session->run();
+
+    return session->sessionId();
+}
+
+QStringList ViewManager::profileList()
+{
+    QList<Profile::Ptr> profilelist = SessionManager::instance()->loadedProfiles();
+    QList<Profile::Ptr>::iterator i = profilelist.begin();
+    QStringList list;
+    while (i != profilelist.end() )
+    {
+        Profile::Ptr ptr = *i;
+        list.push_back(ptr->name());
+        i++;
+    }
+
+    return list;
+}
+
+void ViewManager::nextSession()
+{
+    this->nextView();
+}
+
+void ViewManager::prevSession()
+{
+    this->previousView();
+}
+
+void ViewManager::moveSessionLeft()
+{
+    this->moveActiveViewLeft();
+}
+
+void ViewManager::moveSessionRight()
+{
+    this->moveActiveViewRight();
+}
+
+#include "ViewManager.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewManager.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,373 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef VIEWMANAGER_H
+#define VIEWMANAGER_H
+
+// Qt
+#include <QtCore/QHash>
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+
+// Konsole
+#include "Profile.h"
+
+class QSignalMapper;
+class QMenu;
+class KActionCollection;
+class KConfigGroup;
+
+namespace Konsole
+{
+
+class ColorScheme;
+class IncrementalSearchBar;
+class Session;
+class TerminalDisplay;
+class Profile;
+
+class SessionController;
+class ViewProperties;
+class ViewContainer;
+class ViewSplitter;
+
+/** 
+ * Manages the terminal display widgets in a Konsole window or part.
+ *
+ * When a view manager is created, it constructs a splitter widget ( accessed via 
+ * widget() ) to hold one or more view containers.  Each view container holds
+ * one or more terminal displays and a navigation widget ( eg. tabs or a list )
+ * to allow the user to navigate between the displays in that container.
+ *
+ * The view manager provides menu actions ( defined in the 'konsoleui.rc' XML file )
+ * to manipulate the views and view containers - for example, actions to split the view
+ * left/right or top/bottom, detach a view from the current window and navigate between
+ * views and containers.  These actions are added to the collection specified in the 
+ * ViewManager's constructor.
+ *
+ * The view manager provides facilities to construct display widgets for a terminal
+ * session and also to construct the SessionController which provides the menus and other
+ * user interface elements specific to each display/session pair.
+ *
+ */
+class KONSOLEPRIVATE_EXPORT ViewManager : public QObject
+{
+Q_OBJECT
+Q_CLASSINFO("D-Bus Interface", "org.kde.konsole.Konsole")
+
+public:
+    /** 
+     * Constructs a new view manager with the specified @p parent.  
+     * View-related actions defined in 'konsoleui.rc' are created
+     * and added to the specified @p collection.    
+     */
+    ViewManager(QObject* parent , KActionCollection* collection);
+    ~ViewManager();
+
+    /**
+     * Creates a new view to display the outout from and deliver input to @p session.
+     * Constructs a new container to hold the views if no container has yet been created.
+     */
+    void createView(Session* session);
+
+    /**
+     * Applies the view-specific settings associated with specified @p profile
+     * to the terminal display @p view.  If @p applyContainerSettings is true then
+     * tab bar settings in the profile will also be applied
+     */
+    void applyProfile(TerminalDisplay* view , const Profile::Ptr profile
+                    , bool applyContainerSettings);
+
+    /** 
+     * Return the main widget for the view manager which
+     * holds all of the views managed by this ViewManager instance.
+     */
+    QWidget* widget() const;
+
+    /**
+     * Returns the view manager's active view.
+     */
+    QWidget* activeView() const;
+
+    /**
+     * Returns the list of view properties for views in the active container.
+     * Each view widget is associated with a ViewProperties instance which
+     * provides access to basic information about the session being
+     * displayed in the view, such as title, current directory and 
+     * associated icon.     
+     */
+    QList<ViewProperties*> viewProperties() const;
+
+    /** 
+     * This enum describes the available types of navigation widget 
+     * which newly created containers can provide to allow navigation
+     * between open sessions.
+     */
+    enum NavigationMethod
+    {
+        /** 
+         * Each container has a row of tabs (one per session) which the user
+         * can click on to navigate between open sessions.
+         */
+        TabbedNavigation,
+        /** The container has no navigation widget. */
+        NoNavigation
+    };
+
+    /** 
+     * Sets the type of widget provided to navigate between open sessions 
+     * in a container.  The changes will only apply to newly created containers.
+     *
+     * The default method is TabbedNavigation.  To disable navigation widgets, call
+     * setNavigationMethod(ViewManager::NoNavigation) before creating any sessions. 
+     */
+    void setNavigationMethod(NavigationMethod method);
+
+    /** 
+     * Returns the type of navigation widget created in new containers. 
+     * See setNavigationMethod() 
+     */
+    NavigationMethod navigationMethod() const;
+
+    /** 
+     * Returns the controller for the active view.  activeViewChanged() is 
+     * emitted when this changes.
+     */
+    SessionController* activeViewController() const;
+
+    /**
+     * Returns the search bar.
+     */
+    IncrementalSearchBar* searchBar() const;
+
+    /**
+     * Session management
+     */
+    void saveSessions(KConfigGroup& group);
+    void restoreSessions(const KConfigGroup& group);
+
+signals:
+    /** Emitted when the last view is removed from the view manager */
+    void empty();
+
+    /** Emitted when a session is detached from a view owned by this ViewManager */
+    void viewDetached(Session* session);
+
+    /** 
+     * Emitted when the active view changes. 
+     * @param controller The controller associated with the active view 
+     */
+    void activeViewChanged(SessionController* controller);
+
+    /** 
+     * Emitted when the current session needs unplugged from factory().
+     * @param controller The controller associated with the active view 
+     */
+    void unplugController(SessionController* controller);
+
+    /**
+     * Emitted when the list of view properties ( as returned by viewProperties() ) changes.
+     * This occurs when views are added to or removed from the active container, or 
+     * if the active container is changed.
+     */
+    void viewPropertiesChanged(const QList<ViewProperties*>& propertiesList);
+
+    /** 
+     * Emitted when the number of views containers changes.  This is used to disable or
+     * enable menu items which can only be used when there are one or multiple containers
+     * visible.
+     *
+     * @param multipleViews True if there are multiple view containers open or false if there is 
+     * just a single view.
+     */
+    void splitViewToggle(bool multipleViews);
+
+    /**
+     * Emitted when menu bar visibility changes because a profile that requires so is
+     * activated.
+     */
+    void setMenuBarVisibleRequest(bool);
+    void setSaveGeometryOnExitRequest(bool);
+
+    /** Requests creation of a new view with the default profile. */
+    void newViewRequest();
+    /** Requests creation of a new view, with the selected profile. */
+    void newViewRequest(Profile::Ptr);
+
+public slots:
+    /** DBus slot that returns the number of sessions in the current view. */
+    int sessionCount();
+
+    /** DBus slot that returns the current (active) session window */
+    int currentSession();
+
+    /** DBus slot that creates a new session in the current view.
+     * @param profile the name of the profile to be used
+     * @param directory the working directory where the session is
+     * started.
+     */
+    int newSession(QString profile, QString directory);
+
+    // DBus slot that returns a string list of defined (known) profiles
+    QStringList profileList();
+
+    /** DBus slot that creates a new session in the current view with the associated
+      * default profile and the default working directory
+      */
+    int newSession();
+
+    /** DBus slot that changes the view port to the next session */
+    void nextSession();
+
+    /** DBus slot that changes the view port to the previous session */
+    void prevSession();
+
+    /** DBus slot that switches the current session (as returned by
+      * currentSession()) with the left (or previous) one in the
+      * navigation tab.
+      */
+    void moveSessionLeft();
+
+    /** DBus slot that Switches the current session (as returned by
+      * currentSession()) with the right (or next) one in the navigation
+      * tab.
+      */
+    void moveSessionRight();
+
+private slots:
+    // called when the "Split View Left/Right" menu item is selected
+    void splitLeftRight();
+    void splitTopBottom();
+    void closeActiveView();
+    void closeOtherViews();
+    void expandActiveView();
+    void shrinkActiveView();
+
+    // called when the "Detach View" menu item is selected
+    void detachActiveView();
+    void updateDetachViewState();
+
+    // called when a session terminates - the view manager will delete any
+    // views associated with the session
+    void sessionFinished();
+    // called when the container requests to close a particular view
+    void viewCloseRequest(QWidget* widget);
+
+    // controller detects when an associated view is given the focus
+    // and emits a signal.  ViewManager listens for that signal
+    // and then plugs the action into the UI
+    //void viewFocused( SessionController* controller );
+
+    // called when the active view in a ViewContainer changes, so
+    // that we can plug the appropriate actions into the UI
+    void viewActivated( QWidget* view );
+
+    // called when "Next View" shortcut is activated
+    void nextView();
+
+    // called when "Previous View" shortcut is activated
+    void previousView();
+
+    // called when "Next View Container" shortcut is activated
+    void nextContainer();
+
+    // called when the views in a container owned by this view manager
+    // changes
+    void containerViewsChanged(QObject* container);
+
+    // called when a profile changes
+    void profileChanged(Profile::Ptr profile);
+
+    void updateViewsForSession(Session* session);
+
+    // moves active view to the left
+    void moveActiveViewLeft();
+    // moves active view to the right
+    void moveActiveViewRight();
+    // switches to the view at visual position 'index' 
+    // in the current container
+    void switchToView(int index);
+
+    // called when a SessionController gains focus
+    void controllerChanged(SessionController* controller);
+
+    // called when a ViewContainer requests a view be 
+    // moved 
+    void containerMoveViewRequest(int index, int id, bool& success);
+
+    void detachView(ViewContainer* container, QWidget* view);
+
+private:
+    void createView(Session* session, ViewContainer* container, int index);
+    const ColorScheme* colorSchemeForProfile(const Profile::Ptr profile) const;
+
+    void setupActions();
+    void focusActiveView();
+    void registerView(TerminalDisplay* view);
+    void unregisterView(TerminalDisplay* view);
+  
+    // takes a view from a view container owned by a different manager and places it in 
+    // newContainer owned by this manager
+    void takeView(ViewManager* otherManager , ViewContainer* otherContainer, ViewContainer* newContainer, TerminalDisplay* view); 
+    void splitView(Qt::Orientation orientation);
+    
+    // creates a new container which can hold terminal displays
+    // 'profile' specifies the profile to use to get initial
+    // settings (eg. navigation position) for the container
+    ViewContainer* createContainer(const Profile::Ptr profile);
+    // removes a container and emits appropriate signals
+    void removeContainer(ViewContainer* container);
+
+    // creates a new terminal display
+    // the 'session' is used so that the terminal display's random seed
+    // can be set to something which depends uniquely on that session
+    TerminalDisplay* createTerminalDisplay(Session* session = 0);
+    
+    // creates a new controller for a session/display pair which provides the menu
+    // actions associated with that view, and exposes basic information
+    // about the session ( such as title and associated icon ) to the display.
+    SessionController* createController(Session* session , TerminalDisplay* display);
+
+    // create menu for 'new tab' button
+    QMenu* createNewViewMenu();
+private:
+    QPointer<ViewSplitter>          _viewSplitter;
+    QPointer<SessionController>     _pluggedController;
+    
+    QHash<TerminalDisplay*,Session*> _sessionMap;
+
+    KActionCollection*                  _actionCollection;
+    QSignalMapper*                      _containerSignalMapper;
+    NavigationMethod                _navigationMethod;
+
+    QMenu* _newViewMenu;
+};
+
+}
+
+#endif
+
+/*
+  Local Variables:
+  mode: c++
+  c-file-style: "stroustrup"
+  indent-tabs-mode: nil
+  tab-width: 4
+  End:
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewProperties.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,101 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "ViewProperties.h"
+
+// Qt
+
+using namespace Konsole;
+
+QHash<int,ViewProperties*> ViewProperties::_viewProperties;
+QString ViewProperties::_mimeType = "application/x-konsole-view-id";
+
+ViewProperties::ViewProperties(QObject* parent)
+: QObject(parent)
+, _id(0)
+//, _flags(0)
+{
+}
+ViewProperties::~ViewProperties()
+{
+    _viewProperties.remove(_id);
+}
+ViewProperties* ViewProperties::propertiesById(int id)
+{
+    return _viewProperties[id];
+}
+KUrl ViewProperties::url() const
+{
+    return KUrl();
+}
+QString ViewProperties::currentDir() const
+{
+    return QString();
+}
+void ViewProperties::fireActivity()
+{
+    emit activity(this);
+}
+
+void ViewProperties::rename()
+{
+}
+
+void ViewProperties::setTitle(const QString& title)
+{
+    if ( title != _title )
+    {
+        _title = title;
+        emit titleChanged(this);
+    }
+}
+void ViewProperties::setIcon(const QIcon& icon)
+{
+    // the icon's cache key is used to determine whether this icon is the same
+    // as the old one.  if so no signal is emitted.
+    
+    if ( icon.cacheKey() != _icon.cacheKey() )
+    {
+        _icon = icon;
+        emit iconChanged(this);
+    }
+}
+void ViewProperties::setIdentifier(int id)
+{
+    if (_viewProperties.contains(_id))
+        _viewProperties.remove(_id);
+
+    _id = id;
+
+    _viewProperties.insert(id,this);
+}
+QString ViewProperties::title() const
+{
+    return _title;
+}
+QIcon ViewProperties::icon() const
+{
+    return _icon;
+}
+int ViewProperties::identifier() const
+{
+    return _id;
+}
+#include "ViewProperties.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewProperties.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,156 @@
+/*
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef VIEWPROPERTIES_H
+#define VIEWPROPERTIES_H
+
+// Qt
+#include <QtGui/QIcon>
+#include <QtCore/QObject>
+#include <QtCore/QHash>
+#include <QtCore/QMimeData>
+
+// KDE
+#include <KUrl>
+
+// Konsole
+#include "konsole_export.h"
+
+namespace Konsole
+{
+
+/** 
+ * Encapsulates user-visible information about the terminal session currently being displayed in a view,
+ * such as the associated title and icon.
+ *
+ * This can be used by navigation widgets in a ViewContainer sub-class to provide a tab, label or other
+ * item for switching between views.
+ */
+class KONSOLEPRIVATE_EXPORT ViewProperties : public QObject 
+{
+Q_OBJECT
+
+public:
+    ViewProperties(QObject* parent); 
+    virtual ~ViewProperties();
+
+    /** Returns the icon associated with a view */
+    QIcon icon() const;
+    /** Returns the title associated with a view */
+    QString title() const;
+
+    /** 
+     * Returns the URL current associated with a view.
+     * The default implementation returns an empty URL. 
+     */
+    virtual KUrl url() const;
+
+    /**
+     * Returns the current directory associated with a view.
+     * This may be the same as url()
+     * The default implementation returns an empty string.
+     */
+    virtual QString currentDir() const;
+
+    /** 
+     * A unique identifier associated with this
+     * ViewProperties instance.
+     */
+    int identifier() const;
+
+    /**
+     * Sub-classes may re-implement this method to display a message to the user 
+     * to allow them to confirm whether to close a view.
+     * The default implementation always returns true
+     */
+    virtual bool confirmClose() const
+    { return true; }
+
+    /** Finds a ViewProperties instance given its numeric identifier. */
+    static ViewProperties* propertiesById(int id);
+
+    /** Name of mime format to use in drag-and-drop operations. */
+    static QString mimeType() 
+    { return _mimeType; }
+   
+    /** Returns a new QMimeData instance which represents the view with the given @p id 
+     * (See identifier()).  The QMimeData instance returned must be deleted by the caller.
+     */
+    static QMimeData* createMimeData(int id)
+    {
+        QMimeData* mimeData = new QMimeData;
+        QByteArray data((char*)&id,sizeof(int));
+        mimeData->setData(mimeType(),data);
+        return mimeData;
+    }
+    /** Decodes a QMimeData instance created with createMimeData() and returns the identifier 
+     * of the associated view.  The associated ViewProperties instance can then be retrieved by
+     * calling propertiesById() 
+     *
+     * The QMimeData instance must support the mime format returned by mimeType()
+     */
+    static int decodeMimeData(const QMimeData* mimeData)
+    {
+        return *(int*)(mimeData->data(ViewProperties::mimeType()).constData());
+    }
+
+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 activity has occurred in this view. */
+    void activity(ViewProperties* item);
+
+public slots:
+    /**
+     * Requests the renaming of this view.
+     * The default implementation does nothing.
+     */
+     virtual void rename();
+
+protected slots:
+    /** Emits the activity() signal. */
+    void fireActivity();
+
+protected:
+    /** 
+     * Subclasses may call this method to change the title.  This causes
+     * a titleChanged() signal to be emitted 
+     */
+    void setTitle(const QString& title);
+    /**
+     * Subclasses may call this method to change the icon.  This causes
+     * an iconChanged() signal to be emitted
+     */
+    void setIcon(const QIcon& icon);
+    /** Subclasses may call this method to change the identifier. */
+    void setIdentifier(int id);
+private:
+    QIcon _icon;
+    QString _title;
+    int _id;
+
+    static QHash<int,ViewProperties*> _viewProperties;
+    static QString _mimeType;
+};
+
+}
+
+#endif //VIEWPROPERTIES_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewSplitter.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,287 @@
+/*
+    This file is part of the Konsole Terminal.
+    
+    Copyright 2006-2008 Robert Knight <robertknight@gmail.com>
+
+    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 "ViewSplitter.h"
+
+// Qt
+#include <QtGui/QKeyEvent>
+
+// KDE
+#include "kdebug.h"
+
+// Konsole
+#include "ViewContainer.h"
+
+using namespace Konsole;
+
+ViewSplitter::ViewSplitter(QWidget* parent)
+    : QSplitter(parent)
+    , _recursiveSplitting(true)
+{
+}
+
+void ViewSplitter::childEmpty(ViewSplitter* splitter)
+{
+    delete splitter;
+
+    if ( count() == 0 )
+        emit empty(this);
+}
+
+void ViewSplitter::adjustContainerSize(ViewContainer* container , int percentage)
+{
+    int containerIndex = indexOf(container->containerWidget());
+
+    Q_ASSERT( containerIndex != -1 );
+
+    QList<int> containerSizes = sizes();
+
+    int oldSize = containerSizes[containerIndex];
+    int newSize = (int)(oldSize * ( 1.0 + percentage/100.0 ));
+
+    int perContainerDelta = (count() == 1 ) ? 0 : ( (newSize-oldSize) / (count()-1) ) * (-1);
+
+    for ( int i = 0 ; i < containerSizes.count() ; i++ )
+    {
+        if ( i == containerIndex )
+            containerSizes[i] = newSize;
+        else
+            containerSizes[i] = containerSizes[i] + perContainerDelta;
+    }
+
+    setSizes(containerSizes);
+}
+
+ViewSplitter* ViewSplitter::activeSplitter()
+{
+    QWidget* widget = focusWidget() ? focusWidget() : this;
+    
+    ViewSplitter* splitter = 0;
+
+    while ( !splitter && widget )
+    {
+        splitter = dynamic_cast<ViewSplitter*>(widget);
+        widget = widget->parentWidget();
+    }
+
+    Q_ASSERT( splitter );
+    return splitter;
+}
+
+void ViewSplitter::registerContainer( ViewContainer* container )
+{
+    _containers << container;
+    connect( container , SIGNAL(destroyed(ViewContainer*)) , this , SLOT( containerDestroyed(ViewContainer*) ) );
+    connect( container , SIGNAL(empty(ViewContainer*)) , this , SLOT( containerEmpty(ViewContainer*) ) );
+}
+
+void ViewSplitter::unregisterContainer( ViewContainer* container )
+{
+    _containers.removeAll(container);
+    disconnect( container , 0 , this , 0 );
+}
+
+void ViewSplitter::updateSizes()
+{
+    int space;
+
+    if ( orientation() == Qt::Horizontal )
+    {
+        space = width() / count();
+    }
+    else
+    {
+        space = height() / count();
+    }
+
+    QList<int> widgetSizes;
+    for (int i=0;i<count();i++)
+        widgetSizes << space;
+
+    setSizes(widgetSizes);
+}
+
+void ViewSplitter::setRecursiveSplitting(bool recursive)
+{
+    _recursiveSplitting = recursive;
+}
+bool ViewSplitter::recursiveSplitting() const
+{
+    return _recursiveSplitting;
+}
+
+void ViewSplitter::removeContainer( ViewContainer* container )
+{
+    Q_ASSERT( containers().contains(container) );
+
+    unregisterContainer(container);
+}
+
+void ViewSplitter::addContainer( ViewContainer* container , 
+                                 Qt::Orientation containerOrientation )
+{
+   ViewSplitter* splitter = activeSplitter();   
+    
+    if ( splitter->count() < 2 || 
+         containerOrientation == splitter->orientation() ||
+         !_recursiveSplitting )
+    {
+        splitter->registerContainer(container); 
+        splitter->addWidget(container->containerWidget());
+
+        if ( splitter->orientation() != containerOrientation )
+            splitter->setOrientation( containerOrientation );
+        
+        splitter->updateSizes();
+    }
+    else
+    {
+        ViewSplitter* newSplitter = new ViewSplitter(this);
+        connect( newSplitter , SIGNAL(empty(ViewSplitter*)) , splitter , SLOT(childEmpty(ViewSplitter*)) );
+
+        ViewContainer* oldContainer = splitter->activeContainer();
+        int oldContainerIndex = splitter->indexOf(oldContainer->containerWidget());
+     
+        splitter->unregisterContainer(oldContainer);   
+      
+        newSplitter->registerContainer(oldContainer);
+        newSplitter->registerContainer(container);
+        
+        newSplitter->addWidget(oldContainer->containerWidget());
+        newSplitter->addWidget(container->containerWidget());
+        newSplitter->setOrientation(containerOrientation); 
+        newSplitter->updateSizes();
+        newSplitter->show();
+
+        splitter->insertWidget(oldContainerIndex,newSplitter);
+    }
+
+}
+
+void ViewSplitter::containerEmpty(ViewContainer* /*object*/)
+{
+    QListIterator<ViewContainer*> containerIter(_containers);
+    
+    int children = 0;
+    while (containerIter.hasNext())
+    {
+        children += containerIter.next()->views().count();
+    }
+
+    if ( children == 0 )
+        emit allContainersEmpty(); 
+}
+
+void ViewSplitter::containerDestroyed(ViewContainer* object)
+{
+    Q_ASSERT( _containers.contains(object) );
+    
+    _containers.removeAll(object);
+
+    if ( count() == 0 )
+    {
+        emit empty(this);
+    }
+}
+
+void ViewSplitter::activateNextContainer()
+{
+    ViewContainer* active = activeContainer();
+
+    int index = _containers.indexOf(active);
+
+    if ( index == -1 )
+        return;
+
+    if ( index == _containers.count() -1 )
+        index = 0;
+    else
+        index++;
+
+    setActiveContainer( _containers.at(index) );
+}
+
+void ViewSplitter::activatePreviousContainer() 
+{
+    ViewContainer* active = activeContainer();
+
+    int index = _containers.indexOf(active);
+
+    if ( index == 0 )
+       index = _containers.count() - 1;
+    else
+       index--;
+
+    setActiveContainer( _containers.at(index) ); 
+}
+
+
+void ViewSplitter::setActiveContainer(ViewContainer* container)
+{
+    QWidget* activeView = container->activeView();
+    
+    if ( activeView )
+        activeView->setFocus( Qt::OtherFocusReason );
+}
+
+ViewContainer* ViewSplitter::activeContainer() const
+{
+   if ( QWidget* focusW = focusWidget() )
+   {
+        ViewContainer* focusContainer = 0;
+        
+        while ( focusW != 0 )
+        {
+            QListIterator<ViewContainer*> containerIter(_containers);
+            while (containerIter.hasNext())
+            {
+                ViewContainer* nextContainer = containerIter.next();
+                             
+                if (nextContainer->containerWidget() == focusW)
+                {
+                    focusContainer = nextContainer;
+                    break;
+                }
+            }
+            focusW = focusW->parentWidget();
+        }
+
+        if ( focusContainer )
+            return focusContainer;
+   }
+    
+   QList<ViewSplitter*> splitters = findChildren<ViewSplitter*>();
+
+   if (splitters.count() > 0)
+   {
+        return splitters.last()->activeContainer();
+   }
+   else
+   {
+       if ( _containers.count() > 0 )
+           return _containers.last();
+       else
+           return 0;
+   }
+}
+
+#include "ViewSplitter.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ViewSplitter.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,188 @@
+/*
+    This file is part of the Konsole Terminal.
+    
+    Copyright 2006-2008 Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef VIEWSPLITTER_H
+#define VIEWSPLITTER_H
+
+#include <QtCore/QList>
+#include <QtGui/QSplitter>
+
+class QFocusEvent;
+
+namespace Konsole
+{
+
+class ViewContainer;
+
+/**
+ * A splitter which holds a number of ViewContainer objects and allows
+ * the user to control the size of each view container by dragging a splitter
+ * bar between them.
+ *
+ * Each splitter can also contain child ViewSplitter widgets, allowing
+ * for a hierarchy of view splitters and containers.
+ *
+ * The addContainer() method is used to split the existing view and 
+ * insert a new view container.
+ * Containers can only be removed from the hierarchy by deleting them.
+ */
+class ViewSplitter : public QSplitter
+{
+Q_OBJECT
+
+public:
+    ViewSplitter(QWidget* parent = 0); 
+
+    /**
+     * Locates the child ViewSplitter widget which currently has the focus
+     * and inserts the container into it.   
+     * 
+     * @param container The container to insert
+     * @param orientation Specifies whether the view should be split
+     *                    horizontally or vertically.  If the orientation
+     *                    is the same as the ViewSplitter into which the
+     *                    container is to be inserted, or if the splitter
+     *                    has fewer than two child widgets then the container
+     *                    will be added to that splitter.  If the orientation
+     *                    is different, then a new child splitter
+     *                    will be created, into which the container will
+     *                    be inserted.   
+     */
+    void addContainer( ViewContainer* container , Qt::Orientation orientation );  
+
+    /** Removes a container from the splitter.  The container is not deleted. */
+    void removeContainer( ViewContainer* container );
+
+    /** Returns the child ViewSplitter widget which currently has the focus */
+    ViewSplitter* activeSplitter() ;
+ 
+    /** 
+     * Returns the container which currently has the focus or 0 if none
+     * of the immediate child containers have the focus.  This does not 
+     * search through child splitters.  activeSplitter() can be used
+     * to search recursively through child splitters for the splitter
+     * which currently has the focus.
+     *
+     * To find the currently active container, use
+     * mySplitter->activeSplitter()->activeContainer() where mySplitter
+     * is the ViewSplitter widget at the top of the hierarchy.
+     */
+    ViewContainer* activeContainer() const; 
+
+    /**
+     * Gives the focus to the active view in the specified container 
+     */
+    void setActiveContainer(ViewContainer* container);
+
+    /**
+     * Returns a list of the containers held by this splitter
+     */
+    QList<ViewContainer*> containers() const {return _containers;}
+   
+    /**
+     * Gives the focus to the active view in the next container
+     */
+    void activateNextContainer();
+
+    /**
+     * Changes the size of the specified @p container by a given @p percentage.
+     * @p percentage may be positive ( in which case the size of the container 
+     * is increased ) or negative ( in which case the size of the container 
+     * is decreased ).  
+     *
+     * The sizes of the remaining containers are increased or decreased
+     * uniformly to maintain the width of the splitter.
+     */
+    void adjustContainerSize(ViewContainer* container , int percentage);
+
+   /**
+    * Gives the focus to the active view in the previous container
+    */
+   void activatePreviousContainer();
+
+   /**
+    * Specifies whether the view may be split recursively.
+    * 
+    * If this is false, all containers will be placed into the same
+    * top-level splitter.  Adding a container with an orientation
+    * which is different to that specified when adding the previous
+    * containers will change the orientation for all dividers 
+    * between containers.
+    *
+    * If this is true, adding a container to the view splitter with
+    * an orientation different to the orientation of the previous
+    * area will result in the previously active container being
+    * replaced with a new splitter containing the active container
+    * and the newly added container.  
+    */
+   void setRecursiveSplitting(bool recursive);
+
+   /** 
+    * Returns whether the view may be split recursively.
+    * See setRecursiveSplitting() 
+    */
+   bool recursiveSplitting() const;
+
+signals:
+    /** Signal emitted when the last child widget is removed from the splitter */
+    void empty(ViewSplitter* splitter);
+
+    /** 
+     * Signal emitted when the containers held by this splitter become empty, this
+     * differs from the empty() signal which is only emitted when all of the containers
+     * are deleted.  This signal is emitted even if there are still container widgets.
+     *
+     * TODO: This does not yet work recursively (ie. when splitters inside splitters have empty containers)  
+     */
+    void allContainersEmpty();
+
+protected:
+    //virtual void focusEvent(QFocusEvent* event);
+
+private:
+    // Adds container to splitter's internal list and
+    // connects signals and slots
+    void registerContainer( ViewContainer* container );
+    // Removes container from splitter's internal list and
+    // removes signals and slots
+    void unregisterContainer( ViewContainer* container );
+
+    void updateSizes();
+
+private slots:
+    // Called to indicate that a child ViewContainer has been deleted
+    void containerDestroyed( ViewContainer* object );
+
+    // Called to indicate that a child ViewContainer is empty
+    void containerEmpty( ViewContainer* object );
+
+    // Called to indicate that a child ViewSplitter is empty
+    // (ie. all child widgets have been deleted)
+    void childEmpty( ViewSplitter* splitter );
+
+private:
+    QList<ViewContainer*> _containers;
+    bool _recursiveSplitting;
+};
+
+}
+#endif //VIEWSPLITTER_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Vt102Emulation.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,1224 @@
+/*
+    This file is part of Konsole, an X terminal.
+    
+    Copyright 2007-2008 by Robert Knight <robert.knight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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 "Vt102Emulation.h"
+
+// XKB
+//#include <config-konsole.h>
+
+// this allows konsole to be compiled without XKB and XTEST extensions
+// even though it might be available on a particular system.
+#if defined(AVOID_XKB)
+    #undef HAVE_XKB
+#endif
+
+#if defined(HAVE_XKB)
+    void scrolllock_set_off();
+    void scrolllock_set_on();
+#endif
+
+// Standard 
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+
+// Qt
+#include <QtCore/QEvent>
+#include <QtGui/QKeyEvent>
+#include <QtCore/QByteRef>
+
+// KDE
+//#include <kdebug.h>
+//#include <klocale.h>
+
+// Konsole
+#include "KeyboardTranslator.h"
+#include "Screen.h"
+
+
+using namespace Konsole;
+
+Vt102Emulation::Vt102Emulation() 
+    : Emulation(),
+     _titleUpdateTimer(new QTimer(this))
+{
+  _titleUpdateTimer->setSingleShot(true);
+  QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle()));
+
+  initTokenizer();
+  reset();
+}
+
+Vt102Emulation::~Vt102Emulation()
+{}
+
+void Vt102Emulation::clearEntireScreen()
+{
+  _currentScreen->clearEntireScreen();
+  bufferedUpdate(); 
+}
+
+void Vt102Emulation::reset()
+{
+  resetTokenizer();
+  resetModes();
+  resetCharset(0);
+  _screen[0]->reset();
+  resetCharset(1);
+  _screen[1]->reset();
+  setCodec(LocaleCodec);
+ 
+  bufferedUpdate();
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                     Processing the incoming byte stream                   */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+/* Incoming Bytes Event pipeline
+
+   This section deals with decoding the incoming character stream.
+   Decoding means here, that the stream is first separated into `tokens'
+   which are then mapped to a `meaning' provided as operations by the
+   `Screen' class or by the emulation class itself.
+
+   The pipeline proceeds as follows:
+
+   - Tokenizing the ESC codes (onReceiveChar)
+   - VT100 code page translation of plain characters (applyCharset)
+   - Interpretation of ESC codes (processToken)
+
+   The escape codes and their meaning are described in the
+   technical reference of this program.
+*/
+
+// Tokens ------------------------------------------------------------------ --
+
+/*
+   Since the tokens are the central notion if this section, we've put them
+   in front. They provide the syntactical elements used to represent the
+   terminals operations as byte sequences.
+
+   They are encodes here into a single machine word, so that we can later
+   switch over them easily. Depending on the token itself, additional
+   argument variables are filled with parameter values.
+
+   The tokens are defined below:
+
+   - CHR        - Printable characters     (32..255 but DEL (=127))
+   - CTL        - Control characters       (0..31 but ESC (= 27), DEL)
+   - ESC        - Escape codes of the form <ESC><CHR but `[]()+*#'>
+   - ESC_DE     - Escape codes of the form <ESC><any of `()+*#%'> C
+   - CSI_PN     - Escape codes of the form <ESC>'['     {Pn} ';' {Pn} C
+   - CSI_PS     - Escape codes of the form <ESC>'['     {Pn} ';' ...  C
+   - CSI_PR     - Escape codes of the form <ESC>'[' '?' {Pn} ';' ...  C
+   - CSI_PE     - Escape codes of the form <ESC>'[' '!' {Pn} ';' ...  C
+   - VT52       - VT52 escape codes
+                  - <ESC><Chr>
+                  - <ESC>'Y'{Pc}{Pc}
+   - XTE_HA     - Xterm window/terminal attribute commands 
+                  of the form <ESC>`]' {Pn} `;' {Text} <BEL>
+                  (Note that these are handled differently to the other formats)
+
+   The last two forms allow list of arguments. Since the elements of
+   the lists are treated individually the same way, they are passed
+   as individual tokens to the interpretation. Further, because the
+   meaning of the parameters are names (althought represented as numbers),
+   they are includes within the token ('N').
+
+*/
+
+#define TY_CONSTRUCT(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
+
+#define TY_CHR(   )     TY_CONSTRUCT(0,0,0)
+#define TY_CTL(A  )     TY_CONSTRUCT(1,A,0)
+#define TY_ESC(A  )     TY_CONSTRUCT(2,A,0)
+#define TY_ESC_CS(A,B)  TY_CONSTRUCT(3,A,B)
+#define TY_ESC_DE(A  )  TY_CONSTRUCT(4,A,0)
+#define TY_CSI_PS(A,N)  TY_CONSTRUCT(5,A,N)
+#define TY_CSI_PN(A  )  TY_CONSTRUCT(6,A,0)
+#define TY_CSI_PR(A,N)  TY_CONSTRUCT(7,A,N)
+
+#define TY_VT52(A)    TY_CONSTRUCT(8,A,0)
+#define TY_CSI_PG(A)  TY_CONSTRUCT(9,A,0)
+#define TY_CSI_PE(A)  TY_CONSTRUCT(10,A,0)
+
+#define MAX_ARGUMENT 4096
+
+// Tokenizer --------------------------------------------------------------- --
+
+/* The tokenizer's state
+
+   The state is represented by the buffer (tokenBuffer, tokenBufferPos),
+   and accompanied by decoded arguments kept in (argv,argc).
+   Note that they are kept internal in the tokenizer.
+*/
+
+void Vt102Emulation::resetTokenizer()
+{
+  tokenBufferPos = 0; 
+  argc = 0; 
+  argv[0] = 0; 
+  argv[1] = 0;
+}
+
+void Vt102Emulation::addDigit(int digit)
+{
+  if (argv[argc] < MAX_ARGUMENT)
+      argv[argc] = 10*argv[argc] + digit;
+}
+
+void Vt102Emulation::addArgument()
+{
+  argc = qMin(argc+1,MAXARGS-1);
+  argv[argc] = 0;
+}
+
+void Vt102Emulation::addToCurrentToken(int cc)
+{
+  tokenBuffer[tokenBufferPos] = cc;
+  tokenBufferPos = qMin(tokenBufferPos+1,MAX_TOKEN_LENGTH-1);
+}
+
+// Character Class flags used while decoding
+
+#define CTL  1  // Control character
+#define CHR  2  // Printable character
+#define CPN  4  // TODO: Document me 
+#define DIG  8  // Digit
+#define SCS 16  // TODO: Document me  
+#define GRP 32  // TODO: Document me
+#define CPS 64  // Character which indicates end of window resize
+                // escape sequence '\e[8;<row>;<col>t'
+
+void Vt102Emulation::initTokenizer()
+{ 
+  int i; 
+  quint8* s;
+  for(i = 0;i < 256; ++i) 
+    charClass[i] = 0;
+  for(i = 0;i < 32; ++i) 
+    charClass[i] |= CTL;
+  for(i = 32;i < 256; ++i) 
+    charClass[i] |= CHR;
+  for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; ++s) 
+    charClass[*s] |= CPN;
+  // resize = \e[8;<row>;<col>t
+  for(s = (quint8*)"t"; *s; ++s) 
+    charClass[*s] |= CPS;
+  for(s = (quint8*)"0123456789"; *s; ++s) 
+    charClass[*s] |= DIG;
+  for(s = (quint8*)"()+*%"; *s; ++s) 
+    charClass[*s] |= SCS;
+  for(s = (quint8*)"()+*#[]%"; *s; ++s) 
+    charClass[*s] |= GRP;
+
+  resetTokenizer();
+}
+
+/* Ok, here comes the nasty part of the decoder.
+
+   Instead of keeping an explicit state, we deduce it from the
+   token scanned so far. It is then immediately combined with
+   the current character to form a scanning decision.
+
+   This is done by the following defines.
+
+   - P is the length of the token scanned so far.
+   - L (often P-1) is the position on which contents we base a decision.
+   - C is a character or a group of characters (taken from 'charClass').
+   
+   - 'cc' is the current character
+   - 's' is a pointer to the start of the token buffer
+   - 'p' is the current position within the token buffer 
+
+   Note that they need to applied in proper order.
+*/
+
+#define lec(P,L,C) (p == (P) && s[(L)] == (C))
+#define lun(     ) (p ==  1  && cc >= 32 )
+#define les(P,L,C) (p == (P) && s[L] < 256 && (charClass[s[(L)]] & (C)) == (C))
+#define eec(C)     (p >=  3  && cc == (C))
+#define ees(C)     (p >=  3  && cc < 256 && (charClass[cc] & (C)) == (C))
+#define eps(C)     (p >=  3  && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (charClass[cc] & (C)) == (C))
+#define epp( )     (p >=  3  && s[2] == '?')
+#define epe( )     (p >=  3  && s[2] == '!')
+#define egt( )     (p >=  3  && s[2] == '>')
+#define Xpe        (tokenBufferPos >= 2 && tokenBuffer[1] == ']')
+#define Xte        (Xpe      && cc ==  7 )
+#define ces(C)     (cc < 256 && (charClass[cc] & (C)) == (C) && !Xte)
+
+#define ESC 27
+#define CNTL(c) ((c)-'@')
+
+// process an incoming unicode character
+void Vt102Emulation::receiveChar(int cc)
+{ 
+  if (cc == 127) 
+    return; //VT100: ignore.
+
+  if (ces(CTL))
+  { 
+    // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
+    // This means, they do neither a resetTokenizer() nor a pushToToken(). Some of them, do
+    // of course. Guess this originates from a weakly layered handling of the X-on
+    // X-off protocol, which comes really below this level.
+    if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) 
+        resetTokenizer(); //VT100: CAN or SUB
+    if (cc != ESC)    
+    { 
+        processToken(TY_CTL(cc+'@' ),0,0); 
+        return; 
+    }
+  }
+  // advance the state
+  addToCurrentToken(cc); 
+
+  int* s = tokenBuffer;
+  int  p = tokenBufferPos;
+
+  if (getMode(MODE_Ansi)) 
+  {
+    if (lec(1,0,ESC)) { return; }
+    if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('['); return; }
+    if (les(2,1,GRP)) { return; }
+    if (Xte         ) { processWindowAttributeChange(); resetTokenizer(); return; }
+    if (Xpe         ) { return; }
+    if (lec(3,2,'?')) { return; }
+    if (lec(3,2,'>')) { return; }
+    if (lec(3,2,'!')) { return; }
+    if (lun(       )) { processToken( TY_CHR(), applyCharset(cc), 0);   resetTokenizer(); return; }
+    if (lec(2,0,ESC)) { processToken( TY_ESC(s[1]), 0, 0);              resetTokenizer(); return; }
+    if (les(3,1,SCS)) { processToken( TY_ESC_CS(s[1],s[2]), 0, 0);      resetTokenizer(); return; }
+    if (lec(3,1,'#')) { processToken( TY_ESC_DE(s[2]), 0, 0);           resetTokenizer(); return; }
+    if (eps(    CPN)) { processToken( TY_CSI_PN(cc), argv[0],argv[1]);  resetTokenizer(); return; }
+
+    // resize = \e[8;<row>;<col>t
+    if (eps(CPS)) 
+    { 
+        processToken( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]);   
+        resetTokenizer(); 
+        return; 
+    }
+
+    if (epe(   )) { processToken( TY_CSI_PE(cc), 0, 0); resetTokenizer(); return; }
+    if (ees(DIG)) { addDigit(cc-'0'); return; }
+    if (eec(';')) { addArgument();    return; }
+    for (int i=0;i<=argc;i++)
+    {
+        if (epp())  
+            processToken( TY_CSI_PR(cc,argv[i]), 0, 0);
+        else if (egt())   
+            processToken( TY_CSI_PG(cc), 0, 0); // spec. case for ESC]>0c or ESC]>c
+        else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
+        { 
+            // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m
+            i += 2;
+            processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]);
+            i += 2;
+        }
+        else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5)
+        { 
+            // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m
+            i += 2;
+            processToken( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]);
+        }
+        else
+            processToken( TY_CSI_PS(cc,argv[i]), 0, 0);
+    }
+    resetTokenizer();
+  }
+  else 
+  {
+    // VT52 Mode
+    if (lec(1,0,ESC))                                                      
+        return;
+    if (les(1,0,CHR)) 
+    { 
+        processToken( TY_CHR(), s[0], 0); 
+        resetTokenizer(); 
+        return; 
+    }
+    if (lec(2,1,'Y'))                                                      
+        return;
+    if (lec(3,1,'Y'))                                                      
+        return;
+    if (p < 4) 
+    { 
+        processToken( TY_VT52(s[1] ), 0, 0); 
+        resetTokenizer(); 
+        return; 
+    }
+    processToken( TY_VT52(s[1]), s[2], s[3]); 
+    resetTokenizer(); 
+    return;
+  }
+}
+void Vt102Emulation::processWindowAttributeChange()
+{
+  // Describes the window or terminal session attribute to change
+  // See Session::UserTitleChange for possible values
+  int attributeToChange = 0;
+  int i;
+  for (i = 2; i < tokenBufferPos     && 
+              tokenBuffer[i] >= '0'  && 
+              tokenBuffer[i] <= '9'; i++)
+  {
+    attributeToChange = 10 * attributeToChange + (tokenBuffer[i]-'0');
+  }
+
+  if (tokenBuffer[i] != ';') 
+  { 
+    reportDecodingError(); 
+    return; 
+  }
+  
+  QString newValue;
+  newValue.reserve(tokenBufferPos-i-2);
+  for (int j = 0; j < tokenBufferPos-i-2; j++)
+    newValue[j] = tokenBuffer[i+1+j];
+ 
+  _pendingTitleUpdates[attributeToChange] = newValue;
+  _titleUpdateTimer->start(20);
+}
+
+void Vt102Emulation::updateTitle()
+{
+    QListIterator<int> iter( _pendingTitleUpdates.keys() );
+    while (iter.hasNext()) {
+        int arg = iter.next();
+        emit titleChanged( arg , _pendingTitleUpdates[arg] );    
+    }
+    _pendingTitleUpdates.clear();    
+}
+
+// Interpreting Codes ---------------------------------------------------------
+
+/*
+   Now that the incoming character stream is properly tokenized,
+   meaning is assigned to them. These are either operations of
+   the current _screen, or of the emulation class itself.
+
+   The token to be interpreteted comes in as a machine word
+   possibly accompanied by two parameters.
+
+   Likewise, the operations assigned to, come with up to two
+   arguments. One could consider to make up a proper table
+   from the function below.
+
+   The technical reference manual provides more information
+   about this mapping.
+*/
+
+void Vt102Emulation::processToken(int token, int p, int q)
+{
+  switch (token)
+  {
+
+    case TY_CHR(         ) : _currentScreen->displayCharacter     (p         ); break; //UTF16
+
+    //             127 DEL    : ignored on input
+
+    case TY_CTL('@'      ) : /* NUL: ignored                      */ break;
+    case TY_CTL('A'      ) : /* SOH: ignored                      */ break;
+    case TY_CTL('B'      ) : /* STX: ignored                      */ break;
+    case TY_CTL('C'      ) : /* ETX: ignored                      */ break;
+    case TY_CTL('D'      ) : /* EOT: ignored                      */ break;
+    case TY_CTL('E'      ) :      reportAnswerBack     (          ); break; //VT100
+    case TY_CTL('F'      ) : /* ACK: ignored                      */ break;
+    case TY_CTL('G'      ) : emit stateSet(NOTIFYBELL);
+                                break; //VT100
+    case TY_CTL('H'      ) : _currentScreen->backspace            (          ); break; //VT100
+    case TY_CTL('I'      ) : _currentScreen->tab                  (          ); break; //VT100
+    case TY_CTL('J'      ) : _currentScreen->newLine              (          ); break; //VT100
+    case TY_CTL('K'      ) : _currentScreen->newLine              (          ); break; //VT100
+    case TY_CTL('L'      ) : _currentScreen->newLine              (          ); break; //VT100
+    case TY_CTL('M'      ) : _currentScreen->toStartOfLine        (          ); break; //VT100
+
+    case TY_CTL('N'      ) :      useCharset           (         1); break; //VT100
+    case TY_CTL('O'      ) :      useCharset           (         0); break; //VT100
+
+    case TY_CTL('P'      ) : /* DLE: ignored                      */ break;
+    case TY_CTL('Q'      ) : /* DC1: XON continue                 */ break; //VT100
+    case TY_CTL('R'      ) : /* DC2: ignored                      */ break;
+    case TY_CTL('S'      ) : /* DC3: XOFF halt                    */ break; //VT100
+    case TY_CTL('T'      ) : /* DC4: ignored                      */ break;
+    case TY_CTL('U'      ) : /* NAK: ignored                      */ break;
+    case TY_CTL('V'      ) : /* SYN: ignored                      */ break;
+    case TY_CTL('W'      ) : /* ETB: ignored                      */ break;
+    case TY_CTL('X'      ) : _currentScreen->displayCharacter     (    0x2592); break; //VT100
+    case TY_CTL('Y'      ) : /* EM : ignored                      */ break;
+    case TY_CTL('Z'      ) : _currentScreen->displayCharacter     (    0x2592); break; //VT100
+    case TY_CTL('['      ) : /* ESC: cannot be seen here.         */ break;
+    case TY_CTL('\\'     ) : /* FS : ignored                      */ break;
+    case TY_CTL(']'      ) : /* GS : ignored                      */ break;
+    case TY_CTL('^'      ) : /* RS : ignored                      */ break;
+    case TY_CTL('_'      ) : /* US : ignored                      */ break;
+
+    case TY_ESC('D'      ) : _currentScreen->index                (          ); break; //VT100
+    case TY_ESC('E'      ) : _currentScreen->nextLine             (          ); break; //VT100
+    case TY_ESC('H'      ) : _currentScreen->changeTabStop        (true      ); break; //VT100
+    case TY_ESC('M'      ) : _currentScreen->reverseIndex         (          ); break; //VT100
+    case TY_ESC('Z'      ) :      reportTerminalType   (          ); break;
+    case TY_ESC('c'      ) :      reset                (          ); break;
+
+    case TY_ESC('n'      ) :      useCharset           (         2); break;
+    case TY_ESC('o'      ) :      useCharset           (         3); break;
+    case TY_ESC('7'      ) :      saveCursor           (          ); break;
+    case TY_ESC('8'      ) :      restoreCursor        (          ); break;
+
+    case TY_ESC('='      ) :          setMode      (MODE_AppKeyPad); break;
+    case TY_ESC('>'      ) :        resetMode      (MODE_AppKeyPad); break;
+    case TY_ESC('<'      ) :          setMode      (MODE_Ansi     ); break; //VT100
+
+    case TY_ESC_CS('(', '0') :      setCharset           (0,    '0'); break; //VT100
+    case TY_ESC_CS('(', 'A') :      setCharset           (0,    'A'); break; //VT100
+    case TY_ESC_CS('(', 'B') :      setCharset           (0,    'B'); break; //VT100
+
+    case TY_ESC_CS(')', '0') :      setCharset           (1,    '0'); break; //VT100
+    case TY_ESC_CS(')', 'A') :      setCharset           (1,    'A'); break; //VT100
+    case TY_ESC_CS(')', 'B') :      setCharset           (1,    'B'); break; //VT100
+
+    case TY_ESC_CS('*', '0') :      setCharset           (2,    '0'); break; //VT100
+    case TY_ESC_CS('*', 'A') :      setCharset           (2,    'A'); break; //VT100
+    case TY_ESC_CS('*', 'B') :      setCharset           (2,    'B'); break; //VT100
+
+    case TY_ESC_CS('+', '0') :      setCharset           (3,    '0'); break; //VT100
+    case TY_ESC_CS('+', 'A') :      setCharset           (3,    'A'); break; //VT100
+    case TY_ESC_CS('+', 'B') :      setCharset           (3,    'B'); break; //VT100
+
+    case TY_ESC_CS('%', 'G') :      setCodec             (Utf8Codec   ); break; //LINUX
+    case TY_ESC_CS('%', '@') :      setCodec             (LocaleCodec ); break; //LINUX
+
+    case TY_ESC_DE('3'      ) : /* Double height line, top half    */ 
+                                _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
+                                _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
+                                    break;
+    case TY_ESC_DE('4'      ) : /* Double height line, bottom half */ 
+                                _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
+                                _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
+                                    break;
+    case TY_ESC_DE('5'      ) : /* Single width, single height line*/
+                                _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false);
+                                _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
+                                break;
+    case TY_ESC_DE('6'      ) : /* Double width, single height line*/ 
+                                _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true);    
+                                _currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
+                                break;
+    case TY_ESC_DE('8'      ) : _currentScreen->helpAlign            (          ); break;
+
+// resize = \e[8;<row>;<col>t
+    case TY_CSI_PS('t',   8) : setImageSize( q /* columns */, p /* lines */ );    break;
+
+// change tab text color : \e[28;<color>t  color: 0-16,777,215
+    case TY_CSI_PS('t',   28) : emit changeTabTextColorRequest      ( p        );          break;
+
+    case TY_CSI_PS('K',   0) : _currentScreen->clearToEndOfLine     (          ); break;
+    case TY_CSI_PS('K',   1) : _currentScreen->clearToBeginOfLine   (          ); break;
+    case TY_CSI_PS('K',   2) : _currentScreen->clearEntireLine      (          ); break;
+    case TY_CSI_PS('J',   0) : _currentScreen->clearToEndOfScreen   (          ); break;
+    case TY_CSI_PS('J',   1) : _currentScreen->clearToBeginOfScreen (          ); break;
+    case TY_CSI_PS('J',   2) : _currentScreen->clearEntireScreen    (          ); break;
+    case TY_CSI_PS('J',      3) : clearHistory();                            break;
+    case TY_CSI_PS('g',   0) : _currentScreen->changeTabStop        (false     ); break; //VT100
+    case TY_CSI_PS('g',   3) : _currentScreen->clearTabStops        (          ); break; //VT100
+    case TY_CSI_PS('h',   4) : _currentScreen->    setMode      (MODE_Insert   ); break;
+    case TY_CSI_PS('h',  20) :          setMode      (MODE_NewLine  ); break;
+    case TY_CSI_PS('i',   0) : /* IGNORE: attached printer          */ break; //VT100
+    case TY_CSI_PS('l',   4) : _currentScreen->  resetMode      (MODE_Insert   ); break;
+    case TY_CSI_PS('l',  20) :        resetMode      (MODE_NewLine  ); break;
+    case TY_CSI_PS('s',   0) :      saveCursor           (          ); break;
+    case TY_CSI_PS('u',   0) :      restoreCursor        (          ); break;
+
+    case TY_CSI_PS('m',   0) : _currentScreen->setDefaultRendition  (          ); break;
+    case TY_CSI_PS('m',   1) : _currentScreen->  setRendition     (RE_BOLD     ); break; //VT100
+    case TY_CSI_PS('m',   4) : _currentScreen->  setRendition     (RE_UNDERLINE); break; //VT100
+    case TY_CSI_PS('m',   5) : _currentScreen->  setRendition     (RE_BLINK    ); break; //VT100
+    case TY_CSI_PS('m',   7) : _currentScreen->  setRendition     (RE_REVERSE  ); break;
+    case TY_CSI_PS('m',  10) : /* IGNORED: mapping related          */ break; //LINUX
+    case TY_CSI_PS('m',  11) : /* IGNORED: mapping related          */ break; //LINUX
+    case TY_CSI_PS('m',  12) : /* IGNORED: mapping related          */ break; //LINUX
+    case TY_CSI_PS('m',  22) : _currentScreen->resetRendition     (RE_BOLD     ); break;
+    case TY_CSI_PS('m',  24) : _currentScreen->resetRendition     (RE_UNDERLINE); break;
+    case TY_CSI_PS('m',  25) : _currentScreen->resetRendition     (RE_BLINK    ); break;
+    case TY_CSI_PS('m',  27) : _currentScreen->resetRendition     (RE_REVERSE  ); break;
+
+    case TY_CSI_PS('m',   30) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  0); break;
+    case TY_CSI_PS('m',   31) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  1); break;
+    case TY_CSI_PS('m',   32) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  2); break;
+    case TY_CSI_PS('m',   33) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  3); break;
+    case TY_CSI_PS('m',   34) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  4); break;
+    case TY_CSI_PS('m',   35) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  5); break;
+    case TY_CSI_PS('m',   36) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  6); break;
+    case TY_CSI_PS('m',   37) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  7); break;
+
+    case TY_CSI_PS('m',   38) : _currentScreen->setForeColor         (p,       q); break;
+
+    case TY_CSI_PS('m',   39) : _currentScreen->setForeColor         (COLOR_SPACE_DEFAULT,  0); break;
+
+    case TY_CSI_PS('m',   40) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  0); break;
+    case TY_CSI_PS('m',   41) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  1); break;
+    case TY_CSI_PS('m',   42) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  2); break;
+    case TY_CSI_PS('m',   43) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  3); break;
+    case TY_CSI_PS('m',   44) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  4); break;
+    case TY_CSI_PS('m',   45) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  5); break;
+    case TY_CSI_PS('m',   46) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  6); break;
+    case TY_CSI_PS('m',   47) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  7); break;
+
+    case TY_CSI_PS('m',   48) : _currentScreen->setBackColor         (p,       q); break;
+
+    case TY_CSI_PS('m',   49) : _currentScreen->setBackColor         (COLOR_SPACE_DEFAULT,  1); break;
+
+    case TY_CSI_PS('m',   90) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  8); break;
+    case TY_CSI_PS('m',   91) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  9); break;
+    case TY_CSI_PS('m',   92) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 10); break;
+    case TY_CSI_PS('m',   93) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 11); break;
+    case TY_CSI_PS('m',   94) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 12); break;
+    case TY_CSI_PS('m',   95) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 13); break;
+    case TY_CSI_PS('m',   96) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 14); break;
+    case TY_CSI_PS('m',   97) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 15); break;
+
+    case TY_CSI_PS('m',  100) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  8); break;
+    case TY_CSI_PS('m',  101) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  9); break;
+    case TY_CSI_PS('m',  102) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 10); break;
+    case TY_CSI_PS('m',  103) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 11); break;
+    case TY_CSI_PS('m',  104) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 12); break;
+    case TY_CSI_PS('m',  105) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 13); break;
+    case TY_CSI_PS('m',  106) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 14); break;
+    case TY_CSI_PS('m',  107) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 15); break;
+
+    case TY_CSI_PS('n',   5) :      reportStatus         (          ); break;
+    case TY_CSI_PS('n',   6) :      reportCursorPosition (          ); break;
+    case TY_CSI_PS('q',   0) : /* IGNORED: LEDs off                 */ break; //VT100
+    case TY_CSI_PS('q',   1) : /* IGNORED: LED1 on                  */ break; //VT100
+    case TY_CSI_PS('q',   2) : /* IGNORED: LED2 on                  */ break; //VT100
+    case TY_CSI_PS('q',   3) : /* IGNORED: LED3 on                  */ break; //VT100
+    case TY_CSI_PS('q',   4) : /* IGNORED: LED4 on                  */ break; //VT100
+    case TY_CSI_PS('x',   0) :      reportTerminalParms  (         2); break; //VT100
+    case TY_CSI_PS('x',   1) :      reportTerminalParms  (         3); break; //VT100
+
+    case TY_CSI_PN('@'      ) : _currentScreen->insertChars          (p         ); break;
+    case TY_CSI_PN('A'      ) : _currentScreen->cursorUp             (p         ); break; //VT100
+    case TY_CSI_PN('B'      ) : _currentScreen->cursorDown           (p         ); break; //VT100
+    case TY_CSI_PN('C'      ) : _currentScreen->cursorRight          (p         ); break; //VT100
+    case TY_CSI_PN('D'      ) : _currentScreen->cursorLeft           (p         ); break; //VT100
+    case TY_CSI_PN('G'      ) : _currentScreen->setCursorX           (p         ); break; //LINUX
+    case TY_CSI_PN('H'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
+    case TY_CSI_PN('I'      ) : _currentScreen->tab                  (p         ); break;
+    case TY_CSI_PN('L'      ) : _currentScreen->insertLines          (p         ); break;
+    case TY_CSI_PN('M'      ) : _currentScreen->deleteLines          (p         ); break;
+    case TY_CSI_PN('P'      ) : _currentScreen->deleteChars          (p         ); break;
+    case TY_CSI_PN('S'      ) : _currentScreen->scrollUp             (p         ); break;
+    case TY_CSI_PN('T'      ) : _currentScreen->scrollDown           (p         ); break;
+    case TY_CSI_PN('X'      ) : _currentScreen->eraseChars           (p         ); break;
+    case TY_CSI_PN('Z'      ) : _currentScreen->backtab              (p         ); break;
+    case TY_CSI_PN('c'      ) :      reportTerminalType   (          ); break; //VT100
+    case TY_CSI_PN('d'      ) : _currentScreen->setCursorY           (p         ); break; //LINUX
+    case TY_CSI_PN('f'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
+    case TY_CSI_PN('r'      ) :      setMargins           (p,      q); break; //VT100
+    case TY_CSI_PN('y'      ) : /* IGNORED: Confidence test          */ break; //VT100
+
+    case TY_CSI_PR('h',   1) :          setMode      (MODE_AppCuKeys); break; //VT100
+    case TY_CSI_PR('l',   1) :        resetMode      (MODE_AppCuKeys); break; //VT100
+    case TY_CSI_PR('s',   1) :         saveMode      (MODE_AppCuKeys); break; //FIXME
+    case TY_CSI_PR('r',   1) :      restoreMode      (MODE_AppCuKeys); break; //FIXME
+
+    case TY_CSI_PR('l',   2) :        resetMode      (MODE_Ansi     ); break; //VT100
+
+    case TY_CSI_PR('h',   3) :          setMode      (MODE_132Columns);break; //VT100
+    case TY_CSI_PR('l',   3) :        resetMode      (MODE_132Columns);break; //VT100
+
+    case TY_CSI_PR('h',   4) : /* IGNORED: soft scrolling           */ break; //VT100
+    case TY_CSI_PR('l',   4) : /* IGNORED: soft scrolling           */ break; //VT100
+
+    case TY_CSI_PR('h',   5) : _currentScreen->    setMode      (MODE_Screen   ); break; //VT100
+    case TY_CSI_PR('l',   5) : _currentScreen->  resetMode      (MODE_Screen   ); break; //VT100
+
+    case TY_CSI_PR('h',   6) : _currentScreen->    setMode      (MODE_Origin   ); break; //VT100
+    case TY_CSI_PR('l',   6) : _currentScreen->  resetMode      (MODE_Origin   ); break; //VT100
+    case TY_CSI_PR('s',   6) : _currentScreen->   saveMode      (MODE_Origin   ); break; //FIXME
+    case TY_CSI_PR('r',   6) : _currentScreen->restoreMode      (MODE_Origin   ); break; //FIXME
+
+    case TY_CSI_PR('h',   7) : _currentScreen->    setMode      (MODE_Wrap     ); break; //VT100
+    case TY_CSI_PR('l',   7) : _currentScreen->  resetMode      (MODE_Wrap     ); break; //VT100
+    case TY_CSI_PR('s',   7) : _currentScreen->   saveMode      (MODE_Wrap     ); break; //FIXME
+    case TY_CSI_PR('r',   7) : _currentScreen->restoreMode      (MODE_Wrap     ); break; //FIXME
+
+    case TY_CSI_PR('h',   8) : /* IGNORED: autorepeat on            */ break; //VT100
+    case TY_CSI_PR('l',   8) : /* IGNORED: autorepeat off           */ break; //VT100
+    case TY_CSI_PR('s',   8) : /* IGNORED: autorepeat on            */ break; //VT100
+    case TY_CSI_PR('r',   8) : /* IGNORED: autorepeat off           */ break; //VT100
+
+    case TY_CSI_PR('h',   9) : /* IGNORED: interlace                */ break; //VT100
+    case TY_CSI_PR('l',   9) : /* IGNORED: interlace                */ break; //VT100
+    case TY_CSI_PR('s',   9) : /* IGNORED: interlace                */ break; //VT100
+    case TY_CSI_PR('r',   9) : /* IGNORED: interlace                */ break; //VT100
+
+    case TY_CSI_PR('h',  12) : /* IGNORED: Cursor blink             */ break; //att610
+    case TY_CSI_PR('l',  12) : /* IGNORED: Cursor blink             */ break; //att610
+    case TY_CSI_PR('s',  12) : /* IGNORED: Cursor blink             */ break; //att610
+    case TY_CSI_PR('r',  12) : /* IGNORED: Cursor blink             */ break; //att610
+
+    case TY_CSI_PR('h',  25) :          setMode      (MODE_Cursor   ); break; //VT100
+    case TY_CSI_PR('l',  25) :        resetMode      (MODE_Cursor   ); break; //VT100
+    case TY_CSI_PR('s',  25) :         saveMode      (MODE_Cursor   ); break; //VT100
+    case TY_CSI_PR('r',  25) :      restoreMode      (MODE_Cursor   ); break; //VT100
+
+    case TY_CSI_PR('h',  40) :         setMode(MODE_Allow132Columns ); break; // XTERM
+    case TY_CSI_PR('l',  40) :       resetMode(MODE_Allow132Columns ); break; // XTERM
+
+    case TY_CSI_PR('h',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
+    case TY_CSI_PR('l',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
+    case TY_CSI_PR('s',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
+    case TY_CSI_PR('r',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
+
+    case TY_CSI_PR('h',  47) :          setMode      (MODE_AppScreen); break; //VT100
+    case TY_CSI_PR('l',  47) :        resetMode      (MODE_AppScreen); break; //VT100
+    case TY_CSI_PR('s',  47) :         saveMode      (MODE_AppScreen); break; //XTERM
+    case TY_CSI_PR('r',  47) :      restoreMode      (MODE_AppScreen); break; //XTERM
+
+    case TY_CSI_PR('h',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
+    case TY_CSI_PR('l',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
+    case TY_CSI_PR('s',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
+    case TY_CSI_PR('r',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
+
+    // XTerm defines the following modes:
+    // SET_VT200_MOUSE             1000
+    // SET_VT200_HIGHLIGHT_MOUSE   1001
+    // SET_BTN_EVENT_MOUSE         1002
+    // SET_ANY_EVENT_MOUSE         1003
+    //
+    
+    //Note about mouse modes:
+    //There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003
+    //Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse).
+    //TODO:  Implementation of mouse modes 1001 (something called hilight tracking) and 
+    //1003 (a slight variation on dragging the mouse)
+    //
+ 
+    case TY_CSI_PR('h', 1000) :          setMode      (MODE_Mouse1000); break; //XTERM
+    case TY_CSI_PR('l', 1000) :        resetMode      (MODE_Mouse1000); break; //XTERM
+    case TY_CSI_PR('s', 1000) :         saveMode      (MODE_Mouse1000); break; //XTERM
+    case TY_CSI_PR('r', 1000) :      restoreMode      (MODE_Mouse1000); break; //XTERM
+
+    case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
+    case TY_CSI_PR('l', 1001) :        resetMode      (MODE_Mouse1001); break; //XTERM
+    case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
+    case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
+
+    case TY_CSI_PR('h', 1002) :          setMode      (MODE_Mouse1002); break; //XTERM
+    case TY_CSI_PR('l', 1002) :        resetMode      (MODE_Mouse1002); break; //XTERM
+    case TY_CSI_PR('s', 1002) :         saveMode      (MODE_Mouse1002); break; //XTERM
+    case TY_CSI_PR('r', 1002) :      restoreMode      (MODE_Mouse1002); break; //XTERM
+
+    case TY_CSI_PR('h', 1003) :          setMode      (MODE_Mouse1003); break; //XTERM
+    case TY_CSI_PR('l', 1003) :        resetMode      (MODE_Mouse1003); break; //XTERM
+    case TY_CSI_PR('s', 1003) :         saveMode      (MODE_Mouse1003); break; //XTERM
+    case TY_CSI_PR('r', 1003) :      restoreMode      (MODE_Mouse1003); break; //XTERM
+
+    case TY_CSI_PR('h', 1034) : /* IGNORED: 8bitinput activation     */ break; //XTERM
+
+    case TY_CSI_PR('h', 1047) :          setMode      (MODE_AppScreen); break; //XTERM
+    case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break; //XTERM
+    case TY_CSI_PR('s', 1047) :         saveMode      (MODE_AppScreen); break; //XTERM
+    case TY_CSI_PR('r', 1047) :      restoreMode      (MODE_AppScreen); break; //XTERM
+
+    //FIXME: Unitoken: save translations
+    case TY_CSI_PR('h', 1048) :      saveCursor           (          ); break; //XTERM
+    case TY_CSI_PR('l', 1048) :      restoreCursor        (          ); break; //XTERM
+    case TY_CSI_PR('s', 1048) :      saveCursor           (          ); break; //XTERM
+    case TY_CSI_PR('r', 1048) :      restoreCursor        (          ); break; //XTERM
+
+    //FIXME: every once new sequences like this pop up in xterm.
+    //       Here's a guess of what they could mean.
+    case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM
+    case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM
+
+    //FIXME: weird DEC reset sequence
+    case TY_CSI_PE('p'      ) : /* IGNORED: reset         (        ) */ break;
+
+    //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
+    case TY_VT52('A'      ) : _currentScreen->cursorUp             (         1); break; //VT52
+    case TY_VT52('B'      ) : _currentScreen->cursorDown           (         1); break; //VT52
+    case TY_VT52('C'      ) : _currentScreen->cursorRight          (         1); break; //VT52
+    case TY_VT52('D'      ) : _currentScreen->cursorLeft           (         1); break; //VT52
+
+    case TY_VT52('F'      ) :      setAndUseCharset     (0,    '0'); break; //VT52
+    case TY_VT52('G'      ) :      setAndUseCharset     (0,    'B'); break; //VT52
+
+    case TY_VT52('H'      ) : _currentScreen->setCursorYX          (1,1       ); break; //VT52
+    case TY_VT52('I'      ) : _currentScreen->reverseIndex         (          ); break; //VT52
+    case TY_VT52('J'      ) : _currentScreen->clearToEndOfScreen   (          ); break; //VT52
+    case TY_VT52('K'      ) : _currentScreen->clearToEndOfLine     (          ); break; //VT52
+    case TY_VT52('Y'      ) : _currentScreen->setCursorYX          (p-31,q-31 ); break; //VT52
+    case TY_VT52('Z'      ) :      reportTerminalType   (           ); break; //VT52
+    case TY_VT52('<'      ) :          setMode      (MODE_Ansi     ); break; //VT52
+    case TY_VT52('='      ) :          setMode      (MODE_AppKeyPad); break; //VT52
+    case TY_VT52('>'      ) :        resetMode      (MODE_AppKeyPad); break; //VT52
+
+    case TY_CSI_PG('c'      ) :  reportSecondaryAttributes(          ); break; //VT100
+
+    default: 
+        reportDecodingError();    
+        break;
+  };
+}
+
+void Vt102Emulation::clearScreenAndSetColumns(int columnCount)
+{
+    setImageSize(_currentScreen->getLines(),columnCount); 
+    clearEntireScreen();
+    setDefaultMargins(); 
+    _currentScreen->setCursorYX(0,0);
+}
+
+void Vt102Emulation::sendString(const char* s , int length)
+{
+  if ( length >= 0 )
+    emit sendData(s,length);
+  else
+    emit sendData(s,strlen(s));
+}
+
+void Vt102Emulation::reportCursorPosition()
+{ 
+  char tmp[20];
+  sprintf(tmp,"\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1);
+  sendString(tmp);
+}
+
+void Vt102Emulation::reportTerminalType()
+{
+  // Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide))
+  // VT220:  ^[[?63;1;2;3;6;7;8c   (list deps on emul. capabilities)
+  // VT100:  ^[[?1;2c
+  // VT101:  ^[[?1;0c
+  // VT102:  ^[[?6v
+  if (getMode(MODE_Ansi))
+    sendString("\033[?1;2c"); // I'm a VT100
+  else
+    sendString("\033/Z"); // I'm a VT52
+}
+
+void Vt102Emulation::reportSecondaryAttributes()
+{
+  // Seconday device attribute response (Request was: ^[[>0c or ^[[>c)
+  if (getMode(MODE_Ansi))
+    sendString("\033[>0;115;0c"); // Why 115?  ;)
+  else
+    sendString("\033/Z");         // FIXME I don't think VT52 knows about it but kept for
+                                  // konsoles backward compatibility.
+}
+
+void Vt102Emulation::reportTerminalParms(int p)
+// DECREPTPARM
+{ 
+  char tmp[100];
+  sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
+  sendString(tmp);
+}
+
+void Vt102Emulation::reportStatus()
+{
+  sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
+}
+
+void Vt102Emulation::reportAnswerBack()
+{
+  // FIXME - Test this with VTTEST
+  // This is really obsolete VT100 stuff.
+  const char* ANSWER_BACK = "";
+  sendString(ANSWER_BACK);
+}
+
+/*!
+    `cx',`cy' are 1-based.
+    `eventType' indicates the button pressed (0-2)
+                or a general mouse release (3).
+
+    eventType represents the kind of mouse action that occurred:
+        0 = Mouse button press or release
+        1 = Mouse drag
+*/
+
+void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
+{ 
+  if (cx < 1 || cy < 1) 
+    return;
+
+  // normal buttons are passed as 0x20 + button,
+  // mouse wheel (buttons 4,5) as 0x5c + button
+  if (cb >= 4) 
+    cb += 0x3c;
+
+  //Mouse motion handling
+  if ((getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1)
+      cb += 0x20; //add 32 to signify motion event
+
+  char command[20];
+  sprintf(command,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
+  sendString(command);
+}
+
+void Vt102Emulation::sendText( const QString& text )
+{
+  if (!text.isEmpty()) 
+  {
+    QKeyEvent event(QEvent::KeyPress, 
+                    0, 
+                    Qt::NoModifier, 
+                    text);
+    sendKeyEvent(&event); // expose as a big fat keypress event
+  }
+}
+void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
+{
+    Qt::KeyboardModifiers modifiers = event->modifiers();
+    KeyboardTranslator::States states = KeyboardTranslator::NoState;
+
+    // get current states
+    if (getMode(MODE_NewLine)  ) states |= KeyboardTranslator::NewLineState;
+    if (getMode(MODE_Ansi)     ) states |= KeyboardTranslator::AnsiState;
+    if (getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState;
+    if (getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState;
+    if (getMode(MODE_AppKeyPad) && (modifiers & Qt::KeypadModifier)) 
+        states |= KeyboardTranslator::ApplicationKeypadState;
+
+    // check flow control state
+    if (modifiers & Qt::ControlModifier)
+    {
+        if (event->key() == Qt::Key_S)
+            emit flowControlKeyPressed(true);
+        else if (event->key() == Qt::Key_Q)
+            emit flowControlKeyPressed(false);
+    }
+
+    // lookup key binding
+    if ( _keyTranslator )
+    {
+    KeyboardTranslator::Entry entry = _keyTranslator->findEntry( 
+                                                event->key() , 
+                                                modifiers,
+                                                states );
+
+        // send result to terminal
+        QByteArray textToSend;
+
+        // special handling for the Alt (aka. Meta) modifier.  pressing
+        // Alt+[Character] results in Esc+[Character] being sent
+        // (unless there is an entry defined for this particular combination
+        //  in the keyboard modifier)
+        bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier;
+        bool wantsAnyModifier = entry.state() & 
+                                entry.stateMask() & KeyboardTranslator::AnyModifierState;
+
+        if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) 
+             && !event->text().isEmpty() )
+        {
+            textToSend.prepend("\033");
+        }
+
+        if ( entry.command() != KeyboardTranslator::NoCommand )
+        {
+            if (entry.command() & KeyboardTranslator::EraseCommand)
+                textToSend += eraseChar();
+
+            // TODO command handling
+        }
+        else if ( !entry.text().isEmpty() ) 
+        {
+            textToSend += _codec->fromUnicode(entry.text(true,modifiers));
+        }
+        else
+            textToSend += _codec->fromUnicode(event->text());
+
+        sendData( textToSend.constData() , textToSend.length() );
+    }
+    else
+    {
+        // print an error message to the terminal if no key translator has been
+        // set
+        QString translatorError =  i18n("No keyboard translator available.  "
+                                         "The information needed to convert key presses "
+                                         "into characters to send to the terminal " 
+                                         "is missing.");
+        reset();
+        receiveData( translatorError.toAscii().constData() , translatorError.count() );
+    }
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                                VT100 Charsets                             */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+// Character Set Conversion ------------------------------------------------ --
+
+/* 
+   The processing contains a VT100 specific code translation layer.
+   It's still in use and mainly responsible for the line drawing graphics.
+
+   These and some other glyphs are assigned to codes (0x5f-0xfe)
+   normally occupied by the latin letters. Since this codes also
+   appear within control sequences, the extra code conversion
+   does not permute with the tokenizer and is placed behind it
+   in the pipeline. It only applies to tokens, which represent
+   plain characters.
+
+   This conversion it eventually continued in TerminalDisplay.C, since 
+   it might involve VT100 enhanced fonts, which have these
+   particular glyphs allocated in (0x00-0x1f) in their code page.
+*/
+
+#define CHARSET _charset[_currentScreen==_screen[1]]
+
+// Apply current character map.
+
+unsigned short Vt102Emulation::applyCharset(unsigned short c)
+{
+  if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
+  if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
+  return c;
+}
+
+/*
+   "Charset" related part of the emulation state.
+   This configures the VT100 charset filter.
+
+   While most operation work on the current _screen,
+   the following two are different.
+*/
+
+void Vt102Emulation::resetCharset(int scrno)
+{
+  _charset[scrno].cu_cs = 0;
+  strncpy(_charset[scrno].charset,"BBBB",4);
+  _charset[scrno].sa_graphic = false;
+  _charset[scrno].sa_pound = false;
+  _charset[scrno].graphic = false;
+  _charset[scrno].pound = false;
+}
+
+void Vt102Emulation::setCharset(int n, int cs) // on both screens.
+{
+  _charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs);
+  _charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs);
+}
+
+void Vt102Emulation::setAndUseCharset(int n, int cs)
+{
+  CHARSET.charset[n&3] = cs;
+  useCharset(n&3);
+}
+
+void Vt102Emulation::useCharset(int n)
+{
+  CHARSET.cu_cs   = n&3;
+  CHARSET.graphic = (CHARSET.charset[n&3] == '0');
+  CHARSET.pound   = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
+}
+
+void Vt102Emulation::setDefaultMargins()
+{
+    _screen[0]->setDefaultMargins();
+    _screen[1]->setDefaultMargins();
+}
+
+void Vt102Emulation::setMargins(int t, int b)
+{
+  _screen[0]->setMargins(t, b);
+  _screen[1]->setMargins(t, b);
+}
+
+void Vt102Emulation::saveCursor()
+{
+  CHARSET.sa_graphic = CHARSET.graphic;
+  CHARSET.sa_pound   = CHARSET.pound; //This mode is obsolete
+  // we are not clear about these
+  //sa_charset = charsets[cScreen->_charset];
+  //sa_charset_num = cScreen->_charset;
+  _currentScreen->saveCursor();
+}
+
+void Vt102Emulation::restoreCursor()
+{
+  CHARSET.graphic = CHARSET.sa_graphic;
+  CHARSET.pound   = CHARSET.sa_pound; //This mode is obsolete
+  _currentScreen->restoreCursor();
+}
+
+/* ------------------------------------------------------------------------- */
+/*                                                                           */
+/*                                Mode Operations                            */
+/*                                                                           */
+/* ------------------------------------------------------------------------- */
+
+/*
+   Some of the emulations state is either added to the state of the screens.
+
+   This causes some scoping problems, since different emulations choose to
+   located the mode either to the current _screen or to both.
+
+   For strange reasons, the extend of the rendition attributes ranges over
+   all screens and not over the actual _screen.
+
+   We decided on the precise precise extend, somehow.
+*/
+
+// "Mode" related part of the state. These are all booleans.
+
+void Vt102Emulation::resetModes()
+{
+  // MODE_Allow132Columns is not reset here
+  // to match Xterm's behaviour (see Xterm's VTReset() function)
+
+  resetMode(MODE_132Columns); saveMode(MODE_132Columns);
+  resetMode(MODE_Mouse1000);  saveMode(MODE_Mouse1000);
+  resetMode(MODE_Mouse1001);  saveMode(MODE_Mouse1001);
+  resetMode(MODE_Mouse1002);  saveMode(MODE_Mouse1002);
+  resetMode(MODE_Mouse1003);  saveMode(MODE_Mouse1003);
+
+  resetMode(MODE_AppScreen);  saveMode(MODE_AppScreen);
+  resetMode(MODE_AppCuKeys);  saveMode(MODE_AppCuKeys);
+  resetMode(MODE_AppKeyPad);  saveMode(MODE_AppKeyPad);
+  resetMode(MODE_NewLine);
+  setMode(MODE_Ansi);
+}
+
+void Vt102Emulation::setMode(int m)
+{
+  _currentModes.mode[m] = true;
+  switch (m)
+  {
+    case MODE_132Columns:
+        if (getMode(MODE_Allow132Columns))
+            clearScreenAndSetColumns(132);
+        else
+            _currentModes.mode[m] = false;
+        break;
+    case MODE_Mouse1000:
+    case MODE_Mouse1001:
+    case MODE_Mouse1002:
+    case MODE_Mouse1003:
+         emit programUsesMouseChanged(false); 
+    break;
+
+    case MODE_AppScreen : _screen[1]->clearSelection();
+                          setScreen(1);
+    break;
+  }
+  if (m < MODES_SCREEN || m == MODE_NewLine)
+  {
+    _screen[0]->setMode(m);
+    _screen[1]->setMode(m);
+  }
+}
+
+void Vt102Emulation::resetMode(int m)
+{
+  _currentModes.mode[m] = false;
+  switch (m)
+  {
+    case MODE_132Columns:
+        if (getMode(MODE_Allow132Columns))
+            clearScreenAndSetColumns(80);
+        break;
+    case MODE_Mouse1000 : 
+    case MODE_Mouse1001 :
+    case MODE_Mouse1002 :
+    case MODE_Mouse1003 :
+        emit programUsesMouseChanged(true); 
+    break;
+
+    case MODE_AppScreen : 
+        _screen[0]->clearSelection();
+        setScreen(0);
+    break;
+  }
+  if (m < MODES_SCREEN || m == MODE_NewLine)
+  {
+    _screen[0]->resetMode(m);
+    _screen[1]->resetMode(m);
+  }
+}
+
+void Vt102Emulation::saveMode(int m)
+{
+  _savedModes.mode[m] = _currentModes.mode[m];
+}
+
+void Vt102Emulation::restoreMode(int m)
+{
+  if (_savedModes.mode[m]) 
+      setMode(m); 
+  else 
+      resetMode(m);
+}
+
+bool Vt102Emulation::getMode(int m)
+{
+  return _currentModes.mode[m];
+}
+
+char Vt102Emulation::eraseChar() const
+{
+  KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
+                                            Qt::Key_Backspace,
+                                            0,
+                                            0);
+  if ( entry.text().count() > 0 )
+      return entry.text()[0];
+  else
+      return '\b';
+}
+
+// print contents of the scan buffer
+static void hexdump(int* s, int len)
+{ int i;
+  for (i = 0; i < len; i++)
+  {
+    if (s[i] == '\\')
+      printf("\\\\");
+    else
+    if ((s[i]) > 32 && s[i] < 127)
+      printf("%c",s[i]);
+    else
+      printf("\\%04x(hex)",s[i]);
+  }
+}
+
+void Vt102Emulation::reportDecodingError()
+{
+  if (tokenBufferPos == 0 || ( tokenBufferPos == 1 && (tokenBuffer[0] & 0xff) >= 32) ) 
+    return;
+  printf("Undecodable sequence: "); 
+  hexdump(tokenBuffer,tokenBufferPos); 
+  printf("\n");
+}
+
+#include "Vt102Emulation.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/Vt102Emulation.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,191 @@
+/*
+    This file is part of Konsole, an X terminal.
+    
+    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
+    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
+
+    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.
+*/
+
+#ifndef VT102EMULATION_H
+#define VT102EMULATION_H
+
+// Standard Library
+#include <stdio.h>
+
+// Qt 
+#include <QtGui/QKeyEvent>
+#include <QtCore/QHash>
+#include <QtCore/QTimer>
+
+// Konsole
+#include "Emulation.h"
+#include "Screen.h"
+
+#define MODE_AppScreen       (MODES_SCREEN+0)   // Mode #1
+#define MODE_AppCuKeys       (MODES_SCREEN+1)   // Application cursor keys (DECCKM)
+#define MODE_AppKeyPad       (MODES_SCREEN+2)   // 
+#define MODE_Mouse1000       (MODES_SCREEN+3)   // Send mouse X,Y position on press and release
+#define MODE_Mouse1001       (MODES_SCREEN+4)   // Use Hilight mouse tracking
+#define MODE_Mouse1002       (MODES_SCREEN+5)   // Use cell motion mouse tracking
+#define MODE_Mouse1003       (MODES_SCREEN+6)   // Use all motion mouse tracking 
+#define MODE_Ansi            (MODES_SCREEN+7)   // Use US Ascii for character sets G0-G3 (DECANM) 
+#define MODE_132Columns      (MODES_SCREEN+8)   // 80 <-> 132 column mode switch (DECCOLM)
+#define MODE_Allow132Columns (MODES_SCREEN+9)   // Allow DECCOLM mode
+#define MODE_total           (MODES_SCREEN+10)
+
+namespace Konsole
+{
+
+struct CharCodes
+{
+  // coding info
+  char charset[4]; //
+  int  cu_cs;      // actual charset.
+  bool graphic;    // Some VT100 tricks
+  bool pound  ;    // Some VT100 tricks
+  bool sa_graphic; // saved graphic
+  bool sa_pound;   // saved pound
+};
+
+/**
+ * Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
+ * A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/
+ * 
+ * In addition, various additional xterm escape sequences are supported to provide 
+ * features such as mouse input handling.
+ * See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape
+ * sequences. 
+ *
+ */
+class Vt102Emulation : public Emulation
+{ 
+Q_OBJECT
+
+public:
+  /** Constructs a new emulation */
+  Vt102Emulation();
+  ~Vt102Emulation();
+  
+  // reimplemented from Emulation
+  virtual void clearEntireScreen();
+  virtual void reset();
+  virtual char eraseChar() const;
+  
+public slots: 
+  // reimplemented from Emulation 
+  virtual void sendString(const char*,int length = -1);
+  virtual void sendText(const QString& text);
+  virtual void sendKeyEvent(QKeyEvent*);
+  virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
+  
+protected:
+  // reimplemented from Emulation
+  virtual void setMode(int mode);
+  virtual void resetMode(int mode);
+  virtual void receiveChar(int cc);
+  
+private slots:
+  //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
+  //used to buffer multiple title updates
+  void updateTitle();
+
+private:
+  unsigned short applyCharset(unsigned short c);
+  void setCharset(int n, int cs);
+  void useCharset(int n);
+  void setAndUseCharset(int n, int cs);
+  void saveCursor();
+  void restoreCursor();
+  void resetCharset(int scrno);
+
+  void setMargins(int top, int bottom);
+  //set margins for all screens back to their defaults
+  void setDefaultMargins();
+
+  // returns true if 'mode' is set or false otherwise
+  bool getMode    (int mode);
+  // saves the current boolean value of 'mode'
+  void saveMode   (int mode);
+  // restores the boolean value of 'mode' 
+  void restoreMode(int mode);
+  // resets all modes
+  // (except MODE_Allow132Columns)
+  void resetModes();
+
+  void resetTokenizer();
+  #define MAX_TOKEN_LENGTH 80
+  void addToCurrentToken(int cc);
+  int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow?
+  int tokenBufferPos;
+#define MAXARGS 15
+  void addDigit(int dig);
+  void addArgument();
+  int argv[MAXARGS];
+  int argc;
+  void initTokenizer();
+
+  // Set of flags for each of the ASCII characters which indicates
+  // what category they fall into (printable character, control, digit etc.)
+  // for the purposes of decoding terminal output
+  int charClass[256];
+
+  void reportDecodingError(); 
+
+  void processToken(int code, int p, int q);
+  void processWindowAttributeChange();
+
+  void reportTerminalType();
+  void reportSecondaryAttributes();
+  void reportStatus();
+  void reportAnswerBack();
+  void reportCursorPosition();
+  void reportTerminalParms(int p);
+
+  void onScrollLock();
+  void scrollLock(const bool lock);
+
+  // clears the screen and resizes it to the specified
+  // number of columns
+  void clearScreenAndSetColumns(int columnCount);
+
+  CharCodes _charset[2];
+
+  class TerminalState
+  {
+  public:
+    // Initializes all modes to false
+    TerminalState()
+    { memset(&mode,false,MODE_total * sizeof(bool)); }
+
+    bool mode[MODE_total];
+  };
+
+  TerminalState _currentModes;
+  TerminalState _savedModes;
+
+  //hash table and timer for buffering calls to the session instance 
+  //to update the name of the session
+  //or window title.
+  //these calls occur when certain escape sequences are seen in the 
+  //output from the terminal
+  QHash<int,QString> _pendingTitleUpdates;
+  QTimer* _titleUpdateTimer;
+};
+
+}
+
+#endif // VT102EMULATION_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/WarningBox.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,74 @@
+/*
+    Copyright 2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "WarningBox.h"
+
+// Qt
+#include <QLabel>
+#include <QHBoxLayout>
+
+// KDE
+#include <KIcon>
+#include <KColorScheme>
+#include <KDebug>
+
+using namespace Konsole;
+
+WarningBox::WarningBox(QWidget* parent)
+: QFrame(parent)
+{
+    KColorScheme colorScheme(QPalette::Active);
+    QColor warningColor = colorScheme.background(KColorScheme::NeutralBackground).color();
+    QColor warningColorLight = KColorScheme::shade(warningColor,KColorScheme::LightShade,0.1); 
+    QColor borderColor = KColorScheme::shade(warningColor,KColorScheme::DarkShade,0.15);
+    QString gradient =     "qlineargradient(x1:0, y1:0, x2:0, y2:1,"
+                        "stop: 0 %1, stop: 0.6 %1 ,stop: 1.0 %2)";
+    gradient = gradient.arg(warningColor.name()).arg(warningColorLight.name());
+
+    QString styleSheet = "Konsole--WarningBox { background: %1;"
+                         "border: 2px solid %2; }";
+    setStyleSheet(styleSheet.arg(gradient).arg(borderColor.name()));
+
+    _label = new QLabel();
+    _label->setWordWrap(true);
+    _label->setAlignment(Qt::AlignLeft);
+
+    QLabel* icon = new QLabel();
+    icon->setPixmap(KIcon("dialog-warning").pixmap(QSize(48,48)));
+    icon->setAlignment(Qt::AlignCenter);
+
+    QHBoxLayout* layout = new QHBoxLayout(this);
+    layout->addWidget(icon);
+    layout->addWidget(_label);
+    layout->setStretchFactor(icon,2);
+    layout->setStretchFactor(_label,5);
+}
+void WarningBox::setText(const QString& text)
+{
+    _label->setText(text);
+}
+QString WarningBox::text() const
+{
+    return _label->text();
+}
+
+#include "WarningBox.moc"
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/WarningBox.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,56 @@
+/*
+    Copyright 2008 by Robert Knight <robertknight@gmail.com>
+
+    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.
+*/
+
+#ifndef WARNINGBOX_H
+#define WARNINGBOX_H
+
+// Qt
+#include <QFrame>
+
+class QLabel;
+
+namespace Konsole
+{
+
+/** 
+ * A label which displays a warning message, 
+ * using the appropriate icon from the current icon theme
+ * and background color from KColorScheme
+ */
+class WarningBox : public QFrame
+{
+Q_OBJECT
+
+public:
+    WarningBox(QWidget* parent = 0);
+
+    /** Sets the text displayed in the warning label. */
+    void setText(const QString& text);
+    /** Returns the text displayed in the warning label. */
+    QString text() const;
+
+private:
+    QLabel* _label;
+};
+
+}
+
+#endif // WARNINGBOX_H
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/XKB.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,158 @@
+/*
+ Originally comes from NumLockX http://dforce.sh.charactervut.characterz/~seli/en/numlockx
+
+ NumLockX
+ 
+ Copyright 2000-2001 Lubos Lunak        <l.lunak@kde.org>
+ Copyright 2001      Oswald Buddenhagen <ossi@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+****************************************************************************/
+
+#include <config-konsole.h>
+
+#if defined(HAVE_XKB)
+    #include <QtGui/QX11Info>
+
+
+    #include <X11/Xlib.h>
+
+    #define explicit myexplicit
+    #include <X11/XKBlib.h>
+    #undef explicit
+
+    #include <X11/keysym.h>
+
+/* the XKB stuff is based on code created by Oswald Buddenhagen <ossi@kde.org> */
+int xkb_init()
+{
+    int xkb_opcode, xkb_event, xkb_error;
+    int xkb_lmaj = XkbMajorVersion;
+    int xkb_lmin = XkbMinorVersion;
+    return XkbLibraryVersion( &xkb_lmaj, &xkb_lmin )
+        && XkbQueryExtension( QX11Info::display(), &xkb_opcode, &xkb_event, &xkb_error,
+                   &xkb_lmaj, &xkb_lmin );
+}
+    
+#if 0
+// This method doesn't work in all cases. The atom "ScrollLock" doesn't seem
+// to exist on all XFree versions (at least it's not here with my 3.3.6) - DF
+static unsigned int xkb_mask_modifier( XkbDescPtr xkb, const char *name )
+{
+    int i;
+    if( !xkb || !xkb->names )
+    return 0;
+
+    Atom atom = XInternAtom( xkb->dpy, name, true );
+    if (atom == None)
+        return 0;
+
+    for( i = 0;
+         i < XkbNumVirtualMods;
+     i++ )
+    {
+    if (atom == xkb->names->vmods[i] )
+    {
+        unsigned int mask;
+        XkbVirtualModsToReal( xkb, 1 << i, &mask );
+        return mask;
+    }
+    }
+    return 0;
+}
+
+static unsigned int xkb_scrolllock_mask()
+{
+    XkbDescPtr xkb;
+    if(( xkb = XkbGetKeyboard( QX11Info::display(), XkbAllComponentsMask, XkbUseCoreKbd )) != NULL )
+    {
+        unsigned int mask = xkb_mask_modifier( xkb, "ScrollLock" );
+        XkbFreeKeyboard( xkb, 0, True );
+        return mask;
+    }
+    return 0;
+}
+
+#else
+unsigned int xkb_scrolllock_mask()
+{
+    int scrolllock_mask = 0;
+    XModifierKeymap* map = XGetModifierMapping( QX11Info::display() );
+    KeyCode scrolllock_keycode = XKeysymToKeycode( QX11Info::display(), XK_Scroll_Lock );
+    if( scrolllock_keycode == NoSymbol ) {
+        XFreeModifiermap(map);
+        return 0;
+    }
+    for( int i = 0;
+         i < 8;
+         ++i )
+        {
+       if( map->modifiermap[ map->max_keypermod * i ] == scrolllock_keycode )
+               scrolllock_mask += 1 << i;
+       }
+
+    XFreeModifiermap(map);
+    return scrolllock_mask;
+}
+#endif
+
+
+unsigned int scrolllock_mask = 0;
+        
+int xkb_set_on()
+{
+    if (!scrolllock_mask)
+    {
+       if( !xkb_init())
+          return 0;
+       scrolllock_mask = xkb_scrolllock_mask();
+       if( scrolllock_mask == 0 )
+          return 0;
+    }
+    XkbLockModifiers ( QX11Info::display(), XkbUseCoreKbd, scrolllock_mask, scrolllock_mask);
+    return 1;
+}
+    
+int xkb_set_off()
+{
+    if (!scrolllock_mask)
+    {
+       if( !xkb_init())
+          return 0;
+       scrolllock_mask = xkb_scrolllock_mask();
+       if( scrolllock_mask == 0 )
+          return 0;
+    }
+    XkbLockModifiers ( QX11Info::display(), XkbUseCoreKbd, scrolllock_mask, 0);
+    return 1;
+}
+
+void scrolllock_set_on()
+{
+    xkb_set_on();
+}
+
+void scrolllock_set_off()
+{
+    xkb_set_off();
+}
+
+#endif // defined(HAVE_XKB)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ZModemDialog.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,69 @@
+/*  This file is part of the KDE libraries
+ *  Copyright 2002 Waldo Bastian <bastian@kde.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License version 2 as published by the Free Software Foundation;
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ **/
+
+// Own 
+#include "ZModemDialog.h"
+
+// KDE
+#include <KLocale>
+#include <KTextEdit>
+
+using namespace Konsole;
+
+ZModemDialog::ZModemDialog(QWidget *parent, bool modal, const QString &caption)
+ : KDialog( parent )
+{
+  setObjectName( QLatin1String( "zmodem_progress" ) );
+  setModal( modal );
+  setCaption( caption );
+  setButtons( User1|Close );
+  setButtonGuiItem( User1, KGuiItem(i18n("&Stop")) );
+
+  setDefaultButton( Close );
+  setEscapeButton( User1 );
+
+  enableButton(Close, false);
+  _textEdit = new KTextEdit(this);
+  _textEdit->setMinimumSize(400, 100);
+  _textEdit->setReadOnly(true);
+  setMainWidget(_textEdit);
+  connect(this, SIGNAL(user1Clicked()), this, SLOT(slotClose()));
+  connect(this,SIGNAL(closeClicked()),this,SLOT(slotClose()));
+}
+
+void ZModemDialog::addProgressText(const QString &txt)
+{
+  QTextCursor cursor = _textEdit->textCursor();
+
+  cursor.insertBlock();
+  cursor.insertText(txt);
+}
+
+void ZModemDialog::transferDone()
+{
+  enableButton(Close, true);
+  enableButton(User1, false);
+}
+
+void ZModemDialog::slotClose()
+{
+  delayedDestruct();
+  accept();
+}
+
+#include "ZModemDialog.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/ZModemDialog.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,54 @@
+/*  This file is part of the KDE libraries
+ *  Copyright 2002 Waldo Bastian <bastian@kde.org>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License version 2 as published by the Free Software Foundation;
+ *
+ *  This library 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
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ **/
+
+#ifndef ZMODEM_DIALOG_H
+#define ZMODEM_DIALOG_H
+
+#include <kdialog.h>
+
+class KTextEdit;
+
+namespace Konsole
+{
+
+class ZModemDialog : public KDialog
+{
+  Q_OBJECT
+public:
+  ZModemDialog(QWidget *parent, bool modal, const QString &caption);
+  
+  /**
+   * Adds a line of text to the progress window
+   */
+  void addProgressText(const QString &);
+
+  /**
+   * To indicate the process is finished.
+   */
+  void transferDone();
+
+public Q_SLOTS:
+  void slotClose();
+  
+private:
+  KTextEdit* _textEdit;
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/fontembedder.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,119 @@
+/*
+    This file is part of Konsole, an X terminal.
+    Copyright 2005 by Maksim Orlovich <maksim@kde.org>
+
+    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.
+*/
+
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+#include <stdlib.h>
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+
+static quint32 charVal(QChar val)
+{
+    if (val == ' ')
+        return 0;
+    else
+        return 1;
+}
+
+static quint32 readGlyphLine(QTextStream& input)
+{
+    QString line = input.readLine();
+    while (line.length() < 5)
+        line += ' ';
+
+    quint32 val =  charVal(line[0]) |
+            (charVal(line[1]) << 1)  |
+            (charVal(line[2]) << 2)  |
+            (charVal(line[3]) << 3)  |
+            (charVal(line[4]) << 4);
+    return val;
+}
+
+static quint32 readGlyph(QTextStream& input)
+{
+    return readGlyphLine(input) |
+            (readGlyphLine(input) << 5) |
+            (readGlyphLine(input) << 10) |
+            (readGlyphLine(input) << 15) |
+            (readGlyphLine(input) << 20);
+}
+
+int main(int argc, char **argv)
+{
+    if (argc < 1)
+    {
+        qWarning("usage: fontembedder font.src > font.h");
+        exit(1);
+    }
+    QFile inFile(argv[1]);
+    if (!inFile.open(QIODevice::ReadOnly))
+    {
+        qFatal("Can not open %s", argv[1]);
+    }
+
+    QTextStream input(&inFile);
+
+    quint32 glyphStates[128];
+    for (int i = 0; i < 128; ++i)
+        glyphStates[i] = 0; //nothing..
+
+    while (!input.atEnd())
+    {
+        QString line = input.readLine();
+        line = line.trimmed();
+        if (line.isEmpty())
+            continue; //Skip empty lines
+        if (line[0] == '#')
+            continue; //Skip comments
+
+        //Must be a glyph ID.
+        int glyph = line.toInt(0, 16);
+        if ((glyph < 0x2500) || (glyph > 0x257f))
+            qFatal("Invalid glyph number");
+
+        glyph = glyph - 0x2500;
+
+        glyphStates[glyph] = readGlyph(input);
+    }
+
+    //Output.
+    cout<<"// WARNING: Autogenerated by \"fontembedder " << argv[1] << "\".\n";
+    cout<<"// You probably do not want to hand-edit this!\n\n";
+    cout<<"static const quint32 LineChars[] = {\n";
+
+    //Nicely formatted: 8 per line, 16 lines
+    for (int line = 0; line < 128; line += 8)
+    {
+        cout<<"\t";
+        for (int col = line; col < line + 8; ++col)
+        {
+            cout<<"0x"<<hex<<setw(8)<<setfill('0')<<glyphStates[col];
+            if (col != 127)
+                cout<<", ";
+        }
+        cout<<"\n";
+    }
+    cout<<"};\n";
+    return 0;
+}
+
+//kate: indent-width 4; tab-width 4; space-indent on;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kdecore_export.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,45 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2007 David Faure <faure@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KDECORE_EXPORT_H
+#define KDECORE_EXPORT_H
+
+/* needed for KDE_EXPORT and KDE_IMPORT macros */
+//#include <kdemacros.h>
+#define KDE_EXPORT
+#define KDE_IMPORT
+
+#ifndef KDECORE_EXPORT
+# if defined(KDELIBS_STATIC_LIBS)
+   /* No export/import for static libraries */
+#  define KDECORE_EXPORT
+# elif defined(MAKE_KDECORE_LIB)
+   /* We are building this library */ 
+#  define KDECORE_EXPORT KDE_EXPORT
+# else
+   /* We are using this library */ 
+#  define KDECORE_EXPORT KDE_IMPORT
+# endif
+#endif
+
+# ifndef KDECORE_EXPORT_DEPRECATED
+#  define KDECORE_EXPORT_DEPRECATED KDE_DEPRECATED KDECORE_EXPORT
+# endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/konsole_export.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,67 @@
+/*
+    This file is part of the KDE project
+    Copyright (C) 2009 Patrick Spendrin <ps_ml@gmx.de>
+
+    This library 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 library 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.
+*/
+
+#ifndef KONSOLE_EXPORT_H
+#define KONSOLE_EXPORT_H
+
+/* needed for KDE_EXPORT macros */
+//#include <kdemacros.h>
+#include <QtCore/qglobal.h>
+#define KDE_EXPORT
+#define KDE_IMPORT
+
+#ifndef KONSOLEPRIVATE_EXPORT
+# if defined(MAKE_KONSOLEPRIVATE_LIB)
+   /* We are building this library */
+#  define KONSOLEPRIVATE_EXPORT KDE_EXPORT
+# else
+   /* We are using this library */
+#  define KONSOLEPRIVATE_EXPORT KDE_IMPORT
+# endif
+#endif
+
+#include <iostream>
+#define kWarning(x) std::cout
+
+#include <stdio.h>
+
+//#define i18n 
+inline QString i18n(char *buff,...)
+{
+  char msg[2048];
+    va_list arglist;
+
+    va_start(arglist,buff);
+
+    snprintf(msg,2048,buff, arglist);
+
+    va_end(arglist);
+
+    return QString(msg);
+}
+
+#define i18nc 
+
+
+//#define KDE_fseek ::fseek
+//#define KDE_lseek ::lseek
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/konsole_wcwidth.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,217 @@
+/* $XFree86: xc/programs/xterm/wcwidth.character,v 1.3 2001/07/29 22:08:16 tsi Exp $ */
+/*
+ * This is an implementation of wcwidth() and wcswidth() as defined in
+ * "The Single UNIX Specification, Version 2, The Open Group, 1997"
+ * <http://www.UNIX-systems.org/online.html>
+ *
+ * Markus Kuhn -- 2001-01-12 -- public domain
+ */
+
+#include "konsole_wcwidth.h"
+
+struct interval {
+  unsigned short first;
+  unsigned short last;
+};
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(quint16 ucs, const struct interval *table, int max) {
+  int min = 0;
+  int mid;
+
+  if (ucs < table[0].first || ucs > table[max].last)
+    return 0;
+  while (max >= min) {
+    mid = (min + max) / 2;
+    if (ucs > table[mid].last)
+      min = mid + 1;
+    else if (ucs < table[mid].first)
+      max = mid - 1;
+    else
+      return 1;
+  }
+
+  return 0;
+}
+
+
+/* The following functions define the column width of an ISO 10646
+ * character as follows:
+ *
+ *    - The null character (U+0000) has a column width of 0.
+ *
+ *    - Other C0/C1 control characters and DEL will lead to a return
+ *      value of -1.
+ *
+ *    - Non-spacing and enclosing combining characters (general
+ *      category code Mn or Me in the Unicode database) have a
+ *      column width of 0.
+ *
+ *    - Other format characters (general category code Cf in the Unicode
+ *      database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *
+ *    - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
+ *      have a column width of 0.
+ *
+ *    - Spacing characters in the East Asian Wide (W) or East Asian
+ *      FullWidth (F) category as defined in Unicode Technical
+ *      Report #11 have a column width of 2.
+ *
+ *    - All remaining characters (including all printable
+ *      ISO 8859-1 and WGL4 characters, Unicode control characters,
+ *      etc.) have a column width of 1.
+ *
+ * This implementation assumes that quint16 characters are encoded
+ * in ISO 10646.
+ */
+
+int konsole_wcwidth(quint16 ucs)
+{
+  /* sorted list of non-overlapping intervals of non-spacing characters */
+  static const struct interval combining[] = {
+    { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 },
+    { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 },
+    { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+    { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 },
+    { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+    { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
+    { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C },
+    { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 },
+    { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC },
+    { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 },
+    { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 },
+    { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 },
+    { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 },
+    { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 },
+    { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 },
+    { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 },
+    { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 },
+    { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 },
+    { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+    { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA },
+    { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 },
+    { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 },
+    { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD },
+    { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 },
+    { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 },
+    { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC },
+    { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 },
+    { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 },
+    { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 },
+    { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 },
+    { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F },
+    { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A },
+    { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF },
+    { 0xFFF9, 0xFFFB }
+  };
+
+  /* test for 8-bit control characters */
+  if (ucs == 0)
+    return 0;
+  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
+    return -1;
+
+  /* binary search in table of non-spacing characters */
+  if (bisearch(ucs, combining,
+           sizeof(combining) / sizeof(struct interval) - 1))
+    return 0;
+
+  /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+  return 1 +
+    (ucs >= 0x1100 &&
+     (ucs <= 0x115f ||                    /* Hangul Jamo init. consonants */
+      (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&
+       ucs != 0x303f) ||                  /* CJK ... Yi */
+      (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+      (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+      (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+      (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */
+      (ucs >= 0xffe0 && ucs <= 0xffe6) || /* do not compare UINT16 with 0x20000 */
+      (ucs >= 0x300a && ucs <= 0x300b)  /* Specal character 《 and 》(Unicode Standard Annex #11) ||
+      (ucs >= 0x20000 && ucs <= 0x2ffff) */));
+}
+
+#if 0
+/*
+ * The following function is the same as konsole_wcwidth(), except that
+ * spacing characters in the East Asian Ambiguous (A) category as
+ * defined in Unicode Technical Report #11 have a column width of 2.
+ * This experimental variant might be useful for users of CJK legacy
+ * encodings who want to migrate to UCS. It is not otherwise
+ * recommended for general use.
+ */
+int konsole_wcwidth_cjk(quint16 ucs)
+{
+  /* sorted list of non-overlapping intervals of East Asian Ambiguous
+   * characters */
+  static const struct interval ambiguous[] = {
+    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
+    { 0x00AA, 0x00AA }, { 0x00AD, 0x00AD }, { 0x00B0, 0x00B4 },
+    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
+    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
+    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
+    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
+    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
+    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
+    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
+    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
+    { 0x0148, 0x014A }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
+    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
+    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
+    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
+    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
+    { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, { 0x02CD, 0x02CD },
+    { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, { 0x02DD, 0x02DD },
+    { 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 },
+    { 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, { 0x0410, 0x044F },
+    { 0x0451, 0x0451 }, { 0x2010, 0x2010 }, { 0x2013, 0x2016 },
+    { 0x2018, 0x2019 }, { 0x201C, 0x201D }, { 0x2020, 0x2021 },
+    { 0x2025, 0x2027 }, { 0x2030, 0x2030 }, { 0x2032, 0x2033 },
+    { 0x2035, 0x2035 }, { 0x203B, 0x203B }, { 0x2074, 0x2074 },
+    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
+    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
+    { 0x2113, 0x2113 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 },
+    { 0x212B, 0x212B }, { 0x2154, 0x2155 }, { 0x215B, 0x215B },
+    { 0x215E, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
+    { 0x2190, 0x2199 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 },
+    { 0x2200, 0x2200 }, { 0x2202, 0x2203 }, { 0x2207, 0x2208 },
+    { 0x220B, 0x220B }, { 0x220F, 0x220F }, { 0x2211, 0x2211 },
+    { 0x2215, 0x2215 }, { 0x221A, 0x221A }, { 0x221D, 0x2220 },
+    { 0x2223, 0x2223 }, { 0x2225, 0x2225 }, { 0x2227, 0x222C },
+    { 0x222E, 0x222E }, { 0x2234, 0x2237 }, { 0x223C, 0x223D },
+    { 0x2248, 0x2248 }, { 0x224C, 0x224C }, { 0x2252, 0x2252 },
+    { 0x2260, 0x2261 }, { 0x2264, 0x2267 }, { 0x226A, 0x226B },
+    { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 },
+    { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 },
+    { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF },
+    { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 },
+    { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 },
+    { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 },
+    { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 },
+    { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 },
+    { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, { 0x2609, 0x2609 },
+    { 0x260E, 0x260F }, { 0x261C, 0x261C }, { 0x261E, 0x261E },
+    { 0x2640, 0x2640 }, { 0x2642, 0x2642 }, { 0x2660, 0x2661 },
+    { 0x2663, 0x2665 }, { 0x2667, 0x266A }, { 0x266C, 0x266D },
+    { 0x266F, 0x266F }, { 0x300A, 0x300B }, { 0x301A, 0x301B },
+    { 0xE000, 0xF8FF }, { 0xFFFD, 0xFFFD }
+  };
+
+  /* binary search in table of non-spacing characters */
+  if (bisearch(ucs, ambiguous,
+           sizeof(ambiguous) / sizeof(struct interval) - 1))
+    return 2;
+
+  return konsole_wcwidth(ucs);
+}
+#endif
+
+// single byte char: +1, multi byte char: +2
+int string_width( const QString &txt )
+{
+  int w = 0;
+  for ( int i = 0; i < txt.length(); ++i )
+     w += konsole_wcwidth( txt[ i ].unicode() );
+ return w;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/konsole_wcwidth.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,20 @@
+/* $XFree86: xc/programs/xterm/wcwidth.h,v 1.2 2001/06/18 19:09:27 dickey Exp $ */
+
+/* Markus Kuhn -- 2001-01-12 -- public domain */
+/* Adaptions for KDE by Waldo Bastian <bastian@kde.org> */
+
+#ifndef KONSOLE_WCWIDTH_H
+#define KONSOLE_WCWIDTH_H
+
+// Qt
+#include <QtCore/QBool>
+#include <QtCore/QString>
+
+int konsole_wcwidth(quint16 ucs);
+#if 0
+int konsole_wcwidth_cjk(Q_UINT16 ucs);
+#endif
+
+int string_width( const QString &txt );
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kprocess.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,418 @@
+/*
+    This file is part of the KDE libraries
+
+    Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "kprocess_p.h"
+
+//#include <kstandarddirs.h>
+//#include <kshell.h>
+//#ifdef Q_OS_WIN
+//# include <kshell_p.h>
+//#endif
+
+#include <qfile.h>
+
+#ifdef Q_OS_WIN
+# include <windows.h>
+#else
+# include <unistd.h>
+# include <errno.h>
+#endif
+
+#ifndef Q_OS_WIN
+# define STD_OUTPUT_HANDLE 1
+# define STD_ERROR_HANDLE 2
+#endif
+
+#ifdef _WIN32_WCE
+#include <stdio.h>
+#endif
+
+void KProcessPrivate::writeAll(const QByteArray &buf, int fd)
+{
+#ifdef Q_OS_WIN
+#ifndef _WIN32_WCE
+    HANDLE h = GetStdHandle(fd);
+    if (h) {
+        DWORD wr;
+        WriteFile(h, buf.data(), buf.size(), &wr, 0);
+    }
+#else
+    fwrite(buf.data(), 1, buf.size(), (FILE*)fd);
+#endif
+#else
+    int off = 0;
+    do {
+        int ret = ::write(fd, buf.data() + off, buf.size() - off);
+        if (ret < 0) {
+            if (errno != EINTR)
+                return;
+        } else {
+            off += ret;
+        }
+    } while (off < buf.size());
+#endif
+}
+
+void KProcessPrivate::forwardStd(KProcess::ProcessChannel good, int fd)
+{
+    Q_Q(KProcess);
+
+    QProcess::ProcessChannel oc = q->readChannel();
+    q->setReadChannel(good);
+    writeAll(q->readAll(), fd);
+    q->setReadChannel(oc);
+}
+
+void KProcessPrivate::_k_forwardStdout()
+{
+#ifndef _WIN32_WCE
+    forwardStd(KProcess::StandardOutput, STD_OUTPUT_HANDLE);
+#else
+    forwardStd(KProcess::StandardOutput, (int)stdout);
+#endif
+}
+
+void KProcessPrivate::_k_forwardStderr()
+{
+#ifndef _WIN32_WCE
+    forwardStd(KProcess::StandardError, STD_ERROR_HANDLE);
+#else
+    forwardStd(KProcess::StandardError, (int)stderr);
+#endif
+}
+
+/////////////////////////////
+// public member functions //
+/////////////////////////////
+
+KProcess::KProcess(QObject *parent) :
+    QProcess(parent),
+    d_ptr(new KProcessPrivate)
+{
+    d_ptr->q_ptr = this;
+    setOutputChannelMode(ForwardedChannels);
+}
+
+KProcess::KProcess(KProcessPrivate *d, QObject *parent) :
+    QProcess(parent),
+    d_ptr(d)
+{
+    d_ptr->q_ptr = this;
+    setOutputChannelMode(ForwardedChannels);
+}
+
+KProcess::~KProcess()
+{
+    delete d_ptr;
+}
+
+void KProcess::setOutputChannelMode(OutputChannelMode mode)
+{
+    Q_D(KProcess);
+
+    d->outputChannelMode = mode;
+    disconnect(this, SIGNAL(readyReadStandardOutput()));
+    disconnect(this, SIGNAL(readyReadStandardError()));
+    switch (mode) {
+    case OnlyStdoutChannel:
+        connect(this, SIGNAL(readyReadStandardError()), SLOT(_k_forwardStderr()));
+        break;
+    case OnlyStderrChannel:
+        connect(this, SIGNAL(readyReadStandardOutput()), SLOT(_k_forwardStdout()));
+        break;
+    default:
+        QProcess::setProcessChannelMode((ProcessChannelMode)mode);
+        return;
+    }
+    QProcess::setProcessChannelMode(QProcess::SeparateChannels);
+}
+
+KProcess::OutputChannelMode KProcess::outputChannelMode() const
+{
+    Q_D(const KProcess);
+
+    return d->outputChannelMode;
+}
+
+void KProcess::setNextOpenMode(QIODevice::OpenMode mode)
+{
+    Q_D(KProcess);
+
+    d->openMode = mode;
+}
+
+#define DUMMYENV "_KPROCESS_DUMMY_="
+
+void KProcess::clearEnvironment()
+{
+    setEnvironment(QStringList() << QString::fromLatin1(DUMMYENV));
+}
+
+void KProcess::setEnv(const QString &name, const QString &value, bool overwrite)
+{
+    QStringList env = environment();
+    if (env.isEmpty()) {
+        env = systemEnvironment();
+        env.removeAll(QString::fromLatin1(DUMMYENV));
+    }
+    QString fname(name);
+    fname.append(QLatin1Char('='));
+    for (QStringList::Iterator it = env.begin(); it != env.end(); ++it)
+        if ((*it).startsWith(fname)) {
+            if (overwrite) {
+                *it = fname.append(value);
+                setEnvironment(env);
+            }
+            return;
+        }
+    env.append(fname.append(value));
+    setEnvironment(env);
+}
+
+void KProcess::unsetEnv(const QString &name)
+{
+    QStringList env = environment();
+    if (env.isEmpty()) {
+        env = systemEnvironment();
+        env.removeAll(QString::fromLatin1(DUMMYENV));
+    }
+    QString fname(name);
+    fname.append(QLatin1Char('='));
+    for (QStringList::Iterator it = env.begin(); it != env.end(); ++it)
+        if ((*it).startsWith(fname)) {
+            env.erase(it);
+            if (env.isEmpty())
+                env.append(QString::fromLatin1(DUMMYENV));
+            setEnvironment(env);
+            return;
+        }
+}
+
+void KProcess::setProgram(const QString &exe, const QStringList &args)
+{
+    Q_D(KProcess);
+
+    d->prog = exe;
+    d->args = args;
+#ifdef Q_OS_WIN
+    setNativeArguments(QString());
+#endif
+}
+
+void KProcess::setProgram(const QStringList &argv)
+{
+    Q_D(KProcess);
+
+    Q_ASSERT( !argv.isEmpty() );
+    d->args = argv;
+    d->prog = d->args.takeFirst();
+#ifdef Q_OS_WIN
+    setNativeArguments(QString());
+#endif
+}
+
+KProcess &KProcess::operator<<(const QString &arg)
+{
+    Q_D(KProcess);
+
+    if (d->prog.isEmpty())
+        d->prog = arg;
+    else
+        d->args << arg;
+    return *this;
+}
+
+KProcess &KProcess::operator<<(const QStringList &args)
+{
+    Q_D(KProcess);
+
+    if (d->prog.isEmpty())
+        setProgram(args);
+    else
+        d->args << args;
+    return *this;
+}
+
+void KProcess::clearProgram()
+{
+    Q_D(KProcess);
+
+    d->prog.clear();
+    d->args.clear();
+#ifdef Q_OS_WIN
+    setNativeArguments(QString());
+#endif
+}
+
+void KProcess::setShellCommand(const QString &cmd)
+{
+    Q_D(KProcess);
+
+    // JPS: commented out because I didn't want to pull in KShell also.  It
+    // seems this is mostly for handling program arguments, which I won't be
+    // using.
+    /*
+    KShell::Errors err;
+    d->args = KShell::splitArgs(
+            cmd, KShell::AbortOnMeta | KShell::TildeExpand, &err);
+    if (err == KShell::NoError && !d->args.isEmpty()) {
+        d->prog = KStandardDirs::findExe(d->args[0]);
+        if (!d->prog.isEmpty()) {
+            d->args.removeFirst();
+#ifdef Q_OS_WIN
+            setNativeArguments(QString());
+#endif
+            return;
+        }
+    }
+    */
+
+    d->args.clear();
+
+#ifdef Q_OS_UNIX
+// #ifdef NON_FREE // ... as they ship non-POSIX /bin/sh
+# if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) && !defined(__GNU__)
+    // If /bin/sh is a symlink, we can be pretty sure that it points to a
+    // POSIX shell - the original bourne shell is about the only non-POSIX
+    // shell still in use and it is always installed natively as /bin/sh.
+    /*
+    d->prog = QFile::symLinkTarget(QString::fromLatin1("/bin/sh"));
+    if (d->prog.isEmpty()) {
+        // Try some known POSIX shells.
+        d->prog = KStandardDirs::findExe(QString::fromLatin1("ksh"));
+        if (d->prog.isEmpty()) {
+            d->prog = KStandardDirs::findExe(QString::fromLatin1("ash"));
+            if (d->prog.isEmpty()) {
+                d->prog = KStandardDirs::findExe(QString::fromLatin1("bash"));
+                if (d->prog.isEmpty()) {
+                    d->prog = KStandardDirs::findExe(QString::fromLatin1("zsh"));
+                    if (d->prog.isEmpty())
+                        // We're pretty much screwed, to be honest ...
+                        d->prog = QString::fromLatin1("/bin/sh");
+                }
+            }
+        }
+     }
+*/
+# else
+    d->prog = QString::fromLatin1("/bin/sh");
+# endif
+
+    d->args << QString::fromLatin1("-c") << cmd;
+#else // Q_OS_UNIX
+    // KMacroExpander::expandMacrosShellQuote(), KShell::quoteArg() and
+    // KShell::joinArgs() may generate these for security reasons.
+    setEnv(PERCENT_VARIABLE, QLatin1String("%"));
+
+#ifndef _WIN32_WCE
+    WCHAR sysdir[MAX_PATH + 1];
+    UINT size = GetSystemDirectoryW(sysdir, MAX_PATH + 1);
+    d->prog = QString::fromUtf16((const ushort *) sysdir, size);
+    d->prog += QLatin1String("\\cmd.exe");
+    setNativeArguments(QLatin1String("/V:OFF /S /C \"") + cmd + QLatin1Char('"'));
+#else
+    d->prog = QLatin1String("\\windows\\cmd.exe");
+    setNativeArguments(QLatin1String("/S /C \"") + cmd + QLatin1Char('"'));
+#endif
+#endif
+}
+
+QStringList KProcess::program() const
+{
+    Q_D(const KProcess);
+
+    QStringList argv = d->args;
+    argv.prepend(d->prog);
+    return argv;
+}
+
+void KProcess::start()
+{
+    Q_D(KProcess);
+
+    QProcess::start(d->prog, d->args, d->openMode);
+}
+
+int KProcess::execute(int msecs)
+{
+    start();
+    if (!waitForFinished(msecs)) {
+        kill();
+        waitForFinished(-1);
+        return -2;
+    }
+    return (exitStatus() == QProcess::NormalExit) ? exitCode() : -1;
+}
+
+// static
+int KProcess::execute(const QString &exe, const QStringList &args, int msecs)
+{
+    KProcess p;
+    p.setProgram(exe, args);
+    return p.execute(msecs);
+}
+
+// static
+int KProcess::execute(const QStringList &argv, int msecs)
+{
+    KProcess p;
+    p.setProgram(argv);
+    return p.execute(msecs);
+}
+
+int KProcess::startDetached()
+{
+    Q_D(KProcess);
+
+    qint64 pid;
+    if (!QProcess::startDetached(d->prog, d->args, workingDirectory(), &pid))
+        return 0;
+    return (int) pid;
+}
+
+// static
+int KProcess::startDetached(const QString &exe, const QStringList &args)
+{
+    qint64 pid;
+    if (!QProcess::startDetached(exe, args, QString(), &pid))
+        return 0;
+    return (int) pid;
+}
+
+// static
+int KProcess::startDetached(const QStringList &argv)
+{
+    QStringList args = argv;
+    QString prog = args.takeFirst();
+    return startDetached(prog, args);
+}
+
+int KProcess::pid() const
+{
+#ifdef Q_OS_UNIX
+    return (int) QProcess::pid();
+#else
+    return QProcess::pid() ? QProcess::pid()->dwProcessId : 0;
+#endif
+}
+
+#include "kprocess.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kprocess.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,341 @@
+/*
+    This file is part of the KDE libraries
+
+    Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KPROCESS_H
+#define KPROCESS_H
+
+#include "kdecore_export.h"
+
+#include <QtCore/QProcess>
+
+class KProcessPrivate;
+
+/**
+ * \class KProcess kprocess.h <KProcess>
+ * 
+ * Child process invocation, monitoring and control.
+ *
+ * This class extends QProcess by some useful functionality, overrides
+ * some defaults with saner values and wraps parts of the API into a more
+ * accessible one.
+ * This is the preferred way of spawning child processes in KDE; don't
+ * use QProcess directly.
+ *
+ * @author Oswald Buddenhagen <ossi@kde.org>
+ **/
+class KDECORE_EXPORT KProcess : public QProcess
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(KProcess)
+
+public:
+
+    /**
+     * Modes in which the output channels can be opened.
+     */
+    enum OutputChannelMode {
+        SeparateChannels = QProcess::SeparateChannels,
+            /**< Standard output and standard error are handled by KProcess
+                 as separate channels */
+        MergedChannels = QProcess::MergedChannels,
+            /**< Standard output and standard error are handled by KProcess
+                 as one channel */
+        ForwardedChannels = QProcess::ForwardedChannels,
+            /**< Both standard output and standard error are forwarded
+                 to the parent process' respective channel */
+        OnlyStdoutChannel,
+            /**< Only standard output is handled; standard error is forwarded */
+        OnlyStderrChannel  /**< Only standard error is handled; standard output is forwarded */
+    };
+
+    /**
+     * Constructor
+     */
+    explicit KProcess(QObject *parent = 0);
+
+    /**
+     * Destructor
+     */
+    virtual ~KProcess();
+
+    /**
+     * Set how to handle the output channels of the child process.
+     *
+     * The default is ForwardedChannels, which is unlike in QProcess.
+     * Do not request more than you actually handle, as this output is
+     * simply lost otherwise.
+     *
+     * This function must be called before starting the process.
+     *
+     * @param mode the output channel handling mode
+     */
+    void setOutputChannelMode(OutputChannelMode mode);
+
+    /**
+     * Query how the output channels of the child process are handled.
+     *
+     * @return the output channel handling mode
+     */
+    OutputChannelMode outputChannelMode() const;
+
+    /**
+     * Set the QIODevice open mode the process will be opened in.
+     *
+     * This function must be called before starting the process, obviously.
+     *
+     * @param mode the open mode. Note that this mode is automatically
+     *   "reduced" according to the channel modes and redirections.
+     *   The default is QIODevice::ReadWrite.
+     */
+    void setNextOpenMode(QIODevice::OpenMode mode);
+
+    /**
+     * Adds the variable @p name to the process' environment.
+     *
+     * This function must be called before starting the process.
+     *
+     * @param name the name of the environment variable
+     * @param value the new value for the environment variable
+     * @param overwrite if @c false and the environment variable is already
+     *   set, the old value will be preserved
+     */
+    void setEnv(const QString &name, const QString &value, bool overwrite = true);
+
+    /**
+     * Removes the variable @p name from the process' environment.
+     *
+     * This function must be called before starting the process.
+     *
+     * @param name the name of the environment variable
+     */
+    void unsetEnv(const QString &name);
+
+    /**
+     * Empties the process' environment.
+     *
+     * Note that LD_LIBRARY_PATH/DYLD_LIBRARY_PATH is automatically added
+     * on *NIX.
+     *
+     * This function must be called before starting the process.
+     */
+    void clearEnvironment();
+
+    /**
+     * Set the program and the command line arguments.
+     *
+     * This function must be called before starting the process, obviously.
+     *
+     * @param exe the program to execute
+     * @param args the command line arguments for the program,
+     *   one per list element
+     */
+    void setProgram(const QString &exe, const QStringList &args = QStringList());
+
+    /**
+     * @overload
+     *
+     * @param argv the program to execute and the command line arguments
+     *   for the program, one per list element
+     */
+    void setProgram(const QStringList &argv);
+
+    /**
+     * Append an element to the command line argument list for this process.
+     *
+     * If no executable is set yet, it will be set instead.
+     *
+     * For example, doing an "ls -l /usr/local/bin" can be achieved by:
+     *  \code
+     *  KProcess p;
+     *  p << "ls" << "-l" << "/usr/local/bin";
+     *  ...
+     *  \endcode
+     *
+     * This function must be called before starting the process, obviously.
+     *
+     * @param arg the argument to add
+     * @return a reference to this KProcess
+     */
+    KProcess &operator<<(const QString& arg);
+
+    /**
+     * @overload
+     *
+     * @param args the arguments to add
+     * @return a reference to this KProcess
+     */
+    KProcess &operator<<(const QStringList& args);
+
+    /**
+     * Clear the program and command line argument list.
+     */
+    void clearProgram();
+
+    /**
+     * Set a command to execute through a shell (a POSIX sh on *NIX
+     * and cmd.exe on Windows).
+     *
+     * Using this for anything but user-supplied commands is usually a bad
+     * idea, as the command's syntax depends on the platform.
+     * Redirections including pipes, etc. are better handled by the
+     * respective functions provided by QProcess.
+     *
+     * If KProcess determines that the command does not really need a
+     * shell, it will trasparently execute it without one for performance
+     * reasons.
+     *
+     * This function must be called before starting the process, obviously.
+     *
+     * @param cmd the command to execute through a shell.
+     *   The caller must make sure that all filenames etc. are properly
+     *   quoted when passed as argument. Failure to do so often results in
+     *   serious security holes. See KShell::quoteArg().
+     */
+    void setShellCommand(const QString &cmd);
+
+    /**
+     * Obtain the currently set program and arguments.
+     *
+     * @return a list, the first element being the program, the remaining ones
+     *  being command line arguments to the program.
+     */
+    QStringList program() const;
+
+    /**
+     * Start the process.
+     *
+     * @see QProcess::start(const QString &, const QStringList &, OpenMode)
+     */
+    void start();
+
+    /**
+     * Start the process, wait for it to finish, and return the exit code.
+     *
+     * This method is roughly equivalent to the sequence:
+     * <code>
+     *   start();
+     *   waitForFinished(msecs);
+     *   return exitCode();
+     * </code>
+     *
+     * Unlike the other execute() variants this method is not static,
+     * so the process can be parametrized properly and talked to.
+     *
+     * @param msecs time to wait for process to exit before killing it
+     * @return -2 if the process could not be started, -1 if it crashed,
+     *  otherwise its exit code
+     */
+    int execute(int msecs = -1);
+
+    /**
+     * @overload
+     *
+     * @param exe the program to execute
+     * @param args the command line arguments for the program,
+     *   one per list element
+     * @param msecs time to wait for process to exit before killing it
+     * @return -2 if the process could not be started, -1 if it crashed,
+     *  otherwise its exit code
+     */
+    static int execute(const QString &exe, const QStringList &args = QStringList(), int msecs = -1);
+
+    /**
+     * @overload
+     *
+     * @param argv the program to execute and the command line arguments
+     *   for the program, one per list element
+     * @param msecs time to wait for process to exit before killing it
+     * @return -2 if the process could not be started, -1 if it crashed,
+     *  otherwise its exit code
+     */
+    static int execute(const QStringList &argv, int msecs = -1);
+
+    /**
+     * Start the process and detach from it. See QProcess::startDetached()
+     * for details.
+     *
+     * Unlike the other startDetached() variants this method is not static,
+     * so the process can be parametrized properly.
+     * @note Currently, only the setProgram()/setShellCommand() and
+     * setWorkingDirectory() parametrizations are supported.
+     *
+     * The KProcess object may be re-used immediately after calling this
+     * function.
+     *
+     * @return the PID of the started process or 0 on error
+     */
+    int startDetached();
+
+    /**
+     * @overload
+     *
+     * @param exe the program to start
+     * @param args the command line arguments for the program,
+     *   one per list element
+     * @return the PID of the started process or 0 on error
+     */
+    static int startDetached(const QString &exe, const QStringList &args = QStringList());
+
+    /**
+     * @overload
+     *
+     * @param argv the program to start and the command line arguments
+     *   for the program, one per list element
+     * @return the PID of the started process or 0 on error
+     */
+    static int startDetached(const QStringList &argv);
+
+    /**
+     * Obtain the process' ID as known to the system.
+     *
+     * Unlike with QProcess::pid(), this is a real PID also on Windows.
+     *
+     * This function can be called only while the process is running.
+     * It cannot be applied to detached processes.
+     *
+     * @return the process ID
+     */
+    int pid() const;
+
+protected:
+    /**
+     * @internal
+     */
+    KProcess(KProcessPrivate *d, QObject *parent);
+
+    /**
+     * @internal
+     */
+    KProcessPrivate * const d_ptr;
+
+private:
+    // hide those
+    using QProcess::setReadChannelMode;
+    using QProcess::readChannelMode;
+    using QProcess::setProcessChannelMode;
+    using QProcess::processChannelMode;
+
+    Q_PRIVATE_SLOT(d_func(), void _k_forwardStdout())
+    Q_PRIVATE_SLOT(d_func(), void _k_forwardStderr())
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kprocess_p.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,48 @@
+/*
+    This file is part of the KDE libraries
+
+    Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KPROCESS_P_H
+#define KPROCESS_P_H
+
+#include "kprocess.h"
+
+class KProcessPrivate {
+    Q_DECLARE_PUBLIC(KProcess)
+protected:
+    KProcessPrivate() :
+        openMode(QIODevice::ReadWrite)
+    {
+    }
+    void writeAll(const QByteArray &buf, int fd);
+    void forwardStd(KProcess::ProcessChannel good, int fd);
+    void _k_forwardStdout();
+    void _k_forwardStderr();
+
+    QString prog;
+    QStringList args;
+    KProcess::OutputChannelMode outputChannelMode;
+    QIODevice::OpenMode openMode;
+
+    KProcess *q_ptr;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kpty.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,717 @@
+/*
+
+   This file is part of the KDE libraries
+   Copyright (C) 2002 Waldo Bastian <bastian@kde.org>
+   Copyright (C) 2002-2003,2007-2008 Oswald Buddenhagen <ossi@kde.org>
+   Copyright (C) 2010 KDE e.V. <kde-ev-board@kde.org>
+     Author Adriaan de Groot <groot@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "kpty_p.h"
+
+//#include <config.h>
+
+#ifdef __sgi
+#define __svr4__
+#endif
+
+#ifdef __osf__
+#define _OSF_SOURCE
+#include <float.h>
+#endif
+
+#ifdef _AIX
+#define _ALL_SOURCE
+#endif
+
+// __USE_XOPEN isn't defined by default in ICC
+// (needed for ptsname(), grantpt() and unlockpt())
+#ifdef __INTEL_COMPILER
+#  ifndef __USE_XOPEN
+#    define __USE_XOPEN
+#  endif
+#endif
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <grp.h>
+
+#if defined(HAVE_PTY_H)
+# include <pty.h>
+#endif
+
+#ifdef HAVE_LIBUTIL_H
+# include <libutil.h>
+#elif defined(HAVE_UTIL_H)
+# include <util.h>
+#endif
+
+#define HAVE_UTMPX
+#define _UTMPX_COMPAT
+
+#ifdef HAVE_UTEMPTER
+extern "C" {
+# include <utempter.h>
+}
+#else
+# include <utmp.h>
+# ifdef HAVE_UTMPX
+#  include <utmpx.h>
+# endif
+# if !defined(_PATH_UTMPX) && defined(_UTMPX_FILE)
+#  define _PATH_UTMPX _UTMPX_FILE
+# endif
+# if !defined(_PATH_WTMPX) && defined(_WTMPX_FILE)
+#  define _PATH_WTMPX _WTMPX_FILE
+# endif
+#endif
+
+/* for HP-UX (some versions) the extern C is needed, and for other
+   platforms it doesn't hurt */
+extern "C" {
+#include <termios.h>
+#if defined(HAVE_TERMIO_H)
+# include <termio.h> // struct winsize on some systems
+#endif
+}
+
+#if defined (_HPUX_SOURCE)
+# define _TERMIOS_INCLUDED
+# include <bsdtty.h>
+#endif
+
+#ifdef HAVE_SYS_STROPTS_H
+# include <sys/stropts.h>	// Defines I_PUSH
+# define _NEW_TTY_CTRL
+#endif
+
+#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
+# define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode)
+#else
+# if defined(_HPUX_SOURCE) || defined(__Lynx__) || defined (__CYGWIN__) || defined(__sun)
+#  define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode)
+# else
+#  define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode)
+# endif
+#endif
+
+#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
+# define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode)
+#else
+# if defined(_HPUX_SOURCE) || defined(__CYGWIN__) || defined(__sun)
+#  define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode)
+# else
+#  define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode)
+# endif
+#endif
+
+//#include <kdebug.h>
+//#include <kstandarddirs.h>	// findExe
+//#include <kde_file.h>
+
+#include <QtCore/Q_PID>
+
+#define TTY_GROUP "tty"
+
+#ifndef PATH_MAX
+# ifdef MAXPATHLEN
+#  define PATH_MAX MAXPATHLEN
+# else
+#  define PATH_MAX 1024
+# endif
+#endif
+
+// Fix: Needed to build on Ubuntu.
+#undef HAVE_UTMPX
+
+///////////////////////
+// private functions //
+///////////////////////
+
+//////////////////
+// private data //
+//////////////////
+
+KPtyPrivate::KPtyPrivate(KPty* parent) :
+    masterFd(-1), slaveFd(-1), ownMaster(true), q_ptr(parent)
+{
+}
+
+KPtyPrivate::~KPtyPrivate()
+{
+}
+
+#ifndef HAVE_OPENPTY
+bool KPtyPrivate::chownpty(bool grant)
+{
+    return !QProcess::execute(KStandardDirs::findExe("kgrantpty"),
+        QStringList() << (grant?"--grant":"--revoke") << QString::number(masterFd));
+}
+#endif
+
+/////////////////////////////
+// public member functions //
+/////////////////////////////
+
+KPty::KPty() :
+    d_ptr(new KPtyPrivate(this))
+{
+}
+
+KPty::KPty(KPtyPrivate *d) :
+    d_ptr(d)
+{
+    d_ptr->q_ptr = this;
+}
+
+KPty::~KPty()
+{
+    close();
+    delete d_ptr;
+}
+
+bool KPty::open()
+{
+  Q_D(KPty);
+
+  if (d->masterFd >= 0)
+    return true;
+
+  d->ownMaster = true;
+
+  QByteArray ptyName;
+
+  // Find a master pty that we can open ////////////////////////////////
+
+  // Because not all the pty animals are created equal, they want to
+  // be opened by several different methods.
+
+  // We try, as we know them, one by one.
+
+#ifdef HAVE_OPENPTY
+
+  char ptsn[PATH_MAX];
+  if (::openpty( &d->masterFd, &d->slaveFd, ptsn, 0, 0))
+  {
+    d->masterFd = -1;
+    d->slaveFd = -1;
+    //kWarning(175) << "Can't open a pseudo teletype";
+    return false;
+  }
+  d->ttyName = ptsn;
+
+#else
+
+#ifdef HAVE__GETPTY // irix
+
+  char *ptsn = _getpty(&d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
+  if (ptsn) {
+    d->ttyName = ptsn;
+    goto grantedpt;
+  }
+
+#elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)
+
+#ifdef HAVE_POSIX_OPENPT
+  d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
+#elif defined(HAVE_GETPT)
+  d->masterFd = ::getpt();
+#elif defined(PTM_DEVICE)
+  //d->masterFd = KDE_open(PTM_DEVICE, O_RDWR|O_NOCTTY);
+d->masterFd = ::open(PTM_DEVICE, O_RDWR|O_NOCTTY);
+#else
+# error No method to open a PTY master detected.
+#endif
+  if (d->masterFd >= 0)
+  {
+#ifdef HAVE_PTSNAME
+    char *ptsn = ptsname(d->masterFd);
+    if (ptsn) {
+        d->ttyName = ptsn;
+#else
+    int ptyno;
+    if (!ioctl(d->masterFd, TIOCGPTN, &ptyno)) {
+        char buf[32];
+        sprintf(buf, "/dev/pts/%d", ptyno);
+        d->ttyName = buf;
+#endif
+#ifdef HAVE_GRANTPT
+        if (!grantpt(d->masterFd))
+           goto grantedpt;
+#else
+        goto gotpty;
+#endif
+    }
+    ::close(d->masterFd);
+    d->masterFd = -1;
+  }
+#endif // HAVE_PTSNAME || TIOCGPTN
+
+  // Linux device names, FIXME: Trouble on other systems?
+  for (const char* s3 = "pqrstuvwxyzabcde"; *s3; s3++)
+  {
+    for (const char* s4 = "0123456789abcdef"; *s4; s4++)
+    {
+      ptyName = QString().sprintf("/dev/pty%c%c", *s3, *s4).toAscii();
+      d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toAscii();
+
+      d->masterFd = ::open(ptyName.data(), O_RDWR);
+      if (d->masterFd >= 0)
+      {
+#ifdef Q_OS_SOLARIS
+        /* Need to check the process group of the pty.
+         * If it exists, then the slave pty is in use,
+         * and we need to get another one.
+         */
+        int pgrp_rtn;
+        if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
+          ::close(d->masterFd);
+          d->masterFd = -1;
+          continue;
+        }
+#endif /* Q_OS_SOLARIS */
+        if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits
+        {
+          if (!geteuid())
+          {
+            struct group* p = getgrnam(TTY_GROUP);
+            if (!p)
+              p = getgrnam("wheel");
+            gid_t gid = p ? p->gr_gid : getgid ();
+
+            chown(d->ttyName.data(), getuid(), gid);
+            chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
+          }
+          goto gotpty;
+        }
+        ::close(d->masterFd);
+        d->masterFd = -1;
+      }
+    }
+  }
+
+  //kWarning(175) << "Can't open a pseudo teletype";
+  return false;
+
+ gotpty:
+  KDE_struct_stat st;
+  if (KDE_stat(d->ttyName.data(), &st))
+    return false; // this just cannot happen ... *cough*  Yeah right, I just
+                  // had it happen when pty #349 was allocated.  I guess
+                  // there was some sort of leak?  I only had a few open.
+  if (((st.st_uid != getuid()) ||
+       (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
+      !d->chownpty(true))
+  {
+
+    /*kWarning(175)
+      << "chownpty failed for device " << ptyName << "::" << d->ttyName
+      << "\nThis means the communication can be eavesdropped." << endl;
+*/  
+}
+
+ grantedpt:
+
+#ifdef HAVE_REVOKE
+  revoke(d->ttyName.data());
+#endif
+
+#ifdef HAVE_UNLOCKPT
+  unlockpt(d->masterFd);
+#elif defined(TIOCSPTLCK)
+  int flag = 0;
+  ioctl(d->masterFd, TIOCSPTLCK, &flag);
+#endif
+
+  d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
+  if (d->slaveFd < 0)
+  {
+    //kWarning(175) << "Can't open slave pseudo teletype";
+    ::close(d->masterFd);
+    d->masterFd = -1;
+    return false;
+  }
+
+#if (defined(__svr4__) || defined(__sgi__) || defined(Q_OS_SOLARIS))
+  // Solaris uses STREAMS for terminal handling. It is possible
+  // for the pty handling modules to be left off the stream; in that
+  // case push them on. ioctl(fd, I_FIND, ...) is documented to return
+  // 1 if the module is on the stream already.
+  {
+    static const char *pt = "ptem";
+    static const char *ld = "ldterm";
+    if (ioctl(d->slaveFd, I_FIND, pt) == 0)
+      ioctl(d->slaveFd, I_PUSH, pt);
+    if (ioctl(d->slaveFd, I_FIND, ld) == 0)
+      ioctl(d->slaveFd, I_PUSH, ld);
+  }
+#endif
+
+#endif /* HAVE_OPENPTY */
+
+  fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
+  fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
+
+  return true;
+}
+
+bool KPty::open(int fd)
+{
+#if !defined(HAVE_PTSNAME) && !defined(TIOCGPTN)
+    //kWarning(175) << "Unsupported attempt to open pty with fd" << fd;
+    return false;
+#else
+    Q_D(KPty);
+
+    if (d->masterFd >= 0) {
+        //kWarning(175) << "Attempting to open an already open pty";
+        return false;
+    }
+
+    d->ownMaster = false;
+
+# ifdef HAVE_PTSNAME
+    char *ptsn = ptsname(fd);
+    if (ptsn) {
+        d->ttyName = ptsn;
+# else
+    int ptyno;
+    if (!ioctl(fd, TIOCGPTN, &ptyno)) {
+        char buf[32];
+        sprintf(buf, "/dev/pts/%d", ptyno);
+        d->ttyName = buf;
+# endif
+    } else {
+        //kWarning(175) << "Failed to determine pty slave device for fd" << fd;
+        return false;
+    }
+
+    d->masterFd = fd;
+    if (!openSlave()) {
+        d->masterFd = -1;
+        return false;
+    }
+
+    return true;
+#endif
+}
+
+void KPty::closeSlave()
+{
+    Q_D(KPty);
+
+    if (d->slaveFd < 0)
+        return;
+    ::close(d->slaveFd);
+    d->slaveFd = -1;
+}
+
+bool KPty::openSlave()
+{
+    Q_D(KPty);
+
+    if (d->slaveFd >= 0)
+        return true;
+    if (d->masterFd < 0) {
+        //kWarning(175) << "Attempting to open pty slave while master is closed";
+        return false;
+    }
+    d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
+    if (d->slaveFd < 0) {
+        //kWarning(175) << "Can't open slave pseudo teletype";
+        return false;
+    }
+    fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
+    return true;
+}
+
+void KPty::close()
+{
+    Q_D(KPty);
+
+    if (d->masterFd < 0)
+        return;
+    closeSlave();
+    if (d->ownMaster) {
+#ifndef HAVE_OPENPTY
+        // don't bother resetting unix98 pty, it will go away after closing master anyway.
+        if (memcmp(d->ttyName.data(), "/dev/pts/", 9)) {
+            if (!geteuid()) {
+                struct stat st;
+                if (!stat(d->ttyName.data(), &st)) {
+                    chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1);
+                    chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+                }
+            } else {
+                fcntl(d->masterFd, F_SETFD, 0);
+                d->chownpty(false);
+            }
+        }
+#endif
+        ::close(d->masterFd);
+    }
+    d->masterFd = -1;
+}
+
+void KPty::setCTty()
+{
+    Q_D(KPty);
+
+    // Setup job control //////////////////////////////////
+
+    // Become session leader, process group leader,
+    // and get rid of the old controlling terminal.
+    setsid();
+
+    // make our slave pty the new controlling terminal.
+#ifdef TIOCSCTTY
+    ioctl(d->slaveFd, TIOCSCTTY, 0);
+#else
+    // __svr4__ hack: the first tty opened after setsid() becomes controlling tty
+    ::close(open(d->ttyName, O_WRONLY, 0));
+#endif
+
+    // make our new process group the foreground group on the pty
+    int pgrp = getpid();
+#if defined(_POSIX_VERSION) || defined(__svr4__)
+    tcsetpgrp(d->slaveFd, pgrp);
+#elif defined(TIOCSPGRP)
+    ioctl(d->slaveFd, TIOCSPGRP, (char *)&pgrp);
+#endif
+}
+
+void KPty::login(const char *user, const char *remotehost)
+{
+#ifdef HAVE_UTEMPTER
+    Q_D(KPty);
+
+    addToUtmp(d->ttyName, remotehost, d->masterFd);
+    Q_UNUSED(user);
+#else
+# ifdef HAVE_UTMPX
+    struct utmpx l_struct;
+# else
+    struct utmp l_struct;
+# endif
+    memset(&l_struct, 0, sizeof(l_struct));
+    // note: strncpy without terminators _is_ correct here. man 4 utmp
+
+    if (user)
+      strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name));
+
+    if (remotehost) {
+      strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host));
+# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
+      l_struct.ut_syslen = qMin(strlen(remotehost), sizeof(l_struct.ut_host));
+# endif
+    }
+
+# ifndef __GLIBC__
+    Q_D(KPty);
+    const char *str_ptr = d->ttyName.data();
+    if (!memcmp(str_ptr, "/dev/", 5))
+        str_ptr += 5;
+    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
+#  ifdef HAVE_STRUCT_UTMP_UT_ID
+    strncpy(l_struct.ut_id,
+            str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id),
+            sizeof(l_struct.ut_id));
+#  endif
+# endif
+
+# ifdef HAVE_UTMPX
+    gettimeofday(&l_struct.ut_tv, 0);
+# else
+    l_struct.ut_time = time(0);
+# endif
+
+# ifdef HAVE_LOGIN
+#  ifdef HAVE_LOGINX
+    ::loginx(&l_struct);
+#  else
+    ::login(&l_struct);
+#  endif
+# else
+#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
+    l_struct.ut_type = USER_PROCESS;
+#  endif
+#  ifdef HAVE_STRUCT_UTMP_UT_PID
+    l_struct.ut_pid = getpid();
+#   ifdef HAVE_STRUCT_UTMP_UT_SESSION
+    l_struct.ut_session = getsid(0);
+#   endif
+#  endif
+#  ifdef HAVE_UTMPX
+    utmpxname(_PATH_UTMPX);
+    setutxent();
+    pututxline(&l_struct);
+    endutxent();
+    //updwtmpx(_PATH_WTMPX, &l_struct);
+#  else
+    utmpname(_PATH_UTMP);
+    setutent();
+    pututline(&l_struct);
+    endutent();
+    updwtmp(_PATH_WTMP, &l_struct);
+#  endif
+# endif
+#endif
+}
+
+void KPty::logout()
+{
+#ifdef HAVE_UTEMPTER
+    Q_D(KPty);
+
+    removeLineFromUtmp(d->ttyName, d->masterFd);
+#else
+    Q_D(KPty);
+
+    const char *str_ptr = d->ttyName.data();
+    if (!memcmp(str_ptr, "/dev/", 5))
+        str_ptr += 5;
+# ifdef __GLIBC__
+    else {
+        const char *sl_ptr = strrchr(str_ptr, '/');
+        if (sl_ptr)
+            str_ptr = sl_ptr + 1;
+    }
+# endif
+# ifdef HAVE_LOGIN
+#  ifdef HAVE_LOGINX
+    ::logoutx(str_ptr, 0, DEAD_PROCESS);
+#  else
+    ::logout(str_ptr);
+#  endif
+# else
+#  ifdef HAVE_UTMPX
+    struct utmpx l_struct, *ut;
+#  else
+    struct utmp l_struct, *ut;
+#  endif
+    memset(&l_struct, 0, sizeof(l_struct));
+
+    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
+
+#  ifdef HAVE_UTMPX
+    utmpxname(_PATH_UTMPX);
+    setutxent();
+    if ((ut = getutxline(&l_struct))) {
+#  else
+    utmpname(_PATH_UTMP);
+    setutent();
+    if ((ut = getutline(&l_struct))) {
+#  endif
+        memset(ut->ut_name, 0, sizeof(*ut->ut_name));
+        memset(ut->ut_host, 0, sizeof(*ut->ut_host));
+#  ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
+        ut->ut_syslen = 0;
+#  endif
+#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
+        ut->ut_type = DEAD_PROCESS;
+#  endif
+#  ifdef HAVE_UTMPX
+        gettimeofday(&(ut->ut_tv), 0);
+        pututxline(ut);
+    }
+    endutxent();
+#  else
+        ut->ut_time = time(0);
+        pututline(ut);
+    }
+    endutent();
+#  endif
+# endif
+#endif
+}
+
+bool KPty::tcGetAttr(struct ::termios *ttmode) const
+{
+    Q_D(const KPty);
+
+#ifdef Q_OS_SOLARIS
+    if (_tcgetattr(d->slaveFd, ttmode) == 0) return true;
+#endif
+    return _tcgetattr(d->masterFd, ttmode) == 0;
+}
+
+bool KPty::tcSetAttr(struct ::termios *ttmode)
+{
+    Q_D(KPty);
+
+#ifdef Q_OS_SOLARIS
+    if (_tcsetattr(d->slaveFd, ttmode) == 0) return true;
+#endif
+    return _tcsetattr(d->masterFd, ttmode) == 0;
+}
+
+bool KPty::setWinSize(int lines, int columns)
+{
+    Q_D(KPty);
+
+    struct winsize winSize;
+    memset(&winSize, 0, sizeof(winSize));
+    winSize.ws_row = (unsigned short)lines;
+    winSize.ws_col = (unsigned short)columns;
+    return ioctl(d->masterFd, TIOCSWINSZ, (char *)&winSize) == 0;
+}
+
+bool KPty::setEcho(bool echo)
+{
+    struct ::termios ttmode;
+    if (!tcGetAttr(&ttmode))
+        return false;
+    if (!echo)
+        ttmode.c_lflag &= ~ECHO;
+    else
+        ttmode.c_lflag |= ECHO;
+    return tcSetAttr(&ttmode);
+}
+
+const char *KPty::ttyName() const
+{
+    Q_D(const KPty);
+
+    return d->ttyName.data();
+}
+
+int KPty::masterFd() const
+{
+    Q_D(const KPty);
+
+    return d->masterFd;
+}
+
+int KPty::slaveFd() const
+{
+    Q_D(const KPty);
+
+    return d->slaveFd;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kpty.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,205 @@
+/* This file is part of the KDE libraries
+
+    Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kpty_h
+#define kpty_h
+
+#include "kpty_export.h"
+
+struct KPtyPrivate;
+struct termios;
+
+/**
+ * Provides primitives for opening & closing a pseudo TTY pair, assigning the
+ * controlling TTY, utmp registration and setting various terminal attributes.
+ */
+class KPTY_EXPORT KPty {
+    Q_DECLARE_PRIVATE(KPty)
+
+public:
+
+  /**
+   * Constructor
+   */
+  KPty();
+
+  /**
+   * Destructor:
+   *
+   *  If the pty is still open, it will be closed. Note, however, that
+   *  an utmp registration is @em not undone.
+  */
+  ~KPty();
+
+  /**
+   * Create a pty master/slave pair.
+   *
+   * @return true if a pty pair was successfully opened
+   */
+  bool open();
+
+  /**
+   * Open using an existing pty master.
+   *
+   * @param fd an open pty master file descriptor.
+   *   The ownership of the fd remains with the caller;
+   *   it will not be automatically closed at any point.
+   * @return true if a pty pair was successfully opened
+   */
+  bool open(int fd);
+
+  /**
+   * Close the pty master/slave pair.
+   */
+  void close();
+
+  /**
+   * Close the pty slave descriptor.
+   *
+   * When creating the pty, KPty also opens the slave and keeps it open.
+   * Consequently the master will never receive an EOF notification.
+   * Usually this is the desired behavior, as a closed pty slave can be
+   * reopened any time - unlike a pipe or socket. However, in some cases
+   * pipe-alike behavior might be desired.
+   *
+   * After this function was called, slaveFd() and setCTty() cannot be
+   * used.
+   */
+  void closeSlave();
+
+  /**
+   * Open the pty slave descriptor.
+   *
+   * This undoes the effect of closeSlave().
+   *
+   * @return true if the pty slave was successfully opened
+   */
+  bool openSlave();
+
+  /**
+   * Creates a new session and process group and makes this pty the
+   * controlling tty.
+   */
+  void setCTty();
+
+  /**
+   * Creates an utmp entry for the tty.
+   * This function must be called after calling setCTty and
+   * making this pty the stdin.
+   * @param user the user to be logged on
+   * @param remotehost the host from which the login is coming. This is
+   *  @em not the local host. For remote logins it should be the hostname
+   *  of the client. For local logins from inside an X session it should
+   *  be the name of the X display. Otherwise it should be empty.
+   */
+  void login(const char *user = 0, const char *remotehost = 0);
+
+  /**
+   * Removes the utmp entry for this tty.
+   */
+  void logout();
+
+  /**
+   * Wrapper around tcgetattr(3).
+   *
+   * This function can be used only while the PTY is open.
+   * You will need an #include &lt;termios.h&gt; to do anything useful
+   * with it.
+   *
+   * @param ttmode a pointer to a termios structure.
+   *  Note: when declaring ttmode, @c struct @c ::termios must be used -
+   *  without the '::' some version of HP-UX thinks, this declares
+   *  the struct in your class, in your method.
+   * @return @c true on success, false otherwise
+   */
+  bool tcGetAttr(struct ::termios *ttmode) const;
+
+  /**
+   * Wrapper around tcsetattr(3) with mode TCSANOW.
+   *
+   * This function can be used only while the PTY is open.
+   *
+   * @param ttmode a pointer to a termios structure.
+   * @return @c true on success, false otherwise. Note that success means
+   *  that @em at @em least @em one attribute could be set.
+   */
+  bool tcSetAttr(struct ::termios *ttmode);
+
+  /**
+   * Change the logical (screen) size of the pty.
+   * The default is 24 lines by 80 columns.
+   *
+   * This function can be used only while the PTY is open.
+   *
+   * @param lines the number of rows
+   * @param columns the number of columns
+   * @return @c true on success, false otherwise
+   */
+  bool setWinSize(int lines, int columns);
+
+  /**
+   * Set whether the pty should echo input.
+   *
+   * Echo is on by default.
+   * If the output of automatically fed (non-interactive) PTY clients
+   * needs to be parsed, disabling echo often makes it much simpler.
+   *
+   * This function can be used only while the PTY is open.
+   *
+   * @param echo true if input should be echoed.
+   * @return @c true on success, false otherwise
+   */
+  bool setEcho(bool echo);
+
+  /**
+   * @return the name of the slave pty device.
+   *
+   * This function should be called only while the pty is open.
+   */
+  const char *ttyName() const;
+
+  /**
+   * @return the file descriptor of the master pty
+   *
+   * This function should be called only while the pty is open.
+   */
+  int masterFd() const;
+
+  /**
+   * @return the file descriptor of the slave pty
+   *
+   * This function should be called only while the pty slave is open.
+   */
+  int slaveFd() const;
+
+protected:
+  /**
+   * @internal
+   */
+  KPty(KPtyPrivate *d);
+
+  /**
+   * @internal
+   */
+  KPtyPrivate * const d_ptr;
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kpty_export.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,46 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2007 David Faure <faure@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KPTY_EXPORT_H
+#define KPTY_EXPORT_H
+
+/* needed for KDE_EXPORT and KDE_IMPORT macros */
+//#include <kdemacros.h>
+#include <QtCore/qglobal.h>
+#define KDE_EXPORT
+#define KDE_IMPORT
+
+#ifndef KPTY_EXPORT
+# if defined(KDELIBS_STATIC_LIBS)
+   /* No export/import for static libraries */
+#  define KPTY_EXPORT
+# elif defined(MAKE_KDECORE_LIB)
+   /* We are building this library */ 
+#  define KPTY_EXPORT KDE_EXPORT
+# else
+   /* We are using this library */ 
+#  define KPTY_EXPORT KDE_IMPORT
+# endif
+#endif
+
+# ifndef KPTY_EXPORT_DEPRECATED
+#  define KPTY_EXPORT_DEPRECATED KDE_DEPRECATED KPTY_EXPORT
+# endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kpty_p.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,58 @@
+/* This file is part of the KDE libraries
+
+    Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kpty_p_h
+#define kpty_p_h
+
+#include "kpty.h"
+
+//#include <config-pty.h>
+#if defined(Q_OS_MAC)
+#define HAVE_UTIL_H
+#define HAVE_UTMPX
+#define _UTMPX_COMPAT
+#define HAVE_SYS_TIME_H
+#else
+#define HAVE_PTY_H
+#endif
+
+#define HAVE_OPENPTY
+
+#include <QtCore/QByteArray>
+
+struct KPtyPrivate {
+    Q_DECLARE_PUBLIC(KPty)
+
+    KPtyPrivate(KPty* parent);
+    virtual ~KPtyPrivate();
+#ifndef HAVE_OPENPTY
+    bool chownpty(bool grant);
+#endif
+
+    int masterFd;
+    int slaveFd;
+    bool ownMaster:1;
+
+    QByteArray ttyName;
+
+    KPty *q_ptr;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kptydevice.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,616 @@
+/*
+
+   This file is part of the KDE libraries
+   Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
+   Copyright (C) 2010 KDE e.V. <kde-ev-board@kde.org>
+     Author Adriaan de Groot <groot@kde.org>
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "kptydevice.h"
+#include "kpty_p.h"
+
+//#include <config.h>
+//#include <config-pty.h>
+
+#define i18n
+
+#include <QtCore/QSocketNotifier>
+
+//#include <klocale.h>
+
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#if defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
+  // "the other end's output queue size" - kinda braindead, huh?
+# define PTY_BYTES_AVAILABLE TIOCOUTQ
+#elif defined(TIOCINQ)
+  // "our end's input queue size"
+# define PTY_BYTES_AVAILABLE TIOCINQ
+#else
+  // likewise. more generic ioctl (theoretically)
+# define PTY_BYTES_AVAILABLE FIONREAD
+#endif
+
+#define KMAXINT ((int)(~0U >> 1))
+
+/////////////////////////////////////////////////////
+// Helper. Remove when QRingBuffer becomes public. //
+/////////////////////////////////////////////////////
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qlinkedlist.h>
+
+#define CHUNKSIZE 4096
+
+class KRingBuffer
+{
+public:
+    KRingBuffer()
+    {
+        clear();
+    }
+
+    void clear()
+    {
+        buffers.clear();
+        QByteArray tmp;
+        tmp.resize(CHUNKSIZE);
+        buffers << tmp;
+        head = tail = 0;
+        totalSize = 0;
+    }
+
+    inline bool isEmpty() const
+    {
+        return buffers.count() == 1 && !tail;
+    }
+
+    inline int size() const
+    {
+        return totalSize;
+    }
+
+    inline int readSize() const
+    {
+        return (buffers.count() == 1 ? tail : buffers.first().size()) - head;
+    }
+
+    inline const char *readPointer() const
+    {
+        Q_ASSERT(totalSize > 0);
+        return buffers.first().constData() + head;
+    }
+
+    void free(int bytes)
+    {
+        totalSize -= bytes;
+        Q_ASSERT(totalSize >= 0);
+
+        forever {
+            int nbs = readSize();
+
+            if (bytes < nbs) {
+                head += bytes;
+                if (head == tail && buffers.count() == 1) {
+                    buffers.first().resize(CHUNKSIZE);
+                    head = tail = 0;
+                }
+                break;
+            }
+
+            bytes -= nbs;
+            if (buffers.count() == 1) {
+                buffers.first().resize(CHUNKSIZE);
+                head = tail = 0;
+                break;
+            }
+
+            buffers.removeFirst();
+            head = 0;
+        }
+    }
+
+    char *reserve(int bytes)
+    {
+        totalSize += bytes;
+
+        char *ptr;
+        if (tail + bytes <= buffers.last().size()) {
+            ptr = buffers.last().data() + tail;
+            tail += bytes;
+        } else {
+            buffers.last().resize(tail);
+            QByteArray tmp;
+            tmp.resize(qMax(CHUNKSIZE, bytes));
+            ptr = tmp.data();
+            buffers << tmp;
+            tail = bytes;
+        }
+        return ptr;
+    }
+
+    // release a trailing part of the last reservation
+    inline void unreserve(int bytes)
+    {
+        totalSize -= bytes;
+        tail -= bytes;
+    }
+
+    inline void write(const char *data, int len)
+    {
+        memcpy(reserve(len), data, len);
+    }
+
+    // Find the first occurrence of c and return the index after it.
+    // If c is not found until maxLength, maxLength is returned, provided
+    // it is smaller than the buffer size. Otherwise -1 is returned.
+    int indexAfter(char c, int maxLength = KMAXINT) const
+    {
+        int index = 0;
+        int start = head;
+        QLinkedList<QByteArray>::ConstIterator it = buffers.begin();
+        forever {
+            if (!maxLength)
+                return index;
+            if (index == size())
+                return -1;
+            const QByteArray &buf = *it;
+            ++it;
+            int len = qMin((it == buffers.end() ? tail : buf.size()) - start,
+                           maxLength);
+            const char *ptr = buf.data() + start;
+            if (const char *rptr = (const char *)memchr(ptr, c, len))
+                return index + (rptr - ptr) + 1;
+            index += len;
+            maxLength -= len;
+            start = 0;
+        }
+    }
+
+    inline int lineSize(int maxLength = KMAXINT) const
+    {
+        return indexAfter('\n', maxLength);
+    }
+
+    inline bool canReadLine() const
+    {
+        return lineSize() != -1;
+    }
+
+    int read(char *data, int maxLength)
+    {
+        int bytesToRead = qMin(size(), maxLength);
+        int readSoFar = 0;
+        while (readSoFar < bytesToRead) {
+            const char *ptr = readPointer();
+            int bs = qMin(bytesToRead - readSoFar, readSize());
+            memcpy(data + readSoFar, ptr, bs);
+            readSoFar += bs;
+            free(bs);
+        }
+        return readSoFar;
+    }
+
+    int readLine(char *data, int maxLength)
+    {
+        return read(data, lineSize(qMin(maxLength, size())));
+    }
+
+private:
+    QLinkedList<QByteArray> buffers;
+    int head, tail;
+    int totalSize;
+};
+
+//////////////////
+// private data //
+//////////////////
+
+// Lifted from Qt. I don't think they would mind. ;)
+// Re-lift again from Qt whenever a proper replacement for pthread_once appears
+static void qt_ignore_sigpipe()
+{
+    static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0);
+    if (atom.testAndSetRelaxed(0, 1)) {
+        struct sigaction noaction;
+        memset(&noaction, 0, sizeof(noaction));
+        noaction.sa_handler = SIG_IGN;
+        sigaction(SIGPIPE, &noaction, 0);
+    }
+}
+
+#define NO_INTR(ret,func) do { ret = func; } while (ret < 0 && errno == EINTR)
+
+struct KPtyDevicePrivate : public KPtyPrivate {
+    Q_DECLARE_PUBLIC(KPtyDevice)
+
+    KPtyDevicePrivate(KPty* parent) :
+        KPtyPrivate(parent),
+        emittedReadyRead(false), emittedBytesWritten(false),
+        readNotifier(0), writeNotifier(0)
+    {
+    }
+
+    bool _k_canRead();
+    bool _k_canWrite();
+
+    bool doWait(int msecs, bool reading);
+    void finishOpen(QIODevice::OpenMode mode);
+
+    bool emittedReadyRead;
+    bool emittedBytesWritten;
+    QSocketNotifier *readNotifier;
+    QSocketNotifier *writeNotifier;
+    KRingBuffer readBuffer;
+    KRingBuffer writeBuffer;
+};
+
+bool KPtyDevicePrivate::_k_canRead()
+{
+    Q_Q(KPtyDevice);
+    qint64 readBytes = 0;
+
+#ifdef Q_OS_IRIX // this should use a config define, but how to check it?
+    size_t available;
+#else
+    int available;
+#endif
+    if (!::ioctl(q->masterFd(), PTY_BYTES_AVAILABLE, (char *) &available)) {
+#ifdef Q_OS_SOLARIS
+        // A Pty is a STREAMS module, and those can be activated
+        // with 0 bytes available. This happens either when ^C is
+        // pressed, or when an application does an explicit write(a,b,0)
+        // which happens in experiments fairly often. When 0 bytes are
+        // available, you must read those 0 bytes to clear the STREAMS
+        // module, but we don't want to hit the !readBytes case further down.
+        if (!available) {
+            char c;
+            // Read the 0-byte STREAMS message
+            NO_INTR(readBytes, read(q->masterFd(), &c, 0));
+            // Should return 0 bytes read; -1 is error
+            if (readBytes < 0) {
+                readNotifier->setEnabled(false);
+                emit q->readEof();
+                return false;
+            }
+            return true;
+        }
+#endif
+
+        char *ptr = readBuffer.reserve(available);
+#ifdef Q_OS_SOLARIS
+        // Even if available > 0, it is possible for read()
+        // to return 0 on Solaris, due to 0-byte writes in the stream.
+        // Ignore them and keep reading until we hit *some* data.
+        // In Solaris it is possible to have 15 bytes available
+        // and to (say) get 0, 0, 6, 0 and 9 bytes in subsequent reads.
+        // Because the stream is set to O_NONBLOCK in finishOpen(),
+        // an EOF read will return -1.
+        readBytes = 0;
+        while (!readBytes)
+#endif
+        // Useless block braces except in Solaris
+        {
+          NO_INTR(readBytes, read(q->masterFd(), ptr, available));
+        }
+        if (readBytes < 0) {
+            readBuffer.unreserve(available);
+            q->setErrorString(i18n("Error reading from PTY"));
+            return false;
+        }
+        readBuffer.unreserve(available - readBytes); // *should* be a no-op
+    }
+
+    if (!readBytes) {
+        readNotifier->setEnabled(false);
+        emit q->readEof();
+        return false;
+    } else {
+        if (!emittedReadyRead) {
+            emittedReadyRead = true;
+            emit q->readyRead();
+            emittedReadyRead = false;
+        }
+        return true;
+    }
+}
+
+bool KPtyDevicePrivate::_k_canWrite()
+{
+    Q_Q(KPtyDevice);
+
+    writeNotifier->setEnabled(false);
+    if (writeBuffer.isEmpty())
+        return false;
+
+    qt_ignore_sigpipe();
+    int wroteBytes;
+    NO_INTR(wroteBytes,
+            write(q->masterFd(),
+                  writeBuffer.readPointer(), writeBuffer.readSize()));
+    if (wroteBytes < 0) {
+        q->setErrorString(i18n("Error writing to PTY"));
+        return false;
+    }
+    writeBuffer.free(wroteBytes);
+
+    if (!emittedBytesWritten) {
+        emittedBytesWritten = true;
+        emit q->bytesWritten(wroteBytes);
+        emittedBytesWritten = false;
+    }
+
+    if (!writeBuffer.isEmpty())
+        writeNotifier->setEnabled(true);
+    return true;
+}
+
+#ifndef timeradd
+// Lifted from GLIBC
+# define timeradd(a, b, result) \
+    do { \
+        (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
+        (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
+        if ((result)->tv_usec >= 1000000) { \
+            ++(result)->tv_sec; \
+            (result)->tv_usec -= 1000000; \
+        } \
+    } while (0)
+# define timersub(a, b, result) \
+    do { \
+        (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+        (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+        if ((result)->tv_usec < 0) { \
+            --(result)->tv_sec; \
+            (result)->tv_usec += 1000000; \
+        } \
+    } while (0)
+#endif
+
+bool KPtyDevicePrivate::doWait(int msecs, bool reading)
+{
+    Q_Q(KPtyDevice);
+#ifndef __linux__
+    struct timeval etv;
+#endif
+    struct timeval tv, *tvp;
+
+    if (msecs < 0)
+        tvp = 0;
+    else {
+        tv.tv_sec = msecs / 1000;
+        tv.tv_usec = (msecs % 1000) * 1000;
+#ifndef __linux__
+        gettimeofday(&etv, 0);
+        timeradd(&tv, &etv, &etv);
+#endif
+        tvp = &tv;
+    }
+
+    while (reading ? readNotifier->isEnabled() : !writeBuffer.isEmpty()) {
+        fd_set rfds;
+        fd_set wfds;
+
+        FD_ZERO(&rfds);
+        FD_ZERO(&wfds);
+
+        if (readNotifier->isEnabled())
+            FD_SET(q->masterFd(), &rfds);
+        if (!writeBuffer.isEmpty())
+            FD_SET(q->masterFd(), &wfds);
+
+#ifndef __linux__
+        if (tvp) {
+            gettimeofday(&tv, 0);
+            timersub(&etv, &tv, &tv);
+            if (tv.tv_sec < 0)
+                tv.tv_sec = tv.tv_usec = 0;
+        }
+#endif
+
+        switch (select(q->masterFd() + 1, &rfds, &wfds, 0, tvp)) {
+        case -1:
+            if (errno == EINTR)
+                break;
+            return false;
+        case 0:
+            q->setErrorString(i18n("PTY operation timed out"));
+            return false;
+        default:
+            if (FD_ISSET(q->masterFd(), &rfds)) {
+                bool canRead = _k_canRead();
+                if (reading && canRead)
+                    return true;
+            }
+            if (FD_ISSET(q->masterFd(), &wfds)) {
+                bool canWrite = _k_canWrite();
+                if (!reading)
+                    return canWrite;
+            }
+            break;
+        }
+    }
+    return false;
+}
+
+void KPtyDevicePrivate::finishOpen(QIODevice::OpenMode mode)
+{
+    Q_Q(KPtyDevice);
+
+    q->QIODevice::open(mode);
+    fcntl(q->masterFd(), F_SETFL, O_NONBLOCK);
+    readBuffer.clear();
+    readNotifier = new QSocketNotifier(q->masterFd(), QSocketNotifier::Read, q);
+    writeNotifier = new QSocketNotifier(q->masterFd(), QSocketNotifier::Write, q);
+    QObject::connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_k_canRead()));
+    QObject::connect(writeNotifier, SIGNAL(activated(int)), q, SLOT(_k_canWrite()));
+    readNotifier->setEnabled(true);
+}
+
+/////////////////////////////
+// public member functions //
+/////////////////////////////
+
+KPtyDevice::KPtyDevice(QObject *parent) :
+    QIODevice(parent),
+    KPty(new KPtyDevicePrivate(this))
+{
+}
+
+KPtyDevice::~KPtyDevice()
+{
+    close();
+}
+
+bool KPtyDevice::open(OpenMode mode)
+{
+    Q_D(KPtyDevice);
+
+    if (masterFd() >= 0)
+        return true;
+
+    if (!KPty::open()) {
+        setErrorString(i18n("Error opening PTY"));
+        return false;
+    }
+
+    d->finishOpen(mode);
+
+    return true;
+}
+
+bool KPtyDevice::open(int fd, OpenMode mode)
+{
+    Q_D(KPtyDevice);
+
+    if (!KPty::open(fd)) {
+        setErrorString(i18n("Error opening PTY"));
+        return false;
+    }
+
+    d->finishOpen(mode);
+
+    return true;
+}
+
+void KPtyDevice::close()
+{
+    Q_D(KPtyDevice);
+
+    if (masterFd() < 0)
+        return;
+
+    delete d->readNotifier;
+    delete d->writeNotifier;
+
+    QIODevice::close();
+
+    KPty::close();
+}
+
+bool KPtyDevice::isSequential() const
+{
+    return true;
+}
+
+bool KPtyDevice::canReadLine() const
+{
+    Q_D(const KPtyDevice);
+    return QIODevice::canReadLine() || d->readBuffer.canReadLine();
+}
+
+bool KPtyDevice::atEnd() const
+{
+    Q_D(const KPtyDevice);
+    return QIODevice::atEnd() && d->readBuffer.isEmpty();
+}
+
+qint64 KPtyDevice::bytesAvailable() const
+{
+    Q_D(const KPtyDevice);
+    return QIODevice::bytesAvailable() + d->readBuffer.size();
+}
+
+qint64 KPtyDevice::bytesToWrite() const
+{
+    Q_D(const KPtyDevice);
+    return d->writeBuffer.size();
+}
+
+bool KPtyDevice::waitForReadyRead(int msecs)
+{
+    Q_D(KPtyDevice);
+    return d->doWait(msecs, true);
+}
+
+bool KPtyDevice::waitForBytesWritten(int msecs)
+{
+    Q_D(KPtyDevice);
+    return d->doWait(msecs, false);
+}
+
+void KPtyDevice::setSuspended(bool suspended)
+{
+    Q_D(KPtyDevice);
+    d->readNotifier->setEnabled(!suspended);
+}
+
+bool KPtyDevice::isSuspended() const
+{
+    Q_D(const KPtyDevice);
+    return !d->readNotifier->isEnabled();
+}
+
+// protected
+qint64 KPtyDevice::readData(char *data, qint64 maxlen)
+{
+    Q_D(KPtyDevice);
+    return d->readBuffer.read(data, (int)qMin<qint64>(maxlen, KMAXINT));
+}
+
+// protected
+qint64 KPtyDevice::readLineData(char *data, qint64 maxlen)
+{
+    Q_D(KPtyDevice);
+    return d->readBuffer.readLine(data, (int)qMin<qint64>(maxlen, KMAXINT));
+}
+
+// protected
+qint64 KPtyDevice::writeData(const char *data, qint64 len)
+{
+    Q_D(KPtyDevice);
+    Q_ASSERT(len <= KMAXINT);
+
+    d->writeBuffer.write(data, len);
+    d->writeNotifier->setEnabled(true);
+    return len;
+}
+
+#include "kptydevice.moc"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kptydevice.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,156 @@
+/* This file is part of the KDE libraries
+
+    Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kptydev_h
+#define kptydev_h
+
+#include "kpty.h"
+
+#include <QtCore/QIODevice>
+
+struct KPtyDevicePrivate;
+
+#define Q_DECLARE_PRIVATE_MI(Class, SuperClass) \
+    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(SuperClass::d_ptr); } \
+    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(SuperClass::d_ptr); } \
+    friend class Class##Private;
+
+/**
+ * Encapsulates KPty into a QIODevice, so it can be used with Q*Stream, etc.
+ */
+class KPTY_EXPORT KPtyDevice : public QIODevice, public KPty { //krazy:exclude=dpointer (via macro)
+    Q_OBJECT
+    Q_DECLARE_PRIVATE_MI(KPtyDevice, KPty)
+
+public:
+
+    /**
+     * Constructor
+     */
+    KPtyDevice(QObject *parent = 0);
+
+    /**
+     * Destructor:
+     *
+     *  If the pty is still open, it will be closed. Note, however, that
+     *  an utmp registration is @em not undone.
+     */
+    virtual ~KPtyDevice();
+
+    /**
+     * Create a pty master/slave pair.
+     *
+     * @return true if a pty pair was successfully opened
+     */
+    virtual bool open(OpenMode mode = ReadWrite | Unbuffered);
+
+    /**
+     * Open using an existing pty master. The ownership of the fd
+     * remains with the caller, i.e., close() will not close the fd.
+     *
+     * This is useful if you wish to attach a secondary "controller" to an
+     * existing pty device such as a terminal widget.
+     * Note that you will need to use setSuspended() on both devices to
+     * control which one gets the incoming data from the pty.
+     *
+     * @param fd an open pty master file descriptor.
+     * @param mode the device mode to open the pty with.
+     * @return true if a pty pair was successfully opened
+     */
+    bool open(int fd, OpenMode mode = ReadWrite | Unbuffered);
+
+    /**
+     * Close the pty master/slave pair.
+     */
+    virtual void close();
+
+    /**
+     * Sets whether the KPtyDevice monitors the pty for incoming data.
+     *
+     * When the KPtyDevice is suspended, it will no longer attempt to buffer
+     * data that becomes available from the pty and it will not emit any
+     * signals.
+     *
+     * Do not use on closed ptys.
+     * After a call to open(), the pty is not suspended. If you need to
+     * ensure that no data is read, call this function before the main loop
+     * is entered again (i.e., immediately after opening the pty).
+     */
+    void setSuspended(bool suspended);
+
+    /**
+     * Returns true if the KPtyDevice is not monitoring the pty for incoming
+     * data.
+     *
+     * Do not use on closed ptys.
+     *
+     * See setSuspended()
+     */
+    bool isSuspended() const;
+
+    /**
+     * @return always true
+     */
+    virtual bool isSequential() const;
+
+    /**
+     * @reimp
+     */
+    bool canReadLine() const;
+
+    /**
+     * @reimp
+     */
+    bool atEnd() const;
+
+    /**
+     * @reimp
+     */
+    qint64 bytesAvailable() const;
+
+    /**
+     * @reimp
+     */
+    qint64 bytesToWrite() const;
+
+    bool waitForBytesWritten(int msecs = -1);
+    bool waitForReadyRead(int msecs = -1);
+
+
+Q_SIGNALS:
+    /**
+     * Emitted when EOF is read from the PTY.
+     *
+     * Data may still remain in the buffers.
+     */
+    void readEof();
+
+protected:
+    virtual qint64 readData(char *data, qint64 maxSize);
+    virtual qint64 readLineData(char *data, qint64 maxSize);
+    virtual qint64 writeData(const char *data, qint64 maxSize);
+
+private:
+    Q_PRIVATE_SLOT(d_func(), bool _k_canRead())
+    Q_PRIVATE_SLOT(d_func(), bool _k_canWrite())
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kptyprocess.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,141 @@
+/*
+    This file is part of the KDE libraries
+
+    Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+
+#include "kptyprocess.h"
+#include "kprocess_p.h"
+
+//#include <kuser.h>
+#include "kptydevice.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+//////////////////
+// private data //
+//////////////////
+
+struct KPtyProcessPrivate : KProcessPrivate {
+    KPtyProcessPrivate() :
+        ptyChannels(KPtyProcess::NoChannels),
+        addUtmp(false)
+    {
+    }
+
+    void _k_onStateChanged(QProcess::ProcessState newState)
+    {
+        if (newState == QProcess::NotRunning && addUtmp)
+            pty->logout();
+    }
+
+    KPtyDevice *pty;
+    KPtyProcess::PtyChannels ptyChannels;
+    bool addUtmp : 1;
+};
+
+KPtyProcess::KPtyProcess(QObject *parent) :
+    KProcess(new KPtyProcessPrivate, parent)
+{
+    Q_D(KPtyProcess);
+
+    d->pty = new KPtyDevice(this);
+    d->pty->open();
+    connect(this, SIGNAL(stateChanged(QProcess::ProcessState)),
+            SLOT(_k_onStateChanged(QProcess::ProcessState)));
+}
+
+KPtyProcess::KPtyProcess(int ptyMasterFd, QObject *parent) :
+    KProcess(new KPtyProcessPrivate, parent)
+{
+    Q_D(KPtyProcess);
+
+    d->pty = new KPtyDevice(this);
+    d->pty->open(ptyMasterFd);
+    connect(this, SIGNAL(stateChanged(QProcess::ProcessState)),
+            SLOT(_k_onStateChanged(QProcess::ProcessState)));
+}
+
+KPtyProcess::~KPtyProcess()
+{
+    Q_D(KPtyProcess);
+
+    if (state() != QProcess::NotRunning && d->addUtmp) {
+        d->pty->logout();
+        disconnect(SIGNAL(stateChanged(QProcess::ProcessState)),
+                   this, SLOT(_k_onStateChanged(QProcess::ProcessState)));
+    }
+    delete d->pty;
+}
+
+void KPtyProcess::setPtyChannels(PtyChannels channels)
+{
+    Q_D(KPtyProcess);
+
+    d->ptyChannels = channels;
+}
+
+KPtyProcess::PtyChannels KPtyProcess::ptyChannels() const
+{
+    Q_D(const KPtyProcess);
+
+    return d->ptyChannels;
+}
+
+void KPtyProcess::setUseUtmp(bool value)
+{
+    Q_D(KPtyProcess);
+
+    d->addUtmp = value;
+}
+
+bool KPtyProcess::isUseUtmp() const
+{
+    Q_D(const KPtyProcess);
+
+    return d->addUtmp;
+}
+
+KPtyDevice *KPtyProcess::pty() const
+{
+    Q_D(const KPtyProcess);
+
+    return d->pty;
+}
+
+void KPtyProcess::setupChildProcess()
+{
+    Q_D(KPtyProcess);
+
+    d->pty->setCTty();
+    if (d->addUtmp)
+      d->pty->login(getenv("USER"), getenv("DISPLAY"));
+      //d->pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().data(), qgetenv("DISPLAY"));
+    if (d->ptyChannels & StdinChannel)
+        dup2(d->pty->slaveFd(), 0);
+    if (d->ptyChannels & StdoutChannel)
+        dup2(d->pty->slaveFd(), 1);
+    if (d->ptyChannels & StderrChannel)
+        dup2(d->pty->slaveFd(), 2);
+
+    KProcess::setupChildProcess();
+}
+
+#include "kptyprocess.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/kptyprocess.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,139 @@
+/*
+    This file is part of the KDE libraries
+
+    Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KPTYPROCESS_H
+#define KPTYPROCESS_H
+
+#include "kprocess.h"
+
+#include "kpty_export.h"
+
+class KPtyDevice;
+
+struct KPtyProcessPrivate;
+
+/**
+ * This class extends KProcess by support for PTYs (pseudo TTYs).
+ *
+ * The PTY is opened as soon as the class is instantiated. Verify that
+ * it was opened successfully by checking that pty()->masterFd() is not -1.
+ *
+ * The PTY is always made the process' controlling TTY.
+ * Utmp registration and connecting the stdio handles to the PTY are optional.
+ *
+ * No attempt to integrate with QProcess' waitFor*() functions was made,
+ * for it is impossible. Note that execute() does not work with the PTY, too.
+ * Use the PTY device's waitFor*() functions or use it asynchronously.
+ *
+ * @author Oswald Buddenhagen <ossi@kde.org>
+ */
+class KPTY_EXPORT KPtyProcess : public KProcess
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(KPtyProcess)
+
+public:
+    enum PtyChannelFlag {
+        NoChannels = 0, /**< The PTY is not connected to any channel. */
+        StdinChannel = 1, /**< Connect PTY to stdin. */
+        StdoutChannel = 2, /**< Connect PTY to stdout. */
+        StderrChannel = 4, /**< Connect PTY to stderr. */
+        AllOutputChannels = 6, /**< Connect PTY to all output channels. */
+        AllChannels = 7 /**< Connect PTY to all channels. */
+    };
+
+    Q_DECLARE_FLAGS(PtyChannels, PtyChannelFlag)
+
+    /**
+     * Constructor
+     */
+    explicit KPtyProcess(QObject *parent = 0);
+
+    /**
+     * Construct a process using an open pty master.
+     *
+     * @param ptyMasterFd an open pty master file descriptor.
+     *   The process does not take ownership of the descriptor;
+     *   it will not be automatically closed at any point.
+     */
+    KPtyProcess(int ptyMasterFd, QObject *parent = 0);
+
+    /**
+     * Destructor
+     */
+    virtual ~KPtyProcess();
+
+    /**
+     * Set to which channels the PTY should be assigned.
+     *
+     * This function must be called before starting the process.
+     *
+     * @param channels the output channel handling mode
+     */
+    void setPtyChannels(PtyChannels channels);
+
+    /**
+     * Query to which channels the PTY is assigned.
+     *
+     * @return the output channel handling mode
+     */
+    PtyChannels ptyChannels() const;
+
+    /**
+     * Set whether to register the process as a TTY login in utmp.
+     *
+     * Utmp is disabled by default.
+     * It should enabled for interactively fed processes, like terminal
+     * emulations.
+     *
+     * This function must be called before starting the process.
+     *
+     * @param value whether to register in utmp.
+     */
+    void setUseUtmp(bool value);
+
+    /**
+     * Get whether to register the process as a TTY login in utmp.
+     *
+     * @return whether to register in utmp
+     */
+    bool isUseUtmp() const;
+
+    /**
+     * Get the PTY device of this process.
+     *
+     * @return the PTY device
+     */
+    KPtyDevice *pty() const;
+
+protected:
+    /**
+     * @reimp
+     */
+    virtual void setupChildProcess();
+
+private:
+    Q_PRIVATE_SLOT(d_func(), void _k_onStateChanged(QProcess::ProcessState))
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(KPtyProcess::PtyChannels)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/main.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,188 @@
+/*
+    Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
+
+    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 "Application.h"
+#include "MainWindow.h"
+#include <KDebug>
+
+// Unix
+#include <unistd.h>
+
+// KDE
+#include <KAboutData>
+#include <KCmdLineArgs>
+#include <KLocale>
+
+#define KONSOLE_VERSION "2.6.999"
+
+using namespace Konsole;
+
+// fills the KAboutData structure with information about contributors to 
+// Konsole
+void fillAboutData(KAboutData& aboutData);
+void fillCommandLineOptions(KCmdLineOptions& options);
+bool forceNewProcess();     // returns true if new instance should use a new
+                            // process (instead of re-using an existing one)
+void restoreSession(Application& app);
+
+// ***
+// Entry point into the Konsole terminal application.  
+// ***
+extern "C" int KDE_EXPORT kdemain(int argc,char** argv)
+{
+    KAboutData about(   "konsole", 0,
+                        ki18n("Konsole"),
+                        KONSOLE_VERSION,
+                        ki18n("Terminal emulator"),
+                        KAboutData::License_GPL_V2
+                    );
+    fillAboutData(about);
+
+    KCmdLineArgs::init(argc,argv,&about);
+    KCmdLineOptions options;
+    fillCommandLineOptions(options);
+    KCmdLineArgs::addCmdLineOptions(options);
+    KUniqueApplication::addCmdLineOptions();
+
+    KUniqueApplication::StartFlags startFlags;
+    if (forceNewProcess())
+        startFlags = KUniqueApplication::NonUniqueInstance;
+
+    // create a new application instance if there are no running Konsole instances,
+    // otherwise inform the existing Konsole process and exit
+    if ( !KUniqueApplication::start(startFlags) )
+    {
+        exit(0);
+    }
+    
+    Application app;
+    restoreSession(app);
+    return app.exec();
+}
+bool forceNewProcess()
+{
+    // when starting Konsole from a terminal, a new process must be used 
+    // so that the current environment is propagated into the shells of the new
+    // Konsole and any debug output or warnings from Konsole are written to
+    // the current terminal
+    KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+    return isatty(1) && !args->isSet("new-tab");
+}
+
+void fillCommandLineOptions(KCmdLineOptions& options)
+{
+    options.add("profile <file>", ki18n("Name of profile to use for new Konsole instance"));
+    options.add("list-profiles", ki18n("List the available profiles"));
+    // TODO - Update this when F12 is no longer hard coded
+    options.add("background-mode", ki18n("Start Konsole in the background"
+                                    " and bring to the front when the F12"
+                                    " key is pressed"));
+    options.add("new-tab",ki18n("Create a new tab in an existing window rather than creating a new window"));
+    options.add("tabs-from-file <file>", ki18n("Create tabs as specified in given tabs configuration file"));
+    options.add("workdir <dir>",   ki18n("Set the initial working directory of the new tab "
+                                           "or window to 'dir'"));
+    options.add("notransparency",ki18n("Disable transparent backgrounds, even if the system supports them."));
+    options.add("force-transparency",ki18n("Try to enable transparency, even if the system does not appear to support it."));
+    options.add("hold");
+    options.add("noclose",ki18n("Do not close the initial session automatically when it ends."));
+    // TODO - Document this option more clearly
+    options.add("p <property=value>",ki18n("Change the value of a profile property."));
+    options.add("!e <cmd>",ki18n("Command to execute"));
+    options.add("+[args]",ki18n("Arguments passed to command"));
+}
+
+void fillAboutData(KAboutData& aboutData)
+{
+  aboutData.addAuthor(ki18n("Robert Knight"),ki18n("Maintainer"), "robertknight@gmail.com");
+  aboutData.addAuthor(ki18n("Lars Doelle"),ki18n("Author"), "lars.doelle@on-line.de");
+  aboutData.addCredit(ki18n("Kurt V. Hindenburg"),
+    ki18n("Bug fixes and general improvements"), 
+    "kurt.hindenburg@gmail.com");
+  aboutData.addCredit(ki18n("Waldo Bastian"),
+    ki18n("Bug fixes and general improvements"),
+    "bastian@kde.org");
+  aboutData.addCredit(ki18n("Stephan Binner"),
+    ki18n("Bug fixes and general improvements"),
+    "binner@kde.org");
+  aboutData.addCredit(ki18n("Thomas Dreibholz"),
+    ki18n("General improvements"),
+    "dreibh@iem.uni-due.de");
+  aboutData.addCredit(ki18n("Chris Machemer"),
+    ki18n("Bug fixes"),
+    "machey@ceinetworks.com");
+  aboutData.addCredit(ki18n("Stephan Kulow"),
+    ki18n("Solaris support and history"),
+    "coolo@kde.org");
+  aboutData.addCredit(ki18n("Alexander Neundorf"),
+    ki18n("Bug fixes and improved startup performance"),
+    "neundorf@kde.org");
+  aboutData.addCredit(ki18n("Peter Silva"),
+    ki18n("Marking improvements"),
+    "Peter.A.Silva@gmail.com");
+  aboutData.addCredit(ki18n("Lotzi Boloni"),
+    ki18n("Embedded Konsole\n"
+    "Toolbar and session names"),
+    "boloni@cs.purdue.edu");
+  aboutData.addCredit(ki18n("David Faure"),
+    ki18n("Embedded Konsole\n"
+    "General improvements"),
+    "faure@kde.org");
+  aboutData.addCredit(ki18n("Antonio Larrosa"),
+    ki18n("Visual effects"),
+    "larrosa@kde.org");
+  aboutData.addCredit(ki18n("Matthias Ettrich"),
+    ki18n("Code from the kvt project\n"
+    "General improvements"),
+    "ettrich@kde.org");
+  aboutData.addCredit(ki18n("Warwick Allison"),
+    ki18n("Schema and text selection improvements"),
+    "warwick@troll.no");
+  aboutData.addCredit(ki18n("Dan Pilone"),
+    ki18n("SGI port"),
+    "pilone@slac.com");
+  aboutData.addCredit(ki18n("Kevin Street"),
+    ki18n("FreeBSD port"),
+    "street@iname.com");
+  aboutData.addCredit(ki18n("Sven Fischer"),
+    ki18n("Bug fixes"),
+    "herpes@kawo2.renditionwth-aachen.de");
+  aboutData.addCredit(ki18n("Dale M. Flaven"),
+    ki18n("Bug fixes"),
+    "dflaven@netport.com");
+  aboutData.addCredit(ki18n("Martin Jones"),
+    ki18n("Bug fixes"),
+    "mjones@powerup.com.au");
+  aboutData.addCredit(ki18n("Lars Knoll"),
+    ki18n("Bug fixes"),
+    "knoll@mpi-hd.mpg.de");
+  aboutData.addCredit(ki18n("Thanks to many others.\n"));
+  aboutData.setProgramIconName("utilities-terminal");
+}
+
+void restoreSession(Application& app)
+{
+    if (app.isSessionRestored())
+    {
+        int n = 1;
+        while (KMainWindow::canBeRestored(n))
+            app.newMainWindow()->restore(n++);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/qtermwidget.cpp	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,233 @@
+/*  Copyright (C) 2008 e_k (e_k@users.sourceforge.net)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+		
+    This library 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
+    Library General Public License for more details.
+				
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+						
+
+#include "qtermwidget.h"
+
+#include "Session.h"
+#include "TerminalDisplay.h"
+
+using namespace Konsole;
+
+void *createTermWidget(int startnow, void *parent)
+{ 
+    return (void*) new QTermWidget(startnow, (QWidget*)parent); 
+}
+
+struct TermWidgetImpl
+{
+    TermWidgetImpl(QWidget* parent = 0);
+
+    TerminalDisplay *m_terminalDisplay;
+    Session *m_session;
+    
+    Session* createSession();
+    TerminalDisplay* createTerminalDisplay(Session *session, QWidget* parent);
+};
+
+TermWidgetImpl::TermWidgetImpl(QWidget* parent)
+{
+    this->m_session = createSession();
+    this->m_terminalDisplay = createTerminalDisplay(this->m_session, parent);
+}
+
+
+Session *TermWidgetImpl::createSession()
+{
+    Session *session = new Session();
+
+    session->setTitle(Session::NameRole, "QTermWidget");
+    session->setProgram("/bin/bash");
+    QStringList args("");
+    session->setArguments(args);
+    session->setAutoClose(true);
+		    
+    session->setCodec(QTextCodec::codecForName("UTF-8"));
+			
+    session->setFlowControlEnabled(true);
+    session->setHistoryType(HistoryTypeBuffer(1000));
+    
+    session->setDarkBackground(true);
+	    
+    session->setKeyBindings("");	    
+    return session;
+}
+
+TerminalDisplay *TermWidgetImpl::createTerminalDisplay(Session *session, QWidget* parent)
+{
+//    TerminalDisplay* display = new TerminalDisplay(this);
+    TerminalDisplay* display = new TerminalDisplay(parent);
+    
+    display->setBellMode(TerminalDisplay::NotifyBell);
+    display->setTerminalSizeHint(true);
+    display->setTripleClickMode(TerminalDisplay::SelectWholeLine);
+    display->setTerminalSizeStartup(true);
+
+    display->setRandomSeed(session->sessionId() * 31);
+    
+    return display;
+}
+
+
+QTermWidget::QTermWidget(int startnow, QWidget *parent)
+:QWidget(parent)
+{
+    m_impl = new TermWidgetImpl(this);
+    
+    init();
+
+    if (startnow && m_impl->m_session) {
+	m_impl->m_session->run();
+    }
+    
+    this->setFocus( Qt::OtherFocusReason );
+    m_impl->m_terminalDisplay->resize(this->size());
+    
+    this->setFocusProxy(m_impl->m_terminalDisplay);
+}
+
+void QTermWidget::startShellProgram()
+{
+    if ( m_impl->m_session->isRunning() )
+	return;
+	
+    m_impl->m_session->run();
+}
+
+void QTermWidget::openTeletype(int fd)
+{
+  if ( m_impl->m_session->isRunning() )
+    return;
+	
+  m_impl->m_session->openTeletype(fd);
+}
+
+void QTermWidget::init()
+{    
+    m_impl->m_terminalDisplay->setSize(80, 40);
+    
+    QFont font = QApplication::font(); 
+    font.setFamily("Monospace");
+    font.setPointSize(10);
+    font.setStyleHint(QFont::TypeWriter);
+    setTerminalFont(font);
+    setScrollBarPosition(NoScrollBar);    
+        
+    m_impl->m_session->addView(m_impl->m_terminalDisplay);
+    
+    connect(m_impl->m_session, SIGNAL(finished()), this, SLOT(sessionFinished()));
+}
+
+
+QTermWidget::~QTermWidget()
+{
+    emit destroyed();
+}
+
+
+void QTermWidget::setTerminalFont(QFont &font)
+{
+    if (!m_impl->m_terminalDisplay)
+	return;
+    m_impl->m_terminalDisplay->setVTFont(font);
+}
+
+void QTermWidget::setShellProgram(QString &progname)
+{
+    if (!m_impl->m_session)
+	return;
+    m_impl->m_session->setProgram(progname);	
+}
+
+void QTermWidget::setArgs(QStringList &args)
+{
+    if (!m_impl->m_session)
+	return;
+    m_impl->m_session->setArguments(args);	
+}
+
+void QTermWidget::setTextCodec(QTextCodec *codec)
+{
+    if (!m_impl->m_session)
+	return;
+    m_impl->m_session->setCodec(codec);	
+}
+
+void QTermWidget::setColorScheme(int scheme)
+{
+  // TODO: Fix later when color schemes are more important
+  /*
+    switch(scheme) {
+	case COLOR_SCHEME_WHITE_ON_BLACK:
+		m_impl->m_terminalDisplay->setColorTable(whiteonblack_color_table);
+		break;		
+	case COLOR_SCHEME_GREEN_ON_BLACK:
+		m_impl->m_terminalDisplay->setColorTable(greenonblack_color_table);
+		break;
+	case COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW:
+		m_impl->m_terminalDisplay->setColorTable(blackonlightyellow_color_table);
+		break;
+	default: //do nothing
+	    break;
+    };
+  */
+}
+
+void QTermWidget::setSize(int h, int v)
+{
+    if (!m_impl->m_terminalDisplay)
+	return;
+    m_impl->m_terminalDisplay->setSize(h, v);
+}
+
+void QTermWidget::setHistorySize(int lines)
+{
+    if (lines < 0)
+        m_impl->m_session->setHistoryType(HistoryTypeFile());
+    else
+	m_impl->m_session->setHistoryType(HistoryTypeBuffer(lines));
+}
+
+void QTermWidget::setScrollBarPosition(ScrollBarPosition pos)
+{
+    if (!m_impl->m_terminalDisplay)
+	return;
+    m_impl->m_terminalDisplay->setScrollBarPosition((TerminalDisplay::ScrollBarPosition)pos);
+}
+
+void QTermWidget::sendText(QString &text)
+{
+    m_impl->m_session->sendText(text); 
+}
+
+void QTermWidget::resizeEvent(QResizeEvent*)
+{
+//qDebug("global window resizing...with %d %d", this->size().width(), this->size().height());
+    m_impl->m_terminalDisplay->resize(this->size());
+}
+
+
+
+void QTermWidget::sessionFinished()
+{
+    emit finished();
+}
+
+#include "qtermwidget.moc"
+//#include "moc_consoleq.cpp"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/konsole/qtermwidget.h	Sun Jan 22 14:18:05 2012 +0100
@@ -0,0 +1,110 @@
+/*  Copyright (C) 2008 e_k (e_k@users.sourceforge.net)
+    
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+		    
+    This library 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
+    Library General Public License for more details.
+			    
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+						    
+
+#ifndef _Q_TERM_WIDGET
+#define _Q_TERM_WIDGET
+
+#include <QtGui>
+
+struct TermWidgetImpl;
+
+enum COLOR_SCHEME {     COLOR_SCHEME_WHITE_ON_BLACK	= 1,
+		        COLOR_SCHEME_GREEN_ON_BLACK,
+		        COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW };
+
+class QTermWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    
+    enum ScrollBarPosition
+    {
+        /** Do not show the scroll bar. */
+        NoScrollBar=0,
+        /** Show the scroll bar on the left side of the display. */
+        ScrollBarLeft=1,
+        /** Show the scroll bar on the right side of the display. */
+        ScrollBarRight=2
+    };
+
+
+    //Creation of widget
+    QTermWidget(int startnow = 1, //start shell programm immediatelly
+		QWidget *parent = 0);
+    ~QTermWidget();
+
+    //start shell program if it was not started in constructor
+    void startShellProgram();
+    
+    void openTeletype(int fd);
+
+    //look-n-feel, if you don`t like defaults
+
+    //	Terminal font
+    // Default is application font with family Monospace, size 10
+    void setTerminalFont(QFont &font); 
+    
+    //	Shell program, default is /bin/bash
+    void setShellProgram(QString &progname);
+    
+    // Shell program args, default is none
+    void setArgs(QStringList &args);
+    
+    //Text codec, default is UTF-8
+    void setTextCodec(QTextCodec *codec);
+
+    //Color scheme, default is white on black
+    void setColorScheme(int scheme);
+    
+    //set size
+    void setSize(int h, int v);
+    
+    // History size for scrolling 
+    void setHistorySize(int lines); //infinite if lines < 0
+
+    // Presence of scrollbar
+    void setScrollBarPosition(ScrollBarPosition);
+    
+    // Send some text to terminal
+    void sendText(QString &text);
+            
+signals:
+    void finished();
+        
+protected: 
+    virtual void resizeEvent(QResizeEvent *);
+    
+protected slots:
+    void sessionFinished();        
+    
+private:
+    void init();    
+    TermWidgetImpl *m_impl;
+};
+
+
+//Maybe useful, maybe not
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void *createTermWidget(int startnow, void *parent); 
+
+#endif
+
--- a/gui/qtermwidget/AUTHORS	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-e_k@users.sourceforge.net
\ No newline at end of file
--- a/gui/qtermwidget/COPYING	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
--- a/gui/qtermwidget/CVS/Entries	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-/AUTHORS/1.1.1.1/Sat May 10 21:27:49 2008//
-/COPYING/1.1.1.1/Sat May 10 21:27:49 2008//
-/INSTALL/1.1.1.1/Sat May 10 21:27:49 2008//
-/TODO/1.2/Tue May 27 08:34:53 2008//
-/qtermwidget.pro/1.1.1.1/Sat May 10 21:27:49 2008//
-D/lib////
-D/src////
-/Changelog/1.1/Wed Jul 30 22:06:01 2008//
-/README/1.3/Wed Jul 30 22:01:01 2008//
--- a/gui/qtermwidget/CVS/Repository	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-qtermwidget
--- a/gui/qtermwidget/CVS/Root	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-:ext:e_k@qtermwidget.cvs.sourceforge.net:/cvsroot/qtermwidget
--- a/gui/qtermwidget/Changelog	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-31.07.2008
-Interface class from c-style conversions rewritten with pimpl support.
-
-
-16.07.2008 
-Added optional scrollbar 
-
-
-06.06.2008 
-Some artefacts were removed, some added...
-Also added support for color schemes, and 3 color schemes provided (classical - white on black, green on black, black on light yellow). Is it enough or not? 
-
-
-26.05.2008 
-Added file release as an archive with source code. But preferrable way is still getting code from CVS, cause file release can be outdated. 
-
-
-11.05.2008 
-Initial CVS import - first version comes with number 0.0.1
\ No newline at end of file
--- a/gui/qtermwidget/INSTALL	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-Requirements
-============
-Created with QT4.3.4
-Tested with QT4.3.2
-Maybe should work with other QT4 versions
-
-Basic Installation
-==================
-    
-    These are generic installation instructions.
-
-    There is no 'configure' shell script, `cause this package is just 
-a draft. And it intended for developers rather then for end-users.  
-There is a  'qtermwidget.pro'  file  provided instead. 
-This file is used for generating Makefiles in each appropriate 
-directory via 'qmake' program.
-
-The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `qmake'.
-
-  2. Type `make' to compile the package.
-
-  3. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  
-
-  4. You can remove generated Makefiles form the directory 
-     by typing `make distclean'.  
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking. You can
-provide additional options by modifying the appropriate *.pro files
-according to qmake manual.
-
-Installation
-==================
-   Installation not defined yet.
-
--- a/gui/qtermwidget/README	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-QTermWidget
-version 0.1.0
-
-QTermWidget is an opensource project based on KDE4 Konsole application.
-The main goal of this project is to provide unicode-enabled, embeddable
-QT widget for using as a built-in console (or terminal emulation widget).
-
-Of course I`m aware about embedding abilities of original Konsole,
-but once I had Qt without KDE, and it was a serious obstacle.
-I decided not to rely on a chance. I cannot find any interesting related project,
-so I had to write it.
-
-The original Konsole`s code was rewritten entirely with QT4 only; also I have to
-include in the project some parts of code from kde core library. All code dealing
-with user interface parts and session managers was removed (maybe later I bring it
-back somehow), and the result is quite useful, I suppose.
-
-This library was compiled and tested on three linux systems,
-based on 2.4.32, 2.6.20, 2.6.23 kernels, x86 and amd64.
-Please inform about its behaviour on other systems.
-
--- a/gui/qtermwidget/TODO	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-Global
- - provide more compatibility for vttest
-
-Package
- - migrate to autotools if needed
-
-Source
- - provide more options for customization
- - clean unused code
- - add some QT3 support features if needed
--- a/gui/qtermwidget/lib/BlockArray.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,337 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
-
-    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 "BlockArray.h"
-
-#include <QtCore>
-
-// System
-#include <assert.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <stdio.h>
-
-
-using namespace Konsole;
-
-static int blocksize = 0;
-
-BlockArray::BlockArray()
-    : size(0),
-      current(size_t(-1)),
-      index(size_t(-1)),
-      lastmap(0),
-      lastmap_index(size_t(-1)),
-      lastblock(0), ion(-1),
-      length(0)
-{
-    // lastmap_index = index = current = size_t(-1);
-    if (blocksize == 0)
-        blocksize = ((sizeof(Block) / getpagesize()) + 1) * getpagesize();
-
-}
-
-BlockArray::~BlockArray()
-{
-    setHistorySize(0);
-    assert(!lastblock);
-}
-
-size_t BlockArray::append(Block *block)
-{
-    if (!size)
-        return size_t(-1);
-
-    ++current;
-    if (current >= size) current = 0;
-
-    int rc;
-    rc = lseek(ion, current * blocksize, SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setHistorySize(0); return size_t(-1); }
-    rc = write(ion, block, blocksize); if (rc < 0) { perror("HistoryBuffer::add.write"); setHistorySize(0); return size_t(-1); }
-
-    length++;
-    if (length > size) length = size;
-
-    ++index;
-
-    delete block;
-    return current;
-}
-
-size_t BlockArray::newBlock()
-{
-    if (!size)
-        return size_t(-1);
-    append(lastblock);
-
-    lastblock = new Block();
-    return index + 1;
-}
-
-Block *BlockArray::lastBlock() const
-{
-    return lastblock;
-}
-
-bool BlockArray::has(size_t i) const
-{
-    if (i == index + 1)
-        return true;
-
-    if (i > index)
-        return false;
-    if (index - i >= length)
-        return false;
-    return true;
-}
-
-const Block* BlockArray::at(size_t i)
-{
-    if (i == index + 1)
-        return lastblock;
-
-    if (i == lastmap_index)
-        return lastmap;
-
-    if (i > index) {
-        qDebug() << "BlockArray::at() i > index\n";
-        return 0;
-    }
-    
-//     if (index - i >= length) {
-//         kDebug(1211) << "BlockArray::at() index - i >= length\n";
-//         return 0;
-//     }
-
-    size_t j = i; // (current - (index - i) + (index/size+1)*size) % size ;
-
-    assert(j < size);
-    unmap();
-
-    Block *block = (Block*)mmap(0, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize);
-
-    if (block == (Block*)-1) { perror("mmap"); return 0; }
-
-    lastmap = block;
-    lastmap_index = i;
-
-    return block;
-}
-
-void BlockArray::unmap()
-{
-    if (lastmap) {
-        int res = munmap((char*)lastmap, blocksize);
-        if (res < 0) perror("munmap");
-    }
-    lastmap = 0;
-    lastmap_index = size_t(-1);
-}
-
-bool BlockArray::setSize(size_t newsize)
-{
-    return setHistorySize(newsize * 1024 / blocksize);
-}
-
-bool BlockArray::setHistorySize(size_t newsize)
-{
-//    kDebug(1211) << "setHistorySize " << size << " " << newsize;
-
-    if (size == newsize)
-        return false;
-
-    unmap();
-
-    if (!newsize) {
-        delete lastblock;
-        lastblock = 0;
-        if (ion >= 0) close(ion);
-        ion = -1;
-        current = size_t(-1);
-        return true;
-    }
-
-    if (!size) {
-        FILE* tmp = tmpfile();
-        if (!tmp) {
-            perror("konsole: cannot open temp file.\n");
-        } else {
-            ion = dup(fileno(tmp));
-            if (ion<0) {
-                perror("konsole: cannot dup temp file.\n");
-                fclose(tmp);
-            }
-        }
-        if (ion < 0)
-            return false;
-
-        assert(!lastblock);
-
-        lastblock = new Block();
-        size = newsize;
-        return false;
-    }
-
-    if (newsize > size) {
-        increaseBuffer();
-        size = newsize;
-        return false;
-    } else {
-        decreaseBuffer(newsize);
-        ftruncate(ion, length*blocksize);
-        size = newsize;
-
-        return true;
-    }
-}
-
-void moveBlock(FILE *fion, int cursor, int newpos, char *buffer2)
-{
-    int res = fseek(fion, cursor * blocksize, SEEK_SET);
-    if (res)
-        perror("fseek");
-    res = fread(buffer2, blocksize, 1, fion);
-    if (res != 1)
-        perror("fread");
-
-    res = fseek(fion, newpos * blocksize, SEEK_SET);
-    if (res)
-        perror("fseek");
-    res = fwrite(buffer2, blocksize, 1, fion);
-    if (res != 1)
-        perror("fwrite");
-    //    printf("moving block %d to %d\n", cursor, newpos);
-}
-
-void BlockArray::decreaseBuffer(size_t newsize)
-{
-    if (index < newsize) // still fits in whole
-        return;
-
-    int offset = (current - (newsize - 1) + size) % size;
-
-    if (!offset)
-        return;
-
-    // The Block constructor could do somthing in future...
-    char *buffer1 = new char[blocksize];
-
-    FILE *fion = fdopen(dup(ion), "w+b");
-    if (!fion) {
-        delete [] buffer1;
-        perror("fdopen/dup");
-        return;
-    }
-
-    int firstblock;
-    if (current <= newsize) {
-        firstblock = current + 1;
-    } else {
-        firstblock = 0;
-    }
-
-    size_t oldpos;
-    for (size_t i = 0, cursor=firstblock; i < newsize; i++) {
-        oldpos = (size + cursor + offset) % size;
-        moveBlock(fion, oldpos, cursor, buffer1);
-        if (oldpos < newsize) {
-            cursor = oldpos;
-        } else
-            cursor++;
-    }
-
-    current = newsize - 1;
-    length = newsize;
-
-    delete [] buffer1;
-
-    fclose(fion);
-
-}
-
-void BlockArray::increaseBuffer()
-{
-    if (index < size) // not even wrapped once
-        return;
-
-    int offset = (current + size + 1) % size;
-    if (!offset) // no moving needed
-        return;
-
-    // The Block constructor could do somthing in future...
-    char *buffer1 = new char[blocksize];
-    char *buffer2 = new char[blocksize];
-
-    int runs = 1;
-    int bpr = size; // blocks per run
-
-    if (size % offset == 0) {
-        bpr = size / offset;
-        runs = offset;
-    }
-
-    FILE *fion = fdopen(dup(ion), "w+b");
-    if (!fion) {
-        perror("fdopen/dup");
-	delete [] buffer1;
-	delete [] buffer2;
-        return;
-    }
-
-    int res;
-    for (int i = 0; i < runs; i++)
-    {
-        // free one block in chain
-        int firstblock = (offset + i) % size;
-        res = fseek(fion, firstblock * blocksize, SEEK_SET);
-        if (res)
-            perror("fseek");
-        res = fread(buffer1, blocksize, 1, fion);
-        if (res != 1)
-            perror("fread");
-        int newpos = 0;
-        for (int j = 1, cursor=firstblock; j < bpr; j++)
-        {
-            cursor = (cursor + offset) % size;
-            newpos = (cursor - offset + size) % size;
-            moveBlock(fion, cursor, newpos, buffer2);
-        }
-        res = fseek(fion, i * blocksize, SEEK_SET);
-        if (res)
-            perror("fseek");
-        res = fwrite(buffer1, blocksize, 1, fion);
-        if (res != 1)
-            perror("fwrite");
-    }
-    current = size - 1;
-    length = size;
-
-    delete [] buffer1;
-    delete [] buffer2;
-
-    fclose(fion);
-
-}
-
--- a/gui/qtermwidget/lib/BlockArray.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
-   
-    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.
-*/
-
-#ifndef BLOCKARRAY_H
-#define BLOCKARRAY_H
-
-#include <unistd.h>
-
-//#error Do not use in KDE 2.1
-
-#define BlockSize (1 << 12)
-#define ENTRIES   ((BlockSize - sizeof(size_t) ) / sizeof(unsigned char))
-
-namespace Konsole
-{
-
-struct Block {
-    Block() { size = 0; }
-    unsigned char data[ENTRIES];
-    size_t size;
-};
-
-// ///////////////////////////////////////////////////////
-
-class BlockArray {
-public:
-    /**
-    * Creates a history file for holding
-    * maximal size blocks. If more blocks
-    * are requested, then it drops earlier
-    * added ones.
-    */
-    BlockArray();
-
-    /// destructor
-    ~BlockArray();
-
-    /**
-    * adds the Block at the end of history.
-    * This may drop other blocks.
-    *
-    * The ownership on the block is transfered.
-    * An unique index number is returned for accessing
-    * it later (if not yet dropped then)
-    *
-    * Note, that the block may be dropped completely
-    * if history is turned off.
-    */
-    size_t append(Block *block);
-
-    /**
-    * gets the block at the index. Function may return
-    * 0 if the block isn't available any more.
-    *
-    * The returned block is strictly readonly as only
-    * maped in memory - and will be invalid on the next
-    * operation on this class.
-    */
-    const Block *at(size_t index);
-
-    /**
-    * reorders blocks as needed. If newsize is null,
-    * the history is emptied completely. The indices
-    * returned on append won't change their semantic,
-    * but they may not be valid after this call.
-    */
-    bool setHistorySize(size_t newsize);
-
-    size_t newBlock();
-
-    Block *lastBlock() const;
-
-    /**
-    * Convenient function to set the size in KBytes
-    * instead of blocks
-    */
-    bool setSize(size_t newsize);
-
-    size_t len() const { return length; }
-
-    bool has(size_t index) const;
-
-    size_t getCurrent() const { return current; }
-
-private:
-    void unmap();
-    void increaseBuffer();
-    void decreaseBuffer(size_t newsize);
-
-    size_t size;
-    // current always shows to the last inserted block
-    size_t current;
-    size_t index;
-
-    Block *lastmap;
-    size_t lastmap_index;
-    Block *lastblock;
-
-    int ion;
-    size_t length;
-
-};
-
-}
-
-#endif
--- a/gui/qtermwidget/lib/CVS/Entries	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/BlockArray.cpp/1.2/Wed May 14 19:36:48 2008//
-/BlockArray.h/1.2/Wed May 14 19:36:48 2008//
-/Character.h/1.2/Wed May 14 19:36:48 2008//
-/CharacterColor.h/1.2/Wed May 14 19:36:49 2008//
-/DefaultTranslatorText.h/1.1.1.1/Sat May 10 21:27:57 2008//
-/Emulation.cpp/1.2/Wed May 14 19:36:49 2008//
-/Emulation.h/1.2/Wed May 14 19:36:49 2008//
-/ExtendedDefaultTranslator.h/1.1.1.1/Sat May 10 21:27:52 2008//
-/Filter.cpp/1.2/Wed May 14 19:36:50 2008//
-/Filter.h/1.2/Wed May 14 19:36:50 2008//
-/History.cpp/1.2/Wed May 14 19:36:50 2008//
-/History.h/1.2/Wed May 14 19:36:50 2008//
-/KeyboardTranslator.cpp/1.2/Wed May 14 19:36:50 2008//
-/KeyboardTranslator.h/1.2/Wed May 14 19:36:50 2008//
-/LineFont.h/1.1.1.1/Sat May 10 21:27:49 2008//
-/LineFont.src/1.1.1.1/Sat May 10 21:27:52 2008//
-/Pty.cpp/1.2/Wed May 14 19:36:50 2008//
-/Pty.h/1.2/Wed May 14 19:36:51 2008//
-/README/1.1.1.1/Sat May 10 21:27:52 2008//
-/Screen.cpp/1.2/Wed May 14 19:36:51 2008//
-/Screen.h/1.2/Wed May 14 19:36:51 2008//
-/ScreenWindow.cpp/1.2/Wed May 14 19:36:52 2008//
-/ScreenWindow.h/1.2/Wed May 14 19:36:52 2008//
-/Session.cpp/1.2/Wed May 14 19:36:52 2008//
-/Session.h/1.2/Wed May 14 19:36:52 2008//
-/ShellCommand.cpp/1.3/Fri May 23 12:30:35 2008//
-/ShellCommand.h/1.2/Wed May 14 19:36:53 2008//
-/TerminalCharacterDecoder.cpp/1.2/Wed May 14 19:36:53 2008//
-/TerminalCharacterDecoder.h/1.2/Wed May 14 19:36:53 2008//
-/Vt102Emulation.cpp/1.2/Wed May 14 19:36:53 2008//
-/Vt102Emulation.h/1.2/Wed May 14 19:36:53 2008//
-/default.keytab/1.1.1.1/Sat May 10 21:27:55 2008//
-/k3process.cpp/1.2/Wed May 14 19:36:53 2008//
-/k3process.h/1.2/Wed May 14 19:36:53 2008//
-/k3processcontroller.cpp/1.2/Wed May 14 19:36:54 2008//
-/k3processcontroller.h/1.2/Wed May 14 19:36:54 2008//
-/konsole_wcwidth.cpp/1.1.1.1/Sat May 10 21:27:51 2008//
-/konsole_wcwidth.h/1.2/Wed May 14 19:36:54 2008//
-/kpty.cpp/1.2/Wed May 14 19:36:54 2008//
-/kpty.h/1.2/Wed May 14 19:36:54 2008//
-/kpty_p.h/1.2/Wed May 14 19:36:54 2008//
-D/kb-layouts////
-/ColorTables.h/1.2/Sat Jun  7 20:13:53 2008//
-/TerminalDisplay.cpp/1.4/Sat Jun  7 20:13:54 2008//
-/TerminalDisplay.h/1.3/Sat Jun  7 20:13:54 2008//
-/lib.pro/1.2/Wed Jul 30 22:00:49 2008//
-/qtermwidget.cpp/1.7/Wed Jul 30 21:31:25 2008//
-/qtermwidget.h/1.7/Wed Jul 30 21:48:51 2008//
--- a/gui/qtermwidget/lib/CVS/Repository	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-qtermwidget/lib
--- a/gui/qtermwidget/lib/CVS/Root	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-:ext:e_k@qtermwidget.cvs.sourceforge.net:/cvsroot/qtermwidget
--- a/gui/qtermwidget/lib/Character.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*
-    This file is part of Konsole, KDE's terminal.
-    
-    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
-
-    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.
-*/
-
-#ifndef CHARACTER_H
-#define CHARACTER_H
-
-// Qt
-#include <QtCore/QHash>
-
-// Local
-#include "CharacterColor.h"
-
-namespace Konsole
-{
-
-typedef unsigned char LineProperty;
-
-static const int LINE_DEFAULT		= 0;
-static const int LINE_WRAPPED 	 	= (1 << 0);
-static const int LINE_DOUBLEWIDTH  	= (1 << 1);
-static const int LINE_DOUBLEHEIGHT	= (1 << 2);
-
-#define DEFAULT_RENDITION  0
-#define RE_BOLD            (1 << 0)
-#define RE_BLINK           (1 << 1)
-#define RE_UNDERLINE       (1 << 2)
-#define RE_REVERSE         (1 << 3) // Screen only
-#define RE_INTENSIVE       (1 << 3) // Widget only
-#define RE_CURSOR          (1 << 4)
-#define RE_EXTENDED_CHAR   (1 << 5)
-
-/**
- * A single character in the terminal which consists of a unicode character
- * value, foreground and background colors and a set of rendition attributes
- * which specify how it should be drawn.
- */
-class Character
-{
-public:
-  /** 
-   * Constructs a new character.
-   *
-   * @param _c The unicode character value of this character.
-   * @param _f The foreground color used to draw the character.
-   * @param _b The color used to draw the character's background.
-   * @param _r A set of rendition flags which specify how this character is to be drawn.
-   */
-  inline Character(quint16 _c = ' ',
-            CharacterColor  _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
-            CharacterColor  _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
-            quint8  _r = DEFAULT_RENDITION)
-       : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {}
-
-  union
-  {
-    /** The unicode character value for this character. */
-    quint16 character;
-    /** 
-     * Experimental addition which allows a single Character instance to contain more than
-     * one unicode character.
-     *
-     * charSequence is a hash code which can be used to look up the unicode
-     * character sequence in the ExtendedCharTable used to create the sequence.
-     */
-    quint16 charSequence; 
-  };
-
-  /** A combination of RENDITION flags which specify options for drawing the character. */
-  quint8  rendition;
-
-  /** The foreground color used to draw this character. */
-  CharacterColor  foregroundColor; 
-  /** The color used to draw this character's background. */
-  CharacterColor  backgroundColor;
-
-  /** 
-   * Returns true if this character has a transparent background when
-   * it is drawn with the specified @p palette.
-   */
-  bool   isTransparent(const ColorEntry* palette) const;
-  /**
-   * Returns true if this character should always be drawn in bold when
-   * it is drawn with the specified @p palette, independent of whether
-   * or not the character has the RE_BOLD rendition flag. 
-   */
-  bool   isBold(const ColorEntry* base) const;
-  
-  /** 
-   * Compares two characters and returns true if they have the same unicode character value,
-   * rendition and colors.
-   */
-  friend bool operator == (const Character& a, const Character& b);
-  /**
-   * Compares two characters and returns true if they have different unicode character values,
-   * renditions or colors.
-   */
-  friend bool operator != (const Character& a, const Character& b);
-};
-
-inline bool operator == (const Character& a, const Character& b)
-{ 
-  return a.character == b.character && 
-         a.rendition == b.rendition && 
-         a.foregroundColor == b.foregroundColor && 
-         a.backgroundColor == b.backgroundColor;
-}
-
-inline bool operator != (const Character& a, const Character& b)
-{
-  return    a.character != b.character || 
-            a.rendition != b.rendition || 
-            a.foregroundColor != b.foregroundColor || 
-            a.backgroundColor != b.backgroundColor;
-}
-
-inline bool Character::isTransparent(const ColorEntry* base) const
-{
-  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._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];
-
-
-/**
- * A table which stores sequences of unicode characters, referenced
- * by hash keys.  The hash key itself is the same size as a unicode
- * character ( ushort ) so that it can occupy the same space in
- * a structure.
- */
-class ExtendedCharTable
-{
-public:
-    /** Constructs a new character table. */
-    ExtendedCharTable();
-    ~ExtendedCharTable();
-
-    /**
-     * Adds a sequences of unicode characters to the table and returns
-     * a hash code which can be used later to look up the sequence
-     * using lookupExtendedChar()
-     *
-     * If the same sequence already exists in the table, the hash
-     * of the existing sequence will be returned.
-     *
-     * @param unicodePoints An array of unicode character points
-     * @param length Length of @p unicodePoints
-     */
-    ushort createExtendedChar(ushort* unicodePoints , ushort length);
-    /**
-     * Looks up and returns a pointer to a sequence of unicode characters
-     * which was added to the table using createExtendedChar().
-     *
-     * @param hash The hash key returned by createExtendedChar()
-     * @param length This variable is set to the length of the 
-     * character sequence.
-     *
-     * @return A unicode character sequence of size @p length.
-     */
-    ushort* lookupExtendedChar(ushort hash , ushort& length) const;
-
-    /** The global ExtendedCharTable instance. */
-    static ExtendedCharTable instance;
-private:
-    // calculates the hash key of a sequence of unicode points of size 'length'
-    ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
-    // tests whether the entry in the table specified by 'hash' matches the 
-    // character sequence 'unicodePoints' of size 'length'
-    bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
-    // internal, maps hash keys to character sequence buffers.  The first ushort
-    // in each value is the length of the buffer, followed by the ushorts in the buffer
-    // themselves.
-    QHash<ushort,ushort*> extendedCharTable;
-};
-
-}
-
-#endif // CHARACTER_H
-
--- a/gui/qtermwidget/lib/CharacterColor.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,301 +0,0 @@
-/*
-    This file is part of Konsole, KDE's terminal.
-    
-    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
-
-    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.
-*/
-
-#ifndef CHARACTERCOLOR_H
-#define CHARACTERCOLOR_H
-
-// Qt
-#include <QtGui/QColor>
-
-namespace Konsole
-{
-
-/** 
- * An entry in a terminal display's color palette. 
- *
- * A color palette is an array of 16 ColorEntry instances which map
- * system color indexes (from 0 to 15) into actual colors.
- *
- * Each entry can be set as bold, in which case any text
- * drawn using the color should be drawn in bold.  
- *
- * Each entry can also be transparent, in which case the terminal
- * display should avoid drawing the background for any characters
- * using the entry as a background.
- */
-class ColorEntry
-{
-public:
-  /** 
-   * Constructs a new color palette entry.
-   *
-   * @param c The color value for this entry.
-   * @param tr Specifies that the color should be transparent when used as a background color.
-   * @param b Specifies that text drawn with this color should be bold.
-   */
-  ColorEntry(QColor c, bool tr, bool b) : color(c), transparent(tr), bold(b) {}
-
-  /**
-   * Constructs a new color palette entry with an undefined color, and
-   * with the transparent and bold flags set to false.
-   */ 
-  ColorEntry() : transparent(false), bold(false) {} 
- 
-  /**
-   * Sets the color, transparency and boldness of this color to those of @p rhs.
-   */ 
-  void operator=(const ColorEntry& rhs) 
-  { 
-       color = rhs.color; 
-       transparent = rhs.transparent; 
-       bold = rhs.bold; 
-  }
-
-  /** The color value of this entry for display. */
-  QColor color;
-
-  /** 
-   * If true character backgrounds using this color should be transparent. 
-   * This is not applicable when the color is used to render text.
-   */
-  bool   transparent;
-  /**
-   * If true characters drawn using this color should be bold.
-   * This is not applicable when the color is used to draw a character's background.
-   */
-  bool   bold;        
-};
-
-
-// Attributed Character Representations ///////////////////////////////
-
-// Colors
-
-#define BASE_COLORS   (2+8)
-#define INTENSITIES   2
-#define TABLE_COLORS  (INTENSITIES*BASE_COLORS)
-
-#define DEFAULT_FORE_COLOR 0
-#define DEFAULT_BACK_COLOR 1
-
-//a standard set of colors using black text on a white background.
-//defined in TerminalDisplay.cpp
-
-static const ColorEntry base_color_table[TABLE_COLORS] =
-// The following are almost IBM standard color codes, with some slight
-// gamma correction for the dim colors to compensate for bright X screens.
-// It contains the 8 ansiterm/xterm colors in 2 intensities.
-{
-  // Fixme: could add faint colors here, also.
-  // normal
-  ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
-  ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
-  ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
-  ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
-  ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
-  // intensiv
-  ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
-  ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
-  ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
-  ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ),
-  ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
-};
-
-/* CharacterColor is a union of the various color spaces.
-
-   Assignment is as follows:
-
-   Type  - Space        - Values
-
-   0     - Undefined   - u:  0,      v:0        w:0
-   1     - Default     - u:  0..1    v:intense  w:0
-   2     - System      - u:  0..7    v:intense  w:0
-   3     - Index(256)  - u: 16..255  v:0        w:0
-   4     - RGB         - u:  0..255  v:0..256   w:0..256
-
-   Default colour space has two separate colours, namely
-   default foreground and default background colour.
-*/
-
-#define COLOR_SPACE_UNDEFINED   0
-#define COLOR_SPACE_DEFAULT     1
-#define COLOR_SPACE_SYSTEM      2
-#define COLOR_SPACE_256         3
-#define COLOR_SPACE_RGB         4
-
-/**
- * Describes the color of a single character in the terminal.
- */
-class CharacterColor
-{
-    friend class Character;
-
-public:
-  /** Constructs a new CharacterColor whoose color and color space are undefined. */
-  CharacterColor() 
-      : _colorSpace(COLOR_SPACE_UNDEFINED), 
-        _u(0), 
-        _v(0), 
-        _w(0) 
-  {}
-
-  /** 
-   * Constructs a new CharacterColor using the specified @p colorSpace and with 
-   * color value @p co
-   *
-   * The meaning of @p co depends on the @p colorSpace used.
-   *
-   * TODO : Document how @p co relates to @p colorSpace
-   *
-   * TODO : Add documentation about available color spaces.
-   */
-  CharacterColor(quint8 colorSpace, int co) 
-      : _colorSpace(colorSpace), 
-        _u(0), 
-        _v(0), 
-        _w(0)
-  {
-    switch (colorSpace)
-    {
-        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:
-            _colorSpace = COLOR_SPACE_UNDEFINED;
-    }
-  }
-
-  /** 
-   * Returns true if this character color entry is valid.
-   */
-  bool isValid() 
-  {
-        return _colorSpace != COLOR_SPACE_UNDEFINED;
-  }
-    
-  /** 
-   * Toggles the value of this color between a normal system color and the corresponding intensive
-   * system color.
-   * 
-   * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM
-   * color spaces.
-   */
-  void toggleIntensive();
-
-  /** 
-   * Returns the color within the specified color @palette
-   *
-   * The @p palette is only used if this color is one of the 16 system colors, otherwise
-   * it is ignored.
-   */
-  QColor color(const ColorEntry* palette) const;
- 
-  /** 
-   * Compares two colors and returns true if they represent the same color value and
-   * use the same color space.
-   */
-  friend bool operator == (const CharacterColor& a, const CharacterColor& b);
-  /**
-   * Compares two colors and returns true if they represent different color values
-   * or use different color spaces.
-   */
-  friend bool operator != (const CharacterColor& a, const CharacterColor& b);
-
-private:
-  quint8 _colorSpace;
-
-  // bytes storing the character color 
-  quint8 _u; 
-  quint8 _v; 
-  quint8 _w; 
-};
-
-inline bool operator == (const CharacterColor& a, const CharacterColor& b)
-{ 
-  return *reinterpret_cast<const quint32*>(&a._colorSpace) == 
-         *reinterpret_cast<const quint32*>(&b._colorSpace);
-}
-
-inline bool operator != (const CharacterColor& a, const CharacterColor& b)
-{
-  return *reinterpret_cast<const quint32*>(&a._colorSpace) != 
-         *reinterpret_cast<const quint32*>(&b._colorSpace);
-}
-
-inline const QColor color256(quint8 u, const ColorEntry* base)
-{
-  //   0.. 16: system colors
-  if (u <   8) return base[u+2            ].color; u -= 8;
-  if (u <   8) return base[u+2+BASE_COLORS].color; u -= 8;
-
-  //  16..231: 6x6x6 rgb color cube
-  if (u < 216) return QColor(255*((u/36)%6)/5,
-                             255*((u/ 6)%6)/5,
-                             255*((u/ 1)%6)/5); u -= 216;
-  
-  // 232..255: gray, leaving out black and white
-  int gray = u*10+8; return QColor(gray,gray,gray);
-}
-
-inline QColor CharacterColor::color(const ColorEntry* base) const
-{
-  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);
-    case COLOR_SPACE_UNDEFINED: return QColor();
-  }
-
-  Q_ASSERT(false); // invalid color space
-
-  return QColor();
-}
-
-inline void CharacterColor::toggleIntensive()
-{
-  if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT)
-  {
-    _v = !_v;
-  }
-}
-
-
-}
-
-#endif // CHARACTERCOLOR_H
-
--- a/gui/qtermwidget/lib/ColorTables.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-#ifndef _COLOR_TABLE_H
-#define _COLOR_TABLE_H
-
-#include "CharacterColor.h"
-
-using namespace Konsole;
-
-static const ColorEntry whiteonblack_color_table[TABLE_COLORS] =
-{
-    // normal
-    ColorEntry(QColor(0xFF,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0x00,0x00,0x00), 1, 0 ), // Dfore, Dback
-    ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
-    ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
-    ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
-    ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
-    // intensiv
-    ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
-    ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
-    ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
-    ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ),
-    ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
-};
-
-static const ColorEntry greenonblack_color_table[TABLE_COLORS] =
-{
-    ColorEntry(QColor(    24, 240,  24),  0, 0), ColorEntry(QColor(     0,   0,   0),  1, 0),  
-    ColorEntry(QColor(     0,   0,   0),  0, 0), ColorEntry(QColor(   178,  24,  24),  0, 0), 
-    ColorEntry(QColor(    24, 178,  24),  0, 0), ColorEntry(QColor(   178, 104,  24),  0, 0), 
-    ColorEntry(QColor(    24,  24, 178),  0, 0), ColorEntry(QColor(   178,  24, 178),  0, 0), 
-    ColorEntry(QColor(    24, 178, 178),  0, 0), ColorEntry(QColor(   178, 178, 178),  0, 0), 
-    // intensive colors
-    ColorEntry(QColor(   24, 240,  24),  0, 1 ), ColorEntry(QColor(    0,   0,   0),  1, 0 ),
-    ColorEntry(QColor(  104, 104, 104),  0, 0 ), ColorEntry(QColor(  255,  84,  84),  0, 0 ),
-    ColorEntry(QColor(   84, 255,  84),  0, 0 ), ColorEntry(QColor(  255, 255,  84),  0, 0 ),
-    ColorEntry(QColor(   84,  84, 255),  0, 0 ), ColorEntry(QColor(  255,  84, 255),  0, 0 ),
-    ColorEntry(QColor(   84, 255, 255),  0, 0 ), ColorEntry(QColor(  255, 255, 255),  0, 0 )
-};
-
-static const ColorEntry blackonlightyellow_color_table[TABLE_COLORS] = 
-{
-    ColorEntry(QColor(  0,   0,   0),  0, 0),  ColorEntry(QColor( 255, 255, 221),  1, 0),  
-    ColorEntry(QColor(  0,   0,   0),  0, 0),  ColorEntry(QColor( 178,  24,  24),  0, 0),  
-    ColorEntry(QColor( 24, 178,  24),  0, 0),  ColorEntry(QColor( 178, 104,  24),  0, 0),  
-    ColorEntry(QColor( 24,  24, 178),  0, 0),  ColorEntry(QColor( 178,  24, 178),  0, 0),  
-    ColorEntry(QColor( 24, 178, 178),  0, 0),  ColorEntry(QColor( 178, 178, 178),  0, 0),  
-    ColorEntry(QColor(  0,   0,   0),  0, 1),  ColorEntry(QColor( 255, 255, 221),  1, 0),  
-    ColorEntry(QColor(104, 104, 104),  0, 0),  ColorEntry(QColor( 255,  84,  84),  0, 0),  
-    ColorEntry(QColor( 84, 255,  84),  0, 0),  ColorEntry(QColor( 255, 255,  84),  0, 0),  
-    ColorEntry(QColor( 84,  84, 255),  0, 0),  ColorEntry(QColor( 255,  84, 255),  0, 0),  
-    ColorEntry(QColor( 84, 255, 255),  0, 0),  ColorEntry(QColor( 255, 255, 255),  0, 0)
-};
- 			  
-			  
-			  
-
-
-#endif
-
--- a/gui/qtermwidget/lib/DefaultTranslatorText.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-"keyboard \"Fallback Key Translator\"\n"
-"key Tab : \"\\t\" \0"
--- a/gui/qtermwidget/lib/Emulation.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,543 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-
-    Copyright (C) 2007 Robert Knight <robertknight@gmail.com> 
-    Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
-    Copyright (C) 1996 by Matthias Ettrich <ettrich@kde.org>
-
-    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 "Emulation.h"
-
-// System
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-// Qt
-#include <QtGui/QApplication>
-#include <QtGui/QClipboard>
-#include <QtCore/QHash>
-#include <QtGui/QKeyEvent>
-#include <QtCore/QRegExp>
-#include <QtCore/QTextStream>
-#include <QtCore/QThread>
-
-#include <QtCore/QTime>
-
-// Konsole
-#include "KeyboardTranslator.h"
-#include "Screen.h"
-#include "TerminalCharacterDecoder.h"
-#include "ScreenWindow.h"
-
-using namespace Konsole;
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                               Emulation                                  */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-//#define CNTL(c) ((c)-'@')
-
-/*!
-*/
-
-Emulation::Emulation() :
-  _currentScreen(0),
-  _codec(0),
-  _decoder(0),
-  _keyTranslator(0),
-  _usesMouse(false)
-{
-
-  // create screens with a default size
-  _screen[0] = new Screen(40,80);
-  _screen[1] = new Screen(40,80);
-  _currentScreen = _screen[0];
-
-  QObject::connect(&_bulkTimer1, SIGNAL(timeout()), this, SLOT(showBulk()) );
-  QObject::connect(&_bulkTimer2, SIGNAL(timeout()), this, SLOT(showBulk()) );
-   
-  // listen for mouse status changes
-  connect( this , SIGNAL(programUsesMouseChanged(bool)) , 
-           SLOT(usesMouseChanged(bool)) );
-}
-
-bool Emulation::programUsesMouse() const
-{
-    return _usesMouse;
-}
-
-void Emulation::usesMouseChanged(bool usesMouse)
-{
-    _usesMouse = usesMouse;
-}
-
-ScreenWindow* Emulation::createWindow()
-{
-    ScreenWindow* window = new ScreenWindow();
-    window->setScreen(_currentScreen);
-    _windows << window;
-
-    connect(window , SIGNAL(selectionChanged()),
-            this , SLOT(bufferedUpdate()));
-
-    connect(this , SIGNAL(outputChanged()),
-            window , SLOT(notifyOutputChanged()) );
-    return window;
-}
-
-/*!
-*/
-
-Emulation::~Emulation()
-{
-  QListIterator<ScreenWindow*> windowIter(_windows);
-
-  while (windowIter.hasNext())
-  {
-    delete windowIter.next();
-  }
-
-  delete _screen[0];
-  delete _screen[1];
-  delete _decoder;
-}
-
-/*! change between primary and alternate _screen
-*/
-
-void Emulation::setScreen(int n)
-{
-  Screen *old = _currentScreen;
-  _currentScreen = _screen[n&1];
-  if (_currentScreen != old) 
-  {
-     old->setBusySelecting(false);
-
-     // tell all windows onto this emulation to switch to the newly active _screen
-     QListIterator<ScreenWindow*> windowIter(_windows);
-     while ( windowIter.hasNext() )
-     {
-         windowIter.next()->setScreen(_currentScreen);
-     }
-  }
-}
-
-void Emulation::clearHistory()
-{
-    _screen[0]->setScroll( _screen[0]->getScroll() , false );
-}
-void Emulation::setHistory(const HistoryType& t)
-{
-  _screen[0]->setScroll(t);
-
-  showBulk();
-}
-
-const HistoryType& Emulation::history()
-{
-  return _screen[0]->getScroll();
-}
-
-void Emulation::setCodec(const QTextCodec * qtc)
-{
-  Q_ASSERT( qtc );
-
-  _codec = qtc;
-  delete _decoder;
-  _decoder = _codec->makeDecoder();
-
-  emit useUtf8Request(utf8());
-}
-
-void Emulation::setCodec(EmulationCodec codec)
-{
-    if ( codec == Utf8Codec )
-        setCodec( QTextCodec::codecForName("utf8") );
-    else if ( codec == LocaleCodec )
-        setCodec( QTextCodec::codecForLocale() );
-}
-
-void Emulation::setKeyBindings(const QString& name)
-{
-  _keyTranslator = KeyboardTranslatorManager::instance()->findTranslator(name);
-}
-
-QString Emulation::keyBindings()
-{
-  return _keyTranslator->name();
-}
-
-
-// Interpreting Codes ---------------------------------------------------------
-
-/*
-   This section deals with decoding the incoming character stream.
-   Decoding means here, that the stream is first separated into `tokens'
-   which are then mapped to a `meaning' provided as operations by the
-   `Screen' class.
-*/
-
-/*!
-*/
-
-void Emulation::receiveChar(int c)
-// process application unicode input to terminal
-// this is a trivial scanner
-{
-  c &= 0xff;
-  switch (c)
-  {
-    case '\b'      : _currentScreen->BackSpace();                 break;
-    case '\t'      : _currentScreen->Tabulate();                  break;
-    case '\n'      : _currentScreen->NewLine();                   break;
-    case '\r'      : _currentScreen->Return();                    break;
-    case 0x07      : emit stateSet(NOTIFYBELL);
-                     break;
-    default        : _currentScreen->ShowCharacter(c);            break;
-  };
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                             Keyboard Handling                             */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/*!
-*/
-
-void Emulation::sendKeyEvent( QKeyEvent* ev )
-{
-  emit stateSet(NOTIFYNORMAL);
-  
-  if (!ev->text().isEmpty())
-  { // A block of text
-    // Note that the text is proper unicode.
-    // We should do a conversion here, but since this
-    // routine will never be used, we simply emit plain ascii.
-    //emit sendBlock(ev->text().toAscii(),ev->text().length());
-    emit sendData(ev->text().toUtf8(),ev->text().length());
-  }
-}
-
-void Emulation::sendString(const char*,int)
-{
-    // default implementation does nothing
-}
-
-void Emulation::sendMouseEvent(int /*buttons*/, int /*column*/, int /*row*/, int /*eventType*/)
-{
-    // default implementation does nothing
-}
-
-// Unblocking, Byte to Unicode translation --------------------------------- --
-
-/*
-   We are doing code conversion from locale to unicode first.
-TODO: Character composition from the old code.  See #96536
-*/
-
-void Emulation::receiveData(const char* text, int length)
-{
-	emit stateSet(NOTIFYACTIVITY);
-
-	bufferedUpdate();
-    	
-    QString unicodeText = _decoder->toUnicode(text,length);
-
-	//send characters to terminal emulator
-	for (int i=0;i<unicodeText.length();i++)
-	{
-		receiveChar(unicodeText[i].unicode());
-	}
-
-	//look for z-modem indicator
-	//-- someone who understands more about z-modems that I do may be able to move
-	//this check into the above for loop?
-	for (int i=0;i<length;i++)
-	{
-		if (text[i] == '\030')
-    		{
-      			if ((length-i-1 > 3) && (strncmp(text+i+1, "B00", 3) == 0))
-      				emit zmodemDetected();
-    		}
-	}
-}
-
-//OLDER VERSION
-//This version of onRcvBlock was commented out because
-//	a)  It decoded incoming characters one-by-one, which is slow in the current version of Qt (4.2 tech preview)
-//	b)  It messed up decoding of non-ASCII characters, with the result that (for example) chinese characters
-//	    were not printed properly.
-//
-//There is something about stopping the _decoder if "we get a control code halfway a multi-byte sequence" (see below)
-//which hasn't been ported into the newer function (above).  Hopefully someone who understands this better
-//can find an alternative way of handling the check.  
-
-
-/*void Emulation::onRcvBlock(const char *s, int len)
-{
-  emit notifySessionState(NOTIFYACTIVITY);
-  
-  bufferedUpdate();
-  for (int i = 0; i < len; i++)
-  {
-
-    QString result = _decoder->toUnicode(&s[i],1);
-    int reslen = result.length();
-
-    // If we get a control code halfway a multi-byte sequence
-    // we flush the _decoder and continue with the control code.
-    if ((s[i] < 32) && (s[i] > 0))
-    {
-       // Flush _decoder
-       while(!result.length())
-          result = _decoder->toUnicode(&s[i],1);
-       reslen = 1;
-       result.resize(reslen);
-       result[0] = QChar(s[i]);
-    }
-
-    for (int j = 0; j < reslen; j++)
-    {
-      if (result[j].characterategory() == QChar::Mark_NonSpacing)
-         _currentScreen->compose(result.mid(j,1));
-      else
-         onRcvChar(result[j].unicode());
-    }
-    if (s[i] == '\030')
-    {
-      if ((len-i-1 > 3) && (strncmp(s+i+1, "B00", 3) == 0))
-      	emit zmodemDetected();
-    }
-  }
-}*/
-
-// Selection --------------------------------------------------------------- --
-
-#if 0
-void Emulation::onSelectionBegin(const int x, const int y, const bool columnmode) {
-  if (!connected) return;
-  _currentScreen->setSelectionStart( x,y,columnmode);
-  showBulk();
-}
-
-void Emulation::onSelectionExtend(const int x, const int y) {
-  if (!connected) return;
-  _currentScreen->setSelectionEnd(x,y);
-  showBulk();
-}
-
-void Emulation::setSelection(const bool preserve_line_breaks) {
-  if (!connected) return;
-  QString t = _currentScreen->selectedText(preserve_line_breaks);
-  if (!t.isNull()) 
-  {
-    QListIterator< TerminalDisplay* > viewIter(_views);
-
-    while (viewIter.hasNext())    
-        viewIter.next()->setSelection(t);
-  }
-}
-
-void Emulation::testIsSelected(const int x, const int y, bool &selected)
-{
-  if (!connected) return;
-  selected=_currentScreen->isSelected(x,y);
-}
-
-void Emulation::clearSelection() {
-  if (!connected) return;
-  _currentScreen->clearSelection();
-  showBulk();
-}
-
-#endif 
-
-void Emulation::writeToStream( TerminalCharacterDecoder* _decoder , 
-                               int startLine ,
-                               int endLine) 
-{
-  _currentScreen->writeToStream(_decoder,startLine,endLine);
-}
-
-int Emulation::lineCount()
-{
-    // sum number of lines currently on _screen plus number of lines in history
-    return _currentScreen->getLines() + _currentScreen->getHistLines();
-}
-
-// Refreshing -------------------------------------------------------------- --
-
-#define BULK_TIMEOUT1 10
-#define BULK_TIMEOUT2 40
-
-/*!
-*/
-void Emulation::showBulk()
-{
-    _bulkTimer1.stop();
-    _bulkTimer2.stop();
-
-    emit outputChanged();
-
-    _currentScreen->resetScrolledLines();
-    _currentScreen->resetDroppedLines();
-}
-
-void Emulation::bufferedUpdate()
-{
-   _bulkTimer1.setSingleShot(true);
-   _bulkTimer1.start(BULK_TIMEOUT1);
-   if (!_bulkTimer2.isActive())
-   {
-      _bulkTimer2.setSingleShot(true);
-      _bulkTimer2.start(BULK_TIMEOUT2);
-   }
-}
-
-char Emulation::getErase() const
-{
-  return '\b';
-}
-
-void Emulation::setImageSize(int lines, int columns)
-{
-  //kDebug() << "Resizing image to: " << lines << "by" << columns << QTime::currentTime().msec();
-  Q_ASSERT( lines > 0 );
-  Q_ASSERT( columns > 0 );
-
-  _screen[0]->resizeImage(lines,columns);
-  _screen[1]->resizeImage(lines,columns);
-
-  emit imageSizeChanged(lines,columns);
-
-  bufferedUpdate();
-}
-
-QSize Emulation::imageSize()
-{
-  return QSize(_currentScreen->getColumns(), _currentScreen->getLines());
-}
-
-ushort ExtendedCharTable::extendedCharHash(ushort* unicodePoints , ushort length) const
-{
-    ushort hash = 0;
-    for ( ushort i = 0 ; i < length ; i++ )
-    {
-        hash = 31*hash + unicodePoints[i];
-    }
-    return hash;
-}
-bool ExtendedCharTable::extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const
-{
-    ushort* entry = extendedCharTable[hash];
-
-    // compare given length with stored sequence length ( given as the first ushort in the 
-    // stored buffer ) 
-    if ( entry == 0 || entry[0] != length ) 
-       return false;
-    // if the lengths match, each character must be checked.  the stored buffer starts at
-    // entry[1]
-    for ( int i = 0 ; i < length ; i++ )
-    {
-        if ( entry[i+1] != unicodePoints[i] )
-           return false; 
-    } 
-    return true;
-}
-ushort ExtendedCharTable::createExtendedChar(ushort* unicodePoints , ushort length)
-{
-    // look for this sequence of points in the table
-    ushort hash = extendedCharHash(unicodePoints,length);
-
-    // check existing entry for match
-    while ( extendedCharTable.contains(hash) )
-    {
-        if ( extendedCharMatch(hash,unicodePoints,length) )
-        {
-            // this sequence already has an entry in the table, 
-            // return its hash
-            return hash;
-        }
-        else
-        {
-            // if hash is already used by another, different sequence of unicode character
-            // points then try next hash
-            hash++;
-        }
-    }    
-
-    
-     // add the new sequence to the table and
-     // return that index
-    ushort* buffer = new ushort[length+1];
-    buffer[0] = length;
-    for ( int i = 0 ; i < length ; i++ )
-       buffer[i+1] = unicodePoints[i]; 
-    
-    extendedCharTable.insert(hash,buffer);
-
-    return hash;
-}
-
-ushort* ExtendedCharTable::lookupExtendedChar(ushort hash , ushort& length) const
-{
-    // lookup index in table and if found, set the length
-    // argument and return a pointer to the character sequence
-
-    ushort* buffer = extendedCharTable[hash];
-    if ( buffer )
-    {
-        length = buffer[0];
-        return buffer+1;
-    }
-    else
-    {
-        length = 0;
-        return 0;
-    }
-}
-
-ExtendedCharTable::ExtendedCharTable()
-{
-}
-ExtendedCharTable::~ExtendedCharTable()
-{
-    // free all allocated character buffers
-    QHashIterator<ushort,ushort*> iter(extendedCharTable);
-    while ( iter.hasNext() )
-    {
-        iter.next();
-        delete[] iter.value();
-    }
-}
-
-// global instance
-ExtendedCharTable ExtendedCharTable::instance;
-
-
-//#include "moc_Emulation.cpp"
-
--- a/gui/qtermwidget/lib/Emulation.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,465 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    
-    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
-
-    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.
-*/
-
-#ifndef EMULATION_H
-#define EMULATION_H
-
-// System
-#include <stdio.h>
-
-// Qt 
-#include <QtGui/QKeyEvent>
-//#include <QPointer>
-#include <QtCore/QTextCodec>
-#include <QtCore/QTextStream>
-#include <QtCore/QTimer>
-
-
-namespace Konsole
-{
-
-class KeyboardTranslator;
-class HistoryType;
-class Screen;
-class ScreenWindow;
-class TerminalCharacterDecoder;
-
-/** 
- * This enum describes the available states which 
- * the terminal emulation may be set to.
- *
- * These are the values used by Emulation::stateChanged() 
- */
-enum 
-{ 
-    /** The emulation is currently receiving user input. */
-    NOTIFYNORMAL=0, 
-    /** 
-     * The terminal program has triggered a bell event
-     * to get the user's attention.
-     */
-    NOTIFYBELL=1, 
-    /** 
-     * The emulation is currently receiving data from its 
-     * terminal input.
-     */
-    NOTIFYACTIVITY=2,
-
-    // unused here? 
-    NOTIFYSILENCE=3 
-};
-
-/**
- * Base class for terminal emulation back-ends.
- *
- * The back-end is responsible for decoding an incoming character stream and 
- * producing an output image of characters.
- *
- * When input from the terminal is received, the receiveData() slot should be called with
- * the data which has arrived.  The emulation will process the data and update the 
- * screen image accordingly.  The codec used to decode the incoming character stream
- * into the unicode characters used internally can be specified using setCodec() 
- *
- * The size of the screen image can be specified by calling setImageSize() with the 
- * desired number of lines and columns.  When new lines are added, old content
- * is moved into a history store, which can be set by calling setHistory(). 
- *
- * The screen image can be accessed by creating a ScreenWindow onto this emulation 
- * by calling createWindow().  Screen windows provide access to a section of the 
- * output.  Each screen window covers the same number of lines and columns as the 
- * image size returned by imageSize().  The screen window can be moved up and down
- * and provides transparent access to both the current on-screen image and the 
- * previous output.  The screen windows emit an outputChanged signal
- * when the section of the image they are looking at changes.
- * Graphical views can then render the contents of a screen window, listening for notifications
- * of output changes from the screen window which they are associated with and updating 
- * accordingly. 
- *
- * The emulation also is also responsible for converting input from the connected views such
- * as keypresses and mouse activity into a character string which can be sent
- * to the terminal program.  Key presses can be processed by calling the sendKeyEvent() slot,
- * while mouse events can be processed using the sendMouseEvent() slot.  When the character
- * stream has been produced, the emulation will emit a sendData() signal with a pointer
- * to the character buffer.  This data should be fed to the standard input of the terminal
- * process.  The translation of key presses into an output character stream is performed
- * using a lookup in a set of key bindings which map key sequences to output
- * character sequences.  The name of the key bindings set used can be specified using
- * setKeyBindings()
- *
- * The emulation maintains certain state information which changes depending on the 
- * input received.  The emulation can be reset back to its starting state by calling 
- * reset().  
- *
- * The emulation also maintains an activity state, which specifies whether
- * terminal is currently active ( when data is received ), normal
- * ( when the terminal is idle or receiving user input ) or trying
- * to alert the user ( also known as a "Bell" event ).  The stateSet() signal
- * is emitted whenever the activity state is set.  This can be used to determine
- * how long the emulation has been active/idle for and also respond to
- * a 'bell' event in different ways.
- */
-class Emulation : public QObject
-{ 
-Q_OBJECT
-
-public:
- 
-   /** Constructs a new terminal emulation */ 
-   Emulation();
-  ~Emulation();
-
-  /**
-   * Creates a new window onto the output from this emulation.  The contents
-   * of the window are then rendered by views which are set to use this window using the
-   * TerminalDisplay::setScreenWindow() method.
-   */
-  ScreenWindow* createWindow();
-
-  /** Returns the size of the screen image which the emulation produces */
-  QSize imageSize();
-
-  /**
-   * Returns the total number of lines, including those stored in the history.
-   */ 
-  int lineCount();
-
-  
-  /** 
-   * Sets the history store used by this emulation.  When new lines
-   * are added to the output, older lines at the top of the screen are transferred to a history
-   * store.   
-   *
-   * The number of lines which are kept and the storage location depend on the 
-   * type of store.
-   */
-  void setHistory(const HistoryType&);
-  /** Returns the history store used by this emulation.  See setHistory() */
-  const HistoryType& history();
-  /** Clears the history scroll. */
-  void clearHistory();
-
-  /** 
-   * Copies the output history from @p startLine to @p endLine 
-   * into @p stream, using @p decoder to convert the terminal
-   * characters into text. 
-   *
-   * @param decoder A decoder which converts lines of terminal characters with 
-   * appearance attributes into output text.  PlainTextDecoder is the most commonly
-   * used decoder.
-   * @param startLine The first
-   */
-  virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine);
-  
-  
-  /** Returns the codec used to decode incoming characters.  See setCodec() */
-  const QTextCodec* codec() { return _codec; }
-  /** Sets the codec used to decode incoming characters.  */
-  void setCodec(const QTextCodec*);
-
-  /** 
-   * Convenience method.  
-   * Returns true if the current codec used to decode incoming
-   * characters is UTF-8
-   */
-  bool utf8() { Q_ASSERT(_codec); return _codec->mibEnum() == 106; }
-  
-
-  /** TODO Document me */
-  virtual char getErase() const;
-
-  /** 
-   * Sets the key bindings used to key events
-   * ( received through sendKeyEvent() ) into character
-   * streams to send to the terminal.
-   */
-  void setKeyBindings(const QString& name);
-  /** 
-   * Returns the name of the emulation's current key bindings.
-   * See setKeyBindings()
-   */
-  QString keyBindings();
-
-  /** 
-   * Copies the current image into the history and clears the screen.
-   */
-  virtual void clearEntireScreen() =0;
-
-  /** Resets the state of the terminal. */
-  virtual void reset() =0;
-
-  /** 
-   * Returns true if the active terminal program wants
-   * mouse input events.
-   *
-   * The programUsesMouseChanged() signal is emitted when this
-   * changes.
-   */
-  bool programUsesMouse() const;
-
-public slots: 
-
-  /** Change the size of the emulation's image */
-  virtual void setImageSize(int lines, int columns);
-  
-  /** 
-   * Interprets a sequence of characters and sends the result to the terminal.
-   * This is equivalent to calling sendKeyEvent() for each character in @p text in succession.
-   */
-  virtual void sendText(const QString& text) = 0;
-
-  /** 
-   * Interprets a key press event and emits the sendData() signal with
-   * the resulting character stream. 
-   */
-  virtual void sendKeyEvent(QKeyEvent*);
- 
-  /** 
-   * Converts information about a mouse event into an xterm-compatible escape
-   * sequence and emits the character sequence via sendData()
-   */
-  virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
-  
-  /**
-   * Sends a string of characters to the foreground terminal process. 
-   *
-   * @param string The characters to send.  
-   * @param length Length of @p string or if set to a negative value, @p string will
-   * be treated as a null-terminated string and its length will be determined automatically.
-   */
-  virtual void sendString(const char* string, int length = -1) = 0;
-
-  /** 
-   * Processes an incoming stream of characters.  receiveData() decodes the incoming
-   * character buffer using the current codec(), and then calls receiveChar() for
-   * each unicode character in the resulting buffer.  
-   *
-   * receiveData() also starts a timer which causes the outputChanged() signal
-   * to be emitted when it expires.  The timer allows multiple updates in quick
-   * succession to be buffered into a single outputChanged() signal emission.
-   *
-   * @param buffer A string of characters received from the terminal program.
-   * @param len The length of @p buffer
-   */
-  void receiveData(const char* buffer,int len);
-
-signals:
-
-  /** 
-   * Emitted when a buffer of data is ready to send to the 
-   * standard input of the terminal.
-   *
-   * @param data The buffer of data ready to be sent
-   * @paran len The length of @p data in bytes
-   */
-  void sendData(const char* data,int len);
-
-  /** 
-   * Requests that sending of input to the emulation
-   * from the terminal process be suspended or resumed.
-   *
-   * @param suspend If true, requests that sending of 
-   * input from the terminal process' stdout be 
-   * suspended.  Otherwise requests that sending of
-   * input be resumed. 
-   */
-  void lockPtyRequest(bool suspend);
-
-  /**
-   * Requests that the pty used by the terminal process
-   * be set to UTF 8 mode.  
-   *
-   * TODO: More documentation
-   */
-  void useUtf8Request(bool);
-
-  /**
-   * Emitted when the activity state of the emulation is set.
-   *
-   * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY
-   * or NOTIFYBELL
-   */
-  void stateSet(int state);
-
-  /** TODO Document me */
-  void zmodemDetected();
-
-
-  /**
-   * Requests that the color of the text used
-   * to represent the tabs associated with this
-   * emulation be changed.  This is a Konsole-specific
-   * extension from pre-KDE 4 times.
-   *
-   * TODO: Document how the parameter works.
-   */
-  void changeTabTextColorRequest(int color);
-
-  /** 
-   * This is emitted when the program running in the shell indicates whether or
-   * not it is interested in mouse events.
-   *
-   * @param usesMouse This will be true if the program wants to be informed about
-   * mouse events or false otherwise.
-   */
-  void programUsesMouseChanged(bool usesMouse);
-
-  /** 
-   * Emitted when the contents of the screen image change.
-   * The emulation buffers the updates from successive image changes,
-   * and only emits outputChanged() at sensible intervals when
-   * there is a lot of terminal activity.
-   *
-   * Normally there is no need for objects other than the screen windows
-   * created with createWindow() to listen for this signal.
-   *
-   * ScreenWindow objects created using createWindow() will emit their
-   * own outputChanged() signal in response to this signal. 
-   */
-  void outputChanged();
-
-  /**
-   * Emitted when the program running in the terminal wishes to update the 
-   * session's title.  This also allows terminal programs to customize other
-   * aspects of the terminal emulation display. 
-   *
-   * This signal is emitted when the escape sequence "\033]ARG;VALUE\007"
-   * is received in the input string, where ARG is a number specifying what
-   * should change and VALUE is a string specifying the new value.
-   *
-   * TODO:  The name of this method is not very accurate since this method
-   * is used to perform a whole range of tasks besides just setting
-   * the user-title of the session.    
-   *
-   * @param title Specifies what to change.
-   * <ul>
-   * <li>0 - Set window icon text and session title to @p newTitle</li>
-   * <li>1 - Set window icon text to @p newTitle</li>
-   * <li>2 - Set session title to @p newTitle</li>
-   * <li>11 - Set the session's default background color to @p newTitle,
-   *         where @p newTitle can be an HTML-style string (#RRGGBB) or a named
-   *         color (eg 'red', 'blue').  
-   *         See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more
-   *         details.
-   * </li>
-   * <li>31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)</li>
-   * <li>32 - Sets the icon associated with the session.  @p newTitle is the name 
-   *    of the icon to use, which can be the name of any icon in the current KDE icon
-   *    theme (eg: 'konsole', 'kate', 'folder_home')</li>
-   * </ul>
-   * @param newTitle Specifies the new title 
-   */
-
-  void titleChanged(int title,const QString& newTitle);
-
-  /**
-   * Emitted when the program running in the terminal changes the
-   * screen size.
-   */
-  void imageSizeChanged(int lineCount , int columnCount);
-
-  /** 
-   * Emitted when the terminal program requests to change various properties
-   * of the terminal display.  
-   *
-   * A profile change command occurs when a special escape sequence, followed
-   * by a string containing a series of name and value pairs is received.
-   * This string can be parsed using a ProfileCommandParser instance.
-   *
-   * @param text A string expected to contain a series of key and value pairs in
-   * the form:  name=value;name2=value2 ...
-   */
-  void profileChangeCommandReceived(const QString& text);
-
-protected:
-  virtual void setMode  (int mode) = 0;
-  virtual void resetMode(int mode) = 0;
-   
- /** 
-   * Processes an incoming character.  See receiveData()
-   * @p ch A unicode character code. 
-   */
-  virtual void receiveChar(int ch);
-
-  /** 
-   * Sets the active screen.  The terminal has two screens, primary and alternate.
-   * The primary screen is used by default.  When certain interactive programs such
-   * as Vim are run, they trigger a switch to the alternate screen.
-   *
-   * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen
-   */
-  void setScreen(int index); 
-
-  enum EmulationCodec
-  {
-      LocaleCodec = 0,
-      Utf8Codec   = 1
-  };
-  void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8
-
-
-  QList<ScreenWindow*> _windows;
-  
-  Screen* _currentScreen;  // pointer to the screen which is currently active, 
-                            // this is one of the elements in the screen[] array
-
-  Screen* _screen[2];      // 0 = primary screen ( used by most programs, including the shell
-                            //                      scrollbars are enabled in this mode )
-                            // 1 = alternate      ( used by vi , emacs etc.
-                            //                      scrollbars are not enabled in this mode )
-                            
-  
-  //decodes an incoming C-style character stream into a unicode QString using 
-  //the current text codec.  (this allows for rendering of non-ASCII characters in text files etc.)
-  const QTextCodec* _codec;
-  QTextDecoder* _decoder;
-
-  const KeyboardTranslator* _keyTranslator; // the keyboard layout
-
-protected slots:
-  /** 
-   * Schedules an update of attached views.
-   * Repeated calls to bufferedUpdate() in close succession will result in only a single update,
-   * much like the Qt buffered update of widgets. 
-   */
-  void bufferedUpdate();
-
-private slots: 
-
-  // triggered by timer, causes the emulation to send an updated screen image to each
-  // view
-  void showBulk(); 
-
-  void usesMouseChanged(bool usesMouse);
-
-private:
-
-  bool _usesMouse;
-  QTimer _bulkTimer1;
-  QTimer _bulkTimer2;
-  
-};
-
-}
-
-#endif // ifndef EMULATION_H
--- a/gui/qtermwidget/lib/ExtendedDefaultTranslator.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-"keyboard \"Default (XFree 4)\""
-"key Escape             : \"\\E\""
-"key Tab   -Shift       : \"\\t\"\n"
-"key Tab   +Shift+Ansi  : \"\\E[Z\"\n"
-"key Tab   +Shift-Ansi  : \"\\t\"\n"
-"key Backtab     +Ansi  : \"\\E[Z\"\n"
-"key Backtab     -Ansi  : \"\\t\"\n"
-"key Return-Shift-NewLine : \"\\r\"\n"
-"key Return-Shift+NewLine : \"\\r\\n\"\n"
-"key Return+Shift         : \"\\EOM\"\n"
-"key Backspace      : \"\\x7f\"\n"
-"key Up   -Shift-Ansi : \"\\EA\"\n"
-"key Down -Shift-Ansi : \"\\EB\"\n"
-"key Right-Shift-Ansi : \"\\EC\"\n"
-"key Left -Shift-Ansi : \"\\ED\"\n"
-"key Up    -Shift-AnyMod+Ansi+AppCuKeys           : \"\\EOA\"\n"
-"key Down  -Shift-AnyMod+Ansi+AppCuKeys           : \"\\EOB\"\n"
-"key Right -Shift-AnyMod+Ansi+AppCuKeys           : \"\\EOC\"\n"
-"key Left  -Shift-AnyMod+Ansi+AppCuKeys           : \"\\EOD\"\n"
-"key Up    -Shift-AnyMod+Ansi-AppCuKeys           : \"\\E[A\"\n"
-"key Down  -Shift-AnyMod+Ansi-AppCuKeys           : \"\\E[B\"\n"
-"key Right -Shift-AnyMod+Ansi-AppCuKeys           : \"\\E[C\"\n"
-"key Left  -Shift-AnyMod+Ansi-AppCuKeys           : \"\\E[D\"\n"
-"key Up    -Shift+AnyMod+Ansi                     : \"\\E[1;*A\"\n"
-"key Down  -Shift+AnyMod+Ansi                     : \"\\E[1;*B\"\n"
-"key Right -Shift+AnyMod+Ansi                     : \"\\E[1;*C\"\n"
-"key Left  -Shift+AnyMod+Ansi                     : \"\\E[1;*D\"\n"
-"key Enter+NewLine : \"\\r\\n\"\n"
-"key Enter-NewLine : \"\\r\"\n"
-"key Home        -AnyMod     -AppCuKeys           : \"\\E[H\"  \n"
-"key End         -AnyMod     -AppCuKeys           : \"\\E[F\"  \n"
-"key Home        -AnyMod     +AppCuKeys           : \"\\EOH\"  \n"
-"key End         -AnyMod     +AppCuKeys           : \"\\EOF\"  \n"
-"key Home        +AnyMod                          : \"\\E[1;*H\"\n"
-"key End         +AnyMod                          : \"\\E[1;*F\"\n"
-"key Insert      -AnyMod                          : \"\\E[2~\"\n"
-"key Delete      -AnyMod                          : \"\\E[3~\"\n"
-"key Insert      +AnyMod                          : \"\\E[2;*~\"\n"
-"key Delete      +AnyMod                          : \"\\E[3;*~\"\n"
-"key Prior -Shift-AnyMod                          : \"\\E[5~\"\n"
-"key Next  -Shift-AnyMod                          : \"\\E[6~\"\n"
-"key Prior -Shift+AnyMod                          : \"\\E[5;*~\"\n"
-"key Next  -Shift+AnyMod                          : \"\\E[6;*~\"\n"
-"key F1          -AnyMod                          : \"\\EOP\"\n"
-"key F2          -AnyMod                          : \"\\EOQ\"\n"
-"key F3          -AnyMod                          : \"\\EOR\"\n"
-"key F4          -AnyMod                          : \"\\EOS\"\n"
-"key F5          -AnyMod                          : \"\\E[15~\"\n"
-"key F6          -AnyMod                          : \"\\E[17~\"\n"
-"key F7          -AnyMod                          : \"\\E[18~\"\n"
-"key F8          -AnyMod                          : \"\\E[19~\"\n"
-"key F9          -AnyMod                          : \"\\E[20~\"\n"
-"key F10         -AnyMod                          : \"\\E[21~\"\n"
-"key F11         -AnyMod                          : \"\\E[23~\"\n"
-"key F12         -AnyMod                          : \"\\E[24~\"\n"
-"key F1          +AnyMod                          : \"\\EO*P\"\n"
-"key F2          +AnyMod                          : \"\\EO*Q\"\n"
-"key F3          +AnyMod                          : \"\\EO*R\"\n"
-"key F4          +AnyMod                          : \"\\EO*S\"\n"
-"key F5          +AnyMod                          : \"\\E[15;*~\"\n"
-"key F6          +AnyMod                          : \"\\E[17;*~\"\n"
-"key F7          +AnyMod                          : \"\\E[18;*~\"\n"
-"key F8          +AnyMod                          : \"\\E[19;*~\"\n"
-"key F9          +AnyMod                          : \"\\E[20;*~\"\n"
-"key F10         +AnyMod                          : \"\\E[21;*~\"\n"
-"key F11         +AnyMod                          : \"\\E[23;*~\"\n"
-"key F12         +AnyMod                          : \"\\E[24;*~\"\n"
-"key Space +Control : \"\\x00\"\n"
-"key Up    +Shift-AppScreen  : scrollLineUp\n"
-"key Prior +Shift-AppScreen  : scrollPageUp\n"
-"key Down  +Shift-AppScreen  : scrollLineDown\n"
-"key Next  +Shift-AppScreen  : scrollPageDown\n"
-"key ScrollLock     : scrollLock\n"
-"\0"
--- a/gui/qtermwidget/lib/Filter.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,562 +0,0 @@
-/*
-    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 "Filter.h"
-
-// System
-#include <iostream>
-
-// Qt
-#include <QtGui/QAction>
-#include <QtGui/QApplication>
-#include <QtGui/QClipboard>
-#include <QtCore/QString>
-
-#include <QtCore/QSharedData>
-#include <QtCore>
-
-// KDE
-//#include <KLocale>
-//#include <KRun>
-
-// Konsole
-#include "TerminalCharacterDecoder.h"
-
-using namespace Konsole;
-
-FilterChain::~FilterChain()
-{
-    QMutableListIterator<Filter*> iter(*this);
-    
-    while ( iter.hasNext() )
-    {
-        Filter* filter = iter.next();
-        iter.remove();
-        delete filter;
-    }
-}
-
-void FilterChain::addFilter(Filter* filter)
-{
-    append(filter);
-}
-void FilterChain::removeFilter(Filter* filter)
-{
-    removeAll(filter);
-}
-bool FilterChain::containsFilter(Filter* filter)
-{
-    return contains(filter);
-}
-void FilterChain::reset()
-{
-    QListIterator<Filter*> iter(*this);
-    while (iter.hasNext())
-        iter.next()->reset();
-}
-void FilterChain::setBuffer(const QString* buffer , const QList<int>* linePositions)
-{
-    QListIterator<Filter*> iter(*this);
-    while (iter.hasNext())
-        iter.next()->setBuffer(buffer,linePositions);
-}
-void FilterChain::process()
-{
-    QListIterator<Filter*> iter(*this);
-    while (iter.hasNext())
-        iter.next()->process();
-}
-void FilterChain::clear()
-{
-    QList<Filter*>::clear();
-}
-Filter::HotSpot* FilterChain::hotSpotAt(int line , int column) const
-{
-    QListIterator<Filter*> iter(*this);
-    while (iter.hasNext())
-    {
-        Filter* filter = iter.next();
-        Filter::HotSpot* spot = filter->hotSpotAt(line,column);
-        if ( spot != 0 )
-        {
-            return spot;
-        }
-    }
-
-    return 0;
-}
-
-QList<Filter::HotSpot*> FilterChain::hotSpots() const
-{
-    QList<Filter::HotSpot*> list;
-    QListIterator<Filter*> iter(*this);
-    while (iter.hasNext())
-    {
-        Filter* filter = iter.next();
-        list << filter->hotSpots();
-    }
-    return list;
-}
-//QList<Filter::HotSpot*> FilterChain::hotSpotsAtLine(int line) const;
-
-TerminalImageFilterChain::TerminalImageFilterChain()
-: _buffer(0)
-, _linePositions(0)
-{
-}
-
-TerminalImageFilterChain::~TerminalImageFilterChain()
-{
-    delete _buffer;
-    delete _linePositions;
-}
-
-void TerminalImageFilterChain::setImage(const Character* const image , int lines , int columns, const QVector<LineProperty>& lineProperties)
-{
-//qDebug("%s %d", __FILE__, __LINE__);
-    if (empty())
-        return;
-//qDebug("%s %d", __FILE__, __LINE__);
-
-    // reset all filters and hotspots
-    reset();
-//qDebug("%s %d", __FILE__, __LINE__);
-
-    PlainTextDecoder decoder;
-    decoder.setTrailingWhitespace(false);
-    
-//qDebug("%s %d", __FILE__, __LINE__);
-    // setup new shared buffers for the filters to process on
-    QString* newBuffer = new QString();
-    QList<int>* newLinePositions = new QList<int>();
-    setBuffer( newBuffer , newLinePositions );
-
-    // free the old buffers
-    delete _buffer;
-    delete _linePositions;
-
-    _buffer = newBuffer;
-    _linePositions = newLinePositions;
-
-    QTextStream lineStream(_buffer);
-    decoder.begin(&lineStream);
-
-    for (int i=0 ; i < lines ; i++)
-    {
-        _linePositions->append(_buffer->length());
-        decoder.decodeLine(image + i*columns,columns,LINE_DEFAULT);
-
-        // pretend that each line ends with a newline character.
-        // this prevents a link that occurs at the end of one line
-        // being treated as part of a link that occurs at the start of the next line
-        //
-        // the downside is that links which are spread over more than one line are not
-        // highlighted.  
-        //
-        // TODO - Use the "line wrapped" attribute associated with lines in a
-        // terminal image to avoid adding this imaginary character for wrapped
-        // lines
-        if ( !(lineProperties.value(i,LINE_DEFAULT) & LINE_WRAPPED) )
-        	lineStream << QChar('\n');
-    }
-    decoder.end();
-//    qDebug("%s %d", __FILE__, __LINE__);
-}
-
-Filter::Filter() :
-_linePositions(0),
-_buffer(0)
-{
-}
-
-Filter::~Filter()
-{
-    QListIterator<HotSpot*> iter(_hotspotList);
-    while (iter.hasNext())
-    {
-        delete iter.next();
-    }
-}
-void Filter::reset()
-{
-    _hotspots.clear();
-    _hotspotList.clear();
-}
-
-void Filter::setBuffer(const QString* buffer , const QList<int>* linePositions)
-{
-    _buffer = buffer;
-    _linePositions = linePositions;
-}
-
-void Filter::getLineColumn(int position , int& startLine , int& startColumn)
-{
-    Q_ASSERT( _linePositions );
-    Q_ASSERT( _buffer );
-
-
-    for (int i = 0 ; i < _linePositions->count() ; i++)
-    {
-        //kDebug() << "line position at " << i << " = " << _linePositions[i];
-        int nextLine = 0;
-
-        if ( i == _linePositions->count()-1 )
-        {
-            nextLine = _buffer->length() + 1;
-        }
-        else
-        {
-            nextLine = _linePositions->value(i+1);
-        }
-
-       // kDebug() << "pos - " << position << " line pos(" << i<< ") " << _linePositions->value(i) << 
-       //     " next = " << nextLine << " buffer len = " << _buffer->length();
-
-        if ( _linePositions->value(i) <= position && position < nextLine ) 
-        {
-            startLine = i;
-            startColumn = position - _linePositions->value(i);
-            return;
-        }
-    }
-}
-    
-
-/*void Filter::addLine(const QString& text)
-{
-    _linePositions << _buffer.length();
-    _buffer.append(text);
-}*/
-
-const QString* Filter::buffer()
-{
-    return _buffer;
-}
-Filter::HotSpot::~HotSpot()
-{
-}
-void Filter::addHotSpot(HotSpot* spot)
-{
-    _hotspotList << spot;
-
-    for (int line = spot->startLine() ; line <= spot->endLine() ; line++)
-    {
-        _hotspots.insert(line,spot);
-    }    
-}
-QList<Filter::HotSpot*> Filter::hotSpots() const
-{
-    return _hotspotList;
-}
-QList<Filter::HotSpot*> Filter::hotSpotsAtLine(int line) const
-{
-    return _hotspots.values(line);
-}
-
-Filter::HotSpot* Filter::hotSpotAt(int line , int column) const
-{
-    QListIterator<HotSpot*> spotIter(_hotspots.values(line));
-
-    while (spotIter.hasNext())
-    {
-        HotSpot* spot = spotIter.next();
-        
-        if ( spot->startLine() == line && spot->startColumn() > column )
-            continue;
-        if ( spot->endLine() == line && spot->endColumn() < column )
-            continue;
-       
-        return spot;
-    }
-
-    return 0;
-}
-
-Filter::HotSpot::HotSpot(int startLine , int startColumn , int endLine , int endColumn)
-    : _startLine(startLine)
-    , _startColumn(startColumn)
-    , _endLine(endLine)
-    , _endColumn(endColumn)
-    , _type(NotSpecified)
-{
-}
-QString Filter::HotSpot::tooltip() const
-{
-    return QString();
-}
-QList<QAction*> Filter::HotSpot::actions()
-{
-    return QList<QAction*>();
-}
-int Filter::HotSpot::startLine() const
-{
-    return _startLine;
-}
-int Filter::HotSpot::endLine() const
-{
-    return _endLine;
-}
-int Filter::HotSpot::startColumn() const
-{
-    return _startColumn;
-}
-int Filter::HotSpot::endColumn() const
-{
-    return _endColumn;
-}
-Filter::HotSpot::Type Filter::HotSpot::type() const
-{
-    return _type;
-}
-void Filter::HotSpot::setType(Type type)
-{
-    _type = type;
-}
-
-RegExpFilter::RegExpFilter()
-{
-}
-
-RegExpFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
-    : Filter::HotSpot(startLine,startColumn,endLine,endColumn)
-{
-    setType(Marker);
-}
-
-void RegExpFilter::HotSpot::activate(QObject*)
-{
-}
-
-void RegExpFilter::HotSpot::setCapturedTexts(const QStringList& texts)
-{
-    _capturedTexts = texts;
-}
-QStringList RegExpFilter::HotSpot::capturedTexts() const
-{
-    return _capturedTexts;
-}
-
-void RegExpFilter::setRegExp(const QRegExp& regExp) 
-{
-    _searchText = regExp;
-}
-QRegExp RegExpFilter::regExp() const
-{
-    return _searchText;
-}
-/*void RegExpFilter::reset(int)
-{
-    _buffer = QString();
-}*/
-void RegExpFilter::process()
-{
-    int pos = 0;
-    const QString* text = buffer();
-
-    Q_ASSERT( text );
-
-    // ignore any regular expressions which match an empty string.
-    // otherwise the while loop below will run indefinitely
-    static const QString emptyString("");
-    if ( _searchText.exactMatch(emptyString) )
-        return;
-
-    while(pos >= 0)
-    {
-        pos = _searchText.indexIn(*text,pos);
-
-        if ( pos >= 0 )
-        {
-
-            int startLine = 0;
-            int endLine = 0;
-            int startColumn = 0;
-            int endColumn = 0;
-
-            
-            //kDebug() << "pos from " << pos << " to " << pos + _searchText.matchedLength();
-            
-            getLineColumn(pos,startLine,startColumn);
-            getLineColumn(pos + _searchText.matchedLength(),endLine,endColumn);
-
-            //kDebug() << "start " << startLine << " / " << startColumn;
-            //kDebug() << "end " << endLine << " / " << endColumn;
-
-            RegExpFilter::HotSpot* spot = newHotSpot(startLine,startColumn,
-                                           endLine,endColumn);
-            spot->setCapturedTexts(_searchText.capturedTexts());
-
-            addHotSpot( spot );  
-            pos += _searchText.matchedLength();
-
-            // if matchedLength == 0, the program will get stuck in an infinite loop
-            Q_ASSERT( _searchText.matchedLength() > 0 );
-        }
-    }    
-}
-
-RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn,
-                                                int endLine,int endColumn)
-{
-    return new RegExpFilter::HotSpot(startLine,startColumn,
-                                                  endLine,endColumn);
-}
-RegExpFilter::HotSpot* UrlFilter::newHotSpot(int startLine,int startColumn,int endLine,
-                                                    int endColumn)
-{
-    return new UrlFilter::HotSpot(startLine,startColumn,
-                                               endLine,endColumn);
-}
-UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
-: RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn)
-, _urlObject(new FilterObject(this))
-{
-    setType(Link);
-}
-QString UrlFilter::HotSpot::tooltip() const
-{
-    QString url = capturedTexts().first();
-
-    const UrlType kind = urlType();
-
-    if ( kind == StandardUrl )
-        return QString(); 
-    else if ( kind == Email )
-        return QString(); 
-    else
-        return QString();
-}
-UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
-{
-    QString url = capturedTexts().first();
-    
-    if ( FullUrlRegExp.exactMatch(url) )
-        return StandardUrl;
-    else if ( EmailAddressRegExp.exactMatch(url) )
-        return Email;
-    else
-        return Unknown;
-}
-
-void UrlFilter::HotSpot::activate(QObject* object)
-{
-    QString url = capturedTexts().first();
-
-    const UrlType kind = urlType();
-
-    const QString& actionName = object ? object->objectName() : QString();
-
-    if ( actionName == "copy-action" )
-    {
-        //kDebug() << "Copying url to clipboard:" << url;
-
-        QApplication::clipboard()->setText(url);
-        return;
-    }
-
-    if ( !object || actionName == "open-action" )
-    {
-        if ( kind == StandardUrl )
-        {
-            // if the URL path does not include the protocol ( eg. "www.kde.org" ) then
-            // prepend http:// ( eg. "www.kde.org" --> "http://www.kde.org" )
-            if (!url.contains("://"))
-            {
-                url.prepend("http://");
-            }
-        } 
-        else if ( kind == Email )
-        {
-            url.prepend("mailto:");
-        }
-    
-//        new KRun(url,QApplication::activeWindow());
-    }
-}
-
-// Note:  Altering these regular expressions can have a major effect on the performance of the filters 
-// used for finding URLs in the text, especially if they are very general and could match very long
-// pieces of text.
-// Please be careful when altering them.
-
-//regexp matches:
-// full url:  
-// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, comma and dot
-const QRegExp UrlFilter::FullUrlRegExp("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]");
-// email address:
-// [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
-const QRegExp UrlFilter::EmailAddressRegExp("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b");
-
-// matches full url or email address
-const QRegExp UrlFilter::CompleteUrlRegExp('('+FullUrlRegExp.pattern()+'|'+
-                                            EmailAddressRegExp.pattern()+')');
-
-UrlFilter::UrlFilter()
-{
-    setRegExp( CompleteUrlRegExp );
-}
-UrlFilter::HotSpot::~HotSpot()
-{
-    delete _urlObject;
-}
-void FilterObject::activated()
-{
-    _filter->activate(sender());
-}
-QList<QAction*> UrlFilter::HotSpot::actions()
-{
-    QList<QAction*> list;
-
-    const UrlType kind = urlType();
-
-    QAction* openAction = new QAction(_urlObject);
-    QAction* copyAction = new QAction(_urlObject);;
-
-    Q_ASSERT( kind == StandardUrl || kind == Email );
-
-    if ( kind == StandardUrl )
-    {
-        openAction->setText(("Open Link"));
-        copyAction->setText(("Copy Link Address"));
-    }
-    else if ( kind == Email )
-    {
-        openAction->setText(("Send Email To..."));
-        copyAction->setText(("Copy Email Address"));
-    }
-
-    // object names are set here so that the hotspot performs the
-    // correct action when activated() is called with the triggered
-    // action passed as a parameter.
-    openAction->setObjectName("open-action");
-    copyAction->setObjectName("copy-action");
-
-    QObject::connect( openAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
-    QObject::connect( copyAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
-
-    list << openAction;
-    list << copyAction;
-
-    return list; 
-}
-
-//#include "moc_Filter.cpp"
--- a/gui/qtermwidget/lib/Filter.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,383 +0,0 @@
-/*
-    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.
-*/
-
-#ifndef FILTER_H
-#define FILTER_H
-
-// Qt
-#include <QtGui/QAction>
-#include <QtCore/QList>
-#include <QtCore/QObject>
-#include <QtCore/QStringList>
-#include <QtCore/QHash>
-#include <QtCore/QRegExp>
-
-// Local
-#include "Character.h"
-
-namespace Konsole
-{
-
-/**
- * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
- * and marks the areas which match the filter's patterns as 'hotspots'.
- *
- * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
- * and an action.  When the user performs some activity such as a mouse-click in a hotspot area ( the exact
- * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
- * activate() method should be called.  Depending on the type of hotspot this will trigger a suitable response.
- *
- * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
- * Hotspots may have more than one action, in which case the list of actions can be obtained using the 
- * actions() method.
- *
- * Different subclasses of filter will return different types of hotspot.
- * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
- * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest
- * and add them to the filter's list of hotspots using addHotSpot()
- */
-class Filter
-{
-public:
-    /**
-    * Represents an area of text which matched the pattern a particular filter has been looking for.
-    *
-    * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
-    * and an action.  When the user performs some activity such as a mouse-click in a hotspot area ( the exact
-    * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
-    * activate() method should be called.  Depending on the type of hotspot this will trigger a suitable response.
-    *
-    * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
-    * Hotspots may have more than one action, in which case the list of actions can be obtained using the 
-    * actions() method.  These actions may then be displayed in a popup menu or toolbar for example. 
-    */
-    class HotSpot
-    {
-    public:
-       /** 
-        * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
-        * in a block of text.
-        */
-       HotSpot(int startLine , int startColumn , int endLine , int endColumn);
-       virtual ~HotSpot();
-
-       enum Type
-       {
-            // the type of the hotspot is not specified
-            NotSpecified,
-            // this hotspot represents a clickable link
-            Link,
-            // this hotspot represents a marker
-            Marker
-       }; 
-
-       /** Returns the line when the hotspot area starts */
-       int startLine() const;
-       /** Returns the line where the hotspot area ends */
-       int endLine() const;
-       /** Returns the column on startLine() where the hotspot area starts */
-       int startColumn() const;
-       /** Returns the column on endLine() where the hotspot area ends */
-       int endColumn() const;
-       /** 
-        * Returns the type of the hotspot.  This is usually used as a hint for views on how to represent
-        * the hotspot graphically.  eg.  Link hotspots are typically underlined when the user mouses over them
-        */
-       Type type() const;
-       /** 
-        * Causes the an action associated with a hotspot to be triggered. 
-        *
-        * @param object The object which caused the hotspot to be triggered.  This is
-        * typically null ( in which case the default action should be performed ) or
-        * one of the objects from the actions() list.  In which case the associated
-        * action should be performed. 
-        */
-       virtual void activate(QObject* object = 0) = 0; 
-       /** 
-        * Returns a list of actions associated with the hotspot which can be used in a 
-        * menu or toolbar 
-        */
-       virtual QList<QAction*> actions();
-
-       /** 
-        * Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or
-        * an empty string if there is no tooltip associated with this hotspot.
-        *
-        * The default implementation returns an empty string. 
-        */
-       virtual QString tooltip() const;
-
-    protected:
-       /** Sets the type of a hotspot.  This should only be set once */
-       void setType(Type type);
-
-    private:
-       int    _startLine;
-       int    _startColumn;
-       int    _endLine;
-       int    _endColumn;
-       Type _type;
-    
-    };
-
-    /** Constructs a new filter. */
-    Filter();
-    virtual ~Filter();
-
-    /** Causes the filter to process the block of text currently in its internal buffer */
-    virtual void process() = 0;
-
-    /** 
-     * Empties the filters internal buffer and resets the line count back to 0.
-     * All hotspots are deleted. 
-     */
-    void reset();
-
-    /** Adds a new line of text to the filter and increments the line count */
-    //void addLine(const QString& string);
-
-    /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */
-    HotSpot* hotSpotAt(int line , int column) const;
-
-    /** Returns the list of hotspots identified by the filter */
-    QList<HotSpot*> hotSpots() const;
-
-    /** Returns the list of hotspots identified by the filter which occur on a given line */
-    QList<HotSpot*> hotSpotsAtLine(int line) const;
-
-    /** 
-     * TODO: Document me
-     */
-    void setBuffer(const QString* buffer , const QList<int>* linePositions);
-
-protected:
-    /** Adds a new hotspot to the list */
-    void addHotSpot(HotSpot*);
-    /** Returns the internal buffer */
-    const QString* buffer();
-    /** Converts a character position within buffer() to a line and column */
-    void getLineColumn(int position , int& startLine , int& startColumn);
-
-private:
-    QMultiHash<int,HotSpot*> _hotspots;
-    QList<HotSpot*> _hotspotList;
-    
-    const QList<int>* _linePositions;
-    const QString* _buffer;
-};
-
-/** 
- * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot 
- * instance for them.
- *
- * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression
- * are found. 
- */
-class RegExpFilter : public Filter
-{
-public:
-    /** 
-     * Type of hotspot created by RegExpFilter.  The capturedTexts() method can be used to find the text
-     * matched by the filter's regular expression.
-     */
-    class HotSpot : public Filter::HotSpot
-    {
-    public:
-        HotSpot(int startLine, int startColumn, int endLine , int endColumn);
-        virtual void activate(QObject* object = 0);
-
-        /** Sets the captured texts associated with this hotspot */
-        void setCapturedTexts(const QStringList& texts);
-        /** Returns the texts found by the filter when matching the filter's regular expression */
-        QStringList capturedTexts() const;
-    private:
-        QStringList _capturedTexts;
-    };
-
-    /** Constructs a new regular expression filter */
-    RegExpFilter();
-
-    /** 
-     * Sets the regular expression which the filter searches for in blocks of text. 
-     *
-     * Regular expressions which match the empty string are treated as not matching
-     * anything. 
-     */
-    void setRegExp(const QRegExp& text);
-    /** Returns the regular expression which the filter searches for in blocks of text */
-    QRegExp regExp() const;
-
-    /** 
-     * Reimplemented to search the filter's text buffer for text matching regExp() 
-     *
-     * If regexp matches the empty string, then process() will return immediately
-     * without finding results. 
-     */
-    virtual void process();
-
-protected:
-    /** 
-     * Called when a match for the regular expression is encountered.  Subclasses should reimplement this
-     * to return custom hotspot types
-     */
-    virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn,
-                                    int endLine,int endColumn);
-
-private:
-    QRegExp _searchText;
-};
-
-class FilterObject;
-
-/** A filter which matches URLs in blocks of text */
-class UrlFilter : public RegExpFilter 
-{
-public:
-    /** 
-     * Hotspot type created by UrlFilter instances.  The activate() method opens a web browser 
-     * at the given URL when called.
-     */
-    class HotSpot : public RegExpFilter::HotSpot 
-    {
-    public:
-        HotSpot(int startLine,int startColumn,int endLine,int endColumn);
-        virtual ~HotSpot();
-
-        virtual QList<QAction*> actions();
-
-        /** 
-         * Open a web browser at the current URL.  The url itself can be determined using
-         * the capturedTexts() method.
-         */
-        virtual void activate(QObject* object = 0);
-
-        virtual QString tooltip() const;
-    private:
-        enum UrlType
-        {
-            StandardUrl,
-            Email,
-            Unknown
-        };
-        UrlType urlType() const;
-
-        FilterObject* _urlObject;
-    };
-
-    UrlFilter();
-
-protected:
-    virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int);
-
-private:
-    
-    static const QRegExp FullUrlRegExp;
-    static const QRegExp EmailAddressRegExp;
-
-    // combined OR of FullUrlRegExp and EmailAddressRegExp
-    static const QRegExp CompleteUrlRegExp; 
-};
-
-class FilterObject : public QObject
-{
-Q_OBJECT
-public:
-    FilterObject(Filter::HotSpot* filter) : _filter(filter) {}
-private slots:
-    void activated();
-private:
-    Filter::HotSpot* _filter;
-};
-
-/** 
- * A chain which allows a group of filters to be processed as one. 
- * The chain owns the filters added to it and deletes them when the chain itself is destroyed.
- *
- * Use addFilter() to add a new filter to the chain.  
- * When new text to be filtered arrives, use addLine() to add each additional
- * line of text which needs to be processed and then after adding the last line, use
- * process() to cause each filter in the chain to process the text.
- *
- * After processing a block of text, the reset() method can be used to set the filter chain's
- * internal cursor back to the first line.
- *
- * The hotSpotAt() method will return the first hotspot which covers a given position.
- *
- * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
- * a given line respectively.
- */
-class FilterChain : protected QList<Filter*>
-{
-public:
-    virtual ~FilterChain();
-
-    /** Adds a new filter to the chain.  The chain will delete this filter when it is destroyed */
-    void addFilter(Filter* filter);
-    /** Removes a filter from the chain.  The chain will no longer delete the filter when destroyed */
-    void removeFilter(Filter* filter);
-    /** Returns true if the chain contains @p filter */
-    bool containsFilter(Filter* filter);
-    /** Removes all filters from the chain */
-    void clear();
-
-    /** Resets each filter in the chain */
-    void reset();
-    /**
-     * Processes each filter in the chain 
-     */
-    void process();
-
-    /** Sets the buffer for each filter in the chain to process. */
-    void setBuffer(const QString* buffer , const QList<int>* linePositions); 
-
-    /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
-    Filter::HotSpot* hotSpotAt(int line , int column) const;
-    /** Returns a list of all the hotspots in all the chain's filters */
-    QList<Filter::HotSpot*> hotSpots() const;
-    /** Returns a list of all hotspots at the given line in all the chain's filters */
-    QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
-
-};
-
-/** A filter chain which processes character images from terminal displays */
-class TerminalImageFilterChain : public FilterChain
-{
-public:
-    TerminalImageFilterChain();
-    virtual ~TerminalImageFilterChain();
-
-    /**
-     * Set the current terminal image to @p image.
-     *
-     * @param image The terminal image
-     * @param lines The number of lines in the terminal image
-     * @param columns The number of columns in the terminal image
-     */
-    void setImage(const Character* const image , int lines , int columns,
-				  const QVector<LineProperty>& lineProperties);  
-
-private:
-    QString* _buffer;
-    QList<int>* _linePositions;
-};
-
-}
-#endif //FILTER_H
--- a/gui/qtermwidget/lib/History.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,698 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    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
-
-    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 "History.h"
-
-// System
-#include <iostream>
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <errno.h>
-
-
-// Reasonable line size
-#define LINE_SIZE	1024
-
-using namespace Konsole;
-
-/*
-   An arbitrary long scroll.
-
-   One can modify the scroll only by adding either cells
-   or newlines, but access it randomly.
-
-   The model is that of an arbitrary wide typewriter scroll
-   in that the scroll is a serie of lines and each line is
-   a serie of cells with no overwriting permitted.
-
-   The implementation provides arbitrary length and numbers
-   of cells and line/column indexed read access to the scroll
-   at constant costs.
-
-KDE4: Can we use QTemporaryFile here, instead of KTempFile?
-
-FIXME: some complain about the history buffer comsuming the
-       memory of their machines. This problem is critical
-       since the history does not behave gracefully in cases
-       where the memory is used up completely.
-
-       I put in a workaround that should handle it problem
-       now gracefully. I'm not satisfied with the solution.
-
-FIXME: Terminating the history is not properly indicated
-       in the menu. We should throw a signal.
-
-FIXME: There is noticeable decrease in speed, also. Perhaps,
-       there whole feature needs to be revisited therefore.
-       Disadvantage of a more elaborated, say block-oriented
-       scheme with wrap around would be it's complexity.
-*/
-
-//FIXME: tempory replacement for tmpfile
-//       this is here one for debugging purpose.
-
-//#define tmpfile xTmpFile
-
-// History File ///////////////////////////////////////////
-
-/*
-  A Row(X) data type which allows adding elements to the end.
-*/
-
-HistoryFile::HistoryFile()
-  : ion(-1),
-    length(0),
-	fileMap(0)
-{
-  if (tmpFile.open())
-  { 
-    tmpFile.setAutoRemove(true);
-    ion = tmpFile.handle();
-  }
-}
-
-HistoryFile::~HistoryFile()
-{
-	if (fileMap)
-		unmap();
-}
-
-//TODO:  Mapping the entire file in will cause problems if the history file becomes exceedingly large,
-//(ie. larger than available memory).  HistoryFile::map() should only map in sections of the file at a time,
-//to avoid this.
-void HistoryFile::map()
-{
-	assert( fileMap == 0 );
-
-	fileMap = (char*)mmap( 0 , length , PROT_READ , MAP_PRIVATE , ion , 0 );
-
-    //if mmap'ing fails, fall back to the read-lseek combination
-    if ( fileMap == MAP_FAILED )
-    {
-            readWriteBalance = 0; 
-            fileMap = 0;
-            qDebug() << ": mmap'ing history failed.  errno = " << errno;
-    }
-}
-
-void HistoryFile::unmap()
-{
-	int result = munmap( fileMap , length );
-	assert( result == 0 );
-
-	fileMap = 0;
-}
-
-bool HistoryFile::isMapped()
-{
-	return (fileMap != 0);
-}
-
-void HistoryFile::add(const unsigned char* bytes, int len)
-{
-  if ( fileMap )
-		  unmap();
-		
-  readWriteBalance++;
-
-  int rc = 0;
-
-  rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryFile::add.seek"); return; }
-  rc = write(ion,bytes,len);       if (rc < 0) { perror("HistoryFile::add.write"); return; }
-  length += rc;
-}
-
-void HistoryFile::get(unsigned char* bytes, int len, int loc)
-{
-  //count number of get() calls vs. number of add() calls.  
-  //If there are many more get() calls compared with add() 
-  //calls (decided by using MAP_THRESHOLD) then mmap the log
-  //file to improve performance.
-  readWriteBalance--;
-  if ( !fileMap && readWriteBalance < MAP_THRESHOLD )
-		  map();
-
-  if ( fileMap )
-  {
-	for (int i=0;i<len;i++)
-			bytes[i]=fileMap[loc+i];
-  }
-  else
-  {	
-  	int rc = 0;
-
-  	if (loc < 0 || len < 0 || loc + len > length)
-    	fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
-  	rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryFile::get.seek"); return; }
-  	rc = read(ion,bytes,len);     if (rc < 0) { perror("HistoryFile::get.read"); return; }
-  }
-}
-
-int HistoryFile::len()
-{
-  return length;
-}
-
-
-// History Scroll abstract base class //////////////////////////////////////
-
-
-HistoryScroll::HistoryScroll(HistoryType* t)
-  : m_histType(t)
-{
-}
-
-HistoryScroll::~HistoryScroll()
-{
-  delete m_histType;
-}
-
-bool HistoryScroll::hasScroll()
-{
-  return true;
-}
-
-// History Scroll File //////////////////////////////////////
-
-/* 
-   The history scroll makes a Row(Row(Cell)) from
-   two history buffers. The index buffer contains
-   start of line positions which refere to the cells
-   buffer.
-
-   Note that index[0] addresses the second line
-   (line #1), while the first line (line #0) starts
-   at 0 in cells.
-*/
-
-HistoryScrollFile::HistoryScrollFile(const QString &logFileName)
-  : HistoryScroll(new HistoryTypeFile(logFileName)),
-  m_logFileName(logFileName)
-{
-}
-
-HistoryScrollFile::~HistoryScrollFile()
-{
-}
- 
-int HistoryScrollFile::getLines()
-{
-  return index.len() / sizeof(int);
-}
-
-int HistoryScrollFile::getLineLen(int lineno)
-{
-  return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(Character);
-}
-
-bool HistoryScrollFile::isWrappedLine(int lineno)
-{
-  if (lineno>=0 && lineno <= getLines()) {
-    unsigned char flag;
-    lineflags.get((unsigned char*)&flag,sizeof(unsigned char),(lineno)*sizeof(unsigned char));
-    return flag;
-  }
-  return false;
-}
-
-int HistoryScrollFile::startOfLine(int lineno)
-{
-  if (lineno <= 0) return 0;
-  if (lineno <= getLines())
-    { 
-	
-	if (!index.isMapped())
-			index.map();
-	
-	int res;
-    index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
-    return res;
-    }
-  return cells.len();
-}
-
-void HistoryScrollFile::getCells(int lineno, int colno, int count, Character res[])
-{
-  cells.get((unsigned char*)res,count*sizeof(Character),startOfLine(lineno)+colno*sizeof(Character));
-}
-
-void HistoryScrollFile::addCells(const Character text[], int count)
-{
-  cells.add((unsigned char*)text,count*sizeof(Character));
-}
-
-void HistoryScrollFile::addLine(bool previousWrapped)
-{
-  if (index.isMapped())
-		  index.unmap();
-
-  int locn = cells.len();
-  index.add((unsigned char*)&locn,sizeof(int));
-  unsigned char flags = previousWrapped ? 0x01 : 0x00;
-  lineflags.add((unsigned char*)&flags,sizeof(unsigned char));
-}
-
-
-// History Scroll Buffer //////////////////////////////////////
-HistoryScrollBuffer::HistoryScrollBuffer(unsigned int maxLineCount)
-  : HistoryScroll(new HistoryTypeBuffer(maxLineCount))
-   ,_historyBuffer()
-   ,_maxLineCount(0)
-   ,_usedLines(0)
-   ,_head(0)
-{
-  setMaxNbLines(maxLineCount);
-}
-
-HistoryScrollBuffer::~HistoryScrollBuffer()
-{
-    delete[] _historyBuffer;
-}
-
-void HistoryScrollBuffer::addCellsVector(const QVector<Character>& cells)
-{
-    _head++;
-    if ( _usedLines < _maxLineCount )
-        _usedLines++;
-
-    if ( _head >= _maxLineCount )
-    {
-        _head = 0;
-    }
-
-    _historyBuffer[bufferIndex(_usedLines-1)] = cells;
-    _wrappedLine[bufferIndex(_usedLines-1)] = false;
-}
-void HistoryScrollBuffer::addCells(const Character a[], int count)
-{
-  HistoryLine newLine(count);
-  qCopy(a,a+count,newLine.begin());
-
-  addCellsVector(newLine);
-}
-
-void HistoryScrollBuffer::addLine(bool previousWrapped)
-{
-    _wrappedLine[bufferIndex(_usedLines-1)] = previousWrapped;
-}
-
-int HistoryScrollBuffer::getLines()
-{
-    return _usedLines;
-}
-
-int HistoryScrollBuffer::getLineLen(int lineNumber)
-{
-  Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
-
-  if ( lineNumber < _usedLines )
-  {
-    return _historyBuffer[bufferIndex(lineNumber)].size();
-  }
-  else
-  {
-    return 0;
-  }
-}
-
-bool HistoryScrollBuffer::isWrappedLine(int lineNumber)
-{
-  Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
-    
-  if (lineNumber < _usedLines)
-  {
-    //kDebug() << "Line" << lineNumber << "wrapped is" << _wrappedLine[bufferIndex(lineNumber)];
-    return _wrappedLine[bufferIndex(lineNumber)];
-  }
-  else
-    return false;
-}
-
-void HistoryScrollBuffer::getCells(int lineNumber, int startColumn, int count, Character* buffer)
-{
-  if ( count == 0 ) return;
-
-  Q_ASSERT( lineNumber < _maxLineCount );
-
-  if (lineNumber >= _usedLines) 
-  {
-    memset(buffer, 0, count * sizeof(Character));
-    return;
-  }
-  
-  const HistoryLine& line = _historyBuffer[bufferIndex(lineNumber)];
-
-  //kDebug() << "startCol " << startColumn;
-  //kDebug() << "line.size() " << line.size();
-  //kDebug() << "count " << count;
-
-  Q_ASSERT( startColumn <= line.size() - count );
-    
-  memcpy(buffer, line.constData() + startColumn , count * sizeof(Character));
-}
-
-void HistoryScrollBuffer::setMaxNbLines(unsigned int lineCount)
-{
-    HistoryLine* oldBuffer = _historyBuffer;
-    HistoryLine* newBuffer = new HistoryLine[lineCount];
-    
-    for ( int i = 0 ; i < qMin(_usedLines,(int)lineCount) ; i++ )
-    {
-        newBuffer[i] = oldBuffer[bufferIndex(i)];
-    }
-    
-    _usedLines = qMin(_usedLines,(int)lineCount);
-    _maxLineCount = lineCount;
-    _head = ( _usedLines == _maxLineCount ) ? 0 : _usedLines-1;
-
-    _historyBuffer = newBuffer;
-    delete[] oldBuffer;
-
-    _wrappedLine.resize(lineCount);
-}
-
-int HistoryScrollBuffer::bufferIndex(int lineNumber)
-{
-    Q_ASSERT( lineNumber >= 0 );
-    Q_ASSERT( lineNumber < _maxLineCount );
-    Q_ASSERT( (_usedLines == _maxLineCount) || lineNumber <= _head );
-
-    if ( _usedLines == _maxLineCount )
-    {
-        return (_head+lineNumber+1) % _maxLineCount;
-    }
-    else
-    {   
-        return lineNumber;
-    }
-}
-
-
-// History Scroll None //////////////////////////////////////
-
-HistoryScrollNone::HistoryScrollNone()
-  : HistoryScroll(new HistoryTypeNone())
-{
-}
-
-HistoryScrollNone::~HistoryScrollNone()
-{
-}
-
-bool HistoryScrollNone::hasScroll()
-{
-  return false;
-}
-
-int  HistoryScrollNone::getLines()
-{
-  return 0;
-}
-
-int  HistoryScrollNone::getLineLen(int)
-{
-  return 0;
-}
-
-bool HistoryScrollNone::isWrappedLine(int /*lineno*/)
-{
-  return false;
-}
-
-void HistoryScrollNone::getCells(int, int, int, Character [])
-{
-}
-
-void HistoryScrollNone::addCells(const Character [], int)
-{
-}
-
-void HistoryScrollNone::addLine(bool)
-{
-}
-
-// History Scroll BlockArray //////////////////////////////////////
-
-HistoryScrollBlockArray::HistoryScrollBlockArray(size_t size)
-  : HistoryScroll(new HistoryTypeBlockArray(size))
-{
-  m_blockArray.setHistorySize(size); // nb. of lines.
-}
-
-HistoryScrollBlockArray::~HistoryScrollBlockArray()
-{
-}
-
-int  HistoryScrollBlockArray::getLines()
-{
-  return m_lineLengths.count();
-}
-
-int  HistoryScrollBlockArray::getLineLen(int lineno)
-{
-    if ( m_lineLengths.contains(lineno) )
-        return m_lineLengths[lineno];
-    else
-        return 0;
-}
-
-bool HistoryScrollBlockArray::isWrappedLine(int /*lineno*/)
-{
-  return false;
-}
-
-void HistoryScrollBlockArray::getCells(int lineno, int colno,
-                                       int count, Character res[])
-{
-  if (!count) return;
-
-  const Block *b = m_blockArray.at(lineno);
-
-  if (!b) {
-    memset(res, 0, count * sizeof(Character)); // still better than random data
-    return;
-  }
-
-  assert(((colno + count) * sizeof(Character)) < ENTRIES);
-  memcpy(res, b->data + (colno * sizeof(Character)), count * sizeof(Character));
-}
-
-void HistoryScrollBlockArray::addCells(const Character a[], int count)
-{
-  Block *b = m_blockArray.lastBlock();
-  
-  if (!b) return;
-
-  // put cells in block's data
-  assert((count * sizeof(Character)) < ENTRIES);
-
-  memset(b->data, 0, ENTRIES);
-
-  memcpy(b->data, a, count * sizeof(Character));
-  b->size = count * sizeof(Character);
-
-  size_t res = m_blockArray.newBlock();
-  assert (res > 0);
-  Q_UNUSED( res );
-
-  m_lineLengths.insert(m_blockArray.getCurrent(), count);
-}
-
-void HistoryScrollBlockArray::addLine(bool)
-{
-}
-
-//////////////////////////////////////////////////////////////////////
-// History Types
-//////////////////////////////////////////////////////////////////////
-
-HistoryType::HistoryType()
-{
-}
-
-HistoryType::~HistoryType()
-{
-}
-
-//////////////////////////////
-
-HistoryTypeNone::HistoryTypeNone()
-{
-}
-
-bool HistoryTypeNone::isEnabled() const
-{
-  return false;
-}
-
-HistoryScroll* HistoryTypeNone::scroll(HistoryScroll *old) const
-{
-  delete old;
-  return new HistoryScrollNone();
-}
-
-int HistoryTypeNone::maximumLineCount() const
-{
-  return 0;
-}
-
-//////////////////////////////
-
-HistoryTypeBlockArray::HistoryTypeBlockArray(size_t size)
-  : m_size(size)
-{
-}
-
-bool HistoryTypeBlockArray::isEnabled() const
-{
-  return true;
-}
-
-int HistoryTypeBlockArray::maximumLineCount() const
-{
-  return m_size;
-}
-
-HistoryScroll* HistoryTypeBlockArray::scroll(HistoryScroll *old) const
-{
-  delete old;
-  return new HistoryScrollBlockArray(m_size);
-}
-
-
-//////////////////////////////
-
-HistoryTypeBuffer::HistoryTypeBuffer(unsigned int nbLines)
-  : m_nbLines(nbLines)
-{
-}
-
-bool HistoryTypeBuffer::isEnabled() const
-{
-  return true;
-}
-
-int HistoryTypeBuffer::maximumLineCount() const
-{
-  return m_nbLines;
-}
-
-HistoryScroll* HistoryTypeBuffer::scroll(HistoryScroll *old) const
-{
-  if (old)
-  {
-    HistoryScrollBuffer *oldBuffer = dynamic_cast<HistoryScrollBuffer*>(old);
-    if (oldBuffer)
-    {
-       oldBuffer->setMaxNbLines(m_nbLines);
-       return oldBuffer;
-    }
-
-    HistoryScroll *newScroll = new HistoryScrollBuffer(m_nbLines);
-    int lines = old->getLines();
-    int startLine = 0;
-    if (lines > (int) m_nbLines)
-       startLine = lines - m_nbLines;
-
-    Character line[LINE_SIZE];
-    for(int i = startLine; i < lines; i++)
-    {
-       int size = old->getLineLen(i);
-       if (size > LINE_SIZE)
-       {
-          Character *tmp_line = new Character[size];
-          old->getCells(i, 0, size, tmp_line);
-          newScroll->addCells(tmp_line, size);
-          newScroll->addLine(old->isWrappedLine(i));
-          delete [] tmp_line;
-       }
-       else
-       {
-          old->getCells(i, 0, size, line);
-          newScroll->addCells(line, size);
-          newScroll->addLine(old->isWrappedLine(i));
-       }
-    }
-    delete old;
-    return newScroll;
-  }
-  return new HistoryScrollBuffer(m_nbLines);
-}
-
-//////////////////////////////
-
-HistoryTypeFile::HistoryTypeFile(const QString& fileName)
-  : m_fileName(fileName)
-{
-}
-
-bool HistoryTypeFile::isEnabled() const
-{
-  return true;
-}
-
-const QString& HistoryTypeFile::getFileName() const
-{
-  return m_fileName;
-}
-
-HistoryScroll* HistoryTypeFile::scroll(HistoryScroll *old) const
-{
-  if (dynamic_cast<HistoryFile *>(old)) 
-     return old; // Unchanged.
-
-  HistoryScroll *newScroll = new HistoryScrollFile(m_fileName);
-
-  Character line[LINE_SIZE];
-  int lines = (old != 0) ? old->getLines() : 0;
-  for(int i = 0; i < lines; i++)
-  {
-     int size = old->getLineLen(i);
-     if (size > LINE_SIZE)
-     {
-        Character *tmp_line = new Character[size];
-        old->getCells(i, 0, size, tmp_line);
-        newScroll->addCells(tmp_line, size);
-        newScroll->addLine(old->isWrappedLine(i));
-        delete [] tmp_line;
-     }
-     else
-     {
-        old->getCells(i, 0, size, line);
-        newScroll->addCells(line, size);
-        newScroll->addLine(old->isWrappedLine(i));
-     }
-  }
-
-  delete old;
-  return newScroll; 
-}
-
-int HistoryTypeFile::maximumLineCount() const
-{
-  return 0;
-}
--- a/gui/qtermwidget/lib/History.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    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
-
-    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.
-*/
-
-#ifndef TEHISTORY_H
-#define TEHISTORY_H
-
-// Qt
-#include <QtCore/QBitRef>
-#include <QtCore/QHash>
-#include <QtCore>
-
-// Konsole
-#include "BlockArray.h"
-#include "Character.h"
-
-namespace Konsole
-{
-
-#if 1
-/*
-   An extendable tmpfile(1) based buffer.
-*/
-
-class HistoryFile
-{
-public:
-  HistoryFile();
-  virtual ~HistoryFile();
-
-  virtual void add(const unsigned char* bytes, int len);
-  virtual void get(unsigned char* bytes, int len, int loc);
-  virtual int  len();
-
-  //mmaps the file in read-only mode
-  void map();
-  //un-mmaps the file
-  void unmap();
-  //returns true if the file is mmap'ed
-  bool isMapped();
-
-
-private:
-  int  ion;
-  int  length;
-  QTemporaryFile tmpFile;
-
-  //pointer to start of mmap'ed file data, or 0 if the file is not mmap'ed
-  char* fileMap;
- 
-  //incremented whenver 'add' is called and decremented whenever
-  //'get' is called.
-  //this is used to detect when a large number of lines are being read and processed from the history
-  //and automatically mmap the file for better performance (saves the overhead of many lseek-read calls).
-  int readWriteBalance;
-
-  //when readWriteBalance goes below this threshold, the file will be mmap'ed automatically
-  static const int MAP_THRESHOLD = -1000;
-};
-#endif
-
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-// Abstract base class for file and buffer versions
-//////////////////////////////////////////////////////////////////////
-class HistoryType;
-
-class HistoryScroll
-{
-public:
-  HistoryScroll(HistoryType*);
- virtual ~HistoryScroll();
-
-  virtual bool hasScroll();
-
-  // access to history
-  virtual int  getLines() = 0;
-  virtual int  getLineLen(int lineno) = 0;
-  virtual void getCells(int lineno, int colno, int count, Character res[]) = 0;
-  virtual bool isWrappedLine(int lineno) = 0;
-
-  // backward compatibility (obsolete)
-  Character   getCell(int lineno, int colno) { Character res; getCells(lineno,colno,1,&res); return res; }
-
-  // adding lines.
-  virtual void addCells(const Character a[], int count) = 0;
-  // convenience method - this is virtual so that subclasses can take advantage
-  // of QVector's implicit copying
-  virtual void addCellsVector(const QVector<Character>& cells)
-  {
-    addCells(cells.data(),cells.size());
-  }
-
-  virtual void addLine(bool previousWrapped=false) = 0;
-
-  //
-  // FIXME:  Passing around constant references to HistoryType instances
-  // is very unsafe, because those references will no longer
-  // be valid if the history scroll is deleted.
-  //
-  const HistoryType& getType() { return *m_histType; }
-
-protected:
-  HistoryType* m_histType;
-
-};
-
-#if 1
-
-//////////////////////////////////////////////////////////////////////
-// File-based history (e.g. file log, no limitation in length)
-//////////////////////////////////////////////////////////////////////
-
-class HistoryScrollFile : public HistoryScroll
-{
-public:
-  HistoryScrollFile(const QString &logFileName);
-  virtual ~HistoryScrollFile();
-
-  virtual int  getLines();
-  virtual int  getLineLen(int lineno);
-  virtual void getCells(int lineno, int colno, int count, Character res[]);
-  virtual bool isWrappedLine(int lineno);
-
-  virtual void addCells(const Character a[], int count);
-  virtual void addLine(bool previousWrapped=false);
-
-private:
-  int startOfLine(int lineno);
-
-  QString m_logFileName;
-  HistoryFile index; // lines Row(int)
-  HistoryFile cells; // text  Row(Character)
-  HistoryFile lineflags; // flags Row(unsigned char)
-};
-
-
-//////////////////////////////////////////////////////////////////////
-// Buffer-based history (limited to a fixed nb of lines)
-//////////////////////////////////////////////////////////////////////
-class HistoryScrollBuffer : public HistoryScroll
-{
-public:
-  typedef QVector<Character> HistoryLine;
-
-  HistoryScrollBuffer(unsigned int maxNbLines = 1000);
-  virtual ~HistoryScrollBuffer();
-
-  virtual int  getLines();
-  virtual int  getLineLen(int lineno);
-  virtual void getCells(int lineno, int colno, int count, Character res[]);
-  virtual bool isWrappedLine(int lineno);
-
-  virtual void addCells(const Character a[], int count);
-  virtual void addCellsVector(const QVector<Character>& cells);
-  virtual void addLine(bool previousWrapped=false);
-
-  void setMaxNbLines(unsigned int nbLines);
-  unsigned int maxNbLines() { return _maxLineCount; }
-  
-
-private:
-  int bufferIndex(int lineNumber);
-
-  HistoryLine* _historyBuffer;
-  QBitArray _wrappedLine;
-  int _maxLineCount;
-  int _usedLines;  
-  int _head;
-  
-  //QVector<histline*> m_histBuffer;
-  //QBitArray m_wrappedLine;
-  //unsigned int m_maxNbLines;
-  //unsigned int m_nbLines;
-  //unsigned int m_arrayIndex;
-  //bool         m_buffFilled;
-};
-
-/*class HistoryScrollBufferV2 : public HistoryScroll
-{
-public:
-  virtual int  getLines();
-  virtual int  getLineLen(int lineno);
-  virtual void getCells(int lineno, int colno, int count, Character res[]);
-  virtual bool isWrappedLine(int lineno);
-
-  virtual void addCells(const Character a[], int count);
-  virtual void addCells(const QVector<Character>& cells);
-  virtual void addLine(bool previousWrapped=false);
-
-};*/
-
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// Nothing-based history (no history :-)
-//////////////////////////////////////////////////////////////////////
-class HistoryScrollNone : public HistoryScroll
-{
-public:
-  HistoryScrollNone();
-  virtual ~HistoryScrollNone();
-
-  virtual bool hasScroll();
-
-  virtual int  getLines();
-  virtual int  getLineLen(int lineno);
-  virtual void getCells(int lineno, int colno, int count, Character res[]);
-  virtual bool isWrappedLine(int lineno);
-
-  virtual void addCells(const Character a[], int count);
-  virtual void addLine(bool previousWrapped=false);
-};
-
-//////////////////////////////////////////////////////////////////////
-// BlockArray-based history
-//////////////////////////////////////////////////////////////////////
-class HistoryScrollBlockArray : public HistoryScroll
-{
-public:
-  HistoryScrollBlockArray(size_t size);
-  virtual ~HistoryScrollBlockArray();
-
-  virtual int  getLines();
-  virtual int  getLineLen(int lineno);
-  virtual void getCells(int lineno, int colno, int count, Character res[]);
-  virtual bool isWrappedLine(int lineno);
-
-  virtual void addCells(const Character a[], int count);
-  virtual void addLine(bool previousWrapped=false);
-
-protected:
-  BlockArray m_blockArray;
-  QHash<int,size_t> m_lineLengths;
-};
-
-//////////////////////////////////////////////////////////////////////
-// History type
-//////////////////////////////////////////////////////////////////////
-
-class HistoryType
-{
-public:
-  HistoryType();
-  virtual ~HistoryType();
-
-  /**
-   * Returns true if the history is enabled ( can store lines of output )
-   * or false otherwise. 
-   */
-  virtual bool isEnabled()           const = 0;
-  /**
-   * Returns true if the history size is unlimited.
-   */
-  bool isUnlimited() const { return maximumLineCount() == 0; }
-  /**
-   * Returns the maximum number of lines which this history type
-   * can store or 0 if the history can store an unlimited number of lines.
-   */
-  virtual int maximumLineCount()    const = 0;
-
-  virtual HistoryScroll* scroll(HistoryScroll *) const = 0;
-};
-
-class HistoryTypeNone : public HistoryType
-{
-public:
-  HistoryTypeNone();
-
-  virtual bool isEnabled() const;
-  virtual int maximumLineCount() const;
-
-  virtual HistoryScroll* scroll(HistoryScroll *) const;
-};
-
-class HistoryTypeBlockArray : public HistoryType
-{
-public:
-  HistoryTypeBlockArray(size_t size);
-  
-  virtual bool isEnabled() const;
-  virtual int maximumLineCount() const;
-
-  virtual HistoryScroll* scroll(HistoryScroll *) const;
-
-protected:
-  size_t m_size;
-};
-
-#if 1 
-class HistoryTypeFile : public HistoryType
-{
-public:
-  HistoryTypeFile(const QString& fileName=QString());
-
-  virtual bool isEnabled() const;
-  virtual const QString& getFileName() const;
-  virtual int maximumLineCount() const;
-
-  virtual HistoryScroll* scroll(HistoryScroll *) const;
-
-protected:
-  QString m_fileName;
-};
-
-
-class HistoryTypeBuffer : public HistoryType
-{
-public:
-  HistoryTypeBuffer(unsigned int nbLines);
-  
-  virtual bool isEnabled() const;
-  virtual int maximumLineCount() const;
-
-  virtual HistoryScroll* scroll(HistoryScroll *) const;
-
-protected:
-  unsigned int m_nbLines;
-};
-
-#endif
-
-}
-
-#endif // TEHISTORY_H
--- a/gui/qtermwidget/lib/KeyboardTranslator.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,903 +0,0 @@
-/*
-    This source file was part of Konsole, a terminal emulator.
-
-    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 "KeyboardTranslator.h"
-
-// System
-#include <ctype.h>
-#include <stdio.h>
-
-// Qt
-#include <QtCore/QBuffer>
-//#include <KDebug>
-#include <QtCore/QFile>
-#include <QtCore/QFileInfo>
-#include <QtCore>
-#include <QtGui>
-
-// KDE
-//#include <KDebug>
-//#include <KLocale>
-//#include <KStandardDirs>
-
-using namespace Konsole;
-
-//this is for default REALLY fallback translator.
-
-//const char* KeyboardTranslatorManager::defaultTranslatorText =
-//#include "DefaultTranslatorText.h"
-//;
-
-//and this is default now translator - default.keytab from original Konsole
-const char* KeyboardTranslatorManager::defaultTranslatorText = 
-#include "ExtendedDefaultTranslator.h"
-;
-
-KeyboardTranslatorManager::KeyboardTranslatorManager()
-    : _haveLoadedAll(false)
-{
-}
-KeyboardTranslatorManager::~KeyboardTranslatorManager()
-{
-    qDeleteAll(_translators.values());
-}
-QString KeyboardTranslatorManager::findTranslatorPath(const QString& name)
-{
-    return QString("kb-layouts/" + name + ".keytab");
-}
-void KeyboardTranslatorManager::findTranslators()
-{
-    QDir dir("kb-layouts/");
-    QStringList filters;
-    filters << "*.keytab";
-    dir.setNameFilters(filters);
-    QStringList list = dir.entryList(filters); //(".keytab"); // = KGlobal::dirs()->findAllResources("data",
-                        //                                 "konsole/*.keytab",
-                        //                                 KStandardDirs::NoDuplicates);
-    list = dir.entryList(filters);
-    // add the name of each translator to the list and associated
-    // the name with a null pointer to indicate that the translator
-    // has not yet been loaded from disk
-    QStringListIterator listIter(list);
-    while (listIter.hasNext())
-    {
-        QString translatorPath = listIter.next();
-
-        QString name = QFileInfo(translatorPath).baseName();
-       
-        if ( !_translators.contains(name) ) {
-            _translators.insert(name,0);
-	}
-    }
-    _haveLoadedAll = true;
-}
-
-const KeyboardTranslator* KeyboardTranslatorManager::findTranslator(const QString& name)
-{
-    if ( name.isEmpty() )
-        return defaultTranslator();
-
-//here was smth wrong in original Konsole source 
-    findTranslators();
-
-    if ( _translators.contains(name) && _translators[name] != 0 ) {
-        return _translators[name];
-    }
-
-    KeyboardTranslator* translator = loadTranslator(name);
-
-    if ( translator != 0 )
-        _translators[name] = translator;
-    else if ( !name.isEmpty() )
-        qWarning() << "Unable to load translator" << name;
-
-    return translator;
-}
-
-bool KeyboardTranslatorManager::saveTranslator(const KeyboardTranslator* translator)
-{
-    const QString path = ".keytab";// = KGlobal::dirs()->saveLocation("data","konsole/")+translator->name()
-//           +".keytab";
-
-    qDebug() << "Saving translator to" << path;
-
-    QFile destination(path);
-    
-    if (!destination.open(QIODevice::WriteOnly | QIODevice::Text))
-    {
-        qWarning() << "Unable to save keyboard translation:" 
-                   << destination.errorString();
-
-        return false;
-    }
-
-    {
-        KeyboardTranslatorWriter writer(&destination);
-        writer.writeHeader(translator->description());
-    
-        QListIterator<KeyboardTranslator::Entry> iter(translator->entries());
-        while ( iter.hasNext() )
-            writer.writeEntry(iter.next());
-    }
-
-    destination.close();
-
-    return true;
-}
-
-KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(const QString& name)
-{
-    const QString& path = findTranslatorPath(name);
-
-    QFile source(path); 
-    
-    if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text))
-        return 0;
-
-    return loadTranslator(&source,name);
-}
-
-const KeyboardTranslator* KeyboardTranslatorManager::defaultTranslator()
-{
-    qDebug() << "Loading default translator from text";
-    QBuffer textBuffer;
-    textBuffer.setData(defaultTranslatorText,strlen(defaultTranslatorText));
-
-    if (!textBuffer.open(QIODevice::ReadOnly))
-        return 0;
-
-    return loadTranslator(&textBuffer,"fallback");
-}
-
-KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(QIODevice* source,const QString& name)
-{
-    KeyboardTranslator* translator = new KeyboardTranslator(name);
-    KeyboardTranslatorReader reader(source);
-    translator->setDescription( reader.description() );
-    
-    while ( reader.hasNextEntry() ) {
-        translator->addEntry(reader.nextEntry());
-    }	
-
-    source->close();
-
-    if ( !reader.parseError() )
-    {
-        return translator;
-    }
-    else
-    {
-        delete translator;
-        return 0;
-    }
-}
-
-KeyboardTranslatorWriter::KeyboardTranslatorWriter(QIODevice* destination)
-: _destination(destination)
-{
-    Q_ASSERT( destination && destination->isWritable() );
-
-    _writer = new QTextStream(_destination);
-}
-KeyboardTranslatorWriter::~KeyboardTranslatorWriter()
-{
-    delete _writer;
-}
-void KeyboardTranslatorWriter::writeHeader( const QString& description )
-{
-    *_writer << "keyboard \"" << description << '\"' << '\n';
-}
-void KeyboardTranslatorWriter::writeEntry( const KeyboardTranslator::Entry& entry )
-{
-    QString result;
-
-    if ( entry.command() != KeyboardTranslator::NoCommand )
-        result = entry.resultToString();
-    else
-        result = '\"' + entry.resultToString() + '\"';
-
-    *_writer << "key " << entry.conditionToString() << " : " << result << '\n';
-}
-
-
-// each line of the keyboard translation file is one of:
-//
-// - keyboard "name"
-// - key KeySequence : "characters"
-// - key KeySequence : CommandName
-//
-// KeySequence begins with the name of the key ( taken from the Qt::Key enum )
-// and is followed by the keyboard modifiers and state flags ( with + or - in front
-// of each modifier or flag to indicate whether it is required ).  All keyboard modifiers
-// and flags are optional, if a particular modifier or state is not specified it is 
-// assumed not to be a part of the sequence.  The key sequence may contain whitespace
-//
-// eg:  "key Up+Shift : scrollLineUp"
-//      "key Next-Shift : "\E[6~"
-//
-// (lines containing only whitespace are ignored, parseLine assumes that comments have
-// already been removed)
-//
-
-KeyboardTranslatorReader::KeyboardTranslatorReader( QIODevice* source )
-    : _source(source)
-    , _hasNext(false)
-{
-   // read input until we find the description
-   while ( _description.isEmpty() && !source->atEnd() )
-   {
-        const QList<Token>& tokens = tokenize( QString(source->readLine()) );
-   
-        if ( !tokens.isEmpty() && tokens.first().type == Token::TitleKeyword )
-        {
-            _description = (tokens[1].text.toUtf8());
-        }
-   }
-
-   readNext();
-}
-void KeyboardTranslatorReader::readNext() 
-{
-    // find next entry
-    while ( !_source->atEnd() )
-    {
-        const QList<Token>& tokens = tokenize( QString(_source->readLine()) );
-        if ( !tokens.isEmpty() && tokens.first().type == Token::KeyKeyword )
-        {
-            KeyboardTranslator::States flags = KeyboardTranslator::NoState;
-            KeyboardTranslator::States flagMask = KeyboardTranslator::NoState;
-            Qt::KeyboardModifiers modifiers = Qt::NoModifier;
-            Qt::KeyboardModifiers modifierMask = Qt::NoModifier;
-
-            int keyCode = Qt::Key_unknown;
-
-            decodeSequence(tokens[1].text.toLower(),
-                           keyCode,
-                           modifiers,
-                           modifierMask,
-                           flags,
-                           flagMask); 
-
-            KeyboardTranslator::Command command = KeyboardTranslator::NoCommand;
-            QByteArray text;
-
-            // get text or command
-            if ( tokens[2].type == Token::OutputText )
-            {
-                text = tokens[2].text.toLocal8Bit();
-            }
-            else if ( tokens[2].type == Token::Command )
-            {
-                // identify command
-				if (!parseAsCommand(tokens[2].text,command))
-					qWarning() << "Command" << tokens[2].text << "not understood.";
-            }
-
-            KeyboardTranslator::Entry newEntry;
-            newEntry.setKeyCode( keyCode );
-            newEntry.setState( flags );
-            newEntry.setStateMask( flagMask );
-            newEntry.setModifiers( modifiers );
-            newEntry.setModifierMask( modifierMask );
-            newEntry.setText( text );
-            newEntry.setCommand( command );
-
-            _nextEntry = newEntry;
-
-            _hasNext = true;
-
-            return;
-        }
-    } 
-
-    _hasNext = false;
-}
-
-bool KeyboardTranslatorReader::parseAsCommand(const QString& text,KeyboardTranslator::Command& command) 
-{
-	if ( text.compare("erase",Qt::CaseInsensitive) == 0 )
-		command = KeyboardTranslator::EraseCommand;
-    else if ( text.compare("scrollpageup",Qt::CaseInsensitive) == 0 )
-        command = KeyboardTranslator::ScrollPageUpCommand;
-    else if ( text.compare("scrollpagedown",Qt::CaseInsensitive) == 0 )
-        command = KeyboardTranslator::ScrollPageDownCommand;
-    else if ( text.compare("scrolllineup",Qt::CaseInsensitive) == 0 )
-        command = KeyboardTranslator::ScrollLineUpCommand;
-    else if ( text.compare("scrolllinedown",Qt::CaseInsensitive) == 0 )
-        command = KeyboardTranslator::ScrollLineDownCommand;
-    else if ( text.compare("scrolllock",Qt::CaseInsensitive) == 0 )
-        command = KeyboardTranslator::ScrollLockCommand;
-    else
-    	return false;
-
-	return true;
-}
-
-bool KeyboardTranslatorReader::decodeSequence(const QString& text,
-                                              int& keyCode,
-                                              Qt::KeyboardModifiers& modifiers,
-                                              Qt::KeyboardModifiers& modifierMask,
-                                              KeyboardTranslator::States& flags,
-                                              KeyboardTranslator::States& flagMask)
-{
-    bool isWanted = true; 
-    bool endOfItem = false;
-    QString buffer;
-
-    Qt::KeyboardModifiers tempModifiers = modifiers;
-    Qt::KeyboardModifiers tempModifierMask = modifierMask;
-    KeyboardTranslator::States tempFlags = flags;
-    KeyboardTranslator::States tempFlagMask = flagMask;
-
-    for ( int i = 0 ; i < text.count() ; i++ )
-    {
-        const QChar& ch = text[i];
-        bool isLastLetter = ( i == text.count()-1 );
-
-        endOfItem = true;
-        if ( ch.isLetterOrNumber() )
-        {
-            endOfItem = false;
-            buffer.append(ch);
-        }
-
-        if ( (endOfItem || isLastLetter) && !buffer.isEmpty() )
-        {
-            Qt::KeyboardModifier itemModifier = Qt::NoModifier;
-            int itemKeyCode = 0;
-            KeyboardTranslator::State itemFlag = KeyboardTranslator::NoState;
-
-            if ( parseAsModifier(buffer,itemModifier) )
-            {
-                tempModifierMask |= itemModifier;
-
-                if ( isWanted )
-                    tempModifiers |= itemModifier;
-            }
-            else if ( parseAsStateFlag(buffer,itemFlag) )
-            {
-                tempFlagMask |= itemFlag;
-
-                if ( isWanted )
-                    tempFlags |= itemFlag;
-            }
-            else if ( parseAsKeyCode(buffer,itemKeyCode) )
-                keyCode = itemKeyCode;
-            else
-                qDebug() << "Unable to parse key binding item:" << buffer;
-
-            buffer.clear();
-        }
-
-        // check if this is a wanted / not-wanted flag and update the 
-        // state ready for the next item
-        if ( ch == '+' )
-           isWanted = true;
-        else if ( ch == '-' )
-           isWanted = false; 
-    } 
-
-    modifiers = tempModifiers;
-    modifierMask = tempModifierMask;
-    flags = tempFlags;
-    flagMask = tempFlagMask;
-
-    return true;
-}
-
-bool KeyboardTranslatorReader::parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier)
-{
-    if ( item == "shift" )
-        modifier = Qt::ShiftModifier;
-    else if ( item == "ctrl" || item == "control" )
-        modifier = Qt::ControlModifier;
-    else if ( item == "alt" )
-        modifier = Qt::AltModifier;
-    else if ( item == "meta" )
-        modifier = Qt::MetaModifier;
-	else if ( item == "keypad" )
-		modifier = Qt::KeypadModifier;
-    else
-        return false;
-
-    return true;
-}
-bool KeyboardTranslatorReader::parseAsStateFlag(const QString& item , KeyboardTranslator::State& flag)
-{
-    if ( item == "appcukeys" )
-        flag = KeyboardTranslator::CursorKeysState;
-    else if ( item == "ansi" )
-        flag = KeyboardTranslator::AnsiState;
-    else if ( item == "newline" )
-        flag = KeyboardTranslator::NewLineState;
-    else if ( item == "appscreen" )
-        flag = KeyboardTranslator::AlternateScreenState;
-    else if ( item == "anymod" )
-        flag = KeyboardTranslator::AnyModifierState;
-    else
-        return false;
-
-    return true;
-}
-bool KeyboardTranslatorReader::parseAsKeyCode(const QString& item , int& keyCode)
-{
-    QKeySequence sequence = QKeySequence::fromString(item);
-    if ( !sequence.isEmpty() )
-    {
-        keyCode = sequence[0];
-
-        if ( sequence.count() > 1 )
-        {
-            qDebug() << "Unhandled key codes in sequence: " << item;
-        }
-    }
-    // additional cases implemented for backwards compatibility with KDE 3
-    else if ( item == "prior" )
-        keyCode = Qt::Key_PageUp;
-    else if ( item == "next" )
-        keyCode = Qt::Key_PageDown;
-    else
-        return false;
-
-    return true;
-}
-
-QString KeyboardTranslatorReader::description() const
-{
-    return _description;
-}
-bool KeyboardTranslatorReader::hasNextEntry()
-{
-    return _hasNext;
-}
-KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& condition , 
-                                                                 const QString& result )
-{
-    QString entryString("keyboard \"temporary\"\nkey ");
-    entryString.append(condition);
-    entryString.append(" : ");
-
-	// if 'result' is the name of a command then the entry result will be that command,
-	// otherwise the result will be treated as a string to echo when the key sequence
-	// specified by 'condition' is pressed
-	KeyboardTranslator::Command command;
-	if (parseAsCommand(result,command))
-    	entryString.append(result);
-	else
-		entryString.append('\"' + result + '\"');
-
-    QByteArray array = entryString.toUtf8();
-
-    KeyboardTranslator::Entry entry;
-
-    QBuffer buffer(&array);
-    buffer.open(QIODevice::ReadOnly);
-    KeyboardTranslatorReader reader(&buffer);
-
-    if ( reader.hasNextEntry() )
-        entry = reader.nextEntry();
-
-    return entry;
-}
-
-KeyboardTranslator::Entry KeyboardTranslatorReader::nextEntry() 
-{
-    Q_ASSERT( _hasNext );
-
-
-    KeyboardTranslator::Entry entry = _nextEntry;
-
-    readNext();
-
-    return entry;
-}
-bool KeyboardTranslatorReader::parseError()
-{
-    return false;
-}
-QList<KeyboardTranslatorReader::Token> KeyboardTranslatorReader::tokenize(const QString& line)
-{
-    QString text = line.simplified();
-
-    // comment line: # comment
-    static QRegExp comment("\\#.*");
-    // title line: keyboard "title"
-    static QRegExp title("keyboard\\s+\"(.*)\"");
-    // key line: key KeySequence : "output"
-    // key line: key KeySequence : command
-    static QRegExp key("key\\s+([\\w\\+\\s\\-]+)\\s*:\\s*(\"(.*)\"|\\w+)");
-
-    QList<Token> list;
-
-    if ( text.isEmpty() || comment.exactMatch(text) )
-    {
-        return list;
-    }
-
-    if ( title.exactMatch(text) )
-    {
-        Token titleToken = { Token::TitleKeyword , QString() };
-        Token textToken = { Token::TitleText , title.capturedTexts()[1] };
-    
-        list << titleToken << textToken;
-    }
-    else if  ( key.exactMatch(text) )
-    {
-        Token keyToken = { Token::KeyKeyword , QString() };
-        Token sequenceToken = { Token::KeySequence , key.capturedTexts()[1].remove(' ') };
-
-        list << keyToken << sequenceToken;
-
-        if ( key.capturedTexts()[3].isEmpty() )
-        {
-            // capturedTexts()[2] is a command
-            Token commandToken = { Token::Command , key.capturedTexts()[2] };
-            list << commandToken;    
-        }   
-        else
-        {
-            // capturedTexts()[3] is the output string
-           Token outputToken = { Token::OutputText , key.capturedTexts()[3] };
-           list << outputToken;
-        }     
-    }
-    else
-    {
-        qWarning() << "Line in keyboard translator file could not be understood:" << text;
-    }
-
-    return list;
-}
-
-QList<QString> KeyboardTranslatorManager::allTranslators() 
-{
-    if ( !_haveLoadedAll )
-    {
-        findTranslators();
-    }
-
-    return _translators.keys();
-}
-
-KeyboardTranslator::Entry::Entry()
-: _keyCode(0)
-, _modifiers(Qt::NoModifier)
-, _modifierMask(Qt::NoModifier)
-, _state(NoState)
-, _stateMask(NoState)
-, _command(NoCommand)
-{
-}
-
-bool KeyboardTranslator::Entry::operator==(const Entry& rhs) const
-{
-    return _keyCode == rhs._keyCode &&
-           _modifiers == rhs._modifiers &&
-           _modifierMask == rhs._modifierMask &&
-           _state == rhs._state &&
-           _stateMask == rhs._stateMask &&
-           _command == rhs._command &&
-           _text == rhs._text;
-}
-
-bool KeyboardTranslator::Entry::matches(int keyCode , 
-                                        Qt::KeyboardModifiers modifiers,
-                                        States state) const
-{
-    if ( _keyCode != keyCode )
-        return false;
-
-    if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) ) 
-        return false;
-
-    // if modifiers is non-zero, the 'any modifier' state is implicit
-    if ( modifiers != 0 )
-        state |= AnyModifierState;
-
-    if ( (state & _stateMask) != (_state & _stateMask) )
-        return false;
-
-    // special handling for the 'Any Modifier' state, which checks for the presence of 
-    // any or no modifiers.  In this context, the 'keypad' modifier does not count.
-    bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier;
-    if ( _stateMask & KeyboardTranslator::AnyModifierState )
-    {
-        // test fails if any modifier is required but none are set
-        if ( (_state & KeyboardTranslator::AnyModifierState) && !anyModifiersSet )
-           return false;
-
-        // test fails if no modifier is allowed but one or more are set
-        if ( !(_state & KeyboardTranslator::AnyModifierState) && anyModifiersSet )
-            return false;
-    }
-
-    return true;
-}
-QByteArray KeyboardTranslator::Entry::escapedText(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
-{
-    QByteArray result(text(expandWildCards,modifiers));
-
-    for ( int i = 0 ; i < result.count() ; i++ )
-    {
-        char ch = result[i];
-        char replacement = 0;
-
-        switch ( ch )
-        {
-            case 27 : replacement = 'E'; break;
-            case 8  : replacement = 'b'; break;
-            case 12 : replacement = 'f'; break;
-            case 9  : replacement = 't'; break;
-            case 13 : replacement = 'r'; break;
-            case 10 : replacement = 'n'; break;
-            default:
-                // any character which is not printable is replaced by an equivalent
-                // \xhh escape sequence (where 'hh' are the corresponding hex digits)
-                if ( !QChar(ch).isPrint() )
-                    replacement = 'x';
-        }
-
-        if ( replacement == 'x' )
-        {
-            result.replace(i,1,"\\x"+QByteArray(1,ch).toInt(0, 16)); 
-        } else if ( replacement != 0 )
-        {
-            result.remove(i,1);
-            result.insert(i,'\\');
-            result.insert(i+1,replacement);
-        }
-    }
-
-    return result;
-}
-QByteArray KeyboardTranslator::Entry::unescape(const QByteArray& input) const
-{
-    QByteArray result(input);
-
-    for ( int i = 0 ; i < result.count()-1 ; i++ )
-    {
-
-        QByteRef ch = result[i];
-        if ( ch == '\\' )
-        {
-           char replacement[2] = {0,0};
-           int charsToRemove = 2;
-		   bool escapedChar = true;
-
-           switch ( result[i+1] )
-           {
-              case 'E' : replacement[0] = 27; break;
-              case 'b' : replacement[0] = 8 ; break;
-              case 'f' : replacement[0] = 12; break;
-              case 't' : replacement[0] = 9 ; break;
-              case 'r' : replacement[0] = 13; break;
-              case 'n' : replacement[0] = 10; break;
-              case 'x' :
-			  {
-                    // format is \xh or \xhh where 'h' is a hexadecimal
-                    // digit from 0-9 or A-F which should be replaced
-                    // with the corresponding character value
-                    char hexDigits[3] = {0};
-
-                    if ( (i < result.count()-2) && isxdigit(result[i+2]) )
-                            hexDigits[0] = result[i+2];
-                    if ( (i < result.count()-3) && isxdigit(result[i+3]) )
-                            hexDigits[1] = result[i+3];
-
-                    int charValue = 0;
-                    sscanf(hexDigits,"%x",&charValue);
-                    
-                    replacement[0] = (char)charValue; 
-
-                    charsToRemove = 2 + strlen(hexDigits);
-			  }
-              break;
-			  default:
-			  		escapedChar = false;
-           }
-
-           if ( escapedChar )
-               result.replace(i,charsToRemove,replacement);
-        }
-    }
-    
-    return result;
-}
-
-void KeyboardTranslator::Entry::insertModifier( QString& item , int modifier ) const
-{
-    if ( !(modifier & _modifierMask) )
-        return;
-
-    if ( modifier & _modifiers )
-        item += '+';
-    else
-        item += '-';
-
-    if ( modifier == Qt::ShiftModifier )
-        item += "Shift";
-    else if ( modifier == Qt::ControlModifier )
-        item += "Ctrl";
-    else if ( modifier == Qt::AltModifier )
-        item += "Alt";
-    else if ( modifier == Qt::MetaModifier )
-        item += "Meta";
-	else if ( modifier == Qt::KeypadModifier )
-		item += "KeyPad";
-}
-void KeyboardTranslator::Entry::insertState( QString& item , int state ) const
-{
-    if ( !(state & _stateMask) )
-        return;
-
-    if ( state & _state )
-        item += '+' ;
-    else
-        item += '-' ;
-
-    if ( state == KeyboardTranslator::AlternateScreenState )
-        item += "AppScreen";
-    else if ( state == KeyboardTranslator::NewLineState )
-        item += "NewLine";
-    else if ( state == KeyboardTranslator::AnsiState )
-        item += "Ansi";
-    else if ( state == KeyboardTranslator::CursorKeysState )
-        item += "AppCuKeys";
-    else if ( state == KeyboardTranslator::AnyModifierState )
-        item += "AnyMod";
-}
-QString KeyboardTranslator::Entry::resultToString(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
-{
-    if ( !_text.isEmpty() )
-        return escapedText(expandWildCards,modifiers);
-	else if ( _command == EraseCommand )
-		return "Erase";
-    else if ( _command == ScrollPageUpCommand )
-        return "ScrollPageUp";
-    else if ( _command == ScrollPageDownCommand )
-        return "ScrollPageDown";
-    else if ( _command == ScrollLineUpCommand )
-        return "ScrollLineUp";
-    else if ( _command == ScrollLineDownCommand )
-        return "ScrollLineDown";
-    else if ( _command == ScrollLockCommand )
-        return "ScrollLock";
-
-    return QString();
-}
-QString KeyboardTranslator::Entry::conditionToString() const
-{
-    QString result = QKeySequence(_keyCode).toString();
-
-    // add modifiers
-    insertModifier( result , Qt::ShiftModifier );
-    insertModifier( result , Qt::ControlModifier );
-    insertModifier( result , Qt::AltModifier );
-    insertModifier( result , Qt::MetaModifier ); 
-
-    // add states
-    insertState( result , KeyboardTranslator::AlternateScreenState );
-    insertState( result , KeyboardTranslator::NewLineState );
-    insertState( result , KeyboardTranslator::AnsiState );
-    insertState( result , KeyboardTranslator::CursorKeysState );
-    insertState( result , KeyboardTranslator::AnyModifierState );
-
-    return result;
-}
-
-KeyboardTranslator::KeyboardTranslator(const QString& name)
-: _name(name)
-{
-}
-
-void KeyboardTranslator::setDescription(const QString& description) 
-{
-    _description = description;
-}
-QString KeyboardTranslator::description() const
-{
-    return _description;
-}
-void KeyboardTranslator::setName(const QString& name)
-{
-    _name = name;
-}
-QString KeyboardTranslator::name() const
-{
-    return _name;
-}
-
-QList<KeyboardTranslator::Entry> KeyboardTranslator::entries() const
-{
-    return _entries.values();
-}
-
-void KeyboardTranslator::addEntry(const Entry& entry)
-{
-    const int keyCode = entry.keyCode();
-    _entries.insertMulti(keyCode,entry);
-}
-void KeyboardTranslator::replaceEntry(const Entry& existing , const Entry& replacement)
-{
-    if ( !existing.isNull() )
-        _entries.remove(existing.keyCode());
-    _entries.insertMulti(replacement.keyCode(),replacement);
-}
-void KeyboardTranslator::removeEntry(const Entry& entry)
-{
-    _entries.remove(entry.keyCode());
-}
-KeyboardTranslator::Entry KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const
-{
-    if ( _entries.contains(keyCode) )
-    {
-        QList<Entry> entriesForKey = _entries.values(keyCode);
-        
-        QListIterator<Entry> iter(entriesForKey);
-
-        while (iter.hasNext())
-        {
-            const Entry& next = iter.next();
-            if ( next.matches(keyCode,modifiers,state) )
-                return next;
-        }
-
-        return Entry(); // entry not found
-    }
-    else
-    {
-        return Entry();
-    }
-    
-}
-void KeyboardTranslatorManager::addTranslator(KeyboardTranslator* translator)
-{
-    _translators.insert(translator->name(),translator);
-
-    if ( !saveTranslator(translator) )
-        qWarning() << "Unable to save translator" << translator->name()
-                   << "to disk.";
-}
-bool KeyboardTranslatorManager::deleteTranslator(const QString& name)
-{
-    Q_ASSERT( _translators.contains(name) );
-
-    // locate and delete
-    QString path = findTranslatorPath(name);
-    if ( QFile::remove(path) )
-    {
-        _translators.remove(name);
-        return true; 
-    }
-    else
-    {
-        qWarning() << "Failed to remove translator - " << path;
-        return false;
-    }
-}
-K_GLOBAL_STATIC( KeyboardTranslatorManager , theKeyboardTranslatorManager )
-KeyboardTranslatorManager* KeyboardTranslatorManager::instance()
-{
-    return theKeyboardTranslatorManager;
-}
--- a/gui/qtermwidget/lib/KeyboardTranslator.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,657 +0,0 @@
-/*
-    This source file is part of Konsole, a terminal emulator.
-
-    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.
-*/
-
-#ifndef KEYBOARDTRANSLATOR_H
-#define KEYBOARDTRANSLATOR_H
-
-// Qt
-#include <QtCore/QHash>
-#include <QtCore/QList>
-#include <QtGui/QKeySequence>
-#include <QtCore/QMetaType>
-#include <QtCore/QVarLengthArray>
-#include <QtCore>
-
-typedef void (*CleanUpFunction)();
-
-/**
- * @internal
- *
- * Helper class for K_GLOBAL_STATIC to clean up the object on library unload or application
- * shutdown.
- */
-class CleanUpGlobalStatic
-{
-    public:
-        CleanUpFunction func;
-
-        inline ~CleanUpGlobalStatic() { func(); }
-};
-
-
-//these directives are taken from the heart of kdecore
-
-# define K_GLOBAL_STATIC_STRUCT_NAME(NAME)
-
-#if QT_VERSION < 0x040400
-# define Q_BASIC_ATOMIC_INITIALIZER     Q_ATOMIC_INIT
-# define testAndSetOrdered              testAndSet
-#endif
-
-#define K_GLOBAL_STATIC(TYPE, NAME) K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
-
-#define K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)                            \
-static QBasicAtomicPointer<TYPE > _k_static_##NAME = Q_BASIC_ATOMIC_INITIALIZER(0); \
-static bool _k_static_##NAME##_destroyed;                                      \
-static struct K_GLOBAL_STATIC_STRUCT_NAME(NAME)                                \
-{                                                                              \
-    bool isDestroyed()                                                         \
-    {                                                                          \
-        return _k_static_##NAME##_destroyed;                                   \
-    }                                                                          \
-    inline operator TYPE*()                                                    \
-    {                                                                          \
-        return operator->();                                                   \
-    }                                                                          \
-    inline TYPE *operator->()                                                  \
-    {                                                                          \
-        if (!_k_static_##NAME) {                                               \
-            if (isDestroyed()) {                                               \
-            qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \
-             "Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__);		\
-	     }                                                                  \
-	     TYPE *x = new TYPE ARGS;                                           \
-	     if (!_k_static_##NAME.testAndSetOrdered(0, x)                      \
-	         && _k_static_##NAME != x ) {                                   \
-	         delete x;                                                      \
-	     } else { 								\
-		static CleanUpGlobalStatic cleanUpObject = { destroy };	\
-	     }   								\
-	 }                                                                      \
-         return _k_static_##NAME;                                               \
-    }            								\
-    inline TYPE &operator*()                                                   \
-    {                                                                          \
-        return *operator->();                                                  \
-    }                                                                          \
-    static void destroy()                                                      \
-    {                                                                          \
-        _k_static_##NAME##_destroyed = true;                                   \
-        TYPE *x = _k_static_##NAME;                                            \
-        _k_static_##NAME = 0;                                                  \
-        delete x;                                                              \
-    }                                                                          \
-} NAME;
-								
-								
-
-
-
-class QIODevice;
-class QTextStream;
-
-namespace Konsole
-{
-
-/** 
- * A convertor which maps between key sequences pressed by the user and the
- * character strings which should be sent to the terminal and commands
- * which should be invoked when those character sequences are pressed.
- *
- * Konsole supports multiple keyboard translators, allowing the user to
- * specify the character sequences which are sent to the terminal
- * when particular key sequences are pressed.
- *
- * A key sequence is defined as a key code, associated keyboard modifiers
- * (Shift,Ctrl,Alt,Meta etc.) and state flags which indicate the state
- * which the terminal must be in for the key sequence to apply.
- */
-class KeyboardTranslator
-{
-public:
-    /** 
-     * The meaning of a particular key sequence may depend upon the state which
-     * the terminal emulation is in.  Therefore findEntry() may return a different
-     * Entry depending upon the state flags supplied.
-     *
-     * This enum describes the states which may be associated with with a particular
-     * entry in the keyboard translation entry.
-     */
-    enum State
-    {
-        /** Indicates that no special state is active */
-        NoState = 0,
-        /**
-         * TODO More documentation
-         */
-        NewLineState = 1,
-        /** 
-         * Indicates that the terminal is in 'Ansi' mode.
-         * TODO: More documentation
-         */
-        AnsiState = 2,
-        /**
-         * TODO More documentation
-         */
-        CursorKeysState = 4,
-        /**
-         * Indicates that the alternate screen ( typically used by interactive programs
-         * such as screen or vim ) is active 
-         */
-        AlternateScreenState = 8,
-        /** Indicates that any of the modifier keys is active. */ 
-        AnyModifierState = 16
-    };
-    Q_DECLARE_FLAGS(States,State)
-
-    /**
-     * This enum describes commands which are associated with particular key sequences.
-     */
-    enum Command
-    {
-        /** Indicates that no command is associated with this command sequence */
-        NoCommand = 0,
-        /** TODO Document me */
-        SendCommand = 1,
-        /** Scroll the terminal display up one page */
-        ScrollPageUpCommand = 2,
-        /** Scroll the terminal display down one page */
-        ScrollPageDownCommand = 4,
-        /** Scroll the terminal display up one line */
-        ScrollLineUpCommand = 8,
-        /** Scroll the terminal display down one line */
-        ScrollLineDownCommand = 16,
-        /** Toggles scroll lock mode */
-        ScrollLockCommand = 32,
-		/** Echos the operating system specific erase character. */
-		EraseCommand = 64
-    };
-    Q_DECLARE_FLAGS(Commands,Command)
-
-    /**
-     * Represents an association between a key sequence pressed by the user
-     * and the character sequence and commands associated with it for a particular
-     * KeyboardTranslator.
-     */
-    class Entry
-    {
-    public:
-        /** 
-         * Constructs a new entry for a keyboard translator.
-         */
-        Entry();
-
-        /** 
-         * Returns true if this entry is null.
-         * This is true for newly constructed entries which have no properties set. 
-         */
-        bool isNull() const;
-
-        /** Returns the commands associated with this entry */
-        Command command() const;
-        /** Sets the command associated with this entry. */
-        void setCommand(Command command);
-
-        /** 
-         * Returns the character sequence associated with this entry, optionally replacing 
-         * wildcard '*' characters with numbers to indicate the keyboard modifiers being pressed.
-         *
-         * TODO: The numbers used to replace '*' characters are taken from the Konsole/KDE 3 code.
-         * Document them. 
-         *
-         * @param expandWildCards Specifies whether wild cards (occurrences of the '*' character) in
-         * the entry should be replaced with a number to indicate the modifier keys being pressed. 
-         *
-         * @param modifiers The keyboard modifiers being pressed.
-         */
-        QByteArray text(bool expandWildCards = false,
-                        Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
-
-        /** Sets the character sequence associated with this entry */
-        void setText(const QByteArray& text);
-
-        /** 
-         * Returns the character sequence associated with this entry,
-         * with any non-printable characters replaced with escape sequences.
-         *
-         * eg. \\E for Escape, \\t for tab, \\n for new line.
-         *
-         * @param expandWildCards See text()
-         * @param modifiers See text()
-         */
-        QByteArray escapedText(bool expandWildCards = false,
-                               Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
-
-        /** Returns the character code ( from the Qt::Key enum ) associated with this entry */
-        int keyCode() const;
-        /** Sets the character code associated with this entry */
-        void setKeyCode(int keyCode);
-
-        /** 
-         * Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry. 
-         * If a modifier is set in modifierMask() but not in modifiers(), this means that the entry
-         * only matches when that modifier is NOT pressed.
-         *
-         * If a modifier is not set in modifierMask() then the entry matches whether the modifier
-         * is pressed or not. 
-         */
-        Qt::KeyboardModifiers modifiers() const;
-
-        /** Returns the keyboard modifiers which are valid in this entry.  See modifiers() */
-        Qt::KeyboardModifiers modifierMask() const;
-
-        /** See modifiers() */
-        void setModifiers( Qt::KeyboardModifiers modifiers );
-        /** See modifierMask() and modifiers() */
-        void setModifierMask( Qt::KeyboardModifiers modifiers );
-
-        /** 
-         * Returns a bitwise-OR of the enabled state flags associated with this entry. 
-         * If flag is set in stateMask() but not in state(), this means that the entry only 
-         * matches when the terminal is NOT in that state.
-         *
-         * If a state is not set in stateMask() then the entry matches whether the terminal
-         * is in that state or not. 
-         */
-        States state() const;
-
-        /** Returns the state flags which are valid in this entry.  See state() */
-        States stateMask() const;
-
-        /** See state() */
-        void setState( States state );
-        /** See stateMask() */
-        void setStateMask( States mask );
-
-        /** 
-         * Returns the key code and modifiers associated with this entry 
-         * as a QKeySequence
-         */
-        //QKeySequence keySequence() const;
-
-        /** 
-         * Returns this entry's conditions ( ie. its key code, modifier and state criteria )
-         * as a string.
-         */
-        QString conditionToString() const;
-
-        /**
-         * Returns this entry's result ( ie. its command or character sequence )
-         * as a string.
-         *
-         * @param expandWildCards See text()
-         * @param modifiers See text()
-         */
-        QString resultToString(bool expandWildCards = false,
-                               Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
-
-        /** 
-         * Returns true if this entry matches the given key sequence, specified
-         * as a combination of @p keyCode , @p modifiers and @p state.
-         */
-        bool matches( int keyCode , 
-                      Qt::KeyboardModifiers modifiers , 
-                      States flags ) const;
-
-        bool operator==(const Entry& rhs) const;
-       
-    private:
-        void insertModifier( QString& item , int modifier ) const;
-        void insertState( QString& item , int state ) const;
-        QByteArray unescape(const QByteArray& text) const;
-
-        int _keyCode;
-        Qt::KeyboardModifiers _modifiers;
-        Qt::KeyboardModifiers _modifierMask;
-        States _state;
-        States _stateMask;
-
-        Command _command;
-        QByteArray _text;
-    };
-
-    /** Constructs a new keyboard translator with the given @p name */
-    KeyboardTranslator(const QString& name);
-   
-    //KeyboardTranslator(const KeyboardTranslator& other);
-
-    /** Returns the name of this keyboard translator */
-    QString name() const;
-
-    /** Sets the name of this keyboard translator */
-    void setName(const QString& name);
-
-    /** Returns the descriptive name of this keyboard translator */
-    QString description() const;
-
-    /** Sets the descriptive name of this keyboard translator */
-    void setDescription(const QString& description);
-
-    /**
-     * Looks for an entry in this keyboard translator which matches the given
-     * key code, keyboard modifiers and state flags.
-     * 
-     * Returns the matching entry if found or a null Entry otherwise ( ie.
-     * entry.isNull() will return true )
-     *
-     * @param keyCode A key code from the Qt::Key enum
-     * @param modifiers A combination of modifiers
-     * @param state Optional flags which specify the current state of the terminal
-     */
-    Entry findEntry(int keyCode , 
-                    Qt::KeyboardModifiers modifiers , 
-                    States state = NoState) const;
-
-    /** 
-     * Adds an entry to this keyboard translator's table.  Entries can be looked up according
-     * to their key sequence using findEntry()
-     */
-    void addEntry(const Entry& entry);
-
-    /**
-     * Replaces an entry in the translator.  If the @p existing entry is null,
-     * then this is equivalent to calling addEntry(@p replacement)
-     */
-    void replaceEntry(const Entry& existing , const Entry& replacement);
-
-    /**
-     * Removes an entry from the table.
-     */
-    void removeEntry(const Entry& entry);
-
-    /** Returns a list of all entries in the translator. */
-    QList<Entry> entries() const;
-
-private:
-
-    QHash<int,Entry> _entries; // entries in this keyboard translation,
-                                                 // entries are indexed according to
-                                                 // their keycode
-    QString _name;
-    QString _description;
-};
-Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::States)
-Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::Commands)
-
-/** 
- * Parses the contents of a Keyboard Translator (.keytab) file and 
- * returns the entries found in it.
- *
- * Usage example:
- *
- * @code
- *  QFile source( "/path/to/keytab" );
- *  source.open( QIODevice::ReadOnly );
- *
- *  KeyboardTranslator* translator = new KeyboardTranslator( "name-of-translator" );
- *
- *  KeyboardTranslatorReader reader(source);
- *  while ( reader.hasNextEntry() )
- *      translator->addEntry(reader.nextEntry());
- *
- *  source.close();
- *
- *  if ( !reader.parseError() )
- *  {
- *      // parsing succeeded, do something with the translator
- *  } 
- *  else
- *  {
- *      // parsing failed
- *  }
- * @endcode
- */
-class KeyboardTranslatorReader
-{
-public:
-    /** Constructs a new reader which parses the given @p source */
-    KeyboardTranslatorReader( QIODevice* source );
-
-    /** 
-     * Returns the description text. 
-     * TODO: More documentation 
-     */
-    QString description() const;
-
-    /** Returns true if there is another entry in the source stream */
-    bool hasNextEntry();
-    /** Returns the next entry found in the source stream */
-    KeyboardTranslator::Entry nextEntry(); 
-
-    /** 
-     * Returns true if an error occurred whilst parsing the input or
-     * false if no error occurred.
-     */
-    bool parseError();
-
-    /**
-     * Parses a condition and result string for a translator entry
-     * and produces a keyboard translator entry.
-     *
-     * The condition and result strings are in the same format as in  
-     */
-    static KeyboardTranslator::Entry createEntry( const QString& condition ,
-                                                  const QString& result );
-private:
-    struct Token
-    {
-        enum Type
-        {
-            TitleKeyword,
-            TitleText,
-            KeyKeyword,
-            KeySequence,
-            Command,
-            OutputText
-        };
-        Type type;
-        QString text;
-    };
-    QList<Token> tokenize(const QString&);
-    void readNext();
-    bool decodeSequence(const QString& , 
-                                int& keyCode,
-                                Qt::KeyboardModifiers& modifiers,
-                                Qt::KeyboardModifiers& modifierMask,
-                                KeyboardTranslator::States& state,
-                                KeyboardTranslator::States& stateFlags);
-
-    static bool parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier);
-    static bool parseAsStateFlag(const QString& item , KeyboardTranslator::State& state);
-    static bool parseAsKeyCode(const QString& item , int& keyCode);
-   	static bool parseAsCommand(const QString& text , KeyboardTranslator::Command& command);
-
-    QIODevice* _source;
-    QString _description;
-    KeyboardTranslator::Entry _nextEntry;
-    bool _hasNext;
-};
-
-/** Writes a keyboard translation to disk. */
-class KeyboardTranslatorWriter
-{
-public:
-    /** 
-     * Constructs a new writer which saves data into @p destination.
-     * The caller is responsible for closing the device when writing is complete.
-     */
-    KeyboardTranslatorWriter(QIODevice* destination);
-    ~KeyboardTranslatorWriter();
-
-    /** 
-     * Writes the header for the keyboard translator. 
-     * @param description Description of the keyboard translator. 
-     */
-    void writeHeader( const QString& description );
-    /** Writes a translator entry. */
-    void writeEntry( const KeyboardTranslator::Entry& entry ); 
-
-private:
-    QIODevice* _destination;  
-    QTextStream* _writer;
-};
-
-/**
- * Manages the keyboard translations available for use by terminal sessions,
- * see KeyboardTranslator.
- */
-class KeyboardTranslatorManager
-{
-public:
-    /** 
-     * Constructs a new KeyboardTranslatorManager and loads the list of
-     * available keyboard translations.
-     *
-     * The keyboard translations themselves are not loaded until they are
-     * first requested via a call to findTranslator()
-     */
-    KeyboardTranslatorManager();
-    ~KeyboardTranslatorManager();
-
-    /**
-     * Adds a new translator.  If a translator with the same name 
-     * already exists, it will be replaced by the new translator.
-     *
-     * TODO: More documentation.
-     */
-    void addTranslator(KeyboardTranslator* translator);
-
-    /**
-     * Deletes a translator.  Returns true on successful deletion or false otherwise.
-     *
-     * TODO: More documentation
-     */
-    bool deleteTranslator(const QString& name);
-
-    /** Returns the default translator for Konsole. */
-    const KeyboardTranslator* defaultTranslator();
-
-    /** 
-     * Returns the keyboard translator with the given name or 0 if no translator
-     * with that name exists.
-     *
-     * The first time that a translator with a particular name is requested,
-     * the on-disk .keyboard file is loaded and parsed.  
-     */
-    const KeyboardTranslator* findTranslator(const QString& name);
-    /**
-     * Returns a list of the names of available keyboard translators.
-     *
-     * The first time this is called, a search for available 
-     * translators is started.
-     */
-    QList<QString> allTranslators();
-
-    /** Returns the global KeyboardTranslatorManager instance. */
-   static KeyboardTranslatorManager* instance();
-
-private:
-    static const char* defaultTranslatorText;
-    
-    void findTranslators(); // locate the available translators
-    KeyboardTranslator* loadTranslator(const QString& name); // loads the translator 
-                                                             // with the given name
-    KeyboardTranslator* loadTranslator(QIODevice* device,const QString& name);
-
-    bool saveTranslator(const KeyboardTranslator* translator);
-    QString findTranslatorPath(const QString& name);
-    
-    QHash<QString,KeyboardTranslator*> _translators; // maps translator-name -> KeyboardTranslator
-                                                     // instance
-    bool _haveLoadedAll;
-};
-
-inline int KeyboardTranslator::Entry::keyCode() const { return _keyCode; }
-inline void KeyboardTranslator::Entry::setKeyCode(int keyCode) { _keyCode = keyCode; }
-
-inline void KeyboardTranslator::Entry::setModifiers( Qt::KeyboardModifiers modifier ) 
-{ 
-    _modifiers = modifier;
-}
-inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifiers() const { return _modifiers; }
-
-inline void  KeyboardTranslator::Entry::setModifierMask( Qt::KeyboardModifiers mask ) 
-{ 
-   _modifierMask = mask; 
-}
-inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifierMask() const { return _modifierMask; }
-
-inline bool KeyboardTranslator::Entry::isNull() const
-{
-    return ( *this == Entry() );
-}
-
-inline void KeyboardTranslator::Entry::setCommand( Command command )
-{ 
-    _command = command; 
-}
-inline KeyboardTranslator::Command KeyboardTranslator::Entry::command() const { return _command; }
-
-inline void KeyboardTranslator::Entry::setText( const QByteArray& text )
-{ 
-    _text = unescape(text);
-}
-inline int oneOrZero(int value)
-{
-    return value ? 1 : 0;
-}
-inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards,Qt::KeyboardModifiers modifiers) const 
-{
-    QByteArray expandedText = _text;
-    
-    if (expandWildCards)
-    {
-        int modifierValue = 1;
-        modifierValue += oneOrZero(modifiers & Qt::ShiftModifier);
-        modifierValue += oneOrZero(modifiers & Qt::AltModifier)     << 1;
-        modifierValue += oneOrZero(modifiers & Qt::ControlModifier) << 2;
-
-        for (int i=0;i<_text.length();i++) 
-        {
-            if (expandedText[i] == '*')
-                expandedText[i] = '0' + modifierValue;
-        }
-    }
-
-    return expandedText; 
-}
-
-inline void KeyboardTranslator::Entry::setState( States state )
-{ 
-    _state = state; 
-}
-inline KeyboardTranslator::States KeyboardTranslator::Entry::state() const { return _state; }
-
-inline void KeyboardTranslator::Entry::setStateMask( States stateMask )
-{ 
-    _stateMask = stateMask; 
-}
-inline KeyboardTranslator::States KeyboardTranslator::Entry::stateMask() const { return _stateMask; }
-
-}
-
-Q_DECLARE_METATYPE(Konsole::KeyboardTranslator::Entry)
-Q_DECLARE_METATYPE(const Konsole::KeyboardTranslator*)
-
-#endif // KEYBOARDTRANSLATOR_H
-
--- a/gui/qtermwidget/lib/LineFont.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-// WARNING: Autogenerated by "fontembedder ./linefont.src".
-// You probably do not want to hand-edit this!
-
-static const quint32 LineChars[] = {
-	0x00007c00, 0x000fffe0, 0x00421084, 0x00e739ce, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00427000, 0x004e7380, 0x00e77800, 0x00ef7bc0, 
-	0x00421c00, 0x00439ce0, 0x00e73c00, 0x00e7bde0, 0x00007084, 0x000e7384, 0x000079ce, 0x000f7bce, 
-	0x00001c84, 0x00039ce4, 0x00003dce, 0x0007bdee, 0x00427084, 0x004e7384, 0x004279ce, 0x00e77884, 
-	0x00e779ce, 0x004f7bce, 0x00ef7bc4, 0x00ef7bce, 0x00421c84, 0x00439ce4, 0x00423dce, 0x00e73c84, 
-	0x00e73dce, 0x0047bdee, 0x00e7bde4, 0x00e7bdee, 0x00427c00, 0x0043fce0, 0x004e7f80, 0x004fffe0, 
-	0x004fffe0, 0x00e7fde0, 0x006f7fc0, 0x00efffe0, 0x00007c84, 0x0003fce4, 0x000e7f84, 0x000fffe4, 
-	0x00007dce, 0x0007fdee, 0x000f7fce, 0x000fffee, 0x00427c84, 0x0043fce4, 0x004e7f84, 0x004fffe4, 
-	0x00427dce, 0x00e77c84, 0x00e77dce, 0x0047fdee, 0x004e7fce, 0x00e7fde4, 0x00ef7f84, 0x004fffee, 
-	0x00efffe4, 0x00e7fdee, 0x00ef7fce, 0x00efffee, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 
-	0x000f83e0, 0x00a5294a, 0x004e1380, 0x00a57800, 0x00ad0bc0, 0x004390e0, 0x00a53c00, 0x00a5a1e0, 
-	0x000e1384, 0x0000794a, 0x000f0b4a, 0x000390e4, 0x00003d4a, 0x0007a16a, 0x004e1384, 0x00a5694a, 
-	0x00ad2b4a, 0x004390e4, 0x00a52d4a, 0x00a5a16a, 0x004f83e0, 0x00a57c00, 0x00ad83e0, 0x000f83e4, 
-	0x00007d4a, 0x000f836a, 0x004f93e4, 0x00a57d4a, 0x00ad836a, 0x00000000, 0x00000000, 0x00000000, 
-	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00001c00, 0x00001084, 0x00007000, 0x00421000, 
-	0x00039ce0, 0x000039ce, 0x000e7380, 0x00e73800, 0x000e7f80, 0x00e73884, 0x0003fce0, 0x004239ce
-};
--- a/gui/qtermwidget/lib/LineFont.src	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,786 +0,0 @@
-#2500: single horizontal line
-2500
-     
-     
------
-     
-     
-
-#2501: triple horizontal line
-2501
-     
------
------
------
-     
-
-#2502: single vertical line
-2502
-  |  
-  |  
-  |  
-  |  
-  |  
-
-#2503: triple vertical line
-2503
- ||| 
- ||| 
- ||| 
- ||| 
- ||| 
-
-#2504-250B are dashed - not handled
-
-#250C: top-left corner (lines on bottom + right)
-250C
-     
-     
-  .--
-  |  
-  |  
-
-#250D: as above, but top line triple-width
-250D
-     
-  .--
-  .--
-  |--
-  |  
-
-#250E: now the vert line triple-width
-250E
-     
-     
- ..--
- ||| 
- ||| 
-
-#250F: and now both lines triple-width
-250F
-     
- .___
- |.--
- ||._
- ||| 
-
-#2510: top-right corner
-2510
-     
-     
---.  
-  |  
-  |  
-
-2511
-     
-==.  
-==.  
-==|  
-  | 
-
-2512
-     
-     
-==.. 
- ||| 
- ||| 
-
-2513
-     
-===. 
-==.| 
-=.|| 
- ||| 
-
-#2514: bottom-left corner
-2514
-  |  
-  |  
-  .==
-     
-     
-
-2515
-  |  
-  |==
-  |==
-  ===
-     
-
-
-2516
- ||| 
- ||| 
- |.==
-     
-     
-
-2517
- ||| 
- ||.=
- |.==
- .===
-     
-
-#2518: bottm-right corner
-2518
-  |  
-  |  
-==.  
-     
-     
-
-2519
-  |  
-==|  
-==|  
-===  
-     
-
-
-251A
- ||| 
- ||| 
-==== 
-     
-     
-
-251B
- ||| 
-=.|| 
-==.| 
-===. 
-     
-
-#251C: Join of vertical line and one from the right
-251C
-  |  
-  |  
-  |==
-  |  
-  |  
-
-251D
-  |  
-  |==
-  |==
-  |==
-  |  
-
-251E
- ||| 
- ||| 
- ||==
-  |  
-  |  
-
-251F
-  |  
-  |  
- ||==
- ||| 
- ||| 
-
-
-2520
- ||| 
- ||| 
- ||==
- ||| 
- ||| 
-
-2521
- ||| 
- |||=
- ||==
- .|==
-  |  
-
-2522
-  |  
- .|==
- ||==
- |||=
- ||| 
-
-2523
- ||| 
- ||.=
- ||==
- ||.=
- ||| 
-
-#2524: Join of vertical line and one from the left
-2524
-  |  
-  |  
-==|  
-  |  
-  |  
-
-2525
-  |  
-==|  
-==|  
-==|  
-  |  
-
-2526
- ||| 
- ||| 
-==+| 
-  |  
-  |  
-
-2527
-  |  
-  |  
-==+| 
- ||| 
- ||| 
-
-2528
- ||| 
- ||| 
-==+| 
- ||| 
- ||| 
-
-2529
- ||| 
-=+|| 
-==+| 
-===+ 
-  |  
-
-252A
-  |  
-=+|| 
-==+| 
-===+ 
- ||| 
-
-252B
- |||
-=+|| 
-==+| 
-=+|| 
- |||
-
-#252C: horizontal line joined to from below
-252C
-     
-     
-=====
-  |  
-  |  
-
-252D
-     
-===  
-==|==
-==|  
-  |  
-
-252E
-     
-  ===
-==|==
-  |==
-  |  
-
-252F
-     
-==+==
-==|==
-==|==
-  |  
-
-2530
-     
-=====
-=====
-==|==
-  |  
-
-2531
-     
-===| 
-==||=
-=||| 
- ||| 
-
-2532
-     
- |===
-=||==
- ||==
- ||  
-
-2533
-     
-=====
-==|==
-=+|+=
- ||| 
-
-#2534: bottom line, connected to from top
-2534
-  |
-  |
-=====
-     
-     
-
-2535
-  |
-==|
-=====
-===  
-    
-
-2536
-  |
-  |==
-=====
-  ===
-     
-
-2537
-  |
-==|==
-=====
-=====
-     
-
-2538
- |||
- |||
-=====
-     
-     
-
-2539
- |||
-==||
-=====
-===| 
-    
-
-
-253A
- |||
- ||==
-=|===
- |===
-     
-
-253B
- |||
-==|==
-=====
-=====
-     
-
-#253C: vertical + horizontal lines intersecting
-253C
-  |  
-  |  
-=====
-  |  
-  |
-
-253D
-  |  
-==|  
-=====
-==|  
-  |
-
-253E
-  |  
-  |==
-=====
-  |==
-  |
-
-253F
-  |  
-==|==
-=====
-==|==
-  |
-
-2540
- ||| 
- ||| 
-=====
-  |  
-  |
-
-2541
-  |  
-  |  
-=====
- ||| 
- |||
-
-2542
- ||| 
- ||| 
-=====
- ||| 
- |||
-
-2543
- ||| 
-=|||
-=====
-==|+ 
-  |
-
-2544
- ||| 
- ||==
-=====
-  |==
-  |
-
-2545
-  |
-==|+ 
-=====
-=|||
- ||| 
-
-2546
-  |
-  |==
-=====
- ||==
- ||| 
-
-2547
- ||| 
-=|||=
-=====
-=|||=
-  | 
-
-2548
-  |  
-=|||=
-=====
-=|||=
- |||
-
-2549
- ||| 
-=||| 
-=====
-=||| 
- |||
-
-254A
- ||| 
- |||=
-=====
- |||=
- |||
-
-254B
- ||| 
-=|||=
-=====
-=|||=
- |||
-
-#254C-254F are dashed
-2550
-     
-_____
-     
-_____
-     
-
-2551
- | | 
- | |
- | |
- | |
- | |
-
-2552
-     
-  |--
-  |
-  |--
-  |
-
-2553
-     
-     
- ----
- | | 
- | | 
-
-2554
-     
- +---
- |
- + +-
- | |
-
-2555
-     
---+
-  |  
---+  
-  |  
-
-2556
-    
-    
--+-+
- | |
- | |
-
-2557
-     
----+ 
-   | 
--+ |
- | |
-
-2558
-  |
-  +--
-  |
-  +--
-
-2559
- | | 
- | | 
- +-+-
-     
-     
-
-255A
- | | 
- | +-
- |   
- +---
-     
-
-255B
-  |  
---+  
-  | 
---+  
-     
-
-255C
- | | 
- | | 
--+-+ 
-    
-
-255D
- | | 
--+ | 
-   |
----+
-    
-
-255E
-  |
-  +--
-  |
-  +--
-  |
-
-255F
- | |
- | |
- | +-
- | |
- | |
-
-2560
- | |
- | +-
- | |
- | +-
- | |
-
-2561
-  |
---+
-  |
---+
-  |
-
-2562
- | | 
- | |
--+ +
- | |
- | |
-
-2563
- | |
--+ |
-   |
--+ |
- | |
-
-2564
-     
------
-     
---+--
-  |
-
-2565
-     
-     
--+-+-
- | | 
- | |
-
-2566
-     
------
-     
--+ +-
- | |
-
-2567
-  |  
---+--
-     
------
-     
-
-2568
- | | 
- | | 
--+-+-
-     
-     
-
-2569
- | | 
--+ +-
-     
------
-     
-
-256A
-  |  
---+--
-  |  
---+--
-  |
-
-256B
- | | 
- | | 
--+-+-
- | | 
- | | 
-
-256C
- | | 
--+ +-
-
--+ +-
- | | 
-
-#256F-2570 are curly,
-#2571-2573 are slashes and X
-
-2574
-     
-     
-___  
-     
-     
-
-2575
-  |  
-  |  
-  |  
-     
-    
-
-2576
-     
-     
-  ___
-     
-     
-
-2577
-     
-    
-  |  
-  |  
-  |  
-
-2578
-     
-___  
-___  
-___  
-     
-
-2579
- ||| 
- ||| 
- ||| 
-     
-    
-
-257A
-     
-  ___
-  ___
-  ___
-     
-
-257B
-     
-    
- ||| 
- ||| 
- ||| 
-
-257C
-     
-  ___
-_____
-  ___
-     
-
-257D
-  |  
-  |  
- ||| 
- ||| 
- ||| 
-
-257E
-     
-___  
-_____
-___  
-     
-
-257F
- ||| 
- ||| 
- ||| 
-  |  
-  |  
--- a/gui/qtermwidget/lib/Pty.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,320 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    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
-
-    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 "Pty.h"
-
-// System
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <termios.h>
-
-// Qt
-#include <QtCore>
-
-// KDE
-//#include <KStandardDirs>
-//#include <KLocale>
-//#include <KDebug>
-#include "kpty.h"
-
-using namespace Konsole;
-
-void Pty::donePty()
-{
-  emit done(exitStatus());
-}
-
-void Pty::setWindowSize(int lines, int cols)
-{
-  _windowColumns = cols;
-  _windowLines = lines;
-
-  if (pty()->masterFd() >= 0)
-    pty()->setWinSize(lines, cols);
-}
-QSize Pty::windowSize() const
-{
-    return QSize(_windowColumns,_windowLines);
-}
-
-void Pty::setXonXoff(bool enable)
-{
-  _xonXoff = enable;
-
-  if (pty()->masterFd() >= 0)
-  {
-    struct ::termios ttmode;
-    pty()->tcGetAttr(&ttmode);
-    if (!enable)
-      ttmode.c_iflag &= ~(IXOFF | IXON);
-    else
-      ttmode.c_iflag |= (IXOFF | IXON);
-    if (!pty()->tcSetAttr(&ttmode))
-      qWarning("Unable to set terminal attributes.");
-  }
-}
-
-void Pty::setUtf8Mode(bool enable)
-{
-#ifdef IUTF8 // XXX not a reasonable place to check it.
-  _utf8 = enable;
-
-  if (pty()->masterFd() >= 0)
-  {
-    struct ::termios ttmode;
-    pty()->tcGetAttr(&ttmode);
-    if (!enable)
-      ttmode.c_iflag &= ~IUTF8;
-    else
-      ttmode.c_iflag |= IUTF8;
-    if (!pty()->tcSetAttr(&ttmode))
-      qWarning("Unable to set terminal attributes.");
-  }
-#endif
-}
-
-void Pty::setErase(char erase)
-{
-  _eraseChar = erase;
-  
-  if (pty()->masterFd() >= 0)
-  {
-    struct ::termios ttmode;
-
-    pty()->tcGetAttr(&ttmode);
-
-    ttmode.c_cc[VERASE] = erase;
-
-    if (!pty()->tcSetAttr(&ttmode))
-      qWarning("Unable to set terminal attributes.");
-  }  
-}
-
-char Pty::erase() const
-{
-	if (pty()->masterFd() >= 0)
-	{
-		qDebug() << "Getting erase char";
-		struct ::termios ttyAttributes;
-		pty()->tcGetAttr(&ttyAttributes);
-		return ttyAttributes.c_cc[VERASE];
-	}
-
-	return _eraseChar;
-}
-
-void Pty::addEnvironmentVariables(const QStringList& environment)
-{
-    QListIterator<QString> iter(environment);
-    while (iter.hasNext())
-    {
-        QString pair = iter.next();
-
-        // split on the first '=' character
-        int pos = pair.indexOf('=');
-        
-        if ( pos >= 0 )
-        {
-            QString variable = pair.left(pos);
-            QString value = pair.mid(pos+1);
-
-            //kDebug() << "Setting environment pair" << variable <<
-            //    " set to " << value;
-
-            setEnvironment(variable,value);
-        }
-    }
-}
-
-int Pty::start(const QString& program, 
-               const QStringList& programArguments, 
-               const QStringList& environment, 
-               ulong winid, 
-               bool addToUtmp
-//               const QString& dbusService, 
-//               const QString& dbusSession)
-		)
-{
-  clearArguments();
-
-  setBinaryExecutable(program.toLatin1());
-
-  addEnvironmentVariables(environment);
-
-  QStringListIterator it( programArguments );
-  while (it.hasNext())
-    arguments.append( it.next().toUtf8() );
-
-//  if ( !dbusService.isEmpty() )
-//     setEnvironment("KONSOLE_DBUS_SERVICE",dbusService);
-//  if ( !dbusSession.isEmpty() )
-//     setEnvironment("KONSOLE_DBUS_SESSION", dbusSession);
-
-  setEnvironment("WINDOWID", QString::number(winid));
-
-  // unless the LANGUAGE environment variable has been set explicitly
-  // set it to a null string
-  // this fixes the problem where KCatalog sets the LANGUAGE environment
-  // variable during the application's startup to something which
-  // differs from LANG,LC_* etc. and causes programs run from
-  // the terminal to display mesages in the wrong language
-  //
-  // this can happen if LANG contains a language which KDE
-  // does not have a translation for
-  //
-  // BR:149300
-  if (!environment.contains("LANGUAGE"))
-      setEnvironment("LANGUAGE",QString());
-
-  setUsePty(All, addToUtmp);
-
-  pty()->open();
-  
-  struct ::termios ttmode;
-  pty()->tcGetAttr(&ttmode);
-  if (!_xonXoff)
-    ttmode.c_iflag &= ~(IXOFF | IXON);
-  else
-    ttmode.c_iflag |= (IXOFF | IXON);
-#ifdef IUTF8 // XXX not a reasonable place to check it.
-  if (!_utf8)
-    ttmode.c_iflag &= ~IUTF8;
-  else
-    ttmode.c_iflag |= IUTF8;
-#endif
-
-  if (_eraseChar != 0)
-  	ttmode.c_cc[VERASE] = _eraseChar;
-  
-  if (!pty()->tcSetAttr(&ttmode))
-    qWarning("Unable to set terminal attributes.");
-  
-  pty()->setWinSize(_windowLines, _windowColumns);
-
-  if ( K3Process::start(NotifyOnExit, (Communication) (Stdin | Stdout)) == false )
-     return -1;
-
-  resume(); // Start...
-  return 0;
-
-}
-
-void Pty::setWriteable(bool writeable)
-{
-  struct stat sbuf;
-  stat(pty()->ttyName(), &sbuf);
-  if (writeable)
-    chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP);
-  else
-    chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP|S_IWOTH));
-}
-
-Pty::Pty()
-    : _bufferFull(false),
-      _windowColumns(0),
-      _windowLines(0),
-      _eraseChar(0),
-      _xonXoff(true),
-      _utf8(true)
-{
-  connect(this, SIGNAL(receivedStdout(K3Process *, char *, int )),
-	  this, SLOT(dataReceived(K3Process *,char *, int)));
-  connect(this, SIGNAL(processExited(K3Process *)),
-          this, SLOT(donePty()));
-  connect(this, SIGNAL(wroteStdin(K3Process *)),
-          this, SLOT(writeReady()));
-  _pty = new KPty;
-
-  setUsePty(All, false); // utmp will be overridden later
-}
-
-Pty::~Pty()
-{
-    delete _pty;
-}
-
-void Pty::writeReady()
-{
-  _pendingSendJobs.erase(_pendingSendJobs.begin());
-  _bufferFull = false;
-  doSendJobs();
-}
-
-void Pty::doSendJobs() {
-  if(_pendingSendJobs.isEmpty())
-  {
-     emit bufferEmpty(); 
-     return;
-  }
-  
-  SendJob& job = _pendingSendJobs.first();
-
-  
-  if (!writeStdin( job.data(), job.length() ))
-  {
-    qWarning("Pty::doSendJobs - Could not send input data to terminal process.");
-    return;
-  }
-  _bufferFull = true;
-}
-
-void Pty::appendSendJob(const char* s, int len)
-{
-  _pendingSendJobs.append(SendJob(s,len));
-}
-
-void Pty::sendData(const char* s, int len)
-{
-  appendSendJob(s,len);
-  if (!_bufferFull)
-     doSendJobs();
-}
-
-void Pty::dataReceived(K3Process *,char *buf, int len)
-{
-  emit receivedData(buf,len);
-}
-
-void Pty::lockPty(bool lock)
-{
-  if (lock)
-    suspend();
-  else
-    resume();
-}
-
-int Pty::foregroundProcessGroup() const
-{
-    int pid = tcgetpgrp(pty()->masterFd());
-
-    if ( pid != -1 )
-    {
-        return pid;
-    } 
-
-    return 0;
-}
-
-//#include "moc_Pty.cpp"
--- a/gui/qtermwidget/lib/Pty.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,243 +0,0 @@
-/*
-    This file is part of Konsole, KDE's terminal emulator. 
-    
-    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
-
-    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.
-*/
-
-#ifndef PTY_H
-#define PTY_H
-
-// Qt
-#include <QtCore/QStringList>
-#include <QtCore/QVector>
-#include <QtCore/QList>
-#include <QtCore>
-
-#include "k3process.h"
-
-
-namespace Konsole
-{
-
-/**
- * The Pty class is used to start the terminal process, 
- * send data to it, receive data from it and manipulate 
- * various properties of the pseudo-teletype interface
- * used to communicate with the process.
- *
- * To use this class, construct an instance and connect
- * to the sendData slot and receivedData signal to
- * send data to or receive data from the process.
- *
- * To start the terminal process, call the start() method
- * with the program name and appropriate arguments. 
- */
-class Pty: public K3Process
-{
-Q_OBJECT
-
-  public:
-    
-    /** 
-     * Constructs a new Pty.
-     * 
-     * Connect to the sendData() slot and receivedData() signal to prepare
-     * for sending and receiving data from the terminal process.
-     *
-     * To start the terminal process, call the run() method with the 
-     * name of the program to start and appropriate arguments.
-     */
-    Pty();
-    ~Pty();
-
-    /**
-     * Starts the terminal process.  
-     *
-     * Returns 0 if the process was started successfully or non-zero
-     * otherwise.
-     *
-     * @param program Path to the program to start
-     * @param arguments Arguments to pass to the program being started
-     * @param environment A list of key=value pairs which will be added
-     * to the environment for the new process.  At the very least this
-     * should include an assignment for the TERM environment variable.
-     * @param winid Specifies the value of the WINDOWID environment variable
-     * in the process's environment.
-     * @param addToUtmp Specifies whether a utmp entry should be created for
-     * the pty used.  See K3Process::setUsePty() 
-     * @param dbusService Specifies the value of the KONSOLE_DBUS_SERVICE 
-     * environment variable in the process's environment.
-     * @param dbusSession Specifies the value of the KONSOLE_DBUS_SESSION
-     * environment variable in the process's environment. 
-     */
-    int start( const QString& program, 
-               const QStringList& arguments, 
-               const QStringList& environment, 
-               ulong winid, 
-               bool addToUtmp
-//               const QString& dbusService,
-//               const QString& dbusSession
-             );
-
-    /** TODO: Document me */
-    void setWriteable(bool writeable);
-
-    /** 
-     * Enables or disables Xon/Xoff flow control.
-     */
-    void setXonXoff(bool on);
-
-    /** 
-     * Sets the size of the window (in lines and columns of characters) 
-     * used by this teletype.
-     */
-    void setWindowSize(int lines, int cols);
-    
-    /** Returns the size of the window used by this teletype.  See setWindowSize() */
-    QSize windowSize() const;
-
-    /** TODO Document me */
-    void setErase(char erase);
-
-	/** */
-	char erase() const;
-
-    /**
-     * Returns the process id of the teletype's current foreground
-     * process.  This is the process which is currently reading
-     * input sent to the terminal via. sendData()
-     *
-     * If there is a problem reading the foreground process group,
-     * 0 will be returned.
-     */
-    int foregroundProcessGroup() const;
-   
-    /**
-     * Returns whether the buffer used to send data to the
-     * terminal process is full.
-     */
-    bool bufferFull() const { return _bufferFull; }
-
-
-  public slots:
-
-    /**
-     * Put the pty into UTF-8 mode on systems which support it.
-     */
-    void setUtf8Mode(bool on);
-
-    /**
-     * Suspend or resume processing of data from the standard 
-     * output of the terminal process.
-     *
-     * See K3Process::suspend() and K3Process::resume()
-     *
-     * @param lock If true, processing of output is suspended,
-     * otherwise processing is resumed.
-     */
-    void lockPty(bool lock);
-    
-    /** 
-     * Sends data to the process currently controlling the 
-     * teletype ( whose id is returned by foregroundProcessGroup() )
-     *
-     * @param buffer Pointer to the data to send.
-     * @param length Length of @p buffer.
-     */
-    void sendData(const char* buffer, int length);
-
-  signals:
-
-    /**
-     * Emitted when the terminal process terminates.
-     *
-     * @param exitCode The status code which the process exited with.
-     */
-    void done(int exitCode);
-
-    /**
-     * Emitted when a new block of data is received from
-     * the teletype.
-     *
-     * @param buffer Pointer to the data received.
-     * @param length Length of @p buffer
-     */
-    void receivedData(const char* buffer, int length);
-    
-    /**
-     * Emitted when the buffer used to send data to the terminal
-     * process becomes empty, i.e. all data has been sent.
-     */
-    void bufferEmpty();
-    
-
-  private slots:
-    
-    // called when terminal process exits
-    void donePty();
-    // called when data is received from the terminal process 
-    void dataReceived(K3Process*, char* buffer, int length);
-    // sends the first enqueued buffer of data to the
-    // terminal process
-    void doSendJobs();
-    // called when the terminal process is ready to
-    // receive more data
-    void writeReady();
-
-  private:
-    // takes a list of key=value pairs and adds them
-    // to the environment for the process
-    void addEnvironmentVariables(const QStringList& environment);
-
-    // enqueues a buffer of data to be sent to the 
-    // terminal process
-    void appendSendJob(const char* buffer, int length);
-   
-    // a buffer of data in the queue to be sent to the 
-    // terminal process 
-    class SendJob {
-	public:
-      		SendJob() {}
-      		SendJob(const char* b, int len) : buffer(len)
-		{
-			memcpy( buffer.data() , b , len );
-        }
-	
-		const char* data() const { return buffer.constData(); }
-		int length() const { return buffer.size(); }	
-	private:
-      		QVector<char> buffer;
-    };
-
-    QList<SendJob> _pendingSendJobs;
-    bool _bufferFull;
-
-    int  _windowColumns; 
-    int  _windowLines;
-    char _eraseChar;
-    bool _xonXoff;
-    bool _utf8;
-    KPty *_pty;
-};
-
-}
-
-#endif // PTY_H
--- a/gui/qtermwidget/lib/README	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-lib.pro is a *.pro-file for qmake
-
-It produces static lib (libqtermwidget.a) only. 
-For creating shared lib (*.so) uncomment "dll" in "CONFIG" line in *.pro-file
-
-Library was tested both with HAVE_POSIX_OPENPT and HAVE_GETPT precompiler directives, 
-defined in "DEFINES" line. You should select variant which would be correct for your system.
\ No newline at end of file
--- a/gui/qtermwidget/lib/Screen.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1567 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    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
-
-    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 "Screen.h"
-
-// Standard
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-
-// Qt
-#include <QtCore/QTextStream>
-#include <QtCore/QDate>
-
-// Konsole
-#include "konsole_wcwidth.h"
-#include "TerminalCharacterDecoder.h"
-
-using namespace Konsole;
-
-//FIXME: this is emulation specific. Use false for xterm, true for ANSI.
-//FIXME: see if we can get this from terminfo.
-#define BS_CLEARS false
-
-//Macro to convert x,y position on screen to position within an image.
-//
-//Originally the image was stored as one large contiguous block of 
-//memory, so a position within the image could be represented as an
-//offset from the beginning of the block.  For efficiency reasons this
-//is no longer the case.  
-//Many internal parts of this class still use this representation for parameters and so on,
-//notably moveImage() and clearImage().
-//This macro converts from an X,Y position into an image offset.
-#ifndef loc
-#define loc(X,Y) ((Y)*columns+(X))
-#endif
-
-
-Character Screen::defaultChar = Character(' ',
-					  CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
-					  CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
-					  DEFAULT_RENDITION);
-
-//#define REVERSE_WRAPPED_LINES  // for wrapped line debug
-
-Screen::Screen(int l, int c)
-  : lines(l),
-    columns(c),
-    screenLines(new ImageLine[lines+1] ),
-    _scrolledLines(0),
-    _droppedLines(0),
-    hist(new HistoryScrollNone()),
-    cuX(0), cuY(0),
-    cu_re(0),
-    tmargin(0), bmargin(0),
-    tabstops(0),
-    sel_begin(0), sel_TL(0), sel_BR(0),
-    sel_busy(false),
-    columnmode(false),
-    ef_fg(CharacterColor()), ef_bg(CharacterColor()), ef_re(0),
-    sa_cuX(0), sa_cuY(0),
-    sa_cu_re(0),
-    lastPos(-1)
-{
-  lineProperties.resize(lines+1);
-  for (int i=0;i<lines+1;i++)
-          lineProperties[i]=LINE_DEFAULT;
-
-  initTabStops();
-  clearSelection();
-  reset();
-}
-
-/*! Destructor
-*/
-
-Screen::~Screen()
-{
-  delete[] screenLines;
-  delete[] tabstops;
-  delete hist;
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/* Normalized                    Screen Operations                           */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-// Cursor Setting --------------------------------------------------------------
-
-/*! \section Cursor
-
-    The `cursor' is a location within the screen that is implicitely used in
-    many operations. The operations within this section allow to manipulate
-    the cursor explicitly and to obtain it's value.
-
-    The position of the cursor is guarantied to be between (including) 0 and
-    `columns-1' and `lines-1'.
-*/
-
-/*!
-    Move the cursor up.
-
-    The cursor will not be moved beyond the top margin.
-*/
-
-void Screen::cursorUp(int n)
-//=CUU
-{
-  if (n == 0) n = 1; // Default
-  int stop = cuY < tmargin ? 0 : tmargin;
-  cuX = qMin(columns-1,cuX); // nowrap!
-  cuY = qMax(stop,cuY-n);
-}
-
-/*!
-    Move the cursor down.
-
-    The cursor will not be moved beyond the bottom margin.
-*/
-
-void Screen::cursorDown(int n)
-//=CUD
-{
-  if (n == 0) n = 1; // Default
-  int stop = cuY > bmargin ? lines-1 : bmargin;
-  cuX = qMin(columns-1,cuX); // nowrap!
-  cuY = qMin(stop,cuY+n);
-}
-
-/*!
-    Move the cursor left.
-
-    The cursor will not move beyond the first column.
-*/
-
-void Screen::cursorLeft(int n)
-//=CUB
-{
-  if (n == 0) n = 1; // Default
-  cuX = qMin(columns-1,cuX); // nowrap!
-  cuX = qMax(0,cuX-n);
-}
-
-/*!
-    Move the cursor left.
-
-    The cursor will not move beyond the rightmost column.
-*/
-
-void Screen::cursorRight(int n)
-//=CUF
-{
-  if (n == 0) n = 1; // Default
-  cuX = qMin(columns-1,cuX+n);
-}
-
-void Screen::setMargins(int top, int bot)
-//=STBM
-{
-  if (top == 0) top = 1;      // Default
-  if (bot == 0) bot = lines;  // Default
-  top = top - 1;              // Adjust to internal lineno
-  bot = bot - 1;              // Adjust to internal lineno
-  if ( !( 0 <= top && top < bot && bot < lines ) )
-  { qDebug()<<" setRegion("<<top<<","<<bot<<") : bad range.";
-    return;                   // Default error action: ignore
-  }
-  tmargin = top;
-  bmargin = bot;
-  cuX = 0;
-  cuY = getMode(MODE_Origin) ? top : 0;
-
-}
-
-int Screen::topMargin() const
-{
-    return tmargin;
-}
-int Screen::bottomMargin() const
-{
-    return bmargin;
-}
-
-void Screen::index()
-//=IND
-{
-  if (cuY == bmargin)
-  {
-    scrollUp(1);
-  }
-  else if (cuY < lines-1)
-    cuY += 1;
-}
-
-void Screen::reverseIndex()
-//=RI
-{
-  if (cuY == tmargin)
-     scrollDown(tmargin,1);
-  else if (cuY > 0)
-    cuY -= 1;
-}
-
-/*!
-    Move the cursor to the begin of the next line.
-
-    If cursor is on bottom margin, the region between the
-    actual top and bottom margin is scrolled up.
-*/
-
-void Screen::NextLine()
-//=NEL
-{
-  Return(); index();
-}
-
-void Screen::eraseChars(int n)
-{
-  if (n == 0) n = 1; // Default
-  int p = qMax(0,qMin(cuX+n-1,columns-1));
-  clearImage(loc(cuX,cuY),loc(p,cuY),' ');
-}
-
-void Screen::deleteChars(int n)
-{
-  Q_ASSERT( n >= 0 );
-
-  // always delete at least one char
-  if (n == 0) 
-      n = 1; 
-
-  // if cursor is beyond the end of the line there is nothing to do
-  if ( cuX >= screenLines[cuY].count() )
-      return;
-
-  if ( cuX+n >= screenLines[cuY].count() ) 
-       n = screenLines[cuY].count() - 1 - cuX;
-
-  Q_ASSERT( n >= 0 );
-  Q_ASSERT( cuX+n < screenLines[cuY].count() );
-
-  screenLines[cuY].remove(cuX,n);
-}
-
-void Screen::insertChars(int n)
-{
-  if (n == 0) n = 1; // Default
-
-  if ( screenLines[cuY].size() < cuX )
-    screenLines[cuY].resize(cuX);
-
-  screenLines[cuY].insert(cuX,n,' ');
-
-  if ( screenLines[cuY].count() > columns )
-      screenLines[cuY].resize(columns);
-}
-
-void Screen::deleteLines(int n)
-{
-  if (n == 0) n = 1; // Default
-  scrollUp(cuY,n);
-}
-
-/*! insert `n' lines at the cursor position.
-
-    The cursor is not moved by the operation.
-*/
-
-void Screen::insertLines(int n)
-{
-  if (n == 0) n = 1; // Default
-  scrollDown(cuY,n);
-}
-
-// Mode Operations -----------------------------------------------------------
-
-/*! Set a specific mode. */
-
-void Screen::setMode(int m)
-{
-  currParm.mode[m] = true;
-  switch(m)
-  {
-    case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
-  }
-}
-
-/*! Reset a specific mode. */
-
-void Screen::resetMode(int m)
-{
-  currParm.mode[m] = false;
-  switch(m)
-  {
-    case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
-  }
-}
-
-/*! Save a specific mode. */
-
-void Screen::saveMode(int m)
-{
-  saveParm.mode[m] = currParm.mode[m];
-}
-
-/*! Restore a specific mode. */
-
-void Screen::restoreMode(int m)
-{
-  currParm.mode[m] = saveParm.mode[m];
-}
-
-bool Screen::getMode(int m) const
-{
-  return currParm.mode[m];
-}
-
-void Screen::saveCursor()
-{
-  sa_cuX     = cuX;
-  sa_cuY     = cuY;
-  sa_cu_re   = cu_re;
-  sa_cu_fg   = cu_fg;
-  sa_cu_bg   = cu_bg;
-}
-
-void Screen::restoreCursor()
-{
-  cuX     = qMin(sa_cuX,columns-1);
-  cuY     = qMin(sa_cuY,lines-1);
-  cu_re   = sa_cu_re;
-  cu_fg   = sa_cu_fg;
-  cu_bg   = sa_cu_bg;
-  effectiveRendition();
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                             Screen Operations                             */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/*! Resize the screen image
-
-    The topmost left position is maintained, while lower lines
-    or right hand side columns might be removed or filled with
-    spaces to fit the new size.
-
-    The region setting is reset to the whole screen and the
-    tab positions reinitialized.
-
-    If the new image is narrower than the old image then text on lines
-    which extends past the end of the new image is preserved so that it becomes
-    visible again if the screen is later resized to make it larger.
-*/
-
-void Screen::resizeImage(int new_lines, int new_columns)
-{
-  if ((new_lines==lines) && (new_columns==columns)) return;
-
-  if (cuY > new_lines-1)
-  { // attempt to preserve focus and lines
-    bmargin = lines-1; //FIXME: margin lost
-    for (int i = 0; i < cuY-(new_lines-1); i++)
-    {
-      addHistLine(); scrollUp(0,1);
-    }
-  }
-
-  // create new screen lines and copy from old to new
-  
-   ImageLine* newScreenLines = new ImageLine[new_lines+1];
-   for (int i=0; i < qMin(lines-1,new_lines+1) ;i++)
-           newScreenLines[i]=screenLines[i];
-   for (int i=lines;(i > 0) && (i<new_lines+1);i++)
-           newScreenLines[i].resize( new_columns );
-   
-  lineProperties.resize(new_lines+1);
-  for (int i=lines;(i > 0) && (i<new_lines+1);i++)
-          lineProperties[i] = LINE_DEFAULT;
-
-  clearSelection();
- 
-  delete[] screenLines; 
-  screenLines = newScreenLines;
-
-  lines = new_lines;
-  columns = new_columns;
-  cuX = qMin(cuX,columns-1);
-  cuY = qMin(cuY,lines-1);
-
-  // FIXME: try to keep values, evtl.
-  tmargin=0;
-  bmargin=lines-1;
-  initTabStops();
-  clearSelection();
-}
-
-void Screen::setDefaultMargins()
-{
-	tmargin = 0;
-	bmargin = lines-1;
-}
-
-
-/*
-   Clarifying rendition here and in the display.
-
-   currently, the display's color table is
-     0       1       2 .. 9    10 .. 17
-     dft_fg, dft_bg, dim 0..7, intensive 0..7
-
-   cu_fg, cu_bg contain values 0..8;
-   - 0    = default color
-   - 1..8 = ansi specified color
-
-   re_fg, re_bg contain values 0..17
-   due to the TerminalDisplay's color table
-
-   rendition attributes are
-
-      attr           widget screen
-      -------------- ------ ------
-      RE_UNDERLINE     XX     XX    affects foreground only
-      RE_BLINK         XX     XX    affects foreground only
-      RE_BOLD          XX     XX    affects foreground only
-      RE_REVERSE       --     XX
-      RE_TRANSPARENT   XX     --    affects background only
-      RE_INTENSIVE     XX     --    affects foreground only
-
-   Note that RE_BOLD is used in both widget
-   and screen rendition. Since xterm/vt102
-   is to poor to distinguish between bold
-   (which is a font attribute) and intensive
-   (which is a color attribute), we translate
-   this and RE_BOLD in falls eventually appart
-   into RE_BOLD and RE_INTENSIVE.
-*/
-
-void Screen::reverseRendition(Character& p) const
-{ 
-	CharacterColor f = p.foregroundColor; 
-	CharacterColor b = p.backgroundColor;
-  	
-	p.foregroundColor = b; 
-	p.backgroundColor = f; //p->r &= ~RE_TRANSPARENT;
-}
-
-void Screen::effectiveRendition()
-// calculate rendition
-{
-  //copy "current rendition" straight into "effective rendition", which is then later copied directly
-  //into the image[] array which holds the characters and their appearance properties.
-  //- The old version below filtered out all attributes other than underline and blink at this stage,
-  //so that they would not be copied into the image[] array and hence would not be visible by TerminalDisplay
-  //which actually paints the screen using the information from the image[] array.  
-  //I don't know why it did this, but I'm fairly sure it was the wrong thing to do.  The net result
-  //was that bold text wasn't printed in bold by Konsole.
-  ef_re = cu_re;
-  
-  //OLD VERSION:
-  //ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
-  
-  if (cu_re & RE_REVERSE)
-  {
-    ef_fg = cu_bg;
-    ef_bg = cu_fg;
-  }
-  else
-  {
-    ef_fg = cu_fg;
-    ef_bg = cu_bg;
-  }
- 
-  if (cu_re & RE_BOLD)
-    ef_fg.toggleIntensive();
-}
-
-/*!
-    returns the image.
-
-    Get the size of the image by \sa getLines and \sa getColumns.
-
-    NOTE that the image returned by this function must later be
-    freed.
-
-*/
-
-void Screen::copyFromHistory(Character* dest, int startLine, int count) const
-{
-  Q_ASSERT( startLine >= 0 && count > 0 && startLine + count <= hist->getLines() );
-
-  for (int line = startLine; line < startLine + count; line++) 
-  {
-    const int length = qMin(columns,hist->getLineLen(line));
-    const int destLineOffset  = (line-startLine)*columns;
-
-    hist->getCells(line,0,length,dest + destLineOffset);
-
-    for (int column = length; column < columns; column++) 
-		dest[destLineOffset+column] = defaultChar;
-    
-	// invert selected text
-	if (sel_begin !=-1)
-	{
-    	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
-{
-	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;
-
-       for (int column = 0; column < columns; column++)
-       { 
-		 int srcIndex = srcLineStartIndex + column; 
-		 int destIndex = destLineStartIndex + column;
-
-         dest[destIndex] = screenLines[srcIndex/columns].value(srcIndex%columns,defaultChar);
-
-	     // invert selected text
-         if (sel_begin != -1 && isSelected(column,line + hist->getLines()))
-           reverseRendition(dest[destIndex]); 
-       }
-
-    }
-}
-
-void Screen::getImage( Character* dest, int size, int startLine, int endLine ) const
-{
-  Q_ASSERT( startLine >= 0 ); 
-  Q_ASSERT( endLine >= startLine && endLine < hist->getLines() + lines );
-
-  const int mergedLines = endLine - startLine + 1;
-
-  Q_ASSERT( size >= mergedLines * columns ); 
-
-  const int linesInHistoryBuffer = qBound(0,hist->getLines()-startLine,mergedLines);
-  const int linesInScreenBuffer = mergedLines - linesInHistoryBuffer;
-
-  // copy lines from history buffer
-  if (linesInHistoryBuffer > 0) {
-  	copyFromHistory(dest,startLine,linesInHistoryBuffer); 
-    }
-
-  // copy lines from screen buffer
-  if (linesInScreenBuffer > 0) {
-  	copyFromScreen(dest + linesInHistoryBuffer*columns,
-				   startLine + linesInHistoryBuffer - hist->getLines(),
-				   linesInScreenBuffer);
-    }				
- 
-  // invert display when in screen mode
-  if (getMode(MODE_Screen))
-  {  
-    for (int i = 0; i < mergedLines*columns; i++)
-      reverseRendition(dest[i]); // for reverse display
-  }
-
-  // mark the character at the current cursor position
-  int cursorIndex = loc(cuX, cuY + linesInHistoryBuffer);
-  if(getMode(MODE_Cursor) && cursorIndex < columns*mergedLines)
-    dest[cursorIndex].rendition |= RE_CURSOR;
-}
-
-QVector<LineProperty> Screen::getLineProperties( int startLine , int endLine ) const
-{
-  Q_ASSERT( startLine >= 0 ); 
-  Q_ASSERT( endLine >= startLine && endLine < hist->getLines() + lines );
-
-	const int mergedLines = endLine-startLine+1;
-	const int linesInHistory = qBound(0,hist->getLines()-startLine,mergedLines);
-  const int linesInScreen = mergedLines - linesInHistory;
-
-  QVector<LineProperty> result(mergedLines);
-  int index = 0;
-
-  // copy properties for lines in history
-  for (int line = startLine; line < startLine + linesInHistory; line++) 
-  {
-		//TODO Support for line properties other than wrapped lines
-	  if (hist->isWrappedLine(line))
-	  {
-	  	result[index] = (LineProperty)(result[index] | LINE_WRAPPED);
-	  }
-    index++;
-  }
-  
-  // copy properties for lines in screen buffer
-  const int firstScreenLine = startLine + linesInHistory - hist->getLines();
-  for (int line = firstScreenLine; line < firstScreenLine+linesInScreen; line++)
-	{
-    result[index]=lineProperties[line];
-  	index++;
-	}
-
-  return result;
-}
-
-/*!
-*/
-
-void Screen::reset(bool clearScreen)
-{
-    setMode(MODE_Wrap  ); saveMode(MODE_Wrap  );  // wrap at end of margin
-  resetMode(MODE_Origin); saveMode(MODE_Origin);  // position refere to [1,1]
-  resetMode(MODE_Insert); saveMode(MODE_Insert);  // overstroke
-    setMode(MODE_Cursor);                         // cursor visible
-  resetMode(MODE_Screen);                         // screen not inverse
-  resetMode(MODE_NewLine);
-
-  tmargin=0;
-  bmargin=lines-1;
-
-  setDefaultRendition();
-  saveCursor();
-
-  if ( clearScreen )
-    clear();
-}
-
-/*! Clear the entire screen and home the cursor.
-*/
-
-void Screen::clear()
-{
-  clearEntireScreen();
-  home();
-}
-
-void Screen::BackSpace()
-{
-  cuX = qMin(columns-1,cuX); // nowrap!
-  cuX = qMax(0,cuX-1);
- // if (BS_CLEARS) image[loc(cuX,cuY)].character = ' ';
-
-  if (screenLines[cuY].size() < cuX+1)
-          screenLines[cuY].resize(cuX+1);
-
-  if (BS_CLEARS) screenLines[cuY][cuX].character = ' ';
-}
-
-void Screen::Tabulate(int n)
-{
-  // note that TAB is a format effector (does not write ' ');
-  if (n == 0) n = 1;
-  while((n > 0) && (cuX < columns-1))
-  {
-    cursorRight(1); while((cuX < columns-1) && !tabstops[cuX]) cursorRight(1);
-    n--;
-  }
-}
-
-void Screen::backTabulate(int n)
-{
-  // note that TAB is a format effector (does not write ' ');
-  if (n == 0) n = 1;
-  while((n > 0) && (cuX > 0))
-  {
-     cursorLeft(1); while((cuX > 0) && !tabstops[cuX]) cursorLeft(1);
-     n--;
-  }
-}
-
-void Screen::clearTabStops()
-{
-  for (int i = 0; i < columns; i++) tabstops[i] = false;
-}
-
-void Screen::changeTabStop(bool set)
-{
-  if (cuX >= columns) return;
-  tabstops[cuX] = set;
-}
-
-void Screen::initTabStops()
-{
-  delete[] tabstops;
-  tabstops = new bool[columns];
-
-  // Arrg! The 1st tabstop has to be one longer than the other.
-  // i.e. the kids start counting from 0 instead of 1.
-  // Other programs might behave correctly. Be aware.
-  for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
-}
-
-/*!
-   This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
-   depending on the NewLine Mode (LNM). This mode also
-   affects the key sequence returned for newline ([CR]LF).
-*/
-
-void Screen::NewLine()
-{
-  if (getMode(MODE_NewLine)) Return();
-  index();
-}
-
-/*! put `c' literally onto the screen at the current cursor position.
-
-    VT100 uses the convention to produce an automatic newline (am)
-    with the *first* character that would fall onto the next line (xenl).
-*/
-
-void Screen::checkSelection(int from, int to)
-{
-  if (sel_begin == -1) return;
-  int scr_TL = loc(0, hist->getLines());
-  //Clear entire selection if it overlaps region [from, to]
-  if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
-  {
-    clearSelection();
-  }
-}
-
-void Screen::ShowCharacter(unsigned short c)
-{
-  // Note that VT100 does wrapping BEFORE putting the character.
-  // This has impact on the assumption of valid cursor positions.
-  // We indicate the fact that a newline has to be triggered by
-  // putting the cursor one right to the last column of the screen.
-
-  int w = konsole_wcwidth(c);
-
-  if (w <= 0)
-     return;
-
-  if (cuX+w > columns) {
-    if (getMode(MODE_Wrap)) {
-      lineProperties[cuY] = (LineProperty)(lineProperties[cuY] | LINE_WRAPPED);
-      NextLine();
-    }
-    else
-      cuX = columns-w;
-  }
-
-  // ensure current line vector has enough elements
-  int size = screenLines[cuY].size();
-  if (size == 0 && cuY > 0)
-  {
-          screenLines[cuY].resize( qMax(screenLines[cuY-1].size() , cuX+w) );
-  }
-  else
-  {
-    if (size < cuX+w)
-    {
-          screenLines[cuY].resize(cuX+w);
-    }
-  }
-
-  if (getMode(MODE_Insert)) insertChars(w);
-
-  lastPos = loc(cuX,cuY);
-
-  // check if selection is still valid.
-  checkSelection(cuX,cuY);
-
-  Character& currentChar = screenLines[cuY][cuX];
-
-  currentChar.character = c;
-  currentChar.foregroundColor = ef_fg;
-  currentChar.backgroundColor = ef_bg;
-  currentChar.rendition = ef_re;
-
-  int i = 0;
-  int newCursorX = cuX + w--;
-  while(w)
-  {
-     i++;
-   
-     if ( screenLines[cuY].size() < cuX + i + 1 )
-         screenLines[cuY].resize(cuX+i+1);
-     
-     Character& ch = screenLines[cuY][cuX + i];
-     ch.character = 0;
-     ch.foregroundColor = ef_fg;
-     ch.backgroundColor = ef_bg;
-     ch.rendition = ef_re;
-
-     w--;
-  }
-  cuX = newCursorX;
-}
-
-void Screen::compose(const QString& /*compose*/)
-{
-   Q_ASSERT( 0 /*Not implemented yet*/ );
-
-/*  if (lastPos == -1)
-     return;
-     
-  QChar c(image[lastPos].character);
-  compose.prepend(c);
-  //compose.compose(); ### FIXME!
-  image[lastPos].character = compose[0].unicode();*/
-}
-
-int Screen::scrolledLines() const
-{
-        return _scrolledLines;
-}
-int Screen::droppedLines() const
-{
-    return _droppedLines;
-}
-void Screen::resetDroppedLines()
-{
-    _droppedLines = 0;
-}
-void Screen::resetScrolledLines()
-{
-    //kDebug() << "scrolled lines reset";
-
-    _scrolledLines = 0;
-}
-
-// Region commands -------------------------------------------------------------
-
-void Screen::scrollUp(int n)
-{
-   if (n == 0) n = 1; // Default
-   if (tmargin == 0) addHistLine(); // hist.history
-   scrollUp(tmargin, n);
-}
-
-/*! scroll up `n' lines within current region.
-    The `n' new lines are cleared.
-    \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));
-
-  //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
-  moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin));
-  clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' ');
-}
-
-void Screen::scrollDown(int n)
-{
-   if (n == 0) n = 1; // Default
-   scrollDown(tmargin, n);
-}
-
-/*! scroll down `n' lines within current region.
-    The `n' new lines are cleared.
-    \sa setRegion \sa scrollUp
-*/
-
-void Screen::scrollDown(int from, int n)
-{
-
-  //kDebug() << "Screen::scrollDown( from: " << from << " , n: " << n << ")";
-  
-  _scrolledLines += n;
-
-//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
-  if (n <= 0) return;
-  if (from > bmargin) return;
-  if (from + n > bmargin) n = bmargin - from;
-  moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n));
-  clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
-}
-
-void Screen::setCursorYX(int y, int x)
-{
-  setCursorY(y); setCursorX(x);
-}
-
-void Screen::setCursorX(int x)
-{
-  if (x == 0) x = 1; // Default
-  x -= 1; // Adjust
-  cuX = qMax(0,qMin(columns-1, x));
-}
-
-void Screen::setCursorY(int y)
-{
-  if (y == 0) y = 1; // Default
-  y -= 1; // Adjust
-  cuY = qMax(0,qMin(lines  -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
-}
-
-void Screen::home()
-{
-  cuX = 0;
-  cuY = 0;
-}
-
-void Screen::Return()
-{
-  cuX = 0;
-}
-
-int Screen::getCursorX() const
-{
-  return cuX;
-}
-
-int Screen::getCursorY() const
-{
-  return cuY;
-}
-
-// Erasing ---------------------------------------------------------------------
-
-/*! \section Erasing
-
-    This group of operations erase parts of the screen contents by filling
-    it with spaces colored due to the current rendition settings.
-
-    Althought the cursor position is involved in most of these operations,
-    it is never modified by them.
-*/
-
-/*! fill screen between (including) `loca' (start) and `loce' (end) with spaces.
-
-    This is an internal helper functions. The parameter types are internal
-    addresses of within the screen image and make use of the way how the
-    screen matrix is mapped to the image vector.
-*/
-
-void Screen::clearImage(int loca, int loce, char c)
-{ 
-  int scr_TL=loc(0,hist->getLines());
-  //FIXME: check positions
-
-  //Clear entire selection if it overlaps region to be moved...
-  if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
-  {
-    clearSelection();
-  }
-
-  int topLine = loca/columns;
-  int bottomLine = loce/columns;
-
-  Character clearCh(c,cu_fg,cu_bg,DEFAULT_RENDITION);
-  
-  //if the character being used to clear the area is the same as the
-  //default character, the affected lines can simply be shrunk.
-  bool isDefaultCh = (clearCh == Character());
-
-  for (int y=topLine;y<=bottomLine;y++)
-  {
-        lineProperties[y] = 0;
-
-        int endCol = ( y == bottomLine) ? loce%columns : columns-1;
-        int startCol = ( y == topLine ) ? loca%columns : 0;
-
-        QVector<Character>& line = screenLines[y];
-
-        if ( isDefaultCh && endCol == columns-1 )
-        {
-            line.resize(startCol);
-        }
-        else
-        {
-            if (line.size() < endCol + 1)
-                line.resize(endCol+1);
-
-            Character* data = line.data();
-            for (int i=startCol;i<=endCol;i++)
-                data[i]=clearCh;
-        }
-  }
-}
-
-/*! move image between (including) `sourceBegin' and `sourceEnd' to 'dest'.
-    
-    The 'dest', 'sourceBegin' and 'sourceEnd' parameters can be generated using
-    the loc(column,line) macro.
-
-NOTE:  moveImage() can only move whole lines.
-
-    This is an internal helper functions. The parameter types are internal
-    addresses of within the screen image and make use of the way how the
-    screen matrix is mapped to the image vector.
-*/
-
-void Screen::moveImage(int dest, int sourceBegin, int sourceEnd)
-{
-  //kDebug() << "moving image from (" << (sourceBegin/columns) 
-  //    << "," << (sourceEnd/columns) << ") to " <<
-  //    (dest/columns);
-
-  Q_ASSERT( sourceBegin <= sourceEnd );
- 
-  int lines=(sourceEnd-sourceBegin)/columns;
-
-  //move screen image and line properties:
-  //the source and destination areas of the image may overlap, 
-  //so it matters that we do the copy in the right order - 
-  //forwards if dest < sourceBegin or backwards otherwise.
-  //(search the web for 'memmove implementation' for details)
-  if (dest < sourceBegin)
-  {
-    for (int i=0;i<=lines;i++)
-    {
-        screenLines[ (dest/columns)+i ] = screenLines[ (sourceBegin/columns)+i ];
-        lineProperties[(dest/columns)+i]=lineProperties[(sourceBegin/columns)+i];
-    }
-  }
-  else
-  {
-    for (int i=lines;i>=0;i--)
-    {
-        screenLines[ (dest/columns)+i ] = screenLines[ (sourceBegin/columns)+i ];
-        lineProperties[(dest/columns)+i]=lineProperties[(sourceBegin/columns)+i];
-    }
-  }
-
-  if (lastPos != -1)
-  {
-     int diff = dest - sourceBegin; // Scroll by this amount
-     lastPos += diff;
-     if ((lastPos < 0) || (lastPos >= (lines*columns)))
-        lastPos = -1;
-  }
-     
-  // Adjust selection to follow scroll.
-  if (sel_begin != -1)
-  {
-     bool beginIsTL = (sel_begin == sel_TL);
-     int diff = dest - sourceBegin; // Scroll by this amount
-     int scr_TL=loc(0,hist->getLines());
-     int srca = sourceBegin+scr_TL; // Translate index from screen to global
-     int srce = sourceEnd+scr_TL; // Translate index from screen to global
-     int desta = srca+diff;
-     int deste = srce+diff;
-
-     if ((sel_TL >= srca) && (sel_TL <= srce))
-        sel_TL += diff;
-     else if ((sel_TL >= desta) && (sel_TL <= deste))
-        sel_BR = -1; // Clear selection (see below)
-
-     if ((sel_BR >= srca) && (sel_BR <= srce))
-        sel_BR += diff;
-     else if ((sel_BR >= desta) && (sel_BR <= deste))
-        sel_BR = -1; // Clear selection (see below)
-
-     if (sel_BR < 0)
-     {
-        clearSelection();
-     }
-     else
-     {
-        if (sel_TL < 0)
-           sel_TL = 0;
-     }
-
-     if (beginIsTL)
-        sel_begin = sel_TL;
-     else
-        sel_begin = sel_BR;
-  }
-}
-
-void Screen::clearToEndOfScreen()
-{
-  clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
-}
-
-void Screen::clearToBeginOfScreen()
-{
-  clearImage(loc(0,0),loc(cuX,cuY),' ');
-}
-
-void Screen::clearEntireScreen()
-{
-  // Add entire screen to history
-  for (int i = 0; i < (lines-1); i++)
-  {
-    addHistLine(); scrollUp(0,1);
-  }
-
-  clearImage(loc(0,0),loc(columns-1,lines-1),' ');
-}
-
-/*! fill screen with 'E'
-    This is to aid screen alignment
-*/
-
-void Screen::helpAlign()
-{
-  clearImage(loc(0,0),loc(columns-1,lines-1),'E');
-}
-
-void Screen::clearToEndOfLine()
-{
-  clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
-}
-
-void Screen::clearToBeginOfLine()
-{
-  clearImage(loc(0,cuY),loc(cuX,cuY),' ');
-}
-
-void Screen::clearEntireLine()
-{
-  clearImage(loc(0,cuY),loc(columns-1,cuY),' ');
-}
-
-void Screen::setRendition(int re)
-{
-  cu_re |= re;
-  effectiveRendition();
-}
-
-void Screen::resetRendition(int re)
-{
-  cu_re &= ~re;
-  effectiveRendition();
-}
-
-void Screen::setDefaultRendition()
-{
-  setForeColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR);
-  setBackColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR);
-  cu_re   = DEFAULT_RENDITION;
-  effectiveRendition();
-}
-
-void Screen::setForeColor(int space, int color)
-{
-  cu_fg = CharacterColor(space, color);
-
-  if ( cu_fg.isValid() ) 
-    effectiveRendition();
-  else 
-    setForeColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR);
-}
-
-void Screen::setBackColor(int space, int color)
-{
-  cu_bg = CharacterColor(space, color);
-
-  if ( cu_bg.isValid() ) 
-    effectiveRendition();
-  else
-    setBackColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR);
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                            Marking & Selection                            */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-void Screen::clearSelection()
-{
-  sel_BR = -1;
-  sel_TL = -1;
-  sel_begin = -1;
-}
-
-void Screen::getSelectionStart(int& column , int& line)
-{
-    if ( sel_TL != -1 )
-    {
-        column = sel_TL % columns;
-        line = sel_TL / columns; 
-    }
-    else
-    {
-        column = cuX + getHistLines();
-        line = cuY + getHistLines();
-    }
-}
-void Screen::getSelectionEnd(int& column , int& line)
-{
-    if ( sel_BR != -1 )
-    {
-        column = sel_BR % columns;
-        line = sel_BR / columns;
-    }
-    else
-    {
-        column = cuX + getHistLines();
-        line = cuY + getHistLines();
-    } 
-}
-void Screen::setSelectionStart(/*const ScreenCursor& viewCursor ,*/ const int x, const int y, const bool mode)
-{
-//  kDebug(1211) << "setSelBeginXY(" << x << "," << y << ")";
-  sel_begin = loc(x,y); //+histCursor) ;
-
-  /* FIXME, HACK to correct for x too far to the right... */
-  if (x == columns) sel_begin--;
-
-  sel_BR = sel_begin;
-  sel_TL = sel_begin;
-  columnmode = mode;
-}
-
-void Screen::setSelectionEnd( const int x, const int y)
-{
-//  kDebug(1211) << "setSelExtentXY(" << x << "," << y << ")";
-  if (sel_begin == -1) return;
-  int l =  loc(x,y); // + histCursor);
-
-  if (l < sel_begin)
-  {
-    sel_TL = l;
-    sel_BR = sel_begin;
-  }
-  else
-  {
-    /* FIXME, HACK to correct for x too far to the right... */
-    if (x == columns) l--;
-
-    sel_TL = sel_begin;
-    sel_BR = l;
-  }
-}
-
-bool Screen::isSelected( const int x,const int y) const
-{
-  if (columnmode) {
-    int sel_Left,sel_Right;
-    if ( sel_TL % columns < sel_BR % columns ) {
-      sel_Left = sel_TL; sel_Right = sel_BR;
-    } else {
-      sel_Left = sel_BR; sel_Right = sel_TL;
-    }
-    return ( x >= sel_Left % columns ) && ( x <= sel_Right % columns ) &&
-           ( y >= sel_TL / columns ) && ( y <= sel_BR / columns );
-            //( y+histCursor >= sel_TL / columns ) && ( y+histCursor <= sel_BR / columns );
-  }
-  else {
-  //int pos = loc(x,y+histCursor);
-  int pos = loc(x,y);
-  return ( pos >= sel_TL && pos <= sel_BR );
-  }
-}
-
-QString Screen::selectedText(bool preserveLineBreaks)
-{
-  QString result;
-  QTextStream stream(&result, QIODevice::ReadWrite);
-  
-  PlainTextDecoder decoder;
-  decoder.begin(&stream);
-  writeSelectionToStream(&decoder , preserveLineBreaks);
-  decoder.end();
-  
-  return result;
-}
-
-bool Screen::isSelectionValid() const
-{
-    return ( sel_TL >= 0 && sel_BR >= 0 );
-}
-
-void Screen::writeSelectionToStream(TerminalCharacterDecoder* decoder , 
-                                    bool preserveLineBreaks)
-{
-    // do nothing if selection is invalid
-    if ( !isSelectionValid() )
-        return;
-
-	int top = sel_TL / columns;	
-	int left = sel_TL % columns;
-
-	int bottom = sel_BR / columns;
-	int right = sel_BR % columns;
-
-    Q_ASSERT( top >= 0 && left >= 0 && bottom >= 0 && right >= 0 );
-
-    //kDebug() << "sel_TL = " << sel_TL;
-    //kDebug() << "columns = " << columns;
-
-	for (int y=top;y<=bottom;y++)
-	{
-			int start = 0;
-			if ( y == top || columnmode ) start = left;
-		
-			int count = -1;
-			if ( y == bottom || columnmode ) count = right - start + 1;
-
-            const bool appendNewLine = ( y != bottom );
-			copyLineToStream( y,
-                              start,
-                              count,
-                              decoder, 
-                              appendNewLine,
-                              preserveLineBreaks );
-	}	
-}
-
-
-void Screen::copyLineToStream(int line , 
-                              int start, 
-                              int count,
-                              TerminalCharacterDecoder* decoder,
-                              bool appendNewLine,
-                              bool preserveLineBreaks)
-{
-		//buffer to hold characters for decoding
-		//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];
-		
-		assert( count < MAX_CHARS );
-
-        LineProperty currentLineProperties = 0;
-
-		//determine if the line is in the history buffer or the screen image
-		if (line < hist->getLines())
-		{
-            const int lineLength = hist->getLineLen(line);
-
-            // ensure that start position is before end of line
-            start = qMin(start,qMax(0,lineLength-1));
-
-			//retrieve line from history buffer
-			if (count == -1)
-            {
-					count = lineLength-start;
-            }
-			else
-            {
-					count = qMin(start+count,lineLength)-start;
-            }
-
-            // safety checks
-            assert( start >= 0 );
-            assert( count >= 0 );    
-            assert( (start+count) <= hist->getLineLen(line) );
-
-			hist->getCells(line,start,count,characterBuffer);
-
-            if ( hist->isWrappedLine(line) )
-                currentLineProperties |= LINE_WRAPPED;
-		}
-		else
-		{
-			if ( count == -1 )
-					count = columns - start;
-
-            assert( count >= 0 );
-
-            const int screenLine = line-hist->getLines();
-
-            Character* data = screenLines[screenLine].data();
-            int length = screenLines[screenLine].count();
-
-			//retrieve line from screen image
-			for (int i=start;i < qMin(start+count,length);i++)
-			{
-			    characterBuffer[i-start] = data[i];
-            }
-
-            // count cannot be any greater than length
-			count = qBound(0,count,length-start);
-
-            Q_ASSERT( screenLine < lineProperties.count() );
-            currentLineProperties |= lineProperties[screenLine]; 
-		}
-
-		//do not decode trailing whitespace characters
-		for (int i=count-1 ; i >= 0; i--)
-				if (QChar(characterBuffer[i].character).isSpace())
-						count--;
-				else
-						break;
-
-        // add new line character at end
-        const bool omitLineBreak = (currentLineProperties & LINE_WRAPPED) ||
-                                   !preserveLineBreaks;
-
-        if ( !omitLineBreak && appendNewLine && (count+1 < MAX_CHARS) )
-        {
-            characterBuffer[count] = '\n';
-            count++;
-        }
-
-		//decode line and write to text stream	
-		decoder->decodeLine( (Character*) characterBuffer , 
-                             count, currentLineProperties );
-}
-
-// Method below has been removed because of its reliance on 'histCursor'
-// and I want to restrict the methods which have knowledge of the scroll position
-// to just those which deal with selection and supplying final screen images.
-//
-/*void Screen::writeToStream(QTextStream* stream , TerminalCharacterDecoder* decoder) {
-  sel_begin = 0;
-  sel_BR = sel_begin;
-  sel_TL = sel_begin;
-  setSelectionEnd(columns-1,lines-1+hist->getLines()-histCursor);
-  
-  writeSelectionToStream(stream,decoder);
-  
-  clearSelection();
-}*/
-
-void Screen::writeToStream(TerminalCharacterDecoder* decoder, int from, int to)
-{
-	sel_begin = loc(0,from);
-	sel_TL = sel_begin;
-	sel_BR = loc(columns-1,to);
-	writeSelectionToStream(decoder);
-	clearSelection();
-}
-
-QString Screen::getHistoryLine(int no)
-{
-  sel_begin = loc(0,no);
-  sel_TL = sel_begin;
-  sel_BR = loc(columns-1,no);
-  return selectedText(false);
-}
-
-void Screen::addHistLine()
-{
-  // add line to history buffer
-  // we have to take care about scrolling, too...
-
-  if (hasScroll())
-  {
-    int oldHistLines = hist->getLines();
-
-    hist->addCellsVector(screenLines[0]);
-    hist->addLine( lineProperties[0] & LINE_WRAPPED );
-
-    int newHistLines = hist->getLines();
-
-    bool beginIsTL = (sel_begin == sel_TL);
-
-    // If the history is full, increment the count
-    // of dropped lines
-    if ( newHistLines == oldHistLines )
-        _droppedLines++;
-
-    // Adjust selection for the new point of reference
-    if (newHistLines > oldHistLines)
-    {
-       if (sel_begin != -1)
-       {
-          sel_TL += columns;
-          sel_BR += columns;
-       }
-    }
-
-    if (sel_begin != -1)
-    {
-       // Scroll selection in history up
-       int top_BR = loc(0, 1+newHistLines);
-
-       if (sel_TL < top_BR)
-          sel_TL -= columns;
-
-       if (sel_BR < top_BR)
-          sel_BR -= columns;
-
-       if (sel_BR < 0)
-       {
-          clearSelection();
-       }
-       else
-       {
-          if (sel_TL < 0)
-             sel_TL = 0;
-       }
-
-       if (beginIsTL)
-          sel_begin = sel_TL;
-       else
-          sel_begin = sel_BR;
-    }
-  }
-
-}
-
-int Screen::getHistLines()
-{
-  return hist->getLines();
-}
-
-void Screen::setScroll(const HistoryType& t , bool copyPreviousScroll)
-{
-  clearSelection();
-
-  if ( copyPreviousScroll )
-    hist = t.scroll(hist);
-  else
-  {
-      HistoryScroll* oldScroll = hist;
-      hist = t.scroll(0);
-      delete oldScroll;
-  }
-}
-
-bool Screen::hasScroll()
-{
-  return hist->hasScroll();
-}
-
-const HistoryType& Screen::getScroll()
-{
-  return hist->getType();
-}
-
-void Screen::setLineProperty(LineProperty property , bool enable)
-{
-	if ( enable )
-	{
-		lineProperties[cuY] = (LineProperty)(lineProperties[cuY] | property);
-	}
-	else
-	{
-		lineProperties[cuY] = (LineProperty)(lineProperties[cuY] & ~property);
-	}
-}
-void Screen::fillWithDefaultChar(Character* dest, int count)
-{
-	for (int i=0;i<count;i++)
-		dest[i] = defaultChar;
-}
--- a/gui/qtermwidget/lib/Screen.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,662 +0,0 @@
-/*
-    This file is part of Konsole, KDE's terminal.
-
-    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
-
-    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.
-*/
-
-#ifndef SCREEN_H
-#define SCREEN_H
-
-// Qt
-#include <QtCore/QRect>
-#include <QtCore/QTextStream>
-#include <QtCore/QVarLengthArray>
-
-// Konsole
-#include "Character.h"
-#include "History.h"
-
-#define MODE_Origin    0
-#define MODE_Wrap      1
-#define MODE_Insert    2
-#define MODE_Screen    3
-#define MODE_Cursor    4
-#define MODE_NewLine   5
-#define MODES_SCREEN   6
-
-namespace Konsole
-{
-
-/*!
-*/
-struct ScreenParm
-{
-  int mode[MODES_SCREEN];
-};
-
-class TerminalCharacterDecoder;
-
-/**
-    \brief An image of characters with associated attributes.
-
-    The terminal emulation ( Emulation ) receives a serial stream of
-    characters from the program currently running in the terminal.
-    From this stream it creates an image of characters which is ultimately
-    rendered by the display widget ( TerminalDisplay ).  Some types of emulation
-    may have more than one screen image. 
-
-    getImage() is used to retrieve the currently visible image
-    which is then used by the display widget to draw the output from the
-    terminal. 
-
-    The number of lines of output history which are kept in addition to the current
-    screen image depends on the history scroll being used to store the output.  
-    The scroll is specified using setScroll()
-    The output history can be retrieved using writeToStream()
-
-    The screen image has a selection associated with it, specified using 
-    setSelectionStart() and setSelectionEnd().  The selected text can be retrieved
-    using selectedText().  When getImage() is used to retrieve the the visible image,
-    characters which are part of the selection have their colours inverted.   
-*/
-class Screen
-{
-public:
-    /** Construct a new screen image of size @p lines by @p columns. */
-    Screen(int lines, int columns);
-    ~Screen();
-
-    // VT100/2 Operations 
-    // Cursor Movement
-    
-    /** Move the cursor up by @p n lines. */
-    void cursorUp    (int n);
-    /** Move the cursor down by @p n lines. */
-    void cursorDown  (int n);
-    /** Move the cursor to the left by @p n columns. */
-    void cursorLeft  (int n);
-    /** Move the cursor to the right by @p n columns. */
-    void cursorRight (int n);
-    /** Position the cursor on line @p y. */
-    void setCursorY  (int y);
-    /** Position the cursor at column @p x. */
-    void setCursorX  (int x);
-    /** Position the cursor at line @p y, column @p x. */
-    void setCursorYX (int y, int x);
-    /**
-     * Sets the margins for scrolling the screen.
-     *
-     * @param topLine The top line of the new scrolling margin. 
-     * @param bottomLine The bottom line of the new scrolling margin. 
-     */
-    void setMargins  (int topLine , int bottomLine);
-    /** Returns the top line of the scrolling region. */ 
-    int topMargin() const;
-    /** Returns the bottom line of the scrolling region. */
-    int bottomMargin() const;
-
-    /** 
-     * Resets the scrolling margins back to the top and bottom lines
-     * of the screen.
-     */
-    void setDefaultMargins();
-    
-    /** 
-     * Moves the cursor down one line, if the MODE_NewLine mode 
-     * flag is enabled then the cursor is returned to the leftmost
-     * column first.
-     *
-     * Equivalent to NextLine() if the MODE_NewLine flag is set
-     * or index() otherwise. 
-     */
-    void NewLine     ();
-    /**
-     * Moves the cursor down one line and positions it at the beginning
-     * of the line.
-     */
-    void NextLine    ();
-
-    /** 
-     * Move the cursor down one line.  If the cursor is on the bottom
-     * line of the scrolling region (as returned by bottomMargin()) the
-     * scrolling region is scrolled up by one line instead.
-     */
-    void index       ();
-    /**
-     * Move the cursor up one line.  If the cursor is on the top line
-     * of the scrolling region (as returned by topMargin()) the scrolling
-     * region is scrolled down by one line instead.
-     */
-    void reverseIndex();
-    
-    /** 
-     * Scroll the scrolling region of the screen up by @p n lines. 
-     * The scrolling region is initially the whole screen, but can be changed 
-     * using setMargins()
-     */ 
-    void scrollUp(int n);
-    /**
-     * Scroll the scrolling region of the screen down by @p n lines.
-     * The scrolling region is initially the whole screen, but can be changed
-     * using setMargins()
-     */
-    void scrollDown(int n);
-    
-    /** 
-     * Moves the cursor to the beginning of the current line. 
-     * Equivalent to setCursorX(0)
-     */
-    void Return      ();
-    /** 
-     * Moves the cursor one column to the left and erases the character
-     * at the new cursor position.
-     */
-    void BackSpace   ();
-    /** 
-     * Moves the cursor @p n tab-stops to the right.
-     */
-    void Tabulate    (int n = 1);
-    /** 
-     * Moves the cursor @p n tab-stops to the left. 
-     */
-    void backTabulate(int n);
-    
-    // Editing
-    
-    /** 
-     * Erase @p n characters beginning from the current cursor position. 
-     * This is equivalent to over-writing @p n characters starting with the current
-     * cursor position with spaces.
-     * If @p n is 0 then one character is erased. 
-     */
-    void eraseChars  (int n);
-    /** 
-     * Delete @p n characters beginning from the current cursor position. 
-     * If @p n is 0 then one character is deleted. 
-     */
-    void deleteChars (int n);
-    /**
-     * Insert @p n blank characters beginning from the current cursor position.
-     * The position of the cursor is not altered.  
-     * If @p n is 0 then one character is inserted.
-     */
-    void insertChars (int n);
-    /** 
-     * Removes @p n lines beginning from the current cursor position.
-     * The position of the cursor is not altered.
-     * If @p n is 0 then one line is removed.
-     */
-    void deleteLines (int n);
-    /**
-     * Inserts @p lines beginning from the current cursor position.
-     * The position of the cursor is not altered.
-     * If @p n is 0 then one line is inserted.
-     */
-    void insertLines (int n);
-    /** Clears all the tab stops. */
-    void clearTabStops();
-    /**  Sets or removes a tab stop at the cursor's current column. */ 
-    void changeTabStop(bool set);
-   
-    /** Resets (clears) the specified screen @p mode. */
-    void resetMode   (int mode);
-    /** Sets (enables) the specified screen @p mode. */
-    void setMode     (int mode);
-    /** 
-     * Saves the state of the specified screen @p mode.  It can be restored
-     * using restoreMode()
-     */
-    void saveMode    (int mode);
-    /** Restores the state of a screen @p mode saved by calling saveMode() */
-    void restoreMode (int mode);
-    /** Returns whether the specified screen @p mode is enabled or not .*/
-    bool getMode     (int mode) const;
-   
-    /** 
-     * Saves the current position and appearence (text color and style) of the cursor. 
-     * It can be restored by calling restoreCursor() 
-     */ 
-    void saveCursor  ();
-    /** Restores the position and appearence of the cursor.  See saveCursor() */
-    void restoreCursor();
-   
-    /** Clear the whole screen, moving the current screen contents into the history first. */ 
-    void clearEntireScreen();
-    /** 
-     * Clear the area of the screen from the current cursor position to the end of 
-     * the screen.
-     */
-    void clearToEndOfScreen();
-    /**
-     * Clear the area of the screen from the current cursor position to the start
-     * of the screen.
-     */
-    void clearToBeginOfScreen();
-    /** Clears the whole of the line on which the cursor is currently positioned. */
-    void clearEntireLine();
-    /** Clears from the current cursor position to the end of the line. */
-    void clearToEndOfLine();
-    /** Clears from the current cursor position to the beginning of the line. */
-    void clearToBeginOfLine();
-    
-    /** Fills the entire screen with the letter 'E' */
-    void helpAlign   ();
-       
-    /** 
-     * Enables the given @p rendition flag.  Rendition flags control the appearence 
-     * of characters on the screen.
-     *
-     * @see Character::rendition
-     */  
-    void setRendition  (int rendition);
-    /**
-     * Disables the given @p rendition flag.  Rendition flags control the appearence
-     * of characters on the screen.
-     *
-     * @see Character::rendition
-     */
-    void resetRendition(int rendition);
-    
-    /** 
-     * Sets the cursor's foreground color.
-     * @param space The color space used by the @p color argument
-     * @param color The new foreground color.  The meaning of this depends on
-     * the color @p space used.
-     *
-     * @see CharacterColor
-     */
-    void setForeColor  (int space, int color);
-    /**
-     * Sets the cursor's background color.
-     * @param space The color space used by the @p color argumnet.
-     * @param color The new background color.  The meaning of this depends on
-     * the color @p space used.
-     *
-     * @see CharacterColor
-     */
-    void setBackColor  (int space, int color);
-    /** 
-     * Resets the cursor's color back to the default and sets the 
-     * character's rendition flags back to the default settings.
-     */
-    void setDefaultRendition();
-    
-    /** Returns the column which the cursor is positioned at. */
-    int  getCursorX() const;
-    /** Returns the line which the cursor is positioned on. */
-    int  getCursorY() const;
-   
-	/** TODO Document me */ 
-	void clear();
-    /** 
-     * Sets the position of the cursor to the 'home' position at the top-left
-     * corner of the screen (0,0) 
-     */
-    void home();
-    /**
-     * Resets the state of the screen.  This resets the various screen modes
-     * back to their default states.  The cursor style and colors are reset
-     * (as if setDefaultRendition() had been called)
-     *
-     * <ul>
-     * <li>Line wrapping is enabled.</li>
-     * <li>Origin mode is disabled.</li>
-     * <li>Insert mode is disabled.</li>
-     * <li>Cursor mode is enabled.  TODO Document me</li>
-     * <li>Screen mode is disabled. TODO Document me</li>
-     * <li>New line mode is disabled.  TODO Document me</li>
-     * </ul>
-     *
-     * If @p clearScreen is true then the screen contents are erased entirely, 
-     * otherwise they are unaltered.
-     */
-    void reset(bool clearScreen = true);
-   
-    /** 
-     * Displays a new character at the current cursor position. 
-     * 
-     * If the cursor is currently positioned at the right-edge of the screen and
-     * line wrapping is enabled then the character is added at the start of a new 
-     * line below the current one.
-     *
-     * If the MODE_Insert screen mode is currently enabled then the character 
-     * is inserted at the current cursor position, otherwise it will replace the 
-     * character already at the current cursor position.  
-     */ 
-    void ShowCharacter(unsigned short c);
-    
-    // Do composition with last shown character FIXME: Not implemented yet for KDE 4
-    void compose(const QString& compose);
-    
-    /** 
-     * Resizes the image to a new fixed size of @p new_lines by @p new_columns.  
-     * In the case that @p new_columns is smaller than the current number of columns,
-     * existing lines are not truncated.  This prevents characters from being lost
-     * if the terminal display is resized smaller and then larger again.
-     *
-     * (note that in versions of Konsole prior to KDE 4, existing lines were
-     *  truncated when making the screen image smaller)
-     */
-    void resizeImage(int new_lines, int new_columns);
-    
-    /**
-     * Returns the current screen image.  
-     * The result is an array of Characters of size [getLines()][getColumns()] which
-     * must be freed by the caller after use.
-     *
-     * @param dest Buffer to copy the characters into
-     * @param size Size of @p dest in Characters
-     * @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;
-
-    /** 
-     * Returns the additional attributes associated with lines in the image.
-     * The most important attribute is LINE_WRAPPED which specifies that the 
-     * line is wrapped,
-     * other attributes control the size of characters in the line.
-     */
-    QVector<LineProperty> getLineProperties( int startLine , int endLine ) const;
-	
-
-    /** Return the number of lines. */
-    int  getLines()   { return lines; }
-    /** Return the number of columns. */
-    int  getColumns() { return columns; }
-    /** Return the number of lines in the history buffer. */
-    int  getHistLines ();
-    /** 
-     * Sets the type of storage used to keep lines in the history. 
-     * If @p copyPreviousScroll is true then the contents of the previous 
-     * history buffer are copied into the new scroll.
-     */
-    void setScroll(const HistoryType& , bool copyPreviousScroll = true);
-    /** Returns the type of storage used to keep lines in the history. */
-    const HistoryType& getScroll();
-    /** 
-     * Returns true if this screen keeps lines that are scrolled off the screen
-     * in a history buffer.
-     */
-    bool hasScroll();
-
-    /** 
-     * Sets the start of the selection.
-     *
-     * @param column The column index of the first character in the selection.
-     * @param line The line index of the first character in the selection.
-     * @param columnmode True if the selection is in column mode.
-     */
-    void setSelectionStart(const int column, const int line, const bool columnmode);
-    
-    /**
-     * Sets the end of the current selection.
-     *
-     * @param column The column index of the last character in the selection.
-     * @param line The line index of the last character in the selection. 
-     */ 
-    void setSelectionEnd(const int column, const int line);
-   
-    /**
-     * Retrieves the start of the selection or the cursor position if there
-     * is no selection.
-     */
-    void getSelectionStart(int& column , int& line);
-    
-    /**
-     * Retrieves the end of the selection or the cursor position if there
-     * is no selection.
-     */
-    void getSelectionEnd(int& column , int& line);
-
-    /** Clears the current selection */
-    void clearSelection();
-
-    void setBusySelecting(bool busy) { sel_busy = busy; }
-
-    /** 
- 	 * 	Returns true if the character at (@p column, @p line) is part of the
- 	 *  current selection. 
- 	 */ 
-    bool isSelected(const int column,const int line) const;
-
-    /** 
-     * Convenience method.  Returns the currently selected text. 
-     * @param preserveLineBreaks Specifies whether new line characters should 
-     * be inserted into the returned text at the end of each terminal line.
-     */
-    QString selectedText(bool preserveLineBreaks);
-	    
-	/**
-	 * Copies part of the output to a stream.
-	 *
-	 * @param decoder A decoder which coverts terminal characters into text
-	 * @param from The first line in the history to retrieve
-	 * @param to The last line in the history to retrieve
-	 */
-	void writeToStream(TerminalCharacterDecoder* decoder, int from, int to);
-
-    /** 
-     * Sets the selection to line @p no in the history and returns
-     * the text of that line from the history buffer.
-     */
-    QString getHistoryLine(int no);
-
-	/**
-	 * Copies the selected characters, set using @see setSelBeginXY and @see setSelExtentXY
-	 * into a stream.
-	 *
-	 * @param decoder A decoder which converts terminal characters into text.  
-	 * PlainTextDecoder is the most commonly used decoder which coverts characters 
-	 * into plain text with no formatting.
-     * @param preserveLineBreaks Specifies whether new line characters should 
-     * be inserted into the returned text at the end of each terminal line. 
-	 */
-	void writeSelectionToStream(TerminalCharacterDecoder* decoder , bool
-                                preserveLineBreaks = true);
-
-    /** TODO Document me */
-    void checkSelection(int from, int to);
-
-	/** 
-	 * Sets or clears an attribute of the current line.
-	 * 
-	 * @param property The attribute to set or clear
-	 * Possible properties are:
-	 * LINE_WRAPPED:	 Specifies that the line is wrapped.
-	 * LINE_DOUBLEWIDTH: Specifies that the characters in the current line should be double the normal width.
-	 * LINE_DOUBLEHEIGHT:Specifies that the characters in the current line should be double the normal height.
-     *                   Double-height lines are formed of two lines containing the same characters,
-     *                   with both having the LINE_DOUBLEHEIGHT attribute.  This allows other parts of the 
-     *                   code to work on the assumption that all lines are the same height.
-	 *
-	 * @param enable true to apply the attribute to the current line or false to remove it
-	 */
-	void setLineProperty(LineProperty property , bool enable);
-
-
-    /** 
-     * Returns the number of lines that the image has been scrolled up or down by,
-     * since the last call to resetScrolledLines().
-     *
-     * a positive return value indicates that the image has been scrolled up,
-     * 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()
-     */
-    void resetScrolledLines();
-
-    /**
-     * Returns the number of lines of output which have been
-     * dropped from the history since the last call
-     * to resetDroppedLines()
-     *
-     * If the history is not unlimited then it will drop
-     * the oldest lines of output if new lines are added when
-     * it is full.  
-     */
-    int droppedLines() const;
-
-    /**
-     * Resets the count of the number of lines dropped from
-     * the history.
-     */
-    void resetDroppedLines();
-
-	/** 
- 	 * Fills the buffer @p dest with @p count instances of the default (ie. blank)
- 	 * Character style.
- 	 */
-	static void fillWithDefaultChar(Character* dest, int count);
-
-private: 
-
-	//copies a line of text from the screen or history into a stream using a 
-	//specified character decoder
-	//line - the line number to copy, from 0 (the earliest line in the history) up to 
-	//		 hist->getLines() + lines - 1
-	//start - the first column on the line to copy
-	//count - the number of characters on the line to copy
-	//decoder - a decoder which coverts terminal characters (an Character array) into text
-    //appendNewLine - if true a new line character (\n) is appended to the end of the line
-	void copyLineToStream(int line, 
-                          int start, 
-                          int count, 
-                          TerminalCharacterDecoder* decoder,
-                          bool appendNewLine,
-                          bool preserveLineBreaks);
-	
-    //fills a section of the screen image with the character 'c'
-    //the parameters are specified as offsets from the start of the screen image.
-    //the loc(x,y) macro can be used to generate these values from a column,line pair.
-    void clearImage(int loca, int loce, char c);
-
-    //move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'.
-    //the parameters are specified as offsets from the start of the screen image.
-    //the loc(x,y) macro can be used to generate these values from a column,line pair.
-    void moveImage(int dest, int sourceBegin, int sourceEnd);
-    
-    void scrollUp(int from, int i);
-    void scrollDown(int from, int i);
-
-    void addHistLine();
-
-    void initTabStops();
-
-    void effectiveRendition();
-    void reverseRendition(Character& p) const;
-
-    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;
-	// 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;
-
-
-    // screen image ----------------
-    int lines;
-    int columns;
-
-    typedef QVector<Character> ImageLine;      // [0..columns]
-    ImageLine*          screenLines;    // [lines]
-
-    int _scrolledLines;
-    QRect _lastScrolledRegion;
-
-    int _droppedLines;
-
-    QVarLengthArray<LineProperty,64> lineProperties;    
-	
-    // history buffer ---------------
-    HistoryScroll *hist;
-    
-    // cursor location
-    int cuX;
-    int cuY;
-
-    // cursor color and rendition info
-    CharacterColor cu_fg;      // foreground
-    CharacterColor cu_bg;      // background
-    quint8 cu_re;      // rendition
-
-    // margins ----------------
-    int tmargin;      // top margin
-    int bmargin;      // bottom margin
-
-    // states ----------------
-    ScreenParm currParm;
-
-    // ----------------------------
-
-    bool* tabstops;
-
-    // selection -------------------
-    int sel_begin; // The first location selected.
-    int sel_TL;    // TopLeft Location.
-    int sel_BR;    // Bottom Right Location.
-    bool sel_busy; // Busy making a selection.
-    bool columnmode;  // Column selection mode
-
-    // effective colors and rendition ------------
-    CharacterColor ef_fg;      // These are derived from
-    CharacterColor ef_bg;      // the cu_* variables above
-    quint8 ef_re;      // to speed up operation
-
-    //
-    // save cursor, rendition & states ------------
-    // 
-
-    // cursor location
-    int sa_cuX;
-    int sa_cuY;
-
-    // rendition info
-    quint8 sa_cu_re;
-    CharacterColor sa_cu_fg;
-    CharacterColor sa_cu_bg;
-    
-    // last position where we added a character
-    int lastPos;
-
-    // modes
-    ScreenParm saveParm;
-
-    static Character defaultChar;
-};
-
-}
-
-#endif // SCREEN_H
--- a/gui/qtermwidget/lib/ScreenWindow.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/*
-    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"
--- a/gui/qtermwidget/lib/ScreenWindow.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/*
-    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.
-*/
-
-#ifndef SCREENWINDOW_H
-#define SCREENWINDOW_H
-
-// Qt
-#include <QtCore/QObject>
-#include <QtCore/QPoint>
-#include <QtCore/QRect>
-
-// Konsole
-#include "Character.h"
-
-namespace Konsole
-{
-
-class Screen;
-
-/**
- * Provides a window onto a section of a terminal screen.
- * This window can then be rendered by a terminal display widget ( TerminalDisplay ).
- *
- * To use the screen window, create a new ScreenWindow() instance and associated it with 
- * a terminal screen using setScreen().
- * Use the scrollTo() method to scroll the window up and down on the screen.
- * Call the getImage() method to retrieve the character image which is currently visible in the window.
- *
- * setTrackOutput() controls whether the window moves to the bottom of the associated screen when new
- * lines are added to it.
- *
- * Whenever the output from the underlying screen is changed, the notifyOutputChanged() slot should
- * be called.  This in turn will update the window's position and emit the outputChanged() signal
- * if necessary.
- */
-class ScreenWindow : public QObject
-{
-Q_OBJECT
-
-public:
-    /** 
-     * Constructs a new screen window with the given parent.
-     * A screen must be specified by calling setScreen() before calling getImage() or getLineProperties().
-     *
-     * You should not call this constructor directly, instead use the Emulation::createWindow() method
-     * to create a window on the emulation which you wish to view.  This allows the emulation
-     * to notify the window when the associated screen has changed and synchronize selection updates
-     * between all views on a session.
-     */
-    ScreenWindow(QObject* parent = 0);
-	virtual ~ScreenWindow();
-
-    /** Sets the screen which this window looks onto */
-    void setScreen(Screen* screen);
-    /** Returns the screen which this window looks onto */
-    Screen* screen() const;
-
-    /** 
-     * Returns the image of characters which are currently visible through this window
-     * onto the screen.
-     *
-     * The buffer is managed by the ScreenWindow instance and does not need to be
-     * deleted by the caller.
-     */
-    Character* getImage();
-
-    /**
-     * Returns the line attributes associated with the lines of characters which
-     * are currently visible through this window
-     */
-    QVector<LineProperty> getLineProperties();
-
-    /**
-     * 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;
-
-    /**
-     * Resets the count of scrolled lines returned by scrollCount()
-     */
-    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.
-     */
-    void setSelectionStart( int column , int line , bool columnMode );
-    /**
-     * Sets the end of the selection to the given @p line and @p column within
-     * the window.
-     */
-    void setSelectionEnd( int column , int line ); 
-    /**
-     * Retrieves the start of the selection within the window.
-     */
-    void getSelectionStart( int& column , int& line );
-    /**
-     * Retrieves the end of the selection within the window.
-     */
-    void getSelectionEnd( int& column , int& line );
-    /**
-     * Returns true if the character at @p line , @p column is part of the selection.
-     */
-    bool isSelected( int column , int line );
-    /** 
-     * Clears the current selection
-     */
-    void clearSelection();
-
-	/** Sets the number of lines in the window */
-	void setWindowLines(int lines);
-    /** Returns the number of lines in the window */
-    int windowLines() const;
-    /** Returns the number of columns in the window */
-    int windowColumns() const;
-    
-    /** Returns the total number of lines in the screen */
-    int lineCount() const;
-    /** Returns the total number of columns in the screen */
-    int columnCount() const;
-
-    /** Returns the index of the line which is currently at the top of this window */
-    int currentLine() const;
-
-    /** 
-     * Returns the position of the cursor 
-     * within the window.
-     */
-    QPoint cursorPosition() const;
-
-    /** 
-     * Convenience method. Returns true if the window is currently at the bottom
-     * of the screen.
-     */
-    bool atEndOfOutput() const;
-
-    /** Scrolls the window so that @p line is at the top of the window */
-    void scrollTo( int line );
-
-    enum RelativeScrollMode
-    {
-        ScrollLines,
-        ScrollPages
-    };
-
-    /** 
-     * Scrolls the window relative to its current position on the screen.
-     *
-     * @param mode Specifies whether @p amount refers to the number of lines or the number
-     * of pages to scroll.    
-     * @param amount The number of lines or pages ( depending on @p mode ) to scroll by.  If
-     * this number is positive, the view is scrolled down.  If this number is negative, the view
-     * is scrolled up.
-     */
-    void scrollBy( RelativeScrollMode mode , int amount );
-
-    /** 
-     * Specifies whether the window should automatically move to the bottom
-     * of the screen when new output is added.
-     *
-     * If this is set to true, the window will be moved to the bottom of the associated screen ( see 
-     * screen() ) when the notifyOutputChanged() method is called.
-     */
-    void setTrackOutput(bool trackOutput);
-    /** 
-     * Returns whether the window automatically moves to the bottom of the screen as
-     * new output is added.  See setTrackOutput()
-     */
-    bool trackOutput() const;
-
-    /**
-     * Returns the text which is currently selected.
-     *
-     * @param preserveLineBreaks See Screen::selectedText()
-     */
-    QString selectedText( bool preserveLineBreaks ) const;
-
-public slots:
-    /** 
-     * Notifies the window that the contents of the associated terminal screen have changed.
-     * This moves the window to the bottom of the screen if trackOutput() is true and causes
-     * the outputChanged() signal to be emitted.
-     */
-    void notifyOutputChanged();
-
-signals:
-    /**
-     * Emitted when the contents of the associated terminal screen ( see screen() ) changes. 
-     */
-    void outputChanged();
-
-    /**
-     * Emitted when the screen window is scrolled to a different position.
-     * 
-     * @param line The line which is now at the top of the window.
-     */
-    void scrolled(int line);
-
-    /**
-     * Emitted when the selection is changed.
-     */
-    void selectionChanged();
-
-private:
-	int endWindowLine() const;
-	void fillUnusedArea();
-
-    Screen* _screen; // see setScreen() , screen()
-	Character* _windowBuffer;
-	int _windowBufferSize;
-	bool _bufferNeedsUpdate;
-
-	int  _windowLines;
-    int  _currentLine; // see scrollTo() , currentLine()
-    bool _trackOutput; // see setTrackOutput() , trackOutput() 
-    int  _scrollCount; // count of lines which the window has been scrolled by since
-                       // the last call to resetScrollCount()
-};
-
-}
-#endif // SCREENWINDOW_H
--- a/gui/qtermwidget/lib/Session.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1021 +0,0 @@
-/*
-    This file is part of Konsole
-
-    Copyright (C) 2006-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
-
-    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 "Session.h"
-
-// Standard
-#include <assert.h>
-#include <stdlib.h>
-
-// Qt
-#include <QtGui/QApplication>
-#include <QtCore/QByteRef>
-#include <QtCore/QDir>
-#include <QtCore/QFile>
-#include <QtCore/QRegExp>
-#include <QtCore/QStringList>
-#include <QtCore>
-
-#include "Pty.h"
-#include "TerminalDisplay.h"
-#include "ShellCommand.h"
-#include "Vt102Emulation.h"
-
-using namespace Konsole;
-
-int Session::lastSessionId = 0;
-
-Session::Session() :
-    _shellProcess(0)
-   , _emulation(0)
-   , _monitorActivity(false)
-   , _monitorSilence(false)
-   , _notifiedActivity(false)
-   , _autoClose(true)
-   , _wantedClose(false)
-   , _silenceSeconds(10)
-   , _addToUtmp(false)  // disabled by default because of a bug encountered on certain systems
-                        // which caused Konsole to hang when closing a tab and then opening a new
-                        // one.  A 'QProcess destroyed while still running' warning was being
-                        // printed to the terminal.  Likely a problem in KPty::logout() 
-                        // or KPty::login() which uses a QProcess to start /usr/bin/utempter 
-   , _flowControl(true)
-   , _fullScripting(false)
-   , _sessionId(0)
-//   , _zmodemBusy(false)
-//   , _zmodemProc(0)
-//   , _zmodemProgress(0)
-   , _hasDarkBackground(false)
-{
-    //prepare DBus communication
-//    new SessionAdaptor(this);
-    _sessionId = ++lastSessionId;
-//    QDBusConnection::sessionBus().registerObject(QLatin1String("/Sessions/")+QString::number(_sessionId), this);
-
-    //create teletype for I/O with shell process
-    _shellProcess = new Pty();
-
-    //create emulation backend
-    _emulation = new Vt102Emulation();
-
-    connect( _emulation, SIGNAL( titleChanged( int, const QString & ) ),
-           this, SLOT( setUserTitle( int, const QString & ) ) );
-    connect( _emulation, SIGNAL( stateSet(int) ),
-           this, SLOT( activityStateSet(int) ) );
-//    connect( _emulation, SIGNAL( zmodemDetected() ), this ,
-//            SLOT( fireZModemDetected() ) );
-    connect( _emulation, SIGNAL( changeTabTextColorRequest( int ) ),
-           this, SIGNAL( changeTabTextColorRequest( int ) ) );
-    connect( _emulation, SIGNAL(profileChangeCommandReceived(const QString&)),
-           this, SIGNAL( profileChangeCommandReceived(const QString&)) );
-    // TODO
-    // connect( _emulation,SIGNAL(imageSizeChanged(int,int)) , this ,
-    //        SLOT(onEmulationSizeChange(int,int)) );
-
-    //connect teletype to emulation backend
-    _shellProcess->setUtf8Mode(_emulation->utf8());
-
-    connect( _shellProcess,SIGNAL(receivedData(const char*,int)),this,
-            SLOT(onReceiveBlock(const char*,int)) );
-    connect( _emulation,SIGNAL(sendData(const char*,int)),_shellProcess,
-            SLOT(sendData(const char*,int)) );
-    connect( _emulation,SIGNAL(lockPtyRequest(bool)),_shellProcess,SLOT(lockPty(bool)) );
-    connect( _emulation,SIGNAL(useUtf8Request(bool)),_shellProcess,SLOT(setUtf8Mode(bool)) );
-
-
-    connect( _shellProcess,SIGNAL(done(int)), this, SLOT(done(int)) );
-
-    //setup timer for monitoring session activity
-    _monitorTimer = new QTimer(this);
-    _monitorTimer->setSingleShot(true);
-    connect(_monitorTimer, SIGNAL(timeout()), this, SLOT(monitorTimerDone()));
-}
-
-WId Session::windowId() const
-{
-    // Returns a window ID for this session which is used
-    // to set the WINDOWID environment variable in the shell
-    // process.
-    //
-    // Sessions can have multiple views or no views, which means
-    // that a single ID is not always going to be accurate.
-    //
-    // If there are no views, the window ID is just 0.  If
-    // there are multiple views, then the window ID for the
-    // top-level window which contains the first view is
-    // returned
-
-    if ( _views.count() == 0 )
-       return 0;
-    else
-    {
-        QWidget* window = _views.first();
-
-        Q_ASSERT( window );
-
-        while ( window->parentWidget() != 0 )
-            window = window->parentWidget();
-
-        return window->winId();
-    }
-}
-
-void Session::setDarkBackground(bool darkBackground)
-{
-    _hasDarkBackground = darkBackground;
-}
-bool Session::hasDarkBackground() const
-{
-    return _hasDarkBackground;
-}
-bool Session::isRunning() const
-{
-    return _shellProcess->isRunning();
-}
-
-void Session::setCodec(QTextCodec* codec)
-{
-    emulation()->setCodec(codec);
-}
-
-void Session::setProgram(const QString& program)
-{
-    _program = ShellCommand::expand(program);
-}
-void Session::setInitialWorkingDirectory(const QString& dir)
-{
-    _initialWorkingDir = ShellCommand::expand(dir);
-}
-void Session::setArguments(const QStringList& arguments)
-{
-    _arguments = ShellCommand::expand(arguments);
-}
-
-QList<TerminalDisplay*> Session::views() const
-{
-    return _views;
-}
-
-void Session::addView(TerminalDisplay* widget)
-{
-     Q_ASSERT( !_views.contains(widget) );
-
-    _views.append(widget);
-
-    if ( _emulation != 0 )
-    {
-        // connect emulation - view signals and slots
-        connect( widget , SIGNAL(keyPressedSignal(QKeyEvent*)) , _emulation ,
-               SLOT(sendKeyEvent(QKeyEvent*)) );
-        connect( widget , SIGNAL(mouseSignal(int,int,int,int)) , _emulation ,
-               SLOT(sendMouseEvent(int,int,int,int)) );
-        connect( widget , SIGNAL(sendStringToEmu(const char*)) , _emulation ,
-               SLOT(sendString(const char*)) );
-
-        // allow emulation to notify view when the foreground process
-        // indicates whether or not it is interested in mouse signals
-        connect( _emulation , SIGNAL(programUsesMouseChanged(bool)) , widget ,
-               SLOT(setUsesMouse(bool)) );
-
-        widget->setUsesMouse( _emulation->programUsesMouse() );
-
-        widget->setScreenWindow(_emulation->createWindow());
-    }
-
-    //connect view signals and slots
-    QObject::connect( widget ,SIGNAL(changedContentSizeSignal(int,int)),this,
-                    SLOT(onViewSizeChange(int,int)));
-
-    QObject::connect( widget ,SIGNAL(destroyed(QObject*)) , this ,
-                    SLOT(viewDestroyed(QObject*)) );
-//slot for close
-    QObject::connect(this, SIGNAL(finished()), widget, SLOT(close()));		    
-    
-}
-
-void Session::viewDestroyed(QObject* view)
-{
-    TerminalDisplay* display = (TerminalDisplay*)view;
-
-    Q_ASSERT( _views.contains(display) );
-
-    removeView(display);
-}
-
-void Session::removeView(TerminalDisplay* widget)
-{
-    _views.removeAll(widget);
-
-	disconnect(widget,0,this,0);
-
-    if ( _emulation != 0 )
-    {
-        // disconnect
-        //  - key presses signals from widget
-        //  - mouse activity signals from widget
-        //  - string sending signals from widget
-        //
-        //  ... and any other signals connected in addView()
-        disconnect( widget, 0, _emulation, 0);
-
-        // disconnect state change signals emitted by emulation
-        disconnect( _emulation , 0 , widget , 0);
-    }
-
-	// close the session automatically when the last view is removed
-	if ( _views.count() == 0 )
-	{
-		close();
-	}
-}
-
-void Session::run()
-{
-  //check that everything is in place to run the session
-  if (_program.isEmpty())
-      qDebug() << "Session::run() - program to run not set.";
-  if (_arguments.isEmpty())
-      qDebug() << "Session::run() - no command line arguments specified.";
-
-  // Upon a KPty error, there is no description on what that error was...
-  // Check to see if the given program is executable.
-  QString exec = QFile::encodeName(_program);
-
-  // if 'exec' is not specified, fall back to default shell.  if that 
-  // is not set then fall back to /bin/sh
-  if ( exec.isEmpty() )
-      exec = getenv("SHELL");
-  if ( exec.isEmpty() )
-  	  exec = "/bin/sh";
-
-  // if no arguments are specified, fall back to shell
-  QStringList arguments =  _arguments.join(QChar(' ')).isEmpty() ?
-                                    QStringList() << exec : _arguments;
-  QString pexec = exec;
-
-  if ( pexec.isEmpty() ) {
-    qDebug()<<"can not execute "<<exec<<endl;
-    QTimer::singleShot(1, this, SIGNAL(finished()));
-    return;
-  }
-
-  QString cwd_save = QDir::currentPath();
-  if (!_initialWorkingDir.isEmpty())
-    _shellProcess->setWorkingDirectory(_initialWorkingDir);
-  else
-    _shellProcess->setWorkingDirectory(QDir::homePath());
-
-  _shellProcess->setXonXoff(_flowControl);
-  _shellProcess->setErase(_emulation->getErase());
-
-  // this is not strictly accurate use of the COLORFGBG variable.  This does not
-  // tell the terminal exactly which colors are being used, but instead approximates
-  // the color scheme as "black on white" or "white on black" depending on whether
-  // the background color is deemed dark or not
-  QString backgroundColorHint = _hasDarkBackground ? "COLORFGBG=15;0" : "COLORFGBG=0;15";
-
-  int result = _shellProcess->start(QFile::encodeName(_program),
-                                  arguments,
-                                  _environment << backgroundColorHint,
-                                  windowId(),
-                                  _addToUtmp);
-
-  if (result < 0)
-  {
-    return;
-  }
-
-  _shellProcess->setWriteable(false);  // We are reachable via kwrited.
-
-  emit started();
-}
-
-void Session::setUserTitle( int what, const QString &caption )
-{
-    //set to true if anything is actually changed (eg. old _nameTitle != new _nameTitle )
-	bool modified = false;
-
-    // (btw: what=0 changes _userTitle and icon, what=1 only icon, what=2 only _nameTitle
-    if ((what == 0) || (what == 2)) 
-    {
-       	if ( _userTitle != caption ) {
-			_userTitle = caption;
-			modified = true;
-		}
-    }
-
-    if ((what == 0) || (what == 1))
-	{
-		if ( _iconText != caption ) {
-       		_iconText = caption;
-			modified = true;
-		}
-	}
-
-    if (what == 11) 
-    {
-      QString colorString = caption.section(';',0,0);
-      qDebug() << __FILE__ << __LINE__ << ": setting background colour to " << colorString;
-      QColor backColor = QColor(colorString);
-      if (backColor.isValid()){// change color via \033]11;Color\007
-          if (backColor != _modifiedBackground)
-          {
-              _modifiedBackground = backColor;
-
-              // bail out here until the code to connect the terminal display
-              // to the changeBackgroundColor() signal has been written
-              // and tested - just so we don't forget to do this.
-              Q_ASSERT( 0 );
-
-              emit changeBackgroundColorRequest(backColor);
-          }
-      }
-    }
-
-	if (what == 30) 
-    {
-		if ( _nameTitle != caption ) {
-       		setTitle(Session::NameRole,caption);
-			return;
-		}
-	}
-
-    if (what == 31) 
-    {
-       QString cwd=caption;
-       cwd=cwd.replace( QRegExp("^~"), QDir::homePath() );
-       emit openUrlRequest(cwd);
-	}
-
-    // change icon via \033]32;Icon\007
-    if (what == 32) 
-    { 
-    	if ( _iconName != caption ) {
-	   		_iconName = caption;
-
-			modified = true;
-		}
-    }
-
-    if (what == 50) 
-    {
-        emit profileChangeCommandReceived(caption);
-        return;
-    }
-
-	if ( modified )
-    	emit titleChanged();
-}
-
-QString Session::userTitle() const
-{
-    return _userTitle;
-}
-void Session::setTabTitleFormat(TabTitleContext context , const QString& format)
-{
-    if ( context == LocalTabTitle )
-        _localTabTitleFormat = format;
-    else if ( context == RemoteTabTitle )
-        _remoteTabTitleFormat = format;
-}
-QString Session::tabTitleFormat(TabTitleContext context) const
-{
-    if ( context == LocalTabTitle )
-        return _localTabTitleFormat;
-    else if ( context == RemoteTabTitle )
-        return _remoteTabTitleFormat;
-
-    return QString();
-}
-
-void Session::monitorTimerDone()
-{
-  //FIXME: The idea here is that the notification popup will appear to tell the user than output from
-  //the terminal has stopped and the popup will disappear when the user activates the session.
-  //
-  //This breaks with the addition of multiple views of a session.  The popup should disappear
-  //when any of the views of the session becomes active
-  
-
-  //FIXME: Make message text for this notification and the activity notification more descriptive.	
-  if (_monitorSilence) {
-//    KNotification::event("Silence", ("Silence in session '%1'", _nameTitle), QPixmap(),
-//                    QApplication::activeWindow(),
-//                    KNotification::CloseWhenWidgetActivated);
-    emit stateChanged(NOTIFYSILENCE);
-  }
-  else
-  {
-    emit stateChanged(NOTIFYNORMAL);
-  }
-
-  _notifiedActivity=false;
-}
-
-void Session::activityStateSet(int state)
-{
-  if (state==NOTIFYBELL)
-  {
-      QString s; s.sprintf("Bell in session '%s'",_nameTitle.toAscii().data());
-      
-      emit bellRequest( s );
-  }
-  else if (state==NOTIFYACTIVITY)
-  {
-    if (_monitorSilence) {
-      _monitorTimer->start(_silenceSeconds*1000);
-    }
-
-    if ( _monitorActivity ) {
-      //FIXME:  See comments in Session::monitorTimerDone()
-      if (!_notifiedActivity) {
-//        KNotification::event("Activity", ("Activity in session '%1'", _nameTitle), QPixmap(),
-//                        QApplication::activeWindow(),
-//        KNotification::CloseWhenWidgetActivated);
-        _notifiedActivity=true;
-      }
-    }
-  }
-
-  if ( state==NOTIFYACTIVITY && !_monitorActivity )
-          state = NOTIFYNORMAL;
-  if ( state==NOTIFYSILENCE && !_monitorSilence )
-          state = NOTIFYNORMAL;
-
-  emit stateChanged(state);
-}
-
-void Session::onViewSizeChange(int /*height*/, int /*width*/)
-{
-  updateTerminalSize();
-}
-void Session::onEmulationSizeChange(int lines , int columns)
-{
-  setSize( QSize(lines,columns) );
-}
-
-void Session::updateTerminalSize()
-{
-    QListIterator<TerminalDisplay*> viewIter(_views);
-
-    int minLines = -1;
-    int minColumns = -1;
-
-    // minimum number of lines and columns that views require for
-    // their size to be taken into consideration ( to avoid problems
-    // with new view widgets which haven't yet been set to their correct size )
-    const int VIEW_LINES_THRESHOLD = 2;
-    const int VIEW_COLUMNS_THRESHOLD = 2;
-
-    //select largest number of lines and columns that will fit in all visible views
-    while ( viewIter.hasNext() )
-    {
-        TerminalDisplay* view = viewIter.next();
-        if ( view->isHidden() == false &&
-             view->lines() >= VIEW_LINES_THRESHOLD &&
-             view->columns() >= VIEW_COLUMNS_THRESHOLD )
-        {
-            minLines = (minLines == -1) ? view->lines() : qMin( minLines , view->lines() );
-            minColumns = (minColumns == -1) ? view->columns() : qMin( minColumns , view->columns() );
-        }
-    }
-
-    // backend emulation must have a _terminal of at least 1 column x 1 line in size
-    if ( minLines > 0 && minColumns > 0 )
-    {
-        _emulation->setImageSize( minLines , minColumns );
-        _shellProcess->setWindowSize( minLines , minColumns );
-    }
-}
-
-void Session::refresh()
-{
-    // attempt to get the shell process to redraw the display
-    //
-    // this requires the program running in the shell
-    // to cooperate by sending an update in response to
-    // a window size change
-    //
-    // the window size is changed twice, first made slightly larger and then
-    // resized back to its normal size so that there is actually a change
-    // in the window size (some shells do nothing if the
-    // new and old sizes are the same)
-    //
-    // if there is a more 'correct' way to do this, please
-    // send an email with method or patches to konsole-devel@kde.org
-
-    const QSize existingSize = _shellProcess->windowSize();
-    _shellProcess->setWindowSize(existingSize.height(),existingSize.width()+1);
-    _shellProcess->setWindowSize(existingSize.height(),existingSize.width());
-}
-
-bool Session::sendSignal(int signal)
-{
-  return _shellProcess->kill(signal);
-}
-
-void Session::close()
-{
-  _autoClose = true;
-  _wantedClose = true;
-  if (!_shellProcess->isRunning() || !sendSignal(SIGHUP))
-  {
-     // Forced close.
-     QTimer::singleShot(1, this, SIGNAL(finished()));
-  }
-}
-
-void Session::sendText(const QString &text) const
-{
-  _emulation->sendText(text);
-}
-
-Session::~Session()
-{
-  delete _emulation;
-  delete _shellProcess;
-//  delete _zmodemProc;
-}
-
-void Session::setProfileKey(const QString& key)
-{
-    _profileKey = key;
-    emit profileChanged(key);
-}
-QString Session::profileKey() const { return _profileKey; }
-
-void Session::done(int exitStatus)
-{
-  if (!_autoClose)
-  {
-    _userTitle = ("<Finished>");
-    emit titleChanged();
-    return;
-  }
-  if (!_wantedClose && (exitStatus || _shellProcess->signalled()))
-  {
-    QString message;
-
-    if (_shellProcess->normalExit())
-      message.sprintf ("Session '%s' exited with status %d.", _nameTitle.toAscii().data(), exitStatus);
-    else if (_shellProcess->signalled())
-    {
-      if (_shellProcess->coreDumped())
-      {    
-
-        message.sprintf("Session '%s' exited with signal %d and dumped core.", _nameTitle.toAscii().data(), _shellProcess->exitSignal());
-      }
-      else { 
-        message.sprintf("Session '%s' exited with signal %d.", _nameTitle.toAscii().data(), _shellProcess->exitSignal());
-      }
-    }
-    else
-        message.sprintf ("Session '%s' exited unexpectedly.", _nameTitle.toAscii().data());
-
-    //FIXME: See comments in Session::monitorTimerDone()
-//    KNotification::event("Finished", message , QPixmap(),
-//                         QApplication::activeWindow(),
-//                         KNotification::CloseWhenWidgetActivated);
-  }
-  emit finished();
-}
-
-Emulation* Session::emulation() const
-{
-  return _emulation;
-}
-
-QString Session::keyBindings() const
-{
-  return _emulation->keyBindings();
-}
-
-QStringList Session::environment() const
-{
-  return _environment;
-}
-
-void Session::setEnvironment(const QStringList& environment)
-{
-    _environment = environment;
-}
-
-int Session::sessionId() const
-{
-  return _sessionId;
-}
-
-void Session::setKeyBindings(const QString &id)
-{
-  _emulation->setKeyBindings(id);
-}
-
-void Session::setTitle(TitleRole role , const QString& newTitle)
-{
-    if ( title(role) != newTitle )
-    {
-        if ( role == NameRole )
-            _nameTitle = newTitle;
-        else if ( role == DisplayedTitleRole )
-            _displayTitle = newTitle;
-
-        emit titleChanged();
-    }
-}
-
-QString Session::title(TitleRole role) const
-{
-    if ( role == NameRole )
-        return _nameTitle;
-    else if ( role == DisplayedTitleRole )
-        return _displayTitle;
-    else
-        return QString();
-}
-
-void Session::setIconName(const QString& iconName)
-{
-    if ( iconName != _iconName )
-    {
-        _iconName = iconName;
-        emit titleChanged();
-    }
-}
-
-void Session::setIconText(const QString& iconText)
-{
-  _iconText = iconText;
-  //kDebug(1211)<<"Session setIconText " <<  _iconText;
-}
-
-QString Session::iconName() const
-{
-  return _iconName;
-}
-
-QString Session::iconText() const
-{
-  return _iconText;
-}
-
-void Session::setHistoryType(const HistoryType &hType)
-{
-  _emulation->setHistory(hType);
-}
-
-const HistoryType& Session::historyType() const
-{
-  return _emulation->history();
-}
-
-void Session::clearHistory()
-{
-    _emulation->clearHistory();
-}
-
-QStringList Session::arguments() const
-{
-  return _arguments;
-}
-
-QString Session::program() const
-{
-  return _program;
-}
-
-// unused currently
-bool Session::isMonitorActivity() const { return _monitorActivity; }
-// unused currently
-bool Session::isMonitorSilence()  const { return _monitorSilence; }
-
-void Session::setMonitorActivity(bool _monitor)
-{
-  _monitorActivity=_monitor;
-  _notifiedActivity=false;
-
-  activityStateSet(NOTIFYNORMAL);
-}
-
-void Session::setMonitorSilence(bool _monitor)
-{
-  if (_monitorSilence==_monitor)
-    return;
-
-  _monitorSilence=_monitor;
-  if (_monitorSilence)
-  {
-    _monitorTimer->start(_silenceSeconds*1000);
-  }
-  else
-    _monitorTimer->stop();
-
-  activityStateSet(NOTIFYNORMAL);
-}
-
-void Session::setMonitorSilenceSeconds(int seconds)
-{
-  _silenceSeconds=seconds;
-  if (_monitorSilence) {
-    _monitorTimer->start(_silenceSeconds*1000);
-  }
-}
-
-void Session::setAddToUtmp(bool set)
-{
-  _addToUtmp = set;
-}
-
-void Session::setFlowControlEnabled(bool enabled)
-{
-  if (_flowControl == enabled)
-  	return;
-
-  _flowControl = enabled;
-
-  if (_shellProcess)  
-	_shellProcess->setXonXoff(_flowControl);
-  
-  emit flowControlEnabledChanged(enabled);
-}
-bool Session::flowControlEnabled() const
-{
-	return _flowControl;
-}
-//void Session::fireZModemDetected()
-//{
-//  if (!_zmodemBusy)
-//  {
-//    QTimer::singleShot(10, this, SIGNAL(zmodemDetected()));
-//    _zmodemBusy = true;
-//  }
-//}
-
-//void Session::cancelZModem()
-//{
-//  _shellProcess->sendData("\030\030\030\030", 4); // Abort
-//  _zmodemBusy = false;
-//}
-
-//void Session::startZModem(const QString &zmodem, const QString &dir, const QStringList &list)
-//{
-//  _zmodemBusy = true;
-//  _zmodemProc = new KProcess();
-//  _zmodemProc->setOutputChannelMode( KProcess::SeparateChannels );
-//
-//  *_zmodemProc << zmodem << "-v" << list;
-//
-//  if (!dir.isEmpty())
-//     _zmodemProc->setWorkingDirectory(dir);
-//
-//  _zmodemProc->start();
-//
-//  connect(_zmodemProc,SIGNAL (readyReadStandardOutput()),
-//          this, SLOT(zmodemReadAndSendBlock()));
-//  connect(_zmodemProc,SIGNAL (readyReadStandardError()),
-//          this, SLOT(zmodemReadStatus()));
-//  connect(_zmodemProc,SIGNAL (finished(int,QProcess::ExitStatus)),
-//          this, SLOT(zmodemFinished()));
-//
-//  disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
-//  connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(zmodemRcvBlock(const char*,int)) );
-//
-//  _zmodemProgress = new ZModemDialog(QApplication::activeWindow(), false,
-//                                    i18n("ZModem Progress"));
-//
-//  connect(_zmodemProgress, SIGNAL(user1Clicked()),
-//          this, SLOT(zmodemDone()));
-//
-//  _zmodemProgress->show();
-//}
-
-/*void Session::zmodemReadAndSendBlock()
-{
-  _zmodemProc->setReadChannel( QProcess::StandardOutput );
-  QByteArray data = _zmodemProc->readAll();
-
-  if ( data.count() == 0 )
-      return;
-
-  _shellProcess->sendData(data.constData(),data.count());
-}
-*/
-/*
-void Session::zmodemReadStatus()
-{
-  _zmodemProc->setReadChannel( QProcess::StandardError );
-  QByteArray msg = _zmodemProc->readAll();
-  while(!msg.isEmpty())
-  {
-     int i = msg.indexOf('\015');
-     int j = msg.indexOf('\012');
-     QByteArray txt;
-     if ((i != -1) && ((j == -1) || (i < j)))
-     {
-       msg = msg.mid(i+1);
-     }
-     else if (j != -1)
-     {
-       txt = msg.left(j);
-       msg = msg.mid(j+1);
-     }
-     else
-     {
-       txt = msg;
-       msg.truncate(0);
-     }
-     if (!txt.isEmpty())
-       _zmodemProgress->addProgressText(QString::fromLocal8Bit(txt));
-  }
-}
-*/
-/*
-void Session::zmodemRcvBlock(const char *data, int len)
-{
-  QByteArray ba( data, len );
-
-  _zmodemProc->write( ba );
-}
-*/
-/*
-void Session::zmodemFinished()
-{
-  if (_zmodemProc)
-  {
-    delete _zmodemProc;
-    _zmodemProc = 0;
-    _zmodemBusy = false;
-
-    disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this ,SLOT(zmodemRcvBlock(const char*,int)) );
-    connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
-
-    _shellProcess->sendData("\030\030\030\030", 4); // Abort
-    _shellProcess->sendData("\001\013\n", 3); // Try to get prompt back
-    _zmodemProgress->transferDone();
-  }
-}
-*/
-void Session::onReceiveBlock( const char* buf, int len )
-{
-    _emulation->receiveData( buf, len );
-    emit receivedData( QString::fromLatin1( buf, len ) );
-}
-
-QSize Session::size()
-{
-  return _emulation->imageSize();
-}
-
-void Session::setSize(const QSize& size)
-{
-  if ((size.width() <= 1) || (size.height() <= 1))
-     return;
-
-  emit resizeRequest(size);
-}
-int Session::foregroundProcessId() const
-{
-    return _shellProcess->foregroundProcessGroup();
-}
-int Session::processId() const
-{
-    return _shellProcess->pid();
-}
-
-SessionGroup::SessionGroup()
-    : _masterMode(0)
-{
-}
-SessionGroup::~SessionGroup()
-{
-    // disconnect all
-    connectAll(false);
-}
-int SessionGroup::masterMode() const { return _masterMode; }
-QList<Session*> SessionGroup::sessions() const { return _sessions.keys(); }
-bool SessionGroup::masterStatus(Session* session) const { return _sessions[session]; }
-
-void SessionGroup::addSession(Session* session)
-{
-    _sessions.insert(session,false);
-
-    QListIterator<Session*> masterIter(masters());
-
-    while ( masterIter.hasNext() )
-        connectPair(masterIter.next(),session);
-}
-void SessionGroup::removeSession(Session* session)
-{
-    setMasterStatus(session,false);
-
-    QListIterator<Session*> masterIter(masters());
-
-    while ( masterIter.hasNext() )
-        disconnectPair(masterIter.next(),session);
-
-    _sessions.remove(session);
-}
-void SessionGroup::setMasterMode(int mode)
-{
-   _masterMode = mode;
-
-   connectAll(false);
-   connectAll(true);
-}
-QList<Session*> SessionGroup::masters() const
-{
-    return _sessions.keys(true);
-}
-void SessionGroup::connectAll(bool connect)
-{
-    QListIterator<Session*> masterIter(masters());
-
-    while ( masterIter.hasNext() )
-    {
-        Session* master = masterIter.next();
-
-        QListIterator<Session*> otherIter(_sessions.keys());
-        while ( otherIter.hasNext() )
-        {
-            Session* other = otherIter.next();
-
-            if ( other != master )
-            {
-                if ( connect )
-                    connectPair(master,other);
-                else
-                    disconnectPair(master,other);
-            }
-        }
-    }
-}
-void SessionGroup::setMasterStatus(Session* session , bool master)
-{
-    bool wasMaster = _sessions[session];
-    _sessions[session] = master;
-
-    if (    !wasMaster && !master
-         || wasMaster && master )
-      return;
-
-    QListIterator<Session*> iter(_sessions.keys());
-    while ( iter.hasNext() )
-    {
-        Session* other = iter.next();
-
-        if ( other != session )
-        {
-            if ( master )
-                connectPair(session,other);
-            else
-                disconnectPair(session,other);
-        }
-    }
-}
-void SessionGroup::connectPair(Session* master , Session* other)
-{
-//    qDebug() << k_funcinfo;
-
-    if ( _masterMode & CopyInputToAll )
-    {
-        qDebug() << "Connection session " << master->nameTitle() << "to" << other->nameTitle();
-
-        connect( master->emulation() , SIGNAL(sendData(const char*,int)) , other->emulation() ,
-                 SLOT(sendString(const char*,int)) );
-    }
-}
-void SessionGroup::disconnectPair(Session* master , Session* other)
-{
-//    qDebug() << k_funcinfo;
-
-    if ( _masterMode & CopyInputToAll )
-    {
-        qDebug() << "Disconnecting session " << master->nameTitle() << "from" << other->nameTitle();
-
-        disconnect( master->emulation() , SIGNAL(sendData(const char*,int)) , other->emulation() ,
-                SLOT(sendString(const char*,int)) );
-    }
-}
-
-//#include "moc_Session.cpp"
--- a/gui/qtermwidget/lib/Session.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,621 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-
-    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
-
-    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.
-*/
-
-#ifndef SESSION_H
-#define SESSION_H
-
-// Qt
-#include <QtCore/QStringList>
-#include <QtCore>
-#include <QWidget>
-
-// Konsole
-#include "History.h"
-
-class KProcess;
-
-namespace Konsole
-{
-
-class Emulation;
-class Pty;
-class TerminalDisplay;
-//class ZModemDialog;
-
-/**
- * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation.
- * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole.
- * The terminal emulation ( Emulation and subclasses ) processes the output stream from the
- * PTY and produces a character image which is then shown on views connected to the session.
- *
- * Each Session can be connected to one or more views by using the addView() method.
- * The attached views can then display output from the program running in the terminal
- * or send input to the program in the terminal in the form of keypresses and mouse
- * activity.
- */
-class Session : public QObject
-{
-Q_OBJECT
-
-public:
-  Q_PROPERTY(QString name READ nameTitle)
-  Q_PROPERTY(int processId READ processId)
-  Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings)
-  Q_PROPERTY(QSize size READ size WRITE setSize)
-
-  /**
-   * Constructs a new session.
-   *
-   * To start the terminal process, call the run() method,
-   * after specifying the program and arguments
-   * using setProgram() and setArguments()
-   *
-   * If no program or arguments are specified explicitly, the Session
-   * falls back to using the program specified in the SHELL environment
-   * variable.
-   */
-  Session();
-  ~Session();
-
-  /**
-   * Returns true if the session is currently running.  This will be true
-   * after run() has been called successfully.
-   */
-  bool isRunning() const;
-
-  /**
-   * Sets the profile associated with this session.
-   *
-   * @param profileKey A key which can be used to obtain the current
-   * profile settings from the SessionManager
-   */
-  void setProfileKey(const QString& profileKey);
-  /**
-   * Returns the profile key associated with this session.
-   * This can be passed to the SessionManager to obtain the current
-   * profile settings.
-   */
-  QString profileKey() const;
-
-  /**
-   * Adds a new view for this session.
-   *
-   * The viewing widget will display the output from the terminal and
-   * input from the viewing widget (key presses, mouse activity etc.)
-   * will be sent to the terminal.
-   *
-   * Views can be removed using removeView().  The session is automatically
-   * closed when the last view is removed.
-   */
-  void addView(TerminalDisplay* widget);
-  /**
-   * Removes a view from this session.  When the last view is removed,
-   * the session will be closed automatically.
-   *
-   * @p widget will no longer display output from or send input
-   * to the terminal
-   */
-  void removeView(TerminalDisplay* widget);
-
-  /**
-   * Returns the views connected to this session
-   */
-  QList<TerminalDisplay*> views() const;
-
-  /**
-   * Returns the terminal emulation instance being used to encode / decode
-   * characters to / from the process.
-   */
-  Emulation*  emulation() const;
-
-  /**
-   * Returns the environment of this session as a list of strings like
-   * VARIABLE=VALUE
-   */
-  QStringList environment() const;
-  /**
-   * Sets the environment for this session.
-   * @p environment should be a list of strings like
-   * VARIABLE=VALUE
-   */
-  void setEnvironment(const QStringList& environment);
-
-  /** Returns the unique ID for this session. */
-  int sessionId() const;
-
-  /**
-   * Return the session title set by the user (ie. the program running
-   * in the terminal), or an empty string if the user has not set a custom title
-   */
-  QString userTitle() const;
-
-  /**
-   * This enum describes the contexts for which separate
-   * tab title formats may be specified.
-   */
-  enum TabTitleContext
-  {
-    /** Default tab title format */
-    LocalTabTitle,
-    /**
-     * Tab title format used session currently contains
-     * a connection to a remote computer (via SSH)
-     */
-    RemoteTabTitle
-  };
-  /**
-   * Sets the format used by this session for tab titles.
-   *
-   * @param context The context whoose format should be set.
-   * @param format The tab title format.  This may be a mixture
-   * of plain text and dynamic elements denoted by a '%' character
-   * followed by a letter.  (eg. %d for directory).  The dynamic
-   * elements available depend on the @p context
-   */
-  void setTabTitleFormat(TabTitleContext context , const QString& format);
-  /** Returns the format used by this session for tab titles. */
-  QString tabTitleFormat(TabTitleContext context) const;
-
-
-  /** Returns the arguments passed to the shell process when run() is called. */
-  QStringList arguments() const;
-  /** Returns the program name of the shell process started when run() is called. */
-  QString program() const;
-
-  /**
-   * Sets the command line arguments which the session's program will be passed when
-   * run() is called.
-   */
-  void setArguments(const QStringList& arguments);
-  /** Sets the program to be executed when run() is called. */
-  void setProgram(const QString& program);
-
-  /** Returns the session's current working directory. */
-  QString initialWorkingDirectory() { return _initialWorkingDir; }
-
-  /**
-   * Sets the initial working directory for the session when it is run
-   * This has no effect once the session has been started.
-   */
-  void setInitialWorkingDirectory( const QString& dir );
-
-  /**
-   * Sets the type of history store used by this session.
-   * Lines of output produced by the terminal are added
-   * to the history store.  The type of history store
-   * used affects the number of lines which can be
-   * remembered before they are lost and the storage
-   * (in memory, on-disk etc.) used.
-   */
-  void setHistoryType(const HistoryType& type);
-  /**
-   * Returns the type of history store used by this session.
-   */
-  const HistoryType& historyType() const;
-  /**
-   * Clears the history store used by this session.
-   */
-  void clearHistory();
-
-  /**
-   * Enables monitoring for activity in the session.
-   * This will cause notifySessionState() to be emitted
-   * with the NOTIFYACTIVITY state flag when output is
-   * received from the terminal.
-   */
-  void setMonitorActivity(bool);
-  /** Returns true if monitoring for activity is enabled. */
-  bool isMonitorActivity() const;
-
-  /**
-   * Enables monitoring for silence in the session.
-   * This will cause notifySessionState() to be emitted
-   * with the NOTIFYSILENCE state flag when output is not
-   * received from the terminal for a certain period of
-   * time, specified with setMonitorSilenceSeconds()
-   */
-  void setMonitorSilence(bool);
-  /**
-   * Returns true if monitoring for inactivity (silence)
-   * in the session is enabled.
-   */
-  bool isMonitorSilence()  const;
-  /** See setMonitorSilence() */
-  void setMonitorSilenceSeconds(int seconds);
-
-  /**
-   * Sets the key bindings used by this session.  The bindings
-   * specify how input key sequences are translated into
-   * the character stream which is sent to the terminal.
-   *
-   * @param id The name of the key bindings to use.  The
-   * names of available key bindings can be determined using the
-   * KeyboardTranslatorManager class.
-   */
-  void setKeyBindings(const QString& id);
-  /** Returns the name of the key bindings used by this session. */
-  QString keyBindings() const;
-
-  /**
-   * This enum describes the available title roles.
-   */
-  enum TitleRole
-  {
-      /** The name of the session. */
-      NameRole,
-      /** The title of the session which is displayed in tabs etc. */
-      DisplayedTitleRole
-  };
-
-  /** Sets the session's title for the specified @p role to @p title. */
-  void setTitle(TitleRole role , const QString& title);
-  /** Returns the session's title for the specified @p role. */
-  QString title(TitleRole role) const;
-  /** Convenience method used to read the name property.  Returns title(Session::NameRole). */
-  QString nameTitle() const { return title(Session::NameRole); }
-
-  /** Sets the name of the icon associated with this session. */
-  void setIconName(const QString& iconName);
-  /** Returns the name of the icon associated with this session. */
-  QString iconName() const;
-
-  /** Sets the text of the icon associated with this session. */
-  void setIconText(const QString& iconText);
-  /** Returns the text of the icon associated with this session. */
-  QString iconText() const;
-
-  /** Specifies whether a utmp entry should be created for the pty used by this session. */
-  void setAddToUtmp(bool);
-
-  /** Sends the specified @p signal to the terminal process. */
-  bool sendSignal(int signal);
-
-  /**
-   * Specifies whether to close the session automatically when the terminal
-   * process terminates.
-   */
-  void setAutoClose(bool b) { _autoClose = b; }
-
-  /**
-   * Sets whether flow control is enabled for this terminal
-   * session.
-   */
-  void setFlowControlEnabled(bool enabled);
-
-  /** Returns whether flow control is enabled for this terminal session. */
-  bool flowControlEnabled() const;
-
-  /**
-   * Sends @p text to the current foreground terminal program.
-   */
-  void sendText(const QString& text) const;
-
-  /**
-   * Returns the process id of the terminal process.
-   * This is the id used by the system API to refer to the process.
-   */
-  int processId() const;
-
-  /**
-   * Returns the process id of the terminal's foreground process.
-   * This is initially the same as processId() but can change
-   * as the user starts other programs inside the terminal.
-   */
-  int foregroundProcessId() const;
-
-  /** Returns the terminal session's window size in lines and columns. */
-  QSize size();
-  /**
-   * Emits a request to resize the session to accommodate
-   * the specified window size.
-   *
-   * @param size The size in lines and columns to request.
-   */
-  void setSize(const QSize& size);
-
-  /** Sets the text codec used by this session's terminal emulation. */
-  void setCodec(QTextCodec* codec);
-
-  /**
-   * Sets whether the session has a dark background or not.  The session
-   * uses this information to set the COLORFGBG variable in the process's
-   * environment, which allows the programs running in the terminal to determine
-   * whether the background is light or dark and use appropriate colors by default.
-   *
-   * This has no effect once the session is running.
-   */
-  void setDarkBackground(bool darkBackground);
-  /**
-   * Returns true if the session has a dark background.
-   * See setDarkBackground()
-   */
-  bool hasDarkBackground() const;
-
-  /**
-   * Attempts to get the shell program to redraw the current display area.
-   * This can be used after clearing the screen, for example, to get the
-   * shell to redraw the prompt line.
-   */
-  void refresh();
-
-//  void startZModem(const QString &rz, const QString &dir, const QStringList &list);
-//  void cancelZModem();
-//  bool isZModemBusy() { return _zmodemBusy; }
-
-public slots:
-
-  /**
-   * Starts the terminal session.
-   *
-   * This creates the terminal process and connects the teletype to it.
-   */
-  void run();
-
-  /**
-   * Closes the terminal session.  This sends a hangup signal
-   * (SIGHUP) to the terminal process and causes the done(Session*)
-   * signal to be emitted.
-   */
-  void close();
-
-  /**
-   * Changes the session title or other customizable aspects of the terminal
-   * emulation display. For a list of what may be changed see the
-   * Emulation::titleChanged() signal.
-   */
-  void setUserTitle( int, const QString &caption );
-
-signals:
-
-  /** Emitted when the terminal process starts. */
-  void started();
-
-  /**
-   * Emitted when the terminal process exits.
-   */
-  void finished();
-
-  /**
-   * Emitted when output is received from the terminal process.
-   */
-  void receivedData( const QString& text );
-
-  /** Emitted when the session's title has changed. */
-  void titleChanged();
-
-  /** Emitted when the session's profile has changed. */
-  void profileChanged(const QString& profile);
-
-  /**
-   * Emitted when the activity state of this session changes.
-   *
-   * @param state The new state of the session.  This may be one
-   * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY
-   */
-  void stateChanged(int state);
-
-  /** Emitted when a bell event occurs in the session. */
-  void bellRequest( const QString& message );
-
-  /**
-   * Requests that the color the text for any tabs associated with
-   * this session should be changed;
-   *
-   * TODO: Document what the parameter does
-   */
-  void changeTabTextColorRequest(int);
-
-  /**
-   * Requests that the background color of views on this session
-   * should be changed.
-   */
-  void changeBackgroundColorRequest(const QColor&);
-
-  /** TODO: Document me. */
-  void openUrlRequest(const QString& url);
-
-  /** TODO: Document me. */
-//  void zmodemDetected();
-
-  /**
-   * Emitted when the terminal process requests a change
-   * in the size of the terminal window.
-   *
-   * @param size The requested window size in terms of lines and columns.
-   */
-  void resizeRequest(const QSize& size);
-
-  /**
-   * Emitted when a profile change command is received from the terminal.
-   *
-   * @param text The text of the command.  This is a string of the form
-   * "PropertyName=Value;PropertyName=Value ..."
-   */
-  void profileChangeCommandReceived(const QString& text);
-
- /**
-  * Emitted when the flow control state changes.
-  *
-  * @param enabled True if flow control is enabled or false otherwise.
-  */
-  void flowControlEnabledChanged(bool enabled);
-
-private slots:
-  void done(int);
-
-//  void fireZModemDetected();
-
-  void onReceiveBlock( const char* buffer, int len );
-  void monitorTimerDone();
-
-  void onViewSizeChange(int height, int width);
-  void onEmulationSizeChange(int lines , int columns);
-
-  void activityStateSet(int);
-
-  //automatically detach views from sessions when view is destroyed
-  void viewDestroyed(QObject* view);
-
-//  void zmodemReadStatus();
-//  void zmodemReadAndSendBlock();
-//  void zmodemRcvBlock(const char *data, int len);
-//  void zmodemFinished();
-
-private:
-
-  void updateTerminalSize();
-  WId windowId() const;
-
-  int            _uniqueIdentifier;
-
-  Pty*          _shellProcess;
-  Emulation*    _emulation;
-
-  QList<TerminalDisplay*> _views;
-
-  bool           _monitorActivity;
-  bool           _monitorSilence;
-  bool           _notifiedActivity;
-  bool           _masterMode;
-  bool           _autoClose;
-  bool           _wantedClose;
-  QTimer*        _monitorTimer;
-
-  int            _silenceSeconds;
-
-  QString        _nameTitle;
-  QString        _displayTitle;
-  QString        _userTitle;
-
-  QString        _localTabTitleFormat;
-  QString        _remoteTabTitleFormat;
-
-  QString        _iconName;
-  QString        _iconText; // as set by: echo -en '\033]1;IconText\007
-  bool           _addToUtmp;
-  bool           _flowControl;
-  bool           _fullScripting;
-
-  QString        _program;
-  QStringList    _arguments;
-
-  QStringList    _environment;
-  int            _sessionId;
-
-  QString        _initialWorkingDir;
-
-  // ZModem
-//  bool           _zmodemBusy;
-//  KProcess*      _zmodemProc;
-//  ZModemDialog*  _zmodemProgress;
-
-  // Color/Font Changes by ESC Sequences
-
-  QColor         _modifiedBackground; // as set by: echo -en '\033]11;Color\007
-
-  QString        _profileKey;
-
-  bool _hasDarkBackground;
-
-  static int lastSessionId;
-
-};
-
-/**
- * Provides a group of sessions which is divided into master and slave sessions.
- * Activity in master sessions can be propagated to all sessions within the group.
- * The type of activity which is propagated and method of propagation is controlled
- * by the masterMode() flags.
- */
-class SessionGroup : public QObject
-{
-Q_OBJECT
-
-public:
-    /** Constructs an empty session group. */
-    SessionGroup();
-    /** Destroys the session group and removes all connections between master and slave sessions. */
-    ~SessionGroup();
-
-    /** Adds a session to the group. */
-    void addSession( Session* session );
-    /** Removes a session from the group. */
-    void removeSession( Session* session );
-
-    /** Returns the list of sessions currently in the group. */
-    QList<Session*> sessions() const;
-
-    /**
-     * Sets whether a particular session is a master within the group.
-     * Changes or activity in the group's master sessions may be propagated
-     * to all the sessions in the group, depending on the current masterMode()
-     *
-     * @param session The session whoose master status should be changed.
-     * @param master True to make this session a master or false otherwise
-     */
-    void setMasterStatus( Session* session , bool master );
-    /** Returns the master status of a session.  See setMasterStatus() */
-    bool masterStatus( Session* session ) const;
-
-    /**
-     * This enum describes the options for propagating certain activity or
-     * changes in the group's master sessions to all sessions in the group.
-     */
-    enum MasterMode
-    {
-        /**
-         * Any input key presses in the master sessions are sent to all
-         * sessions in the group.
-         */
-        CopyInputToAll = 1
-    };
-
-    /**
-     * Specifies which activity in the group's master sessions is propagated
-     * to all sessions in the group.
-     *
-     * @param mode A bitwise OR of MasterMode flags.
-     */
-    void setMasterMode( int mode );
-    /**
-     * Returns a bitwise OR of the active MasterMode flags for this group.
-     * See setMasterMode()
-     */
-    int masterMode() const;
-
-private:
-    void connectPair(Session* master , Session* other);
-    void disconnectPair(Session* master , Session* other);
-    void connectAll(bool connect);
-    QList<Session*> masters() const;
-
-    // maps sessions to their master status
-    QHash<Session*,bool> _sessions;
-
-    int _masterMode;
-};
-
-}
-
-#endif
--- a/gui/qtermwidget/lib/ShellCommand.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
-    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 "ShellCommand.h"
-
-//some versions of gcc(4.3) require explicit include
-#include <cstdlib>
-
-
-using namespace Konsole;
-
-// expands environment variables in 'text'
-// function copied from kdelibs/kio/kio/kurlcompletion.cpp
-static bool expandEnv(QString& text);
-
-ShellCommand::ShellCommand(const QString& fullCommand)
-{
-    bool inQuotes = false;
-
-    QString builder;
-
-    for ( int i = 0 ; i < fullCommand.count() ; i++ )
-    {
-        QChar ch = fullCommand[i];
-
-        const bool isLastChar = ( i == fullCommand.count() - 1 );
-        const bool isQuote = ( ch == '\'' || ch == '\"' );
-
-        if ( !isLastChar && isQuote )
-            inQuotes = !inQuotes;
-        else
-        { 
-            if ( (!ch.isSpace() || inQuotes) && !isQuote )
-                builder.append(ch);
-
-            if ( (ch.isSpace() && !inQuotes) || ( i == fullCommand.count()-1 ) )
-            {
-                _arguments << builder;      
-                builder.clear(); 
-            }
-        }
-    }
-}
-ShellCommand::ShellCommand(const QString& command , const QStringList& arguments)
-{
-    _arguments = arguments;
-    
-    if ( !_arguments.isEmpty() )
-        _arguments[0] == command;
-}
-QString ShellCommand::fullCommand() const
-{
-    return _arguments.join(QChar(' '));
-}
-QString ShellCommand::command() const
-{
-    if ( !_arguments.isEmpty() )
-        return _arguments[0];
-    else
-        return QString();
-}
-QStringList ShellCommand::arguments() const
-{
-    return _arguments;
-}
-bool ShellCommand::isRootCommand() const
-{
-    Q_ASSERT(0); // not implemented yet
-    return false;
-}
-bool ShellCommand::isAvailable() const
-{
-    Q_ASSERT(0); // not implemented yet
-    return false; 
-}
-QStringList ShellCommand::expand(const QStringList& items)
-{
-    QStringList result;
-
-    foreach( QString item , items )
-        result << expand(item);
-
-    return result;
-}
-QString ShellCommand::expand(const QString& text)
-{
-    QString result = text;
-    expandEnv(result);
-    return result;
-}
-
-/*
- * expandEnv
- *
- * Expand environment variables in text. Escaped '$' characters are ignored.
- * Return true if any variables were expanded
- */
-static bool expandEnv( QString &text )
-{
-	// Find all environment variables beginning with '$'
-	//
-	int pos = 0;
-
-	bool expanded = false;
-
-	while ( (pos = text.indexOf(QLatin1Char('$'), pos)) != -1 ) {
-
-		// Skip escaped '$'
-		//
-		if ( pos > 0 && text.at(pos-1) == QLatin1Char('\\') ) {
-			pos++;
-		}
-		// Variable found => expand
-		//
-		else {
-			// Find the end of the variable = next '/' or ' '
-			//
-			int pos2 = text.indexOf( QLatin1Char(' '), pos+1 );
-			int pos_tmp = text.indexOf( QLatin1Char('/'), pos+1 );
-
-			if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) )
-				pos2 = pos_tmp;
-
-			if ( pos2 == -1 )
-				pos2 = text.length();
-
-			// Replace if the variable is terminated by '/' or ' '
-			// and defined
-			//
-			if ( pos2 >= 0 ) {
-				int len	= pos2 - pos;
-				QString key	= text.mid( pos+1, len-1);
-				QString value =
-					QString::fromLocal8Bit( ::getenv(key.toLocal8Bit()) );
-
-				if ( !value.isEmpty() ) {
-					expanded = true;
-					text.replace( pos, len, value );
-					pos = pos + value.length();
-				}
-				else {
-					pos = pos2;
-				}
-			}
-		}
-	}
-
-	return expanded;
-}
--- a/gui/qtermwidget/lib/ShellCommand.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
-    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.
-*/
-
-#ifndef SHELLCOMMAND_H
-#define SHELLCOMMAND_H
-
-// Qt
-#include <QtCore/QStringList>
-
-namespace Konsole
-{
-
-/** 
- * A class to parse and extract information about shell commands. 
- *
- * ShellCommand can be used to:
- *
- * <ul>
- *      <li>Take a command-line (eg "/bin/sh -c /path/to/my/script") and split it
- *          into its component parts (eg. the command "/bin/sh" and the arguments
- *          "-c","/path/to/my/script")
- *      </li>
- *      <li>Take a command and a list of arguments and combine them to 
- *          form a complete command line.
- *      </li>
- *      <li>Determine whether the binary specified by a command exists in the
- *          user's PATH.
- *      </li>
- *      <li>Determine whether a command-line specifies the execution of
- *          another command as the root user using su/sudo etc.
- *      </li>
- * </ul> 
- */
-class ShellCommand
-{
-public:
-    /**
-     * Constructs a ShellCommand from a command line.
-     *
-     * @param fullCommand The command line to parse.  
-     */
-    ShellCommand(const QString& fullCommand);
-    /**
-     * Constructs a ShellCommand with the specified @p command and @p arguments.
-     */
-    ShellCommand(const QString& command , const QStringList& arguments);
-
-    /** Returns the command. */
-    QString command() const;
-    /** Returns the arguments. */
-    QStringList arguments() const;
-
-    /** 
-     * Returns the full command line. 
-     */
-    QString fullCommand() const;
-
-    /** Returns true if this is a root command. */
-    bool isRootCommand() const;
-    /** Returns true if the program specified by @p command() exists. */
-    bool isAvailable() const;
-
-    /** Expands environment variables in @p text .*/
-    static QString expand(const QString& text);
-
-    /** Expands environment variables in each string in @p list. */
-    static QStringList expand(const QStringList& items);
-
-private:
-    QStringList _arguments;    
-};
-
-}
-
-#endif // SHELLCOMMAND_H
-
--- a/gui/qtermwidget/lib/TerminalCharacterDecoder.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    
-    Copyright (C) 2006 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 Lesser 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 Lesser 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 "TerminalCharacterDecoder.h"
-
-// Qt
-#include <QtCore/QTextStream>
-
-
-using namespace Konsole;
-
-PlainTextDecoder::PlainTextDecoder()
- : _output(0)
- , _includeTrailingWhitespace(true)
-{
-
-}
-void PlainTextDecoder::setTrailingWhitespace(bool enable)
-{
-    _includeTrailingWhitespace = enable;
-}
-bool PlainTextDecoder::trailingWhitespace() const
-{
-    return _includeTrailingWhitespace;
-}
-void PlainTextDecoder::begin(QTextStream* output)
-{
-   _output = output; 
-}
-void PlainTextDecoder::end()
-{
-    _output = 0;
-}
-void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
-							 )
-{
-    Q_ASSERT( _output );
-
-	//TODO should we ignore or respect the LINE_WRAPPED line property?
-
-	//note:  we build up a QString and send it to the text stream rather writing into the text
-	//stream a character at a time because it is more efficient.
-	//(since QTextStream always deals with QStrings internally anyway)
-	QString plainText;
-	plainText.reserve(count);
-   
-    int outputCount = count;
-
-    // if inclusion of trailing whitespace is disabled then find the end of the
-    // line
-    if ( !_includeTrailingWhitespace )
-    {
-        for (int i = count-1 ; i >= 0 ; i--)
-        {
-            if ( characters[i].character != ' '  )
-                break;
-            else
-                outputCount--;
-        }
-    }
-
-	for (int i=0;i<outputCount;i++)
-	{
-		plainText.append( QChar(characters[i].character) );
-	}
-
-	*_output << plainText;
-}
-
-HTMLDecoder::HTMLDecoder() :
-        _output(0)
-	   ,_colorTable(base_color_table)
-       ,_innerSpanOpen(false)
-       ,_lastRendition(DEFAULT_RENDITION)
-{
-	
-}
-
-void HTMLDecoder::begin(QTextStream* output)
-{
-    _output = output;
-
-    QString text;
-
-	//open monospace span
-    openSpan(text,"font-family:monospace");
-
-    *output << text;
-}
-
-void HTMLDecoder::end()
-{
-    Q_ASSERT( _output );
-
-    QString text;
-
-    closeSpan(text);
-
-    *_output << text;
-
-    _output = 0;
-
-}
-
-//TODO: Support for LineProperty (mainly double width , double height)
-void HTMLDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
-							)
-{
-    Q_ASSERT( _output );
-
-	QString text;
-
-	int spaceCount = 0;
-		
-	for (int i=0;i<count;i++)
-	{
-		QChar ch(characters[i].character);
-
-		//check if appearance of character is different from previous char
-		if ( characters[i].rendition != _lastRendition  ||
-		     characters[i].foregroundColor != _lastForeColor  ||
-			 characters[i].backgroundColor != _lastBackColor )
-		{
-			if ( _innerSpanOpen )
-					closeSpan(text);
-
-			_lastRendition = characters[i].rendition;
-			_lastForeColor = characters[i].foregroundColor;
-			_lastBackColor = characters[i].backgroundColor;
-			
-			//build up style string
-			QString style;
-
-			if ( _lastRendition & RE_BOLD ||
-                             (_colorTable && characters[i].isBold(_colorTable)) )
-					style.append("font-weight:bold;");
-
-
-			if ( _lastRendition & RE_UNDERLINE )
-					style.append("font-decoration:underline;");
-		
-			//colours - a colour table must have been defined first
-			if ( _colorTable )	
-			{
-				style.append( QString("color:%1;").arg(_lastForeColor.color(_colorTable).name() ) );
-
-				if (!characters[i].isTransparent(_colorTable))
-				{
-					style.append( QString("background-color:%1;").arg(_lastBackColor.color(_colorTable).name() ) );
-				}
-			}
-		
-			//open the span with the current style	
-			openSpan(text,style);
-			_innerSpanOpen = true;
-		}
-
-		//handle whitespace
-		if (ch.isSpace())
-			spaceCount++;
-		else
-			spaceCount = 0;
-		
-
-		//output current character
-		if (spaceCount < 2)
-		{
-			//escape HTML tag characters and just display others as they are
-			if ( ch == '<' )
-				text.append("&lt;");
-			else if (ch == '>')
-					text.append("&gt;");
-			else	
-					text.append(ch);
-		}
-		else
-		{
-			text.append("&nbsp;"); //HTML truncates multiple spaces, so use a space marker instead
-		}
-		
-	}
-
-	//close any remaining open inner spans
-	if ( _innerSpanOpen )
-		closeSpan(text);
-
-	//start new line
-	text.append("<br>");
-	
-	*_output << text;
-}
-
-void HTMLDecoder::openSpan(QString& text , const QString& style)
-{
-	text.append( QString("<span style=\"%1\">").arg(style) );
-}
-
-void HTMLDecoder::closeSpan(QString& text)
-{
-	text.append("</span>");
-}
-
-void HTMLDecoder::setColorTable(const ColorEntry* table)
-{
-	_colorTable = table;
-}
--- a/gui/qtermwidget/lib/TerminalCharacterDecoder.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    
-    Copyright (C) 2006-7 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 Lesser 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 Lesser 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.
-*/
-
-#ifndef TERMINAL_CHARACTER_DECODER_H
-#define TERMINAL_CHARACTER_DECODER_H
-
-#include "Character.h"
-
-class QTextStream;
-
-namespace Konsole
-{
-
-/**
- * Base class for terminal character decoders
- *
- * The decoder converts lines of terminal characters which consist of a unicode character, foreground
- * and background colours and other appearance-related properties into text strings.
- *
- * Derived classes may produce either plain text with no other colour or appearance information, or
- * they may produce text which incorporates these additional properties. 
- */
-class TerminalCharacterDecoder
-{
-public:
-	virtual ~TerminalCharacterDecoder() {}
-
-    /** Begin decoding characters.  The resulting text is appended to @p output. */
-    virtual void begin(QTextStream* output) = 0;
-    /** End decoding. */
-    virtual void end() = 0;
-
-	/**
-	 * Converts a line of terminal characters with associated properties into a text string
-	 * and writes the string into an output QTextStream.
-	 *
-	 * @param characters An array of characters of length @p count.
-	 * @param properties Additional properties which affect all characters in the line
-	 * @param output The output stream which receives the decoded text
-	 */
-	virtual void decodeLine(const Character* const characters, 
-							int count,
-							LineProperty properties) = 0; 
-};
-
-/**
- * A terminal character decoder which produces plain text, ignoring colours and other appearance-related
- * properties of the original characters.
- */
-class PlainTextDecoder : public TerminalCharacterDecoder
-{
-public:
-	PlainTextDecoder(); 
-
-    /** 
-     * Set whether trailing whitespace at the end of lines should be included 
-     * in the output.
-     * Defaults to true.
-     */
-    void setTrailingWhitespace(bool enable);
-    /**
-     * Returns whether trailing whitespace at the end of lines is included
-     * in the output.
-     */
-    bool trailingWhitespace() const;
-
-    virtual void begin(QTextStream* output);
-    virtual void end();
-
-	virtual void decodeLine(const Character* const characters,
-							int count,
-							LineProperty properties);	
-
-    
-private:
-    QTextStream* _output;
-    bool _includeTrailingWhitespace;
-};
-
-/**
- * A terminal character decoder which produces pretty HTML markup
- */
-class HTMLDecoder : public TerminalCharacterDecoder
-{
-public:
-	/** 
-	 * Constructs an HTML decoder using a default black-on-white color scheme.
-	 */
-	HTMLDecoder();
-
-	/**
-	 * Sets the colour table which the decoder uses to produce the HTML colour codes in its
-	 * output
-	 */
-	void setColorTable( const ColorEntry* table );
-		
-	virtual void decodeLine(const Character* const characters,
-							int count,
-							LineProperty properties);
-
-    virtual void begin(QTextStream* output);
-    virtual void end();
-
-private:
-	void openSpan(QString& text , const QString& style);
-	void closeSpan(QString& text);
-
-    QTextStream* _output;
-	const ColorEntry* _colorTable;
-    bool _innerSpanOpen; 
-	quint8 _lastRendition;
-	CharacterColor _lastForeColor;
-	CharacterColor _lastBackColor;
-
-};
-
-}
-
-#endif
--- a/gui/qtermwidget/lib/TerminalDisplay.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2724 +0,0 @@
-/*
-    This file is part of Konsole, a terminal emulator for KDE.
-    
-    Copyright (C) 2006-7 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
-
-    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 "TerminalDisplay.h"
-
-// Qt
-#include <QtGui/QApplication>
-#include <QtGui/QBoxLayout>
-#include <QtGui/QClipboard>
-#include <QtGui/QKeyEvent>
-#include <QtCore/QEvent>
-#include <QtCore/QTime>
-#include <QtCore/QFile>
-#include <QtGui/QGridLayout>
-#include <QtGui/QLabel>
-#include <QtGui/QLayout>
-#include <QtGui/QPainter>
-#include <QtGui/QPixmap>
-#include <QtGui/QScrollBar>
-#include <QtGui/QStyle>
-#include <QtCore>
-#include <QtGui>
-
-#include "Filter.h"
-#include "konsole_wcwidth.h"
-#include "ScreenWindow.h"
-#include "TerminalCharacterDecoder.h"
-#include "ColorTables.h"
-
-using namespace Konsole;
-
-#ifndef loc
-#define loc(X,Y) ((Y)*_columns+(X))
-#endif
-
-#define yMouseScroll 1
-
-#define REPCHAR   "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
-                  "abcdefgjijklmnopqrstuvwxyz" \
-                  "0123456789./+@"
-
-// scroll increment used when dragging selection at top/bottom of window.
-
-// static
-bool TerminalDisplay::_antialiasText = true;
-bool TerminalDisplay::HAVE_TRANSPARENCY = false;
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                                Colors                                     */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
-
-   Code        0       1       2       3       4       5       6       7
-   ----------- ------- ------- ------- ------- ------- ------- ------- -------
-   ANSI  (bgr) Black   Red     Green   Yellow  Blue    Magenta Cyan    White
-   IBMPC (rgb) Black   Blue    Green   Cyan    Red     Magenta Yellow  White
-*/
-
-ScreenWindow* TerminalDisplay::screenWindow() const
-{
-    return _screenWindow;
-}
-void TerminalDisplay::setScreenWindow(ScreenWindow* window)
-{
-    // disconnect existing screen window if any
-    if ( _screenWindow )
-    {
-        disconnect( _screenWindow , 0 , this , 0 );
-    }
-
-    _screenWindow = window;
-
-    if ( window )
-    {
-//#warning "The order here is not specified - does it matter whether updateImage or updateLineProperties comes first?"
-        connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateLineProperties()) );
-        connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateImage()) );
-	window->setWindowLines(_lines);
-    }
-}
-
-const ColorEntry* TerminalDisplay::colorTable() const
-{
-  return _colorTable;
-}
-
-void TerminalDisplay::setColorTable(const ColorEntry table[])
-{
-  for (int i = 0; i < TABLE_COLORS; i++)
-      _colorTable[i] = table[i];
-
-  QPalette p = palette();
-  p.setColor( backgroundRole(), _colorTable[DEFAULT_BACK_COLOR].color );
-  setPalette( p );
-
-  // Avoid propagating the palette change to the scroll bar 
-  _scrollBar->setPalette( QApplication::palette() );  
-
-  update();
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                                   Font                                    */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/*
-   The VT100 has 32 special graphical characters. The usual vt100 extended
-   xterm fonts have these at 0x00..0x1f.
-
-   QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
-   come in here as proper unicode characters.
-
-   We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
-   from unicode to 0x00..0x1f. The remaining translation is then left to the
-   QCodec.
-*/
-
-static inline bool isLineChar(quint16 c) { return ((c & 0xFF80) == 0x2500);}
-static inline bool isLineCharString(const QString& string)
-{
-		return (string.length() > 0) && (isLineChar(string.at(0).unicode()));
-}
-						
-
-// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
-
-unsigned short Konsole::vt100_graphics[32] =
-{ // 0/8     1/9    2/10    3/11    4/12    5/13    6/14    7/15
-  0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
-  0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
-  0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
-  0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
-};
-
-void TerminalDisplay::fontChange(const QFont&)
-{
-  QFontMetrics fm(font());
-  _fontHeight = fm.height() + _lineSpacing;
-
-
-  // waba TerminalDisplay 1.123:
-  // "Base character width on widest ASCII character. This prevents too wide
-  //  characters in the presence of double wide (e.g. Japanese) characters."
-  // Get the width from representative normal width characters
-  _fontWidth = qRound((double)fm.width(REPCHAR)/(double)strlen(REPCHAR));
-
-  _fixedFont = true;
-
-  int fw = fm.width(REPCHAR[0]);
-  for(unsigned int i=1; i< strlen(REPCHAR); i++)
-  {
-    if (fw != fm.width(REPCHAR[i]))
-    {
-      _fixedFont = false;
-      break;
-    }
-  }
-
-  if (_fontWidth < 1)
-    _fontWidth=1;
-
-  _fontAscent = fm.ascent();
-
-  emit changedFontMetricSignal( _fontHeight, _fontWidth );
-  propagateSize();
-  update();
-}
-
-void TerminalDisplay::setVTFont(const QFont& f)
-{
-  QFont font = f;
-
-  QFontMetrics metrics(font);
-
-  if ( metrics.height() < height() && metrics.maxWidth() < width() )
-  {
-    // hint that text should be drawn without anti-aliasing.  
-    // depending on the user's font configuration, this may not be respected
-    if (!_antialiasText)
-        font.setStyleStrategy( QFont::NoAntialias );
- 
-    // experimental optimization.  Konsole assumes that the terminal is using a 
-    // mono-spaced font, in which case kerning information should have an effect.
-    // Disabling kerning saves some computation when rendering text. 
-    font.setKerning(false);
-
-    QWidget::setFont(font);
-    fontChange(font);
-  }
-}
-
-void TerminalDisplay::setFont(const QFont &)
-{
-  // ignore font change request if not coming from konsole itself
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                         Constructor / Destructor                          */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-TerminalDisplay::TerminalDisplay(QWidget *parent)
-:QWidget(parent)
-,_screenWindow(0)
-,_allowBell(true)
-,_gridLayout(0)
-,_fontHeight(1)
-,_fontWidth(1)
-,_fontAscent(1)
-,_lines(1)
-,_columns(1)
-,_usedLines(1)
-,_usedColumns(1)
-,_contentHeight(1)
-,_contentWidth(1)
-,_image(0)
-,_randomSeed(0)
-,_resizing(false)
-,_terminalSizeHint(false)
-,_terminalSizeStartup(true)
-,_bidiEnabled(false)
-,_actSel(0)
-,_wordSelectionMode(false)
-,_lineSelectionMode(false)
-,_preserveLineBreaks(false)
-,_columnSelectionMode(false)
-,_scrollbarLocation(NoScrollBar)
-,_wordCharacters(":@-./_~")
-,_bellMode(SystemBeepBell)
-,_blinking(false)
-,_cursorBlinking(false)
-,_hasBlinkingCursor(false)
-,_ctrlDrag(false)
-,_tripleClickMode(SelectWholeLine)
-,_isFixedSize(false)
-,_possibleTripleClick(false)
-,_resizeWidget(0)
-,_resizeTimer(0)
-,_flowControlWarningEnabled(false)
-,_outputSuspendedLabel(0)
-,_lineSpacing(0)
-,_colorsInverted(false)
-,_blendColor(qRgba(0,0,0,0xff))
-,_filterChain(new TerminalImageFilterChain())
-,_cursorShape(BlockCursor)
-{
-  // terminal applications are not designed with Right-To-Left in mind,
-  // so the layout is forced to Left-To-Right
-  setLayoutDirection(Qt::LeftToRight);
-
-  // The offsets are not yet calculated.
-  // Do not calculate these too often to be more smoothly when resizing
-  // konsole in opaque mode.
-  _topMargin = DEFAULT_TOP_MARGIN;
-  _leftMargin = DEFAULT_LEFT_MARGIN;
-
-  // create scroll bar for scrolling output up and down
-  // set the scroll bar's slider to occupy the whole area of the scroll bar initially
-  _scrollBar = new QScrollBar(this);
-  setScroll(0,0); 
-  _scrollBar->setCursor( Qt::ArrowCursor );
-  connect(_scrollBar, SIGNAL(valueChanged(int)), this, 
-  					  SLOT(scrollBarPositionChanged(int)));
-
-  // setup timers for blinking cursor and text
-  _blinkTimer   = new QTimer(this);
-  connect(_blinkTimer, SIGNAL(timeout()), this, SLOT(blinkEvent()));
-  _blinkCursorTimer   = new QTimer(this);
-  connect(_blinkCursorTimer, SIGNAL(timeout()), this, SLOT(blinkCursorEvent()));
-
-//  QCursor::setAutoHideCursor( this, true );
-  
-  setUsesMouse(true);
-  setColorTable(whiteonblack_color_table); 
-//  setColorTable(blackonlightyellow_color_table); 
-  setMouseTracking(true);
-
-  // Enable drag and drop 
-  setAcceptDrops(true); // attempt
-  dragInfo.state = diNone;
-
-  setFocusPolicy( Qt::WheelFocus );
-
-  // enable input method support
-  setAttribute(Qt::WA_InputMethodEnabled, true);
-
-  // this is an important optimization, it tells Qt
-  // that TerminalDisplay will handle repainting its entire area.
-  setAttribute(Qt::WA_OpaquePaintEvent);
-
-  _gridLayout = new QGridLayout(this);
-  _gridLayout->setMargin(0);
-
-  setLayout( _gridLayout ); 
-
-  //set up a warning message when the user presses Ctrl+S to avoid confusion
-  connect( this,SIGNAL(flowControlKeyPressed(bool)),this,SLOT(outputSuspended(bool)) );
-}
-
-TerminalDisplay::~TerminalDisplay()
-{
-  qApp->removeEventFilter( this );
-  
-  delete[] _image;
-
-  delete _gridLayout;
-  delete _outputSuspendedLabel;
-  delete _filterChain;
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                             Display Operations                            */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/**
- A table for emulating the simple (single width) unicode drawing chars.
- It represents the 250x - 257x glyphs. If it's zero, we can't use it.
- if it's not, it's encoded as follows: imagine a 5x5 grid where the points are numbered
- 0 to 24 left to top, top to bottom. Each point is represented by the corresponding bit.
-
- Then, the pixels basically have the following interpretation:
- _|||_
- -...-
- -...-
- -...-
- _|||_
-
-where _ = none
-      | = vertical line.
-      - = horizontal line.
- */
-
-
-enum LineEncode
-{
-    TopL  = (1<<1),
-    TopC  = (1<<2),
-    TopR  = (1<<3),
-
-    LeftT = (1<<5),
-    Int11 = (1<<6),
-    Int12 = (1<<7),
-    Int13 = (1<<8),
-    RightT = (1<<9),
-
-    LeftC = (1<<10),
-    Int21 = (1<<11),
-    Int22 = (1<<12),
-    Int23 = (1<<13),
-    RightC = (1<<14),
-
-    LeftB = (1<<15),
-    Int31 = (1<<16),
-    Int32 = (1<<17),
-    Int33 = (1<<18),
-    RightB = (1<<19),
-
-    BotL  = (1<<21),
-    BotC  = (1<<22),
-    BotR  = (1<<23)
-};
-
-#include "LineFont.h"
-
-static void drawLineChar(QPainter& paint, int x, int y, int w, int h, uchar code)
-{
-    //Calculate cell midpoints, end points.
-    int cx = x + w/2;
-    int cy = y + h/2;
-    int ex = x + w - 1;
-    int ey = y + h - 1;
-
-    quint32 toDraw = LineChars[code];
-
-    //Top _lines:
-    if (toDraw & TopL)
-        paint.drawLine(cx-1, y, cx-1, cy-2);
-    if (toDraw & TopC)
-        paint.drawLine(cx, y, cx, cy-2);
-    if (toDraw & TopR)
-        paint.drawLine(cx+1, y, cx+1, cy-2);
-
-    //Bot _lines:
-    if (toDraw & BotL)
-        paint.drawLine(cx-1, cy+2, cx-1, ey);
-    if (toDraw & BotC)
-        paint.drawLine(cx, cy+2, cx, ey);
-    if (toDraw & BotR)
-        paint.drawLine(cx+1, cy+2, cx+1, ey);
-
-    //Left _lines:
-    if (toDraw & LeftT)
-        paint.drawLine(x, cy-1, cx-2, cy-1);
-    if (toDraw & LeftC)
-        paint.drawLine(x, cy, cx-2, cy);
-    if (toDraw & LeftB)
-        paint.drawLine(x, cy+1, cx-2, cy+1);
-
-    //Right _lines:
-    if (toDraw & RightT)
-        paint.drawLine(cx+2, cy-1, ex, cy-1);
-    if (toDraw & RightC)
-        paint.drawLine(cx+2, cy, ex, cy);
-    if (toDraw & RightB)
-        paint.drawLine(cx+2, cy+1, ex, cy+1);
-
-    //Intersection points.
-    if (toDraw & Int11)
-        paint.drawPoint(cx-1, cy-1);
-    if (toDraw & Int12)
-        paint.drawPoint(cx, cy-1);
-    if (toDraw & Int13)
-        paint.drawPoint(cx+1, cy-1);
-
-    if (toDraw & Int21)
-        paint.drawPoint(cx-1, cy);
-    if (toDraw & Int22)
-        paint.drawPoint(cx, cy);
-    if (toDraw & Int23)
-        paint.drawPoint(cx+1, cy);
-
-    if (toDraw & Int31)
-        paint.drawPoint(cx-1, cy+1);
-    if (toDraw & Int32)
-        paint.drawPoint(cx, cy+1);
-    if (toDraw & Int33)
-        paint.drawPoint(cx+1, cy+1);
-
-}
-
-void TerminalDisplay::drawLineCharString(	QPainter& painter, int x, int y, const QString& str, 
-									const Character* attributes)
-{
-		const QPen& currentPen = painter.pen();
-		
-		if ( attributes->rendition & RE_BOLD )
-		{
-			QPen boldPen(currentPen);
-			boldPen.setWidth(3);
-			painter.setPen( boldPen );
-		}	
-		
-		for (int i=0 ; i < str.length(); i++)
-		{
-			uchar code = str[i].cell();
-        	if (LineChars[code])
-            	drawLineChar(painter, x + (_fontWidth*i), y, _fontWidth, _fontHeight, code);
-		}
-
-		painter.setPen( currentPen );
-}
-
-void TerminalDisplay::setKeyboardCursorShape(KeyboardCursorShape shape)
-{
-    _cursorShape = shape;
-}
-TerminalDisplay::KeyboardCursorShape TerminalDisplay::keyboardCursorShape() const
-{
-    return _cursorShape;
-}
-void TerminalDisplay::setKeyboardCursorColor(bool useForegroundColor, const QColor& color)
-{
-    if (useForegroundColor)
-        _cursorColor = QColor(); // an invalid color means that
-                                 // the foreground color of the
-                                 // current character should
-                                 // be used
-
-    else
-        _cursorColor = color;
-}
-QColor TerminalDisplay::keyboardCursorColor() const
-{
-    return _cursorColor;
-}
-
-void TerminalDisplay::setOpacity(qreal opacity)
-{
-    QColor color(_blendColor);
-    color.setAlphaF(opacity);
-
-    // enable automatic background filling to prevent the display
-    // flickering if there is no transparency
-    if ( color.alpha() == 255 ) 
-    {
-        setAutoFillBackground(true);
-    }
-    else
-    {
-        setAutoFillBackground(false);
-    }
-
-    _blendColor = color.rgba();
-}
-
-void TerminalDisplay::drawBackground(QPainter& painter, const QRect& rect, const QColor& backgroundColor, bool useOpacitySetting )
-{
-        // the area of the widget showing the contents of the terminal display is drawn
-        // using the background color from the color scheme set with setColorTable()
-        //
-        // the area of the widget behind the scroll-bar is drawn using the background
-        // brush from the scroll-bar's palette, to give the effect of the scroll-bar
-        // being outside of the terminal display and visual consistency with other KDE
-        // applications.  
-        //
-        QRect scrollBarArea = _scrollBar->isVisible() ? 
-                                    rect.intersected(_scrollBar->geometry()) :
-                                    QRect();
-        QRegion contentsRegion = QRegion(rect).subtracted(scrollBarArea);
-        QRect contentsRect = contentsRegion.boundingRect();
-
-        if ( HAVE_TRANSPARENCY && qAlpha(_blendColor) < 0xff && useOpacitySetting ) 
-        {
-            QColor color(backgroundColor);
-            color.setAlpha(qAlpha(_blendColor));
-
-            painter.save();
-            painter.setCompositionMode(QPainter::CompositionMode_Source);
-            painter.fillRect(contentsRect, color);
-            painter.restore();
-        } 
-        else {
-	    painter.fillRect(contentsRect, backgroundColor);
-	}
-
-        painter.fillRect(scrollBarArea,_scrollBar->palette().background());
-}
-
-void TerminalDisplay::drawCursor(QPainter& painter, 
-                                 const QRect& rect,
-                                 const QColor& foregroundColor,
-                                 const QColor& /*backgroundColor*/,
-                                 bool& invertCharacterColor)
-{
-    QRect cursorRect = rect;
-    cursorRect.setHeight(_fontHeight - _lineSpacing - 1);
-    
-    if (!_cursorBlinking)
-    {
-       if ( _cursorColor.isValid() )
-           painter.setPen(_cursorColor);
-       else {
-    	    painter.setPen(foregroundColor);
-	}
-
-       if ( _cursorShape == BlockCursor )
-       {
-            // draw the cursor outline, adjusting the area so that
-            // it is draw entirely inside 'rect'
-            int penWidth = qMax(1,painter.pen().width());
-
-            painter.drawRect(cursorRect.adjusted(penWidth/2,
-                                                 penWidth/2,
-                                                 - penWidth/2 - penWidth%2,
-                                                 - penWidth/2 - penWidth%2));
-            if ( hasFocus() )
-            {
-                painter.fillRect(cursorRect, _cursorColor.isValid() ? _cursorColor : foregroundColor);
-	    
-                if ( !_cursorColor.isValid() )
-                {
-                    // invert the colour used to draw the text to ensure that the character at
-                    // the cursor position is readable
-                    invertCharacterColor = true;
-                }
-            }
-       }
-       else if ( _cursorShape == UnderlineCursor )
-            painter.drawLine(cursorRect.left(),
-                             cursorRect.bottom(),
-                             cursorRect.right(),
-                             cursorRect.bottom());
-       else if ( _cursorShape == IBeamCursor )
-            painter.drawLine(cursorRect.left(),
-                             cursorRect.top(),
-                             cursorRect.left(),
-                             cursorRect.bottom());
-    
-    }
-}
-
-void TerminalDisplay::drawCharacters(QPainter& painter,
-                                     const QRect& rect,
-                                     const QString& text,
-                                     const Character* style,
-                                     bool invertCharacterColor)
-{
-    // don't draw text which is currently blinking
-    if ( _blinking && (style->rendition & RE_BLINK) )
-            return;
-   
-    // setup bold and underline
-    bool useBold = style->rendition & RE_BOLD || style->isBold(_colorTable) || font().bold();
-    bool useUnderline = style->rendition & RE_UNDERLINE || font().underline();
-
-    QFont font = painter.font();
-    if (    font.bold() != useBold 
-         || font.underline() != useUnderline )
-    {
-       font.setBold(useBold);
-       font.setUnderline(useUnderline);
-       painter.setFont(font);
-    }
-
-    const CharacterColor& textColor = ( invertCharacterColor ? style->backgroundColor : style->foregroundColor );
-    const QColor color = textColor.color(_colorTable);
-
-    QPen pen = painter.pen();
-    if ( pen.color() != color )
-    {
-        pen.setColor(color);
-        painter.setPen(color);
-    }
-    // draw text
-    if ( isLineCharString(text) ) {
-	  	drawLineCharString(painter,rect.x(),rect.y(),text,style);
-    }
-    else
-	{
-		// the drawText(rect,flags,string) overload is used here with null flags
-		// instead of drawText(rect,string) because the (rect,string) overload causes 
-		// the application's default layout direction to be used instead of 
-		// the widget-specific layout direction, which should always be
-		// Qt::LeftToRight for this widget
-        painter.drawText(rect,0,text);
-	}
-}
-
-void TerminalDisplay::drawTextFragment(QPainter& painter , 
-                                       const QRect& rect,
-                                       const QString& text, 
-                                       const Character* style)
-{
-    painter.save();
-
-    // setup painter 
-    const QColor foregroundColor = style->foregroundColor.color(_colorTable);
-    const QColor backgroundColor = style->backgroundColor.color(_colorTable);
-    
-    // draw background if different from the display's background color
-    if ( backgroundColor != palette().background().color() )
-        drawBackground(painter,rect,backgroundColor, false /* do not use transparency */);
-
-    // draw cursor shape if the current character is the cursor
-    // this may alter the foreground and background colors
-    bool invertCharacterColor = false;
-
-    if ( style->rendition & RE_CURSOR )
-        drawCursor(painter,rect,foregroundColor,backgroundColor,invertCharacterColor);
-    // draw text
-    drawCharacters(painter,rect,text,style,invertCharacterColor);
-
-    painter.restore();
-}
-
-void TerminalDisplay::setRandomSeed(uint randomSeed) { _randomSeed = randomSeed; }
-uint TerminalDisplay::randomSeed() const { return _randomSeed; }
-
-#if 0
-/*!
-    Set XIM Position
-*/
-void TerminalDisplay::setCursorPos(const int curx, const int cury)
-{
-    QPoint tL  = contentsRect().topLeft();
-    int    tLx = tL.x();
-    int    tLy = tL.y();
-
-    int xpos, ypos;
-    ypos = _topMargin + tLy + _fontHeight*(cury-1) + _fontAscent;
-    xpos = _leftMargin + tLx + _fontWidth*curx;
-    //setMicroFocusHint(xpos, ypos, 0, _fontHeight); //### ???
-    // fprintf(stderr, "x/y = %d/%d\txpos/ypos = %d/%d\n", curx, cury, xpos, ypos);
-    _cursorLine = cury;
-    _cursorCol = curx;
-}
-#endif
-
-// 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() 
-// 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
-//
-// 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 (_leftMargin,_topMargin) , 
-// a cell width of _fontWidth and a cell height of _fontHeight).    
-void TerminalDisplay::scrollImage(int lines , const QRect& screenWindowRegion)
-{
-	// if the flow control warning is enabled this will interfere with the 
-	// scrolling optimisations and cause artifacts.  the simple solution here
-	// is to just disable the optimisation whilst it is visible
-	if ( _outputSuspendedLabel && _outputSuspendedLabel->isVisible() ) {
-		return;
-	}
-
-    // constrain the region to the display
-    // the bottom of the region is capped to the number of lines in the display's
-    // internal image - 2, so that the height of 'region' is strictly less
-    // than the height of the internal image.
-    QRect region = screenWindowRegion;
-    region.setBottom( qMin(region.bottom(),this->_lines-2) ); 
-
-    if (    lines == 0 
-         || _image == 0
-         || !region.isValid() 
-         || (region.top() + abs(lines)) >= region.bottom() 
-         || this->_lines <= region.height() ) return;
-
-    QRect scrollRect;
-
-    void* firstCharPos = &_image[ region.top() * this->_columns ];
-    void* lastCharPos = &_image[ (region.top() + abs(lines)) * this->_columns ];
-
-    int top = _topMargin + (region.top() * _fontHeight);
-    int linesToMove = region.height() - abs(lines);
-    int bytesToMove = linesToMove * 
-                      this->_columns *
-                      sizeof(Character);
-
-    Q_ASSERT( linesToMove > 0 );
-    Q_ASSERT( bytesToMove > 0 );
-
-    //scroll internal image
-    if ( lines > 0 )
-    {
-        // check that the memory areas that we are going to move are valid
-        Q_ASSERT( (char*)lastCharPos + bytesToMove < 
-                  (char*)(_image + (this->_lines * this->_columns)) );
-        
-        Q_ASSERT( (lines*this->_columns) < _imageSize ); 
-
-        //scroll internal image down
-        memmove( firstCharPos , lastCharPos , bytesToMove ); 
-      
-        //set region of display to scroll, making sure that
-        //the region aligns correctly to the character grid 
-        scrollRect = QRect( _leftMargin , top, 
-                            this->_usedColumns * _fontWidth , 
-                            linesToMove * _fontHeight );
-    }
-    else
-    {
-        // check that the memory areas that we are going to move are valid
-        Q_ASSERT( (char*)firstCharPos + bytesToMove < 
-                  (char*)(_image + (this->_lines * this->_columns)) );
-
-        //scroll internal image up
-        memmove( lastCharPos , firstCharPos , bytesToMove ); 
-     
-        //set region of the display to scroll, making sure that
-        //the region aligns correctly to the character grid
-        QPoint topPoint( _leftMargin , top + abs(lines)*_fontHeight );
-
-        scrollRect = QRect( topPoint ,
-                     QSize( this->_usedColumns*_fontWidth , 
-                            linesToMove * _fontHeight ));
-    }
-
-    //scroll the display vertically to match internal _image
-    scroll( 0 , _fontHeight * (-lines) , scrollRect );
-}
-
-QRegion TerminalDisplay::hotSpotRegion() const 
-{
-	QRegion region;
-	foreach( Filter::HotSpot* hotSpot , _filterChain->hotSpots() )
-	{
-		QRect rect;
-		rect.setLeft(hotSpot->startColumn());
-		rect.setTop(hotSpot->startLine());
-		rect.setRight(hotSpot->endColumn());
-		rect.setBottom(hotSpot->endLine());
-
-		region |= imageToWidget(rect); 
-	}
-	return region;
-}
-
-void TerminalDisplay::processFilters() 
-{
-	if (!_screenWindow)
-		return;
-
-	QRegion preUpdateHotSpots = hotSpotRegion();
-
-	// use _screenWindow->getImage() here rather than _image because
-	// other classes may call processFilters() when this display's
-	// ScreenWindow emits a scrolled() signal - which will happen before
-	// updateImage() is called on the display and therefore _image is 
-	// out of date at this point
-	_filterChain->setImage( _screenWindow->getImage(),
-							_screenWindow->windowLines(),
-							_screenWindow->windowColumns(),
-							_screenWindow->getLineProperties() );
-    _filterChain->process();
-
-	QRegion postUpdateHotSpots = hotSpotRegion();
-
-	update( preUpdateHotSpots | postUpdateHotSpots );
-}
-
-void TerminalDisplay::updateImage() 
-{
-  if ( !_screenWindow )
-      return;
-
-  // 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() ,
-               _screenWindow->scrollRegion() );
-  _screenWindow->resetScrollCount();
-
-  Character* const newimg = _screenWindow->getImage();
-  int lines = _screenWindow->windowLines();
-  int columns = _screenWindow->windowColumns();
-
-  setScroll( _screenWindow->currentLine() , _screenWindow->lineCount() );
-
-  if (!_image)
-     updateImageSize(); // Create _image
-
-  Q_ASSERT( this->_usedLines <= this->_lines );
-  Q_ASSERT( this->_usedColumns <= this->_columns );
-
-  int y,x,len;
-
-  QPoint tL  = contentsRect().topLeft();
-
-  int    tLx = tL.x();
-  int    tLy = tL.y();
-  _hasBlinker = false;
-
-  CharacterColor cf;       // undefined
-  CharacterColor _clipboard;       // undefined
-  int cr  = -1;   // undefined
-
-  const int linesToUpdate = qMin(this->_lines, qMax(0,lines  ));
-  const int columnsToUpdate = qMin(this->_columns,qMax(0,columns));
-
-  QChar *disstrU = new QChar[columnsToUpdate];
-  char *dirtyMask = new char[columnsToUpdate+2]; 
-  QRegion dirtyRegion;
-
-  // debugging variable, this records the number of lines that are found to
-  // be 'dirty' ( ie. have changed from the old _image to the new _image ) and
-  // which therefore need to be repainted
-  int dirtyLineCount = 0;
-
-  for (y = 0; y < linesToUpdate; y++)
-  {
-    const Character*       currentLine = &_image[y*this->_columns];
-    const Character* const newLine = &newimg[y*columns];
-
-    bool updateLine = false;
-    
-    // The dirty mask indicates which characters need repainting. We also
-    // mark surrounding neighbours dirty, in case the character exceeds
-    // its cell boundaries
-    memset(dirtyMask, 0, columnsToUpdate+2);
-   
-    for( x = 0 ; x < columnsToUpdate ; x++)
-    {
-        if ( newLine[x] != currentLine[x] ) 
-        {
-            dirtyMask[x] = true;
-        }
-    }
-
-    if (!_resizing) // not while _resizing, we're expecting a paintEvent
-    for (x = 0; x < columnsToUpdate; x++)
-    {
-      _hasBlinker |= (newLine[x].rendition & RE_BLINK);
-    
-      // Start drawing if this character or the next one differs.
-      // We also take the next one into account to handle the situation
-      // where characters exceed their cell width.
-      if (dirtyMask[x])
-      {
-        quint16 c = newLine[x+0].character;
-        if ( !c )
-            continue;
-        int p = 0;
-        disstrU[p++] = c; //fontMap(c);
-        bool lineDraw = isLineChar(c);
-        bool doubleWidth = (x+1 == columnsToUpdate) ? false : (newLine[x+1].character == 0);
-        cr = newLine[x].rendition;
-        _clipboard = newLine[x].backgroundColor;
-        if (newLine[x].foregroundColor != cf) cf = newLine[x].foregroundColor;
-        int lln = columnsToUpdate - x;
-        for (len = 1; len < lln; len++)
-        {
-            const Character& ch = newLine[x+len];
-
-            if (!ch.character)
-                continue; // Skip trailing part of multi-col chars.
-
-			bool nextIsDoubleWidth = (x+len+1 == columnsToUpdate) ? false : (newLine[x+len+1].character == 0);
-
-            if (  ch.foregroundColor != cf || 
-                  ch.backgroundColor != _clipboard || 
-                  ch.rendition != cr ||
-                  !dirtyMask[x+len] || 
-                  isLineChar(c) != lineDraw || 
-                  nextIsDoubleWidth != doubleWidth )
-            break;
-
-          disstrU[p++] = c; //fontMap(c);
-        }
-
-        QString unistr(disstrU, p);
-
-        bool saveFixedFont = _fixedFont;
-        if (lineDraw)
-           _fixedFont = false;
-        if (doubleWidth)
-           _fixedFont = false;
-
-		updateLine = true;
-
-		_fixedFont = saveFixedFont;
-        x += len - 1;
-      }
-      
-    }
-
-	//both the top and bottom halves of double height _lines must always be redrawn
-	//although both top and bottom halves contain the same characters, only 
-    //the top one is actually 
-	//drawn.
-    if (_lineProperties.count() > y)
-        updateLine |= (_lineProperties[y] & LINE_DOUBLEHEIGHT);
-
-    // if the characters on the line are different in the old and the new _image
-    // then this line must be repainted.    
-    if (updateLine)
-    {
-        dirtyLineCount++;
-
-        // add the area occupied by this line to the region which needs to be
-        // repainted
-        QRect dirtyRect = QRect( _leftMargin+tLx , 
-                                 _topMargin+tLy+_fontHeight*y , 
-                                 _fontWidth * columnsToUpdate , 
-                                 _fontHeight ); 	
-
-        dirtyRegion |= dirtyRect;
-    }
-
-    // replace the line of characters in the old _image with the 
-    // current line of the new _image 
-    memcpy((void*)currentLine,(const void*)newLine,columnsToUpdate*sizeof(Character));
-  }
-
-  // if the new _image is smaller than the previous _image, then ensure that the area
-  // outside the new _image is cleared 
-  if ( linesToUpdate < _usedLines )
-  {
-    dirtyRegion |= QRect(   _leftMargin+tLx , 
-                            _topMargin+tLy+_fontHeight*linesToUpdate , 
-                            _fontWidth * this->_columns , 
-                            _fontHeight * (_usedLines-linesToUpdate) );
-  }
-  _usedLines = linesToUpdate;
-  
-  if ( columnsToUpdate < _usedColumns )
-  {
-    dirtyRegion |= QRect(   _leftMargin+tLx+columnsToUpdate*_fontWidth , 
-                            _topMargin+tLy , 
-                            _fontWidth * (_usedColumns-columnsToUpdate) , 
-                            _fontHeight * this->_lines );
-  }
-  _usedColumns = columnsToUpdate;
-
-  dirtyRegion |= _inputMethodData.previousPreeditRect;
-
-  // update the parts of the display which have changed
-  update(dirtyRegion);
-
-  if ( _hasBlinker && !_blinkTimer->isActive()) _blinkTimer->start( BLINK_DELAY ); 
-  if (!_hasBlinker && _blinkTimer->isActive()) { _blinkTimer->stop(); _blinking = false; }
-  delete[] dirtyMask;
-  delete[] disstrU;
-
-}
-
-void TerminalDisplay::showResizeNotification()
-{
-  if (_terminalSizeHint && isVisible())
-  {
-     if (_terminalSizeStartup) {
-       		_terminalSizeStartup=false;
-       return;
-     }
-     if (!_resizeWidget)
-     {
-        _resizeWidget = new QLabel(("Size: XXX x XXX"), this);
-        _resizeWidget->setMinimumWidth(_resizeWidget->fontMetrics().width(("Size: XXX x XXX")));
-        _resizeWidget->setMinimumHeight(_resizeWidget->sizeHint().height());
-		_resizeWidget->setAlignment(Qt::AlignCenter);
-
-        _resizeWidget->setStyleSheet("background-color:palette(window);border-style:solid;border-width:1px;border-color:palette(dark)");
-
-		_resizeTimer = new QTimer(this);
-		_resizeTimer->setSingleShot(true);
-        connect(_resizeTimer, SIGNAL(timeout()), _resizeWidget, SLOT(hide()));
-
-     }
-     QString sizeStr;
-     sizeStr.sprintf("Size: %d x %d", _columns, _lines);
-     _resizeWidget->setText(sizeStr);
-     _resizeWidget->move((width()-_resizeWidget->width())/2,
-                         (height()-_resizeWidget->height())/2+20);
-     _resizeWidget->show();
-     _resizeTimer->start(1000);
-  }
-}
-
-void TerminalDisplay::setBlinkingCursor(bool blink)
-{
-  _hasBlinkingCursor=blink;
-  
-  if (blink && !_blinkCursorTimer->isActive()) 
-      _blinkCursorTimer->start(BLINK_DELAY);
-  
-  if (!blink && _blinkCursorTimer->isActive()) 
-  {
-    _blinkCursorTimer->stop();
-    if (_cursorBlinking)
-      blinkCursorEvent();
-    else
-      _cursorBlinking = false;
-  }
-}
-
-void TerminalDisplay::paintEvent( QPaintEvent* pe )
-{
-//qDebug("%s %d paintEvent", __FILE__, __LINE__);
-  QPainter paint(this);
-
-  foreach (QRect rect, (pe->region() & contentsRect()).rects())
-  {
-    drawBackground(paint,rect,palette().background().color(),	true /* use opacity setting */);
-    drawContents(paint, rect);    
-  }
-//    drawBackground(paint,contentsRect(),palette().background().color(),	true /* use opacity setting */);
-//    drawContents(paint, contentsRect());    
-  drawInputMethodPreeditString(paint,preeditRect());
-  paintFilters(paint);
-
-  paint.end();
-}
-
-QPoint TerminalDisplay::cursorPosition() const
-{
-	if (_screenWindow)
-		return _screenWindow->cursorPosition();
-	else
-		return QPoint(0,0);
-}
-
-QRect TerminalDisplay::preeditRect() const
-{
-    const int preeditLength = string_width(_inputMethodData.preeditString);
-
-    if ( preeditLength == 0 )
-        return QRect();
-
-    return QRect(_leftMargin + _fontWidth*cursorPosition().x(),
-                 _topMargin + _fontHeight*cursorPosition().y(),
-                 _fontWidth*preeditLength,
-                 _fontHeight);
-}   
-
-void TerminalDisplay::drawInputMethodPreeditString(QPainter& painter , const QRect& rect)
-{
-    if ( _inputMethodData.preeditString.isEmpty() ) {
-        return;
-    }
-    const QPoint cursorPos = cursorPosition(); 
-
-    bool invertColors = false;
-    const QColor background = _colorTable[DEFAULT_BACK_COLOR].color;
-    const QColor foreground = _colorTable[DEFAULT_FORE_COLOR].color;
-    const Character* style = &_image[loc(cursorPos.x(),cursorPos.y())];
-
-    drawBackground(painter,rect,background,true);
-    drawCursor(painter,rect,foreground,background,invertColors);
-    drawCharacters(painter,rect,_inputMethodData.preeditString,style,invertColors);
-
-    _inputMethodData.previousPreeditRect = rect; 
-}
-
-FilterChain* TerminalDisplay::filterChain() const
-{
-    return _filterChain;
-}
-
-void TerminalDisplay::paintFilters(QPainter& painter)
-{
-//qDebug("%s %d paintFilters", __FILE__, __LINE__);
-
-    // get color of character under mouse and use it to draw
-    // lines for filters
-    QPoint cursorPos = mapFromGlobal(QCursor::pos());
-    int cursorLine;
-    int cursorColumn;
-    getCharacterPosition( cursorPos , cursorLine , cursorColumn );
-    Character cursorCharacter = _image[loc(cursorColumn,cursorLine)];
-
-    painter.setPen( QPen(cursorCharacter.foregroundColor.color(colorTable())) );
-
-    // iterate over hotspots identified by the display's currently active filters 
-    // and draw appropriate visuals to indicate the presence of the hotspot
-
-    QList<Filter::HotSpot*> spots = _filterChain->hotSpots();
-    QListIterator<Filter::HotSpot*> iter(spots);
-    while (iter.hasNext())
-    {
-        Filter::HotSpot* spot = iter.next();
-
-        for ( int line = spot->startLine() ; line <= spot->endLine() ; line++ )
-        {
-            int startColumn = 0;
-            int endColumn = _columns-1; // TODO use number of _columns which are actually 
-                                        // occupied on this line rather than the width of the 
-                                        // display in _columns
-
-            // ignore whitespace at the end of the lines
-            while ( QChar(_image[loc(endColumn,line)].character).isSpace() && endColumn > 0 )
-                endColumn--;
-              
-            // increment here because the column which we want to set 'endColumn' to
-            // is the first whitespace character at the end of the line
-            endColumn++;
-
-            if ( line == spot->startLine() )
-                startColumn = spot->startColumn();
-            if ( line == spot->endLine() )
-                endColumn = spot->endColumn();
-
-            // subtract one pixel from
-            // the right and bottom so that
-            // we do not overdraw adjacent
-            // hotspots
-            //
-            // subtracting one pixel from all sides also prevents an edge case where
-            // moving the mouse outside a link could still leave it underlined 
-            // because the check below for the position of the cursor
-            // finds it on the border of the target area
-            QRect r;
-            r.setCoords( startColumn*_fontWidth + 1, line*_fontHeight + 1,
-                             endColumn*_fontWidth - 1, (line+1)*_fontHeight - 1 ); 
-                                                                           
-            // Underline link hotspots 
-            if ( spot->type() == Filter::HotSpot::Link )
-            {
-                QFontMetrics metrics(font());
-        
-                // find the baseline (which is the invisible line that the characters in the font sit on,
-                // with some having tails dangling below)
-                int baseline = r.bottom() - metrics.descent();
-                // find the position of the underline below that
-                int underlinePos = baseline + metrics.underlinePos();
-
-                if ( r.contains( mapFromGlobal(QCursor::pos()) ) )
-                    painter.drawLine( r.left() , underlinePos , 
-                                      r.right() , underlinePos );
-            }
-            // Marker hotspots simply have a transparent rectanglular shape
-            // drawn on top of them
-            else if ( spot->type() == Filter::HotSpot::Marker )
-            {
-            //TODO - Do not use a hardcoded colour for this
-                painter.fillRect(r,QBrush(QColor(255,0,0,120)));
-            }
-        }
-    }
-}
-void TerminalDisplay::drawContents(QPainter &paint, const QRect &rect)
-{
-//qDebug("%s %d drawContents and rect x=%d y=%d w=%d h=%d", __FILE__, __LINE__, rect.x(), rect.y(),rect.width(),rect.height());
-
-  QPoint tL  = contentsRect().topLeft();
-//  int    tLx = tL.x();
-  int    tLy = tL.y();
-
-  int tLx = (_contentWidth - _usedColumns * _fontWidth)/2;
-//  int tLy = (_contentHeight - _usedLines * _fontHeight)/2; 
-//qDebug("%d %d %d %d", tLx, tLy, _contentWidth, _usedColumns * _fontWidth);  
-
-  int lux = qMin(_usedColumns-1, qMax(0,(rect.left()   - tLx - _leftMargin ) / _fontWidth));
-  int luy = qMin(_usedLines-1,  qMax(0, (rect.top()    - tLy - _topMargin  ) / _fontHeight));
-  int rlx = qMin(_usedColumns-1, qMax(0, (rect.right()  - tLx - _leftMargin ) / _fontWidth));
-  int rly = qMin(_usedLines-1,  qMax(0, (rect.bottom() - tLy - _topMargin  ) / _fontHeight));
-
-  const int bufferSize = _usedColumns;
-  QChar *disstrU = new QChar[bufferSize];
-  for (int y = luy; y <= rly; y++)
-  {
-    quint16 c = _image[loc(lux,y)].character;
-    int x = lux;
-    if(!c && x)
-      x--; // Search for start of multi-column character
-    for (; x <= rlx; x++)
-    {
-      int len = 1;
-      int p = 0;
-
-      // is this a single character or a sequence of characters ?
-      if ( _image[loc(x,y)].rendition & RE_EXTENDED_CHAR )
-      {
-        // sequence of characters
-        ushort extendedCharLength = 0;
-        ushort* chars = ExtendedCharTable::instance
-                            .lookupExtendedChar(_image[loc(x,y)].charSequence,extendedCharLength);
-        for ( int index = 0 ; index < extendedCharLength ; index++ ) 
-        {
-            Q_ASSERT( p < bufferSize );
-            disstrU[p++] = chars[index];
-        }
-      }
-      else
-      {
-        // single character
-        c = _image[loc(x,y)].character;
-        if (c)
-        {
-             Q_ASSERT( p < bufferSize );
-             disstrU[p++] = c; //fontMap(c);
-        }
-      }
-
-      bool lineDraw = isLineChar(c);
-      bool doubleWidth = (_image[ qMin(loc(x,y)+1,_imageSize) ].character == 0);
-      CharacterColor currentForeground = _image[loc(x,y)].foregroundColor;
-      CharacterColor currentBackground = _image[loc(x,y)].backgroundColor;
-      quint8 currentRendition = _image[loc(x,y)].rendition;
-	  
-      while (x+len <= rlx &&
-             _image[loc(x+len,y)].foregroundColor == currentForeground &&
-             _image[loc(x+len,y)].backgroundColor == currentBackground &&
-             _image[loc(x+len,y)].rendition == currentRendition &&
-             (_image[ qMin(loc(x+len,y)+1,_imageSize) ].character == 0) == doubleWidth &&
-             isLineChar( c = _image[loc(x+len,y)].character) == lineDraw) // Assignment!
-      {
-        if (c)
-          disstrU[p++] = c; //fontMap(c);
-        if (doubleWidth) // assert((_image[loc(x+len,y)+1].character == 0)), see above if condition
-          len++; // Skip trailing part of multi-column character
-        len++;
-      }
-      if ((x+len < _usedColumns) && (!_image[loc(x+len,y)].character))
-        len++; // Adjust for trailing part of multi-column character
-
-   	     bool save__fixedFont = _fixedFont;
-         if (lineDraw)
-            _fixedFont = false;
-         if (doubleWidth)
-            _fixedFont = false;
-         QString unistr(disstrU,p);
-		 
-		 if (y < _lineProperties.size())
-		 {
-			if (_lineProperties[y] & LINE_DOUBLEWIDTH) {
-				paint.scale(2,1);
-			}
-			
-			if (_lineProperties[y] & LINE_DOUBLEHEIGHT) {
-  		 		paint.scale(1,2);
-			}
-		 }
-
-		 //calculate the area in which the text will be drawn
-		 QRect textArea = QRect( _leftMargin+tLx+_fontWidth*x , 
-					_topMargin+tLy+_fontHeight*y , 
-					_fontWidth*len, 
-					_fontHeight);
-		
-		 //move the calculated area to take account of scaling applied to the painter.
-		 //the position of the area from the origin (0,0) is scaled 
-         //by the opposite of whatever
-		 //transformation has been applied to the painter.  this ensures that 
-		 //painting does actually start from textArea.topLeft() 
-         //(instead of textArea.topLeft() * painter-scale)	
-		 QMatrix inverted = paint.matrix().inverted();
-//		 textArea.moveTopLeft( inverted.map(textArea.topLeft()) );
-		 textArea.moveCenter( inverted.map(textArea.center()) );
-
-		 
-		 //paint text fragment
-         drawTextFragment(	paint,
-                		    textArea,
-                		    unistr, 
-					    	&_image[loc(x,y)] ); //, 
-						    //0, 
-						    //!_isPrinting );
-         
-		 _fixedFont = save__fixedFont;
-     
-		 //reset back to single-width, single-height _lines 
-		 paint.resetMatrix();
-
-		 if (y < _lineProperties.size()-1)
-		 {
-			//double-height _lines are represented by two adjacent _lines 
-            //containing the same characters
-			//both _lines will have the LINE_DOUBLEHEIGHT attribute.  
-            //If the current line has the LINE_DOUBLEHEIGHT attribute, 
-            //we can therefore skip the next line
-			if (_lineProperties[y] & LINE_DOUBLEHEIGHT)
-				y++;
-		 }
-		 
-	    x += len - 1;
-    }
-  }
-  delete [] disstrU;
-}
-
-void TerminalDisplay::blinkEvent()
-{
-  _blinking = !_blinking;
-
-  //TODO:  Optimise to only repaint the areas of the widget 
-  // where there is blinking text
-  // rather than repainting the whole widget.
-  update();
-}
-
-QRect TerminalDisplay::imageToWidget(const QRect& imageArea) const
-{
-//qDebug("%s %d imageToWidget", __FILE__, __LINE__);
-    QRect result;
-    result.setLeft( _leftMargin + _fontWidth * imageArea.left() );
-    result.setTop( _topMargin + _fontHeight * imageArea.top() );
-    result.setWidth( _fontWidth * imageArea.width() );
-    result.setHeight( _fontHeight * imageArea.height() );
-
-    return result;
-}
-
-void TerminalDisplay::blinkCursorEvent()
-{
-  _cursorBlinking = !_cursorBlinking;
-
-  QRect cursorRect = imageToWidget( QRect(cursorPosition(),QSize(1,1)) ); 
-
-  update(cursorRect);
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                                  Resizing                                 */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-void TerminalDisplay::resizeEvent(QResizeEvent*)
-{
-  updateImageSize();
-}
-
-void TerminalDisplay::propagateSize()
-{
-  if (_isFixedSize)
-  {
-     setSize(_columns, _lines);
-     QWidget::setFixedSize(sizeHint());
-     parentWidget()->adjustSize();
-     parentWidget()->setFixedSize(parentWidget()->sizeHint());
-     return;
-  }
-  if (_image)
-     updateImageSize();
-}
-
-void TerminalDisplay::updateImageSize()
-{
-//qDebug("%s %d updateImageSize", __FILE__, __LINE__);
-  Character* oldimg = _image;
-  int oldlin = _lines;
-  int oldcol = _columns;
-
-  makeImage();
-
-  
-  // copy the old image to reduce flicker
-  int lines = qMin(oldlin,_lines);
-  int columns = qMin(oldcol,_columns);
-
-  if (oldimg)
-  {
-    for (int line = 0; line < lines; line++) 
-    {
-      memcpy((void*)&_image[_columns*line],
-             (void*)&oldimg[oldcol*line],columns*sizeof(Character));
-    }
-    delete[] oldimg;
-  }
-
-  if (_screenWindow)
-  	_screenWindow->setWindowLines(_lines);
-
-  _resizing = (oldlin!=_lines) || (oldcol!=_columns);
-
-  if ( _resizing )
-  {
-  	showResizeNotification();
-    emit changedContentSizeSignal(_contentHeight, _contentWidth); // expose resizeEvent
-  }
-  
-  _resizing = false;
-}
-
-//showEvent and hideEvent are reimplemented here so that it appears to other classes that the 
-//display has been resized when the display is hidden or shown.
-//
-//this allows  
-//TODO: Perhaps it would be better to have separate signals for show and hide instead of using
-//the same signal as the one for a content size change 
-void TerminalDisplay::showEvent(QShowEvent*)
-{
-    emit changedContentSizeSignal(_contentHeight,_contentWidth);
-}
-void TerminalDisplay::hideEvent(QHideEvent*)
-{
-    emit changedContentSizeSignal(_contentHeight,_contentWidth);
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                                Scrollbar                                  */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-void TerminalDisplay::scrollBarPositionChanged(int)
-{
-  if ( !_screenWindow ) 
-      return;
-
-  _screenWindow->scrollTo( _scrollBar->value() );
-
-  // if the thumb has been moved to the bottom of the _scrollBar then set
-  // the display to automatically track new output, 
-  // that is, scroll down automatically
-  // to how new _lines as they are added
-  const bool atEndOfOutput = (_scrollBar->value() == _scrollBar->maximum());
-  _screenWindow->setTrackOutput( atEndOfOutput );
-
-  updateImage();
-}
-
-void TerminalDisplay::setScroll(int cursor, int slines)
-{
-//qDebug("%s %d setScroll", __FILE__, __LINE__);
-  // update _scrollBar if the range or value has changed,
-  // otherwise return
-  //
-  // setting the range or value of a _scrollBar will always trigger
-  // a repaint, so it should be avoided if it is not necessary
-  if ( _scrollBar->minimum() == 0                 &&
-       _scrollBar->maximum() == (slines - _lines) &&
-       _scrollBar->value()   == cursor )
-  {
-        return;
-  }
-
-  disconnect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int)));
-  _scrollBar->setRange(0,slines - _lines);
-  _scrollBar->setSingleStep(1);
-  _scrollBar->setPageStep(_lines);
-  _scrollBar->setValue(cursor);
-  connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int)));
-}
-
-void TerminalDisplay::setScrollBarPosition(ScrollBarPosition position)
-{
-  if (_scrollbarLocation == position) {
-//      return; 
-  }
- 
-  if ( position == NoScrollBar )
-     _scrollBar->hide();
-  else 
-     _scrollBar->show(); 
-
-  _topMargin = _leftMargin = 1;
-  _scrollbarLocation = position;
-  
-  propagateSize();
-  update();
-}
-
-void TerminalDisplay::mousePressEvent(QMouseEvent* ev)
-{
-  if ( _possibleTripleClick && (ev->button()==Qt::LeftButton) ) {
-    mouseTripleClickEvent(ev);
-    return;
-  }
-
-  if ( !contentsRect().contains(ev->pos()) ) return;
-  
-  if ( !_screenWindow ) return;
-
-  int charLine;
-  int charColumn;
-  getCharacterPosition(ev->pos(),charLine,charColumn);
-  QPoint pos = QPoint(charColumn,charLine);
-
-  if ( ev->button() == Qt::LeftButton)
-  {
-    _lineSelectionMode = false;
-    _wordSelectionMode = false;
-
-    emit isBusySelecting(true); // Keep it steady...
-    // Drag only when the Control key is hold
-    bool selected = false;
-    
-    // The receiver of the testIsSelected() signal will adjust
-    // 'selected' accordingly.
-    //emit testIsSelected(pos.x(), pos.y(), selected);
-    
-    selected =  _screenWindow->isSelected(pos.x(),pos.y());
-
-    if ((!_ctrlDrag || ev->modifiers() & Qt::ControlModifier) && selected ) {
-      // The user clicked inside selected text
-      dragInfo.state = diPending;
-      dragInfo.start = ev->pos();
-    }
-    else {
-      // No reason to ever start a drag event
-      dragInfo.state = diNone;
-
-      _preserveLineBreaks = !( ( ev->modifiers() & Qt::ControlModifier ) && !(ev->modifiers() & Qt::AltModifier) );
-      _columnSelectionMode = (ev->modifiers() & Qt::AltModifier) && (ev->modifiers() & Qt::ControlModifier);
-
-      if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier))
-      {
-         _screenWindow->clearSelection();
-
-        //emit clearSelectionSignal();
-        pos.ry() += _scrollBar->value();
-        _iPntSel = _pntSel = pos;
-        _actSel = 1; // left mouse button pressed but nothing selected yet.
-        
-      }
-      else
-      {
-        emit mouseSignal( 0, charColumn + 1, charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 0);
-      }
-    }
-  }
-  else if ( ev->button() == Qt::MidButton )
-  {
-    if ( _mouseMarks || (!_mouseMarks && (ev->modifiers() & Qt::ShiftModifier)) )
-      emitSelection(true,ev->modifiers() & Qt::ControlModifier);
-    else
-      emit mouseSignal( 1, charColumn +1, charLine +1 +_scrollBar->value() -_scrollBar->maximum() , 0);
-  }
-  else if ( ev->button() == Qt::RightButton )
-  {
-    if (_mouseMarks || (ev->modifiers() & Qt::ShiftModifier)) 
-    {
-        emit configureRequest( this, 
-                               ev->modifiers() & (Qt::ShiftModifier|Qt::ControlModifier), 
-                               ev->pos()
-                             );
-    }
-    else
-      emit mouseSignal( 2, charColumn +1, charLine +1 +_scrollBar->value() -_scrollBar->maximum() , 0);
-  }
-}
-
-QList<QAction*> TerminalDisplay::filterActions(const QPoint& position)
-{
-  int charLine, charColumn;
-  getCharacterPosition(position,charLine,charColumn);
-
-  Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn);
-
-  return spot ? spot->actions() : QList<QAction*>();
-}
-
-void TerminalDisplay::mouseMoveEvent(QMouseEvent* ev)
-{
-  int charLine = 0;
-  int charColumn = 0;
-
-  getCharacterPosition(ev->pos(),charLine,charColumn); 
-
-  // handle filters
-  // change link hot-spot appearance on mouse-over
-  Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn);
-  if ( spot && spot->type() == Filter::HotSpot::Link)
-  {
-    QRect previousHotspotArea = _mouseOverHotspotArea;
-    _mouseOverHotspotArea.setCoords( qMin(spot->startColumn() , spot->endColumn()) * _fontWidth,
-                                     spot->startLine() * _fontHeight,
-                                     qMax(spot->startColumn() , spot->endColumn()) * _fontHeight,
-                                     (spot->endLine()+1) * _fontHeight );
-
-    // display tooltips when mousing over links
-    // TODO: Extend this to work with filter types other than links
-    const QString& tooltip = spot->tooltip();
-    if ( !tooltip.isEmpty() )
-    {
-        QToolTip::showText( mapToGlobal(ev->pos()) , tooltip , this , _mouseOverHotspotArea );
-    }
-
-    update( _mouseOverHotspotArea | previousHotspotArea );
-  }
-  else if ( _mouseOverHotspotArea.isValid() )
-  {
-        update( _mouseOverHotspotArea );
-        // set hotspot area to an invalid rectangle
-        _mouseOverHotspotArea = QRect();
-  }
-  
-  // for auto-hiding the cursor, we need mouseTracking
-  if (ev->buttons() == Qt::NoButton ) return;
-
-  // if the terminal is interested in mouse movements 
-  // then emit a mouse movement signal, unless the shift
-  // key is being held down, which overrides this.
-  if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier))
-  {
-	int button = 3;
-	if (ev->buttons() & Qt::LeftButton)
-		button = 0;
-	if (ev->buttons() & Qt::MidButton)
-		button = 1;
-	if (ev->buttons() & Qt::RightButton)
-		button = 2;
-
-        
-        emit mouseSignal( button, 
-                        charColumn + 1,
-                        charLine + 1 +_scrollBar->value() -_scrollBar->maximum(),
-			 1 );
-      
-	return;
-  }
-      
-  if (dragInfo.state == diPending) 
-  {
-    // we had a mouse down, but haven't confirmed a drag yet
-    // if the mouse has moved sufficiently, we will confirm
-
-   int distance = 10; //KGlobalSettings::dndEventDelay();
-   if ( ev->x() > dragInfo.start.x() + distance || ev->x() < dragInfo.start.x() - distance ||
-        ev->y() > dragInfo.start.y() + distance || ev->y() < dragInfo.start.y() - distance) 
-   {
-      // we've left the drag square, we can start a real drag operation now
-      emit isBusySelecting(false); // Ok.. we can breath again.
-      
-       _screenWindow->clearSelection();
-      doDrag();
-    }
-    return;
-  } 
-  else if (dragInfo.state == diDragging) 
-  {
-    // this isn't technically needed because mouseMoveEvent is suppressed during
-    // Qt drag operations, replaced by dragMoveEvent
-    return;
-  }
-
-  if (_actSel == 0) return;
-
- // don't extend selection while pasting
-  if (ev->buttons() & Qt::MidButton) return;
-
-  extendSelection( ev->pos() );
-}
-
-#if 0
-void TerminalDisplay::setSelectionEnd()
-{
-  extendSelection( _configureRequestPoint );
-}
-#endif
-
-void TerminalDisplay::extendSelection( const QPoint& position )
-{
-  QPoint pos = position;
-
-  if ( !_screenWindow )
-      return;
-
-  //if ( !contentsRect().contains(ev->pos()) ) return;
-  QPoint tL  = contentsRect().topLeft();
-  int    tLx = tL.x();
-  int    tLy = tL.y();
-  int    scroll = _scrollBar->value();
-
-  // we're in the process of moving the mouse with the left button pressed
-  // the mouse cursor will kept caught within the bounds of the text in
-  // this widget.
-
-  // Adjust position within text area bounds. See FIXME above.
-  QPoint oldpos = pos;
-  if ( pos.x() < tLx+_leftMargin )                  
-      pos.setX( tLx+_leftMargin );
-  if ( pos.x() > tLx+_leftMargin+_usedColumns*_fontWidth-1 ) 
-      pos.setX( tLx+_leftMargin+_usedColumns*_fontWidth );
-  if ( pos.y() < tLy+_topMargin )                   
-      pos.setY( tLy+_topMargin );
-  if ( pos.y() > tLy+_topMargin+_usedLines*_fontHeight-1 )    
-      pos.setY( tLy+_topMargin+_usedLines*_fontHeight-1 );
-
-  if ( pos.y() == tLy+_topMargin+_usedLines*_fontHeight-1 )
-  {
-    _scrollBar->setValue(_scrollBar->value()+yMouseScroll); // scrollforward
-  }
-  if ( pos.y() == tLy+_topMargin )
-  {
-    _scrollBar->setValue(_scrollBar->value()-yMouseScroll); // scrollback
-  }
-
-  int charColumn = 0;
-  int charLine = 0;
-  getCharacterPosition(pos,charLine,charColumn);
-
-  QPoint here = QPoint(charColumn,charLine); //QPoint((pos.x()-tLx-_leftMargin+(_fontWidth/2))/_fontWidth,(pos.y()-tLy-_topMargin)/_fontHeight);
-  QPoint ohere;
-  QPoint _iPntSelCorr = _iPntSel;
-  _iPntSelCorr.ry() -= _scrollBar->value();
-  QPoint _pntSelCorr = _pntSel;
-  _pntSelCorr.ry() -= _scrollBar->value();
-  bool swapping = false;
-
-  if ( _wordSelectionMode )
-  {
-    // Extend to word boundaries
-    int i;
-    int selClass;
-
-    bool left_not_right = ( here.y() < _iPntSelCorr.y() ||
-	   here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x() );
-    bool old_left_not_right = ( _pntSelCorr.y() < _iPntSelCorr.y() ||
-	   _pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x() );
-    swapping = left_not_right != old_left_not_right;
-
-    // Find left (left_not_right ? from here : from start)
-    QPoint left = left_not_right ? here : _iPntSelCorr;
-    i = loc(left.x(),left.y());
-    if (i>=0 && i<=_imageSize) {
-      selClass = charClass(_image[i].character);
-      while ( ((left.x()>0) || (left.y()>0 && (_lineProperties[left.y()-1] & LINE_WRAPPED) )) 
-					  && charClass(_image[i-1].character) == selClass )
-      { i--; if (left.x()>0) left.rx()--; else {left.rx()=_usedColumns-1; left.ry()--;} }
-    }
-
-    // Find left (left_not_right ? from start : from here)
-    QPoint right = left_not_right ? _iPntSelCorr : here;
-    i = loc(right.x(),right.y());
-    if (i>=0 && i<=_imageSize) {
-      selClass = charClass(_image[i].character);
-      while( ((right.x()<_usedColumns-1) || (right.y()<_usedLines-1 && (_lineProperties[right.y()] & LINE_WRAPPED) )) 
-					  && charClass(_image[i+1].character) == selClass )
-      { i++; if (right.x()<_usedColumns-1) right.rx()++; else {right.rx()=0; right.ry()++; } }
-    }
-
-    // Pick which is start (ohere) and which is extension (here)
-    if ( left_not_right )
-    {
-      here = left; ohere = right;
-    }
-    else
-    {
-      here = right; ohere = left;
-    }
-    ohere.rx()++;
-  }
-
-  if ( _lineSelectionMode )
-  {
-    // Extend to complete line
-    bool above_not_below = ( here.y() < _iPntSelCorr.y() );
-
-    QPoint above = above_not_below ? here : _iPntSelCorr;
-    QPoint below = above_not_below ? _iPntSelCorr : here;
-
-    while (above.y()>0 && (_lineProperties[above.y()-1] & LINE_WRAPPED) )
-      above.ry()--;
-    while (below.y()<_usedLines-1 && (_lineProperties[below.y()] & LINE_WRAPPED) )
-      below.ry()++;
-
-    above.setX(0);
-    below.setX(_usedColumns-1);
-
-    // Pick which is start (ohere) and which is extension (here)
-    if ( above_not_below )
-    {
-      here = above; ohere = below;
-    }
-    else
-    {
-      here = below; ohere = above;
-    }
-
-    QPoint newSelBegin = QPoint( ohere.x(), ohere.y() );
-    swapping = !(_tripleSelBegin==newSelBegin);
-    _tripleSelBegin = newSelBegin;
-
-    ohere.rx()++;
-  }
-
-  int offset = 0;
-  if ( !_wordSelectionMode && !_lineSelectionMode )
-  {
-    int i;
-    int selClass;
-
-    bool left_not_right = ( here.y() < _iPntSelCorr.y() ||
-	   here.y() == _iPntSelCorr.y() && here.x() < _iPntSelCorr.x() );
-    bool old_left_not_right = ( _pntSelCorr.y() < _iPntSelCorr.y() ||
-	   _pntSelCorr.y() == _iPntSelCorr.y() && _pntSelCorr.x() < _iPntSelCorr.x() );
-    swapping = left_not_right != old_left_not_right;
-
-    // Find left (left_not_right ? from here : from start)
-    QPoint left = left_not_right ? here : _iPntSelCorr;
-
-    // Find left (left_not_right ? from start : from here)
-    QPoint right = left_not_right ? _iPntSelCorr : here;
-    if ( right.x() > 0 && !_columnSelectionMode )
-    {
-      i = loc(right.x(),right.y());
-      if (i>=0 && i<=_imageSize) {
-        selClass = charClass(_image[i-1].character);
-        if (selClass == ' ')
-        {
-          while ( right.x() < _usedColumns-1 && charClass(_image[i+1].character) == selClass && (right.y()<_usedLines-1) && 
-						  !(_lineProperties[right.y()] & LINE_WRAPPED))
-          { i++; right.rx()++; }
-          if (right.x() < _usedColumns-1)
-            right = left_not_right ? _iPntSelCorr : here;
-          else
-            right.rx()++;  // will be balanced later because of offset=-1;
-        }
-      }
-    }
-
-    // Pick which is start (ohere) and which is extension (here)
-    if ( left_not_right )
-    {
-      here = left; ohere = right; offset = 0;
-    }
-    else
-    {
-      here = right; ohere = left; offset = -1;
-    }
-  }
-
-  if ((here == _pntSelCorr) && (scroll == _scrollBar->value())) return; // not moved
-
-  if (here == ohere) return; // It's not left, it's not right.
-
-  if ( _actSel < 2 || swapping )
-  {
-    if ( _columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode )
-    {
-        _screenWindow->setSelectionStart( ohere.x() , ohere.y() , true );
-    }
-    else
-    {
-        _screenWindow->setSelectionStart( ohere.x()-1-offset , ohere.y() , false );
-    }
-
-  }
-
-  _actSel = 2; // within selection
-  _pntSel = here;
-  _pntSel.ry() += _scrollBar->value();
-
-  if ( _columnSelectionMode && !_lineSelectionMode && !_wordSelectionMode )
-  {
-     _screenWindow->setSelectionEnd( here.x() , here.y() );
-  }
-  else
-  {
-     _screenWindow->setSelectionEnd( here.x()+offset , here.y() );
-  }
-
-}
-
-void TerminalDisplay::mouseReleaseEvent(QMouseEvent* ev)
-{
-    if ( !_screenWindow )
-        return;
-
-    int charLine;
-    int charColumn;
-    getCharacterPosition(ev->pos(),charLine,charColumn);
-
-  if ( ev->button() == Qt::LeftButton)
-  {
-    emit isBusySelecting(false); 
-    if(dragInfo.state == diPending)
-    {
-      // We had a drag event pending but never confirmed.  Kill selection
-       _screenWindow->clearSelection();
-      //emit clearSelectionSignal();
-    }
-    else
-    {
-      if ( _actSel > 1 )
-      {
-          setSelection(  _screenWindow->selectedText(_preserveLineBreaks)  );
-      }
-
-      _actSel = 0;
-
-      //FIXME: emits a release event even if the mouse is
-      //       outside the range. The procedure used in `mouseMoveEvent'
-      //       applies here, too.
-
-      if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier))
-        emit mouseSignal( 3, // release
-                        charColumn + 1,
-                        charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 0);
-    }
-    dragInfo.state = diNone;
-  }
-  
-  
-  if ( !_mouseMarks && 
-       ((ev->button() == Qt::RightButton && !(ev->modifiers() & Qt::ShiftModifier))
-                        || ev->button() == Qt::MidButton) ) 
-  {
-    emit mouseSignal( 3, 
-                      charColumn + 1, 
-                      charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 
-                      0);
-  }
-}
-
-void TerminalDisplay::getCharacterPosition(const QPoint& widgetPoint,int& line,int& column) const
-{
-
-    column = (widgetPoint.x() + _fontWidth/2 -contentsRect().left()-_leftMargin) / _fontWidth;
-    line = (widgetPoint.y()-contentsRect().top()-_topMargin) / _fontHeight;
-
-    if ( line < 0 )
-        line = 0;
-    if ( column < 0 )
-        column = 0;
-
-    if ( line >= _usedLines )
-        line = _usedLines-1;
-
-    // the column value returned can be equal to _usedColumns, which
-    // is the position just after the last character displayed in a line.
-    //
-    // this is required so that the user can select characters in the right-most
-    // column (or left-most for right-to-left input)
-    if ( column > _usedColumns )
-        column = _usedColumns;
-}
-
-void TerminalDisplay::updateLineProperties()
-{
-    if ( !_screenWindow ) 
-        return;
-
-    _lineProperties = _screenWindow->getLineProperties();    
-}
-
-void TerminalDisplay::mouseDoubleClickEvent(QMouseEvent* ev)
-{
-  if ( ev->button() != Qt::LeftButton) return;
-  if ( !_screenWindow ) return;
-
-  int charLine = 0;
-  int charColumn = 0;
-
-  getCharacterPosition(ev->pos(),charLine,charColumn);
-
-  QPoint pos(charColumn,charLine);
-
-  // pass on double click as two clicks.
-  if (!_mouseMarks && !(ev->modifiers() & Qt::ShiftModifier))
-  {
-    // Send just _ONE_ click event, since the first click of the double click
-    // was already sent by the click handler
-    emit mouseSignal( 0, 
-                      pos.x()+1, 
-                      pos.y()+1 +_scrollBar->value() -_scrollBar->maximum(),
-                      0 ); // left button
-    return;
-  }
-
-  _screenWindow->clearSelection();
-  QPoint bgnSel = pos;
-  QPoint endSel = pos;
-  int i = loc(bgnSel.x(),bgnSel.y());
-  _iPntSel = bgnSel;
-  _iPntSel.ry() += _scrollBar->value();
-
-  _wordSelectionMode = true;
-
-  // find word boundaries...
-  int selClass = charClass(_image[i].character);
-  {
-     // find the start of the word
-     int x = bgnSel.x();
-     while ( ((x>0) || (bgnSel.y()>0 && (_lineProperties[bgnSel.y()-1] & LINE_WRAPPED) )) 
-					 && charClass(_image[i-1].character) == selClass )
-     {  
-       i--; 
-       if (x>0) 
-           x--; 
-       else 
-       {
-           x=_usedColumns-1; 
-           bgnSel.ry()--;
-       } 
-     }
-
-     bgnSel.setX(x);
-     _screenWindow->setSelectionStart( bgnSel.x() , bgnSel.y() , false );
-
-     // find the end of the word
-     i = loc( endSel.x(), endSel.y() );
-     x = endSel.x();
-     while( ((x<_usedColumns-1) || (endSel.y()<_usedLines-1 && (_lineProperties[endSel.y()] & LINE_WRAPPED) )) 
-					 && charClass(_image[i+1].character) == selClass )
-     { 
-         i++; 
-         if (x<_usedColumns-1) 
-             x++; 
-         else 
-         {  
-             x=0; 
-             endSel.ry()++; 
-         } 
-     }
-
-     endSel.setX(x);
-
-     // In word selection mode don't select @ (64) if at end of word.
-     if ( ( QChar( _image[i].character ) == '@' ) && ( ( endSel.x() - bgnSel.x() ) > 0 ) )
-       endSel.setX( x - 1 );
-
-
-     _actSel = 2; // within selection
-     
-     _screenWindow->setSelectionEnd( endSel.x() , endSel.y() );
-    
-     setSelection( _screenWindow->selectedText(_preserveLineBreaks) ); 
-   }
-
-  _possibleTripleClick=true;
-
-  QTimer::singleShot(QApplication::doubleClickInterval(),this,
-                     SLOT(tripleClickTimeout()));
-}
-
-void TerminalDisplay::wheelEvent( QWheelEvent* ev )
-{
-  if (ev->orientation() != Qt::Vertical)
-    return;
-
-  if ( _mouseMarks )
-    _scrollBar->event(ev);
-  else
-  {
-    int charLine;
-    int charColumn;
-    getCharacterPosition( ev->pos() , charLine , charColumn );
-    
-    emit mouseSignal( ev->delta() > 0 ? 4 : 5, 
-                      charColumn + 1, 
-                      charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 
-                      0);
-  }
-}
-
-void TerminalDisplay::tripleClickTimeout()
-{
-  _possibleTripleClick=false;
-}
-
-void TerminalDisplay::mouseTripleClickEvent(QMouseEvent* ev)
-{
-  if ( !_screenWindow ) return;
-
-  int charLine;
-  int charColumn;
-  getCharacterPosition(ev->pos(),charLine,charColumn);
-  _iPntSel = QPoint(charColumn,charLine);
-
-  _screenWindow->clearSelection();
-
-  _lineSelectionMode = true;
-  _wordSelectionMode = false;
-
-  _actSel = 2; // within selection
-  emit isBusySelecting(true); // Keep it steady...
-
-  while (_iPntSel.y()>0 && (_lineProperties[_iPntSel.y()-1] & LINE_WRAPPED) )
-    _iPntSel.ry()--;
-  
-  if (_tripleClickMode == SelectForwardsFromCursor) {
-    // find word boundary start
-    int i = loc(_iPntSel.x(),_iPntSel.y());
-    int selClass = charClass(_image[i].character);
-    int x = _iPntSel.x();
-    
-    while ( ((x>0) || 
-             (_iPntSel.y()>0 && (_lineProperties[_iPntSel.y()-1] & LINE_WRAPPED) )
-            ) 
-            && charClass(_image[i-1].character) == selClass )
-    {
-        i--; 
-        if (x>0) 
-            x--; 
-        else 
-        {
-            x=_columns-1; 
-            _iPntSel.ry()--;
-        } 
-    }
-
-    _screenWindow->setSelectionStart( x , _iPntSel.y() , false );
-    _tripleSelBegin = QPoint( x, _iPntSel.y() );
-  }
-  else if (_tripleClickMode == SelectWholeLine) {
-    _screenWindow->setSelectionStart( 0 , _iPntSel.y() , false );
-    _tripleSelBegin = QPoint( 0, _iPntSel.y() );
-  }
-
-  while (_iPntSel.y()<_lines-1 && (_lineProperties[_iPntSel.y()] & LINE_WRAPPED) )
-    _iPntSel.ry()++;
-  
-  _screenWindow->setSelectionEnd( _columns - 1 , _iPntSel.y() );
-
-  setSelection(_screenWindow->selectedText(_preserveLineBreaks));
-
-  _iPntSel.ry() += _scrollBar->value();
-}
-
-
-bool TerminalDisplay::focusNextPrevChild( bool next )
-{
-  if (next)
-    return false; // This disables changing the active part in konqueror
-                  // when pressing Tab
-  return QWidget::focusNextPrevChild( next );
-}
-
-
-int TerminalDisplay::charClass(quint16 ch) const
-{
-    QChar qch=QChar(ch);
-    if ( qch.isSpace() ) return ' ';
-
-    if ( qch.isLetterOrNumber() || _wordCharacters.contains(qch, Qt::CaseInsensitive ) )
-    return 'a';
-
-    // Everything else is weird
-    return 1;
-}
-
-void TerminalDisplay::setWordCharacters(const QString& wc)
-{
-	_wordCharacters = wc;
-}
-
-void TerminalDisplay::setUsesMouse(bool on)
-{
-  _mouseMarks = on;
-  setCursor( _mouseMarks ? Qt::IBeamCursor : Qt::ArrowCursor );
-}
-bool TerminalDisplay::usesMouse() const
-{
-    return _mouseMarks;
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                               Clipboard                                   */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-#undef KeyPress
-
-void TerminalDisplay::emitSelection(bool useXselection,bool appendReturn)
-{
-  if ( !_screenWindow ) 
-      return;
-
-  // Paste Clipboard by simulating keypress events
-  QString text = QApplication::clipboard()->text(useXselection ? QClipboard::Selection :
-                                                                 QClipboard::Clipboard);
-  if(appendReturn)
-    text.append("\r");
-  if ( ! text.isEmpty() )
-  {
-    text.replace("\n", "\r");
-    QKeyEvent e(QEvent::KeyPress, 0, Qt::NoModifier, text);
-    emit keyPressedSignal(&e); // expose as a big fat keypress event
-    
-    _screenWindow->clearSelection();
-  }
-}
-
-void TerminalDisplay::setSelection(const QString& t)
-{
-  QApplication::clipboard()->setText(t, QClipboard::Selection);
-}
-
-void TerminalDisplay::copyClipboard()
-{
-  if ( !_screenWindow )
-      return;
-
-  QString text = _screenWindow->selectedText(_preserveLineBreaks);
-  QApplication::clipboard()->setText(text);
-}
-
-void TerminalDisplay::pasteClipboard()
-{
-  emitSelection(false,false);
-}
-
-void TerminalDisplay::pasteSelection()
-{
-  emitSelection(true,false);
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                                Keyboard                                   */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-void TerminalDisplay::setFlowControlWarningEnabled( bool enable )
-{
-	_flowControlWarningEnabled = enable;
-	
-	// if the dialog is currently visible and the flow control warning has 
-	// been disabled then hide the dialog
-	if (!enable)
-		outputSuspended(false);
-}
-
-void TerminalDisplay::keyPressEvent( QKeyEvent* event )
-{
-//qDebug("%s %d keyPressEvent and key is %d", __FILE__, __LINE__, event->key());
-
-    bool emitKeyPressSignal = true;
-
-    // XonXoff flow control
-    if (event->modifiers() & Qt::ControlModifier && _flowControlWarningEnabled)
-	{
-		if ( event->key() == Qt::Key_S ) {
-		//qDebug("%s %d keyPressEvent, output suspended", __FILE__, __LINE__);
-				emit flowControlKeyPressed(true /*output suspended*/);
-		}
-		else if ( event->key() == Qt::Key_Q ) {
-		//qDebug("%s %d keyPressEvent, output enabled", __FILE__, __LINE__);
-				emit flowControlKeyPressed(false /*output enabled*/);
-		}
-	}
-
-    // Keyboard-based navigation
-    if ( event->modifiers() == Qt::ShiftModifier )
-    {
-        bool update = true;
-
-        if ( event->key() == Qt::Key_PageUp )
-        {
-	    //qDebug("%s %d pageup", __FILE__, __LINE__);
-            _screenWindow->scrollBy( ScreenWindow::ScrollPages , -1 );
-        }
-        else if ( event->key() == Qt::Key_PageDown )
-        {
-	    //qDebug("%s %d pagedown", __FILE__, __LINE__);
-            _screenWindow->scrollBy( ScreenWindow::ScrollPages , 1 );
-        }
-        else if ( event->key() == Qt::Key_Up )
-        {
-	    //qDebug("%s %d keyup", __FILE__, __LINE__);	
-            _screenWindow->scrollBy( ScreenWindow::ScrollLines , -1 );
-        }
-        else if ( event->key() == Qt::Key_Down )
-        {
-	    //qDebug("%s %d keydown", __FILE__, __LINE__);	
-            _screenWindow->scrollBy( ScreenWindow::ScrollLines , 1 );
-        }
-        else {
-            update = false;
-	}
-
-        if ( update )
-        {
-	    //qDebug("%s %d updating", __FILE__, __LINE__);	
-            _screenWindow->setTrackOutput( _screenWindow->atEndOfOutput() );
-            
-            updateLineProperties();
-            updateImage();
-
-            // do not send key press to terminal
-            emitKeyPressSignal = false;
-        }
-    }
-    
-    _screenWindow->setTrackOutput( true );
-    
-    _actSel=0; // Key stroke implies a screen update, so TerminalDisplay won't
-              // know where the current selection is.
-
-    if (_hasBlinkingCursor) 
-    {
-      _blinkCursorTimer->start(BLINK_DELAY);
-      if (_cursorBlinking)
-        blinkCursorEvent();
-      else
-        _cursorBlinking = false;
-    }
-
-    if ( emitKeyPressSignal )
-        emit keyPressedSignal(event);
-
-    event->accept();
-}
-
-void TerminalDisplay::inputMethodEvent( QInputMethodEvent* event )
-{
-    QKeyEvent keyEvent(QEvent::KeyPress,0,Qt::NoModifier,event->commitString());
-    emit keyPressedSignal(&keyEvent);
-
-    _inputMethodData.preeditString = event->preeditString();
-    update(preeditRect() | _inputMethodData.previousPreeditRect);
-    
-    event->accept();
-}
-QVariant TerminalDisplay::inputMethodQuery( Qt::InputMethodQuery query ) const
-{
-    const QPoint cursorPos = _screenWindow ? _screenWindow->cursorPosition() : QPoint(0,0);
-    switch ( query ) 
-    {
-        case Qt::ImMicroFocus:
-                return imageToWidget(QRect(cursorPos.x(),cursorPos.y(),1,1));
-            break;
-        case Qt::ImFont:
-                return font();
-            break;
-        case Qt::ImCursorPosition:
-                // return the cursor position within the current line
-                return cursorPos.x();
-            break;
-        case Qt::ImSurroundingText:
-            {
-                // return the text from the current line
-                QString lineText;
-                QTextStream stream(&lineText);
-                PlainTextDecoder decoder;
-                decoder.begin(&stream);
-                decoder.decodeLine(&_image[loc(0,cursorPos.y())],_usedColumns,_lineProperties[cursorPos.y()]);
-                decoder.end();
-                return lineText;
-            }
-            break;
-        case Qt::ImCurrentSelection:
-                return QString();
-            break;
-    }
-
-    return QVariant();
-}
-
-bool TerminalDisplay::event( QEvent *e )
-{
-  if ( e->type() == QEvent::ShortcutOverride )
-  {
-    QKeyEvent* keyEvent = static_cast<QKeyEvent *>( e );
-
-    // a check to see if keyEvent->text() is empty is used
-    // to avoid intercepting the press of the modifier key on its own.
-    //
-    // this is important as it allows a press and release of the Alt key
-    // on its own to focus the menu bar, making it possible to
-    // work with the menu without using the mouse
-    if ( (keyEvent->modifiers() == Qt::AltModifier) && 
-         !keyEvent->text().isEmpty() )
-    {
-    	keyEvent->accept();
-      	return true;
-    }
-
-    // Override any of the following shortcuts because
-    // they are needed by the terminal
-    int keyCode = keyEvent->key() | keyEvent->modifiers();
-    switch ( keyCode )
-    {
-      // list is taken from the QLineEdit::event() code
-      case Qt::Key_Tab:
-      case Qt::Key_Delete:
-      case Qt::Key_Home:
-      case Qt::Key_End:
-      case Qt::Key_Backspace:
-      case Qt::Key_Left:
-      case Qt::Key_Right:
-        keyEvent->accept();
-        return true;
-    }
-  }
-  return QWidget::event( e );
-}
-
-void TerminalDisplay::setBellMode(int mode)
-{
-  _bellMode=mode;
-}
-
-void TerminalDisplay::enableBell()
-{
-    _allowBell = true;
-}
-
-void TerminalDisplay::bell(const QString&)
-{
-  if (_bellMode==NoBell) return;
-
-  //limit the rate at which bells can occur 
-  //...mainly for sound effects where rapid bells in sequence 
-  //produce a horrible noise
-  if ( _allowBell )
-  {
-    _allowBell = false;
-    QTimer::singleShot(500,this,SLOT(enableBell()));
- 
-    if (_bellMode==SystemBeepBell) 
-    {
-//        KNotification::beep();
-    } 
-    else if (_bellMode==NotifyBell) 
-    {
-//        KNotification::event("BellVisible", message,QPixmap(),this);
-    } 
-    else if (_bellMode==VisualBell) 
-    {
-        swapColorTable();
-        QTimer::singleShot(200,this,SLOT(swapColorTable()));
-    }
-  }
-}
-
-void TerminalDisplay::swapColorTable()
-{
-  ColorEntry color = _colorTable[1];
-  _colorTable[1]=_colorTable[0];
-  _colorTable[0]= color;
-  _colorsInverted = !_colorsInverted;
-  update();
-}
-
-void TerminalDisplay::clearImage()
-{
-  // We initialize _image[_imageSize] too. See makeImage()
-  for (int i = 0; i <= _imageSize; i++)
-  {
-    _image[i].character = ' ';
-    _image[i].foregroundColor = CharacterColor(COLOR_SPACE_DEFAULT,
-                                               DEFAULT_FORE_COLOR);
-    _image[i].backgroundColor = CharacterColor(COLOR_SPACE_DEFAULT,
-                                               DEFAULT_BACK_COLOR);
-    _image[i].rendition = DEFAULT_RENDITION;
-  }
-}
-
-void TerminalDisplay::calcGeometry()
-{
-  _scrollBar->resize(QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent),
-                    contentsRect().height());
-  switch(_scrollbarLocation)
-  {
-    case NoScrollBar :
-     _leftMargin = DEFAULT_LEFT_MARGIN;
-     _contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN;
-     break;
-    case ScrollBarLeft :
-     _leftMargin = DEFAULT_LEFT_MARGIN + _scrollBar->width();
-     _contentWidth = contentsRect().width() - 2 * DEFAULT_LEFT_MARGIN - _scrollBar->width();
-     _scrollBar->move(contentsRect().topLeft());
-     break;
-    case ScrollBarRight:
-     _leftMargin = DEFAULT_LEFT_MARGIN;
-     _contentWidth = contentsRect().width()  - 2 * DEFAULT_LEFT_MARGIN - _scrollBar->width();
-     _scrollBar->move(contentsRect().topRight() - QPoint(_scrollBar->width()-1,0));
-     break;
-  }
-
-  _topMargin = DEFAULT_TOP_MARGIN;
-  _contentHeight = contentsRect().height() - 2 * DEFAULT_TOP_MARGIN + /* mysterious */ 1;
-
-  if (!_isFixedSize)
-  {
-     // ensure that display is always at least one column wide
-     _columns = qMax(1,_contentWidth / _fontWidth);
-     _usedColumns = qMin(_usedColumns,_columns);
-     
-     // ensure that display is always at least one line high
-     _lines = qMax(1,_contentHeight / _fontHeight);
-     _usedLines = qMin(_usedLines,_lines);
-  }
-}
-
-void TerminalDisplay::makeImage()
-{
-//qDebug("%s %d makeImage", __FILE__, __LINE__);
-  calcGeometry();
-
-  // confirm that array will be of non-zero size, since the painting code 
-  // assumes a non-zero array length
-  Q_ASSERT( _lines > 0 && _columns > 0 );
-  Q_ASSERT( _usedLines <= _lines && _usedColumns <= _columns );
-
-  _imageSize=_lines*_columns;
-  
-  // We over-commit one character so that we can be more relaxed in dealing with
-  // certain boundary conditions: _image[_imageSize] is a valid but unused position
-  _image = new Character[_imageSize+1];
-
-  clearImage();
-}
-
-// calculate the needed size
-void TerminalDisplay::setSize(int columns, int lines)
-{
-  //FIXME - Not quite correct, a small amount of additional space
-  // will be used for margins, the scrollbar etc.
-  // we need to allow for this so that '_size' does allow
-  // enough room for the specified number of columns and lines to fit
-
-  QSize newSize = QSize( columns * _fontWidth  ,
-				 lines * _fontHeight   );
-
-  if ( newSize != size() )
-  {
-    _size = newSize;
-    updateGeometry();
-  }
-}
-
-void TerminalDisplay::setFixedSize(int cols, int lins)
-{
-  _isFixedSize = true;
-  
-  //ensure that display is at least one line by one column in size
-  _columns = qMax(1,cols);
-  _lines = qMax(1,lins);
-  _usedColumns = qMin(_usedColumns,_columns);
-  _usedLines = qMin(_usedLines,_lines);
-
-  if (_image)
-  {
-     delete[] _image;
-     makeImage();
-  }
-  setSize(cols, lins);
-  QWidget::setFixedSize(_size);
-}
-
-QSize TerminalDisplay::sizeHint() const
-{
-  return _size;
-}
-
-
-/* --------------------------------------------------------------------- */
-/*                                                                       */
-/* Drag & Drop                                                           */
-/*                                                                       */
-/* --------------------------------------------------------------------- */
-
-void TerminalDisplay::dragEnterEvent(QDragEnterEvent* event)
-{
-  if (event->mimeData()->hasFormat("text/plain"))
-      event->acceptProposedAction();
-}
-
-void TerminalDisplay::dropEvent(QDropEvent* event)
-{
-//  KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
-
-  QString dropText;
-/*  if (!urls.isEmpty()) 
-  {
-    for ( int i = 0 ; i < urls.count() ; i++ ) 
-    {
-        KUrl url = KIO::NetAccess::mostLocalUrl( urls[i] , 0 );
-        QString urlText;
-
-        if (url.isLocalFile())
-            urlText = url.path(); 
-        else
-            urlText = url.url();
-    
-        // in future it may be useful to be able to insert file names with drag-and-drop
-        // without quoting them (this only affects paths with spaces in) 
-        urlText = KShell::quoteArg(urlText);
-      
-        dropText += urlText;
-
-        if ( i != urls.count()-1 ) 
-            dropText += ' ';
-    }
-  }
-  else 
-  {
-    dropText = event->mimeData()->text();
-  }
-*/
-  if(event->mimeData()->hasFormat("text/plain")) 
-  {
-    emit sendStringToEmu(dropText.toLocal8Bit());
-  }
-}
-
-void TerminalDisplay::doDrag()
-{
-  dragInfo.state = diDragging;
-  dragInfo.dragObject = new QDrag(this);
-  QMimeData *mimeData = new QMimeData;
-  mimeData->setText(QApplication::clipboard()->text(QClipboard::Selection));
-  dragInfo.dragObject->setMimeData(mimeData);
-  dragInfo.dragObject->start(Qt::CopyAction);
-  // Don't delete the QTextDrag object.  Qt will delete it when it's done with it.
-}
-
-void TerminalDisplay::outputSuspended(bool suspended)
-{
-	//create the label when this function is first called
-	if (!_outputSuspendedLabel)
-	{
-            //This label includes a link to an English language website
-            //describing the 'flow control' (Xon/Xoff) feature found in almost 
-            //all terminal emulators.
-            //If there isn't a suitable article available in the target language the link
-            //can simply be removed.
-			_outputSuspendedLabel = new QLabel( ("<qt>Output has been "
-                                                "<a href=\"http://en.wikipedia.org/wiki/XON\">suspended</a>"
-                                                " by pressing Ctrl+S."
-											   "  Press <b>Ctrl+Q</b> to resume.</qt>"),
-											   this );
-
-            QPalette palette(_outputSuspendedLabel->palette());
-	    
-	    palette.setColor(QPalette::Normal, QPalette::WindowText, QColor(Qt::white));
-	    palette.setColor(QPalette::Normal, QPalette::Window, QColor(Qt::black));
-//            KColorScheme::adjustForeground(palette,KColorScheme::NeutralText);
-//		KColorScheme::adjustBackground(palette,KColorScheme::NeutralBackground);
-    	    _outputSuspendedLabel->setPalette(palette);
-	    _outputSuspendedLabel->setAutoFillBackground(true);
-	    _outputSuspendedLabel->setBackgroundRole(QPalette::Base);
-	    _outputSuspendedLabel->setFont(QApplication::font());
-            _outputSuspendedLabel->setMargin(5);
-
-            //enable activation of "Xon/Xoff" link in label
-            _outputSuspendedLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | 
-                                                          Qt::LinksAccessibleByKeyboard);
-            _outputSuspendedLabel->setOpenExternalLinks(true);
-            _outputSuspendedLabel->setVisible(false);
-
-            _gridLayout->addWidget(_outputSuspendedLabel);       
-            _gridLayout->addItem( new QSpacerItem(0,0,QSizePolicy::Expanding,
-                                                      QSizePolicy::Expanding),
-                                 1,0);
-
-    }
-
-	_outputSuspendedLabel->setVisible(suspended);
-}
-
-uint TerminalDisplay::lineSpacing() const
-{
-  return _lineSpacing;
-}
-
-void TerminalDisplay::setLineSpacing(uint i)
-{
-  _lineSpacing = i;
-  setVTFont(font()); // Trigger an update.
-}
-
-//#include "moc_TerminalDisplay.cpp"
--- a/gui/qtermwidget/lib/TerminalDisplay.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,754 +0,0 @@
-/*
-    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
-
-    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.
-*/
-
-#ifndef TERMINALDISPLAY_H
-#define TERMINALDISPLAY_H
-
-// Qt
-#include <QtGui/QColor>
-#include <QtCore/QPointer>
-#include <QtGui/QWidget>
-
-// Konsole
-#include "Filter.h"
-#include "Character.h"
-#include "ColorTables.h"
-
-class QDrag;
-class QDragEnterEvent;
-class QDropEvent;
-class QLabel;
-class QTimer;
-class QEvent;
-class QFrame;
-class QGridLayout;
-class QKeyEvent;
-class QScrollBar;
-class QShowEvent;
-class QHideEvent;
-class QWidget;
-
-//class KMenu;
-
-namespace Konsole
-{
-
-extern unsigned short vt100_graphics[32];
-
-class ScreenWindow;
-
-/**
- * A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
- * to the terminal.
- *
- * When the terminal emulation receives new output from the program running in the terminal, 
- * it will update the display by calling updateImage().
- *
- * TODO More documentation
- */
-class TerminalDisplay : public QWidget
-{
-   Q_OBJECT
-
-public:
-    /** Constructs a new terminal display widget with the specified parent. */
-    TerminalDisplay(QWidget *parent=0);
-    virtual ~TerminalDisplay();
-
-    /** Returns the terminal color palette used by the display. */
-    const ColorEntry* colorTable() const;
-    /** Sets the terminal color palette used by the display. */
-    void setColorTable(const ColorEntry table[]);
-    /**
-     * Sets the seed used to generate random colors for the display
-     * (in color schemes that support them).
-     */
-    void setRandomSeed(uint seed);
-    /**
-     * Returns the seed used to generate random colors for the display
-     * (in color schemes that support them).
-     */
-    uint randomSeed() const;
-
-    /** Sets the opacity of the terminal display. */
-    void setOpacity(qreal opacity);
-
-    /** 
-     * This enum describes the location where the scroll bar is positioned in the display widget.
-     */
-    enum ScrollBarPosition 
-    { 
-        /** Do not show the scroll bar. */
-        NoScrollBar=0, 
-        /** Show the scroll bar on the left side of the display. */
-        ScrollBarLeft=1, 
-        /** Show the scroll bar on the right side of the display. */
-        ScrollBarRight=2 
-    };
-    /** 
-     * Specifies whether the terminal display has a vertical scroll bar, and if so whether it
-     * is shown on the left or right side of the display.
-     */
-    void setScrollBarPosition(ScrollBarPosition position);
-
-    /** 
-     * Sets the current position and range of the display's scroll bar.
-     *
-     * @param cursor The position of the scroll bar's thumb.
-     * @param lines The maximum value of the scroll bar.
-     */
-    void setScroll(int cursor, int lines);
-
-    /** 
-     * 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).
-     * Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
-     * the view will draw visual cues such as underlines on mouse-over for links or translucent
-     * rectangles for markers.
-     *
-     * To add a new filter to the view, call:
-     *      viewWidget->filterChain()->addFilter( filterObject );
-     */
-    FilterChain* filterChain() const;
-
-    /** 
-     * Updates the filters in the display's filter chain.  This will cause
-     * the hotspots to be updated to match the current image.
-     *
-     * WARNING:  This function can be expensive depending on the 
-     * image size and number of filters in the filterChain()
-     *
-     * TODO - This API does not really allow efficient usage.  Revise it so
-     * that the processing can be done in a better way.
-     *
-     * eg:
-     *      - Area of interest may be known ( eg. mouse cursor hovering
-     *      over an area )
-     */  
-    void processFilters();
-
-    /** 
-     * Returns a list of menu actions created by the filters for the content
-     * at the given @p position.
-     */
-    QList<QAction*> filterActions(const QPoint& position);
-
-    /** Returns true if the cursor is set to blink or false otherwise. */
-    bool blinkingCursor() { return _hasBlinkingCursor; }
-    /** Specifies whether or not the cursor blinks. */
-    void setBlinkingCursor(bool blink);
-
-    void setCtrlDrag(bool enable) { _ctrlDrag=enable; }
-    bool ctrlDrag() { return _ctrlDrag; }
-
-	/** 
-     *  This enum describes the methods for selecting text when
- 	 *  the user triple-clicks within the display. 
- 	 */
-	enum TripleClickMode
-	{
-		/** Select the whole line underneath the cursor. */
-		SelectWholeLine,
-		/** Select from the current cursor position to the end of the line. */
-		SelectForwardsFromCursor
-	};
-    /** Sets how the text is selected when the user triple clicks within the display. */	
-    void setTripleClickMode(TripleClickMode mode) { _tripleClickMode = mode; }
-	/** See setTripleClickSelectionMode() */
-    TripleClickMode tripleClickMode() { return _tripleClickMode; }
-
-    void setLineSpacing(uint);
-    uint lineSpacing() const;
-
-    void emitSelection(bool useXselection,bool appendReturn);
-
-    /**
-     * This enum describes the available shapes for the keyboard cursor.
-     * See setKeyboardCursorShape()
-     */
-    enum KeyboardCursorShape
-    {
-        /** A rectangular block which covers the entire area of the cursor character. */
-        BlockCursor,
-        /** 
-         * A single flat line which occupies the space at the bottom of the cursor
-         * character's area.
-         */
-        UnderlineCursor,
-        /** 
-         * An cursor shaped like the capital letter 'I', similar to the IBeam 
-         * cursor used in Qt/KDE text editors.
-         */
-        IBeamCursor
-    };
-    /** 
-     * Sets the shape of the keyboard cursor.  This is the cursor drawn   
-     * at the position in the terminal where keyboard input will appear.
-     *
-     * In addition the terminal display widget also has a cursor for 
-     * the mouse pointer, which can be set using the QWidget::setCursor()
-     * method.
-     *
-     * Defaults to BlockCursor
-     */
-    void setKeyboardCursorShape(KeyboardCursorShape shape);
-    /**
-     * Returns the shape of the keyboard cursor.  See setKeyboardCursorShape()
-     */
-    KeyboardCursorShape keyboardCursorShape() const;
-
-    /**
-     * Sets the color used to draw the keyboard cursor.  
-     *
-     * The keyboard cursor defaults to using the foreground color of the character
-     * underneath it.
-     *
-     * @param useForegroundColor If true, the cursor color will change to match
-     * the foreground color of the character underneath it as it is moved, in this
-     * case, the @p color parameter is ignored and the color of the character
-     * under the cursor is inverted to ensure that it is still readable.
-     * @param color The color to use to draw the cursor.  This is only taken into
-     * account if @p useForegroundColor is false.
-     */
-    void setKeyboardCursorColor(bool useForegroundColor , const QColor& color);
-
-    /** 
-     * Returns the color of the keyboard cursor, or an invalid color if the keyboard
-     * cursor color is set to change according to the foreground color of the character
-     * underneath it. 
-     */
-    QColor keyboardCursorColor() const;
-
-    /**
-     * Returns the number of lines of text which can be displayed in the widget.
-     *
-     * This will depend upon the height of the widget and the current font.
-     * See fontHeight()
-     */
-    int  lines()   { return _lines;   }
-    /**
-     * Returns the number of characters of text which can be displayed on
-     * each line in the widget.
-     *
-     * This will depend upon the width of the widget and the current font.
-     * See fontWidth()
-     */
-    int  columns() { return _columns; }
-
-    /**
-     * Returns the height of the characters in the font used to draw the text in the display.
-     */
-    int  fontHeight()   { return _fontHeight;   }
-    /**
-     * Returns the width of the characters in the display.  
-     * This assumes the use of a fixed-width font.
-     */
-    int  fontWidth()    { return _fontWidth; }
-
-    void setSize(int cols, int lins);
-    void setFixedSize(int cols, int lins);
-    
-    // reimplemented
-    QSize sizeHint() const;
-
-    /**
-     * Sets which characters, in addition to letters and numbers, 
-     * are regarded as being part of a word for the purposes
-     * of selecting words in the display by double clicking on them.
-     *
-     * The word boundaries occur at the first and last characters which
-     * are either a letter, number, or a character in @p wc
-     *
-     * @param wc An array of characters which are to be considered parts
-     * of a word ( in addition to letters and numbers ).
-     */
-    void setWordCharacters(const QString& wc);
-    /** 
-     * Returns the characters which are considered part of a word for the 
-     * purpose of selecting words in the display with the mouse.
-     *
-     * @see setWordCharacters()
-     */
-    QString wordCharacters() { return _wordCharacters; }
-
-    /** 
-     * Sets the type of effect used to alert the user when a 'bell' occurs in the 
-     * terminal session.
-     *
-     * The terminal session can trigger the bell effect by calling bell() with
-     * the alert message.
-     */
-    void setBellMode(int mode);
-    /** 
-     * Returns the type of effect used to alert the user when a 'bell' occurs in
-     * the terminal session.
-     * 
-     * See setBellMode()
-     */
-    int bellMode() { return _bellMode; }
-
-    /**
-     * This enum describes the different types of sounds and visual effects which
-     * can be used to alert the user when a 'bell' occurs in the terminal
-     * session.
-     */
-    enum BellMode
-    { 
-        /** A system beep. */
-        SystemBeepBell=0, 
-        /** 
-         * KDE notification.  This may play a sound, show a passive popup
-         * or perform some other action depending on the user's settings.
-         */
-        NotifyBell=1, 
-        /** A silent, visual bell (eg. inverting the display's colors briefly) */
-        VisualBell=2, 
-        /** No bell effects */
-        NoBell=3 
-    };
-
-    void setSelection(const QString &t);
-
-    /** 
-     * Reimplemented.  Has no effect.  Use setVTFont() to change the font
-     * used to draw characters in the display.
-     */
-    virtual void setFont(const QFont &);
-
-    /** Returns the font used to draw characters in the display */
-    QFont getVTFont() { return font(); }
-
-    /** 
-     * Sets the font used to draw the display.  Has no effect if @p font
-     * is larger than the size of the display itself.    
-     */
-    void setVTFont(const QFont& font);
-
-    /**
-     * Specified whether anti-aliasing of text in the terminal display
-     * is enabled or not.  Defaults to enabled.
-     */
-    static void setAntialias( bool antialias ) { _antialiasText = antialias; }
-    /** 
-     * Returns true if anti-aliasing of text in the terminal is enabled.
-     */
-    static bool antialias()                 { return _antialiasText;   }
-    
-    /**
-     * Sets whether or not the current height and width of the 
-     * terminal in lines and columns is displayed whilst the widget
-     * is being resized.
-     */
-    void setTerminalSizeHint(bool on) { _terminalSizeHint=on; }
-    /** 
-     * Returns whether or not the current height and width of
-     * the terminal in lines and columns is displayed whilst the widget
-     * is being resized.
-     */
-    bool terminalSizeHint() { return _terminalSizeHint; }
-    /** 
-     * Sets whether the terminal size display is shown briefly
-     * after the widget is first shown.
-     *
-     * See setTerminalSizeHint() , isTerminalSizeHint()
-     */
-    void setTerminalSizeStartup(bool on) { _terminalSizeStartup=on; }
-
-    void setBidiEnabled(bool set) { _bidiEnabled=set; }
-    bool isBidiEnabled() { return _bidiEnabled; }
-
-    /**
-     * Sets the terminal screen section which is displayed in this widget.
-     * When updateImage() is called, the display fetches the latest character image from the
-     * the associated terminal screen window.
-     *
-     * In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
-     * by the TerminalDisplay.
-     */
-    void setScreenWindow( ScreenWindow* window );
-    /** Returns the terminal screen section which is displayed in this widget.  See setScreenWindow() */
-    ScreenWindow* screenWindow() const;
-
-    static bool HAVE_TRANSPARENCY;
-
-public slots:
-
-    /** 
-     * Causes the terminal display to fetch the latest character image from the associated
-     * terminal screen ( see setScreenWindow() ) and redraw the display.
-     */
-    void updateImage(); 
-    /**
-     * Causes the terminal display to fetch the latest line status flags from the 
-     * associated terminal screen ( see setScreenWindow() ).  
-     */ 
-    void updateLineProperties();
-
-    /** Copies the selected text to the clipboard. */
-    void copyClipboard();
-    /** 
-     * Pastes the content of the clipboard into the 
-     * display.
-     */
-    void pasteClipboard();
-    /**
-     * Pastes the content of the selection into the
-     * display.
-     */
-    void pasteSelection();
-
-	/** 
- 	  * Changes whether the flow control warning box should be shown when the flow control
- 	  * stop key (Ctrl+S) are pressed.
- 	  */
-	void setFlowControlWarningEnabled(bool enabled);
-	
-    /** 
-	 * Causes the widget to display or hide a message informing the user that terminal
-	 * output has been suspended (by using the flow control key combination Ctrl+S)
-	 *
-	 * @param suspended True if terminal output has been suspended and the warning message should
-	 *				 	be shown or false to indicate that terminal output has been resumed and that
-	 *				 	the warning message should disappear.
-	 */ 
-	void outputSuspended(bool suspended);
-
-    /**
-     * Sets whether the program whoose output is being displayed in the view
-     * is interested in mouse events.
-     *
-     * If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
-     * or otherwise moves the mouse inside the view.
-     * The user interaction needed to create selections will also change, and the user will be required
-     * to hold down the shift key to create a selection or perform other mouse activities inside the 
-     * view area - since the program running in the terminal is being allowed to handle normal mouse
-     * events itself.
-     *
-     * @param usesMouse Set to true if the program running in the terminal is interested in mouse events
-     * or false otherwise.
-     */
-    void setUsesMouse(bool usesMouse);
-  
-    /** See setUsesMouse() */
-    bool usesMouse() const;
-
-    /** 
-     * Shows a notification that a bell event has occurred in the terminal.
-     * TODO: More documentation here
-     */
-    void bell(const QString& message);
-
-signals:
-
-    /**
-     * Emitted when the user presses a key whilst the terminal widget has focus.
-     */
-    void keyPressedSignal(QKeyEvent *e);
-
-    /**
-     * Emitted when the user presses the suspend or resume flow control key combinations 
-     * 
-     * @param suspend true if the user pressed Ctrl+S (the suspend output key combination) or
-     * false if the user pressed Ctrl+Q (the resume output key combination)
-     */
-    void flowControlKeyPressed(bool suspend);
-    
-    /** 
-     * A mouse event occurred.
-     * @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
-     * @param column The character column where the event occurred
-     * @param line The character row where the event occurred
-     * @param eventType The type of event.  0 for a mouse press / release or 1 for mouse motion
-     */
-    void mouseSignal(int button, int column, int line, int eventType);
-    void changedFontMetricSignal(int height, int width);
-    void changedContentSizeSignal(int height, int width);
-
-    /** 
-     * Emitted when the user right clicks on the display, or right-clicks with the Shift
-     * key held down if usesMouse() is true.
-     *
-     * This can be used to display a context menu.
-     */
-    void configureRequest( TerminalDisplay*, int state, const QPoint& position );
-
-   void isBusySelecting(bool);
-   void sendStringToEmu(const char*);
-
-protected:
-    virtual bool event( QEvent * );
-
-    virtual void paintEvent( QPaintEvent * );
-
-    virtual void showEvent(QShowEvent*);
-    virtual void hideEvent(QHideEvent*);
-    virtual void resizeEvent(QResizeEvent*);
-
-    virtual void fontChange(const QFont &font);
-
-    virtual void keyPressEvent(QKeyEvent* event);
-    virtual void mouseDoubleClickEvent(QMouseEvent* ev);
-    virtual void mousePressEvent( QMouseEvent* );
-    virtual void mouseReleaseEvent( QMouseEvent* );
-    virtual void mouseMoveEvent( QMouseEvent* );
-    virtual void extendSelection( const QPoint& pos );
-    virtual void wheelEvent( QWheelEvent* );
-
-    virtual bool focusNextPrevChild( bool next );
-    
-    // drag and drop
-    virtual void dragEnterEvent(QDragEnterEvent* event);
-    virtual void dropEvent(QDropEvent* event);
-    void doDrag();
-    enum DragState { diNone, diPending, diDragging };
-
-    struct _dragInfo {
-      DragState       state;
-      QPoint          start;
-      QDrag           *dragObject;
-    } dragInfo;
-
-    virtual int charClass(quint16) const;
-
-    void clearImage();
-
-    void mouseTripleClickEvent(QMouseEvent* ev);
-
-    // reimplemented
-    virtual void inputMethodEvent ( QInputMethodEvent* event );
-    virtual QVariant inputMethodQuery( Qt::InputMethodQuery query ) const;
-
-protected slots:
-
-    void scrollBarPositionChanged(int value);
-    void blinkEvent();
-    void blinkCursorEvent();
-    
-    //Renables bell noises and visuals.  Used to disable further bells for a short period of time
-    //after emitting the first in a sequence of bell events.
-    void enableBell();
-
-private slots:
-
-    void swapColorTable();
-    void tripleClickTimeout();  // resets possibleTripleClick
-
-private:
-
-    // -- Drawing helpers --
-
-    // divides the part of the display specified by 'rect' into
-    // fragments according to their colors and styles and calls
-    // drawTextFragment() to draw the fragments 
-    void drawContents(QPainter &paint, const QRect &rect);
-    // draws a section of text, all the text in this section
-    // has a common color and style
-    void drawTextFragment(QPainter& painter, const QRect& rect, 
-                          const QString& text, const Character* style); 
-    // draws the background for a text fragment
-    // if useOpacitySetting is true then the color's alpha value will be set to
-    // the display's transparency (set with setOpacity()), otherwise the background
-    // will be drawn fully opaque
-    void drawBackground(QPainter& painter, const QRect& rect, const QColor& color,
-						bool useOpacitySetting);
-    // draws the cursor character
-    void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor, 
-                                       const QColor& backgroundColor , bool& invertColors);
-    // draws the characters or line graphics in a text fragment
-    void drawCharacters(QPainter& painter, const QRect& rect,  const QString& text, 
-                                           const Character* style, bool invertCharacterColor);
-    // draws a string of line graphics
-	void drawLineCharString(QPainter& painter, int x, int y, 
-                            const QString& str, const Character* attributes);
-
-    // draws the preedit string for input methods
-    void drawInputMethodPreeditString(QPainter& painter , const QRect& rect);
-
-    // --
-
-    // maps an area in the character image to an area on the widget 
-    QRect imageToWidget(const QRect& imageArea) const;
-
-    // maps a point on the widget to the position ( ie. line and column ) 
-    // of the character at that point.
-    void getCharacterPosition(const QPoint& widgetPoint,int& line,int& column) const;
-
-    // the area where the preedit string for input methods will be draw
-    QRect preeditRect() const;
-
-    // shows a notification window in the middle of the widget indicating the terminal's
-    // current size in columns and lines
-    void showResizeNotification();
-
-    // scrolls the image by a number of lines.  
-    // 'lines' may be positive ( to scroll the image down ) 
-    // or negative ( to scroll the image up )
-    // '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();
-    void updateImageSize();
-    void makeImage();
-    
-    void paintFilters(QPainter& painter);
-
-	// returns a region covering all of the areas of the widget which contain
-	// a hotspot
-	QRegion hotSpotRegion() const;
-
-	// returns the position of the cursor in columns and lines
-	QPoint cursorPosition() const;
-
-    // the window onto the terminal screen which this display
-    // is currently showing.  
-    QPointer<ScreenWindow> _screenWindow;
-
-    bool _allowBell;
-
-    QGridLayout* _gridLayout;
-
-    bool _fixedFont; // has fixed pitch
-    int  _fontHeight;     // height
-    int  _fontWidth;     // width
-    int  _fontAscent;     // ascend
-
-    int _leftMargin;    // offset
-    int _topMargin;    // offset
-
-    int _lines;      // the number of lines that can be displayed in the widget
-    int _columns;    // the number of columns that can be displayed in the widget
-    
-    int _usedLines;  // the number of lines that are actually being used, this will be less
-                    // than 'lines' if the character image provided with setImage() is smaller
-                    // than the maximum image size which can be displayed
-
-    int _usedColumns; // the number of columns that are actually being used, this will be less
-                     // than 'columns' if the character image provided with setImage() is smaller
-                     // than the maximum image size which can be displayed
-    
-    int _contentHeight;
-    int _contentWidth;
-    Character* _image; // [lines][columns]
-               // only the area [usedLines][usedColumns] in the image contains valid data
-
-    int _imageSize;
-    QVector<LineProperty> _lineProperties;
-
-    ColorEntry _colorTable[TABLE_COLORS];
-    uint _randomSeed;
-
-    bool _resizing;
-    bool _terminalSizeHint;
-    bool _terminalSizeStartup;
-    bool _bidiEnabled;
-    bool _mouseMarks;
-
-    QPoint  _iPntSel; // initial selection point
-    QPoint  _pntSel; // current selection point
-    QPoint  _tripleSelBegin; // help avoid flicker
-    int     _actSel; // selection state
-    bool    _wordSelectionMode;
-    bool    _lineSelectionMode;
-    bool    _preserveLineBreaks;
-    bool    _columnSelectionMode;
-
-    QClipboard*  _clipboard;
-    QScrollBar* _scrollBar;
-    ScrollBarPosition _scrollbarLocation;
-    QString     _wordCharacters;
-    int         _bellMode;
-
-    bool _blinking;   // hide text in paintEvent
-    bool _hasBlinker; // has characters to blink
-    bool _cursorBlinking;     // hide cursor in paintEvent
-    bool _hasBlinkingCursor;  // has blinking cursor enabled
-    bool _ctrlDrag;           // require Ctrl key for drag
-    TripleClickMode _tripleClickMode;
-    bool _isFixedSize; //Columns / lines are locked.
-    QTimer* _blinkTimer;  // active when hasBlinker
-    QTimer* _blinkCursorTimer;  // active when hasBlinkingCursor
-
-//    KMenu* _drop;
-    QString _dropText;
-    int _dndFileCount;
-
-    bool _possibleTripleClick;  // is set in mouseDoubleClickEvent and deleted
-                               // after QApplication::doubleClickInterval() delay
-
-
-    QLabel* _resizeWidget;
-    QTimer* _resizeTimer;
-
-	bool _flowControlWarningEnabled;
-
-    //widgets related to the warning message that appears when the user presses Ctrl+S to suspend
-    //terminal output - informing them what has happened and how to resume output
-    QLabel* _outputSuspendedLabel; 
-    	
-    uint _lineSpacing;
-
-    bool _colorsInverted; // true during visual bell
-
-    QSize _size;
-	
-    QRgb _blendColor;
-
-    // list of filters currently applied to the display.  used for links and
-    // search highlight
-    TerminalImageFilterChain* _filterChain;
-    QRect _mouseOverHotspotArea;
-
-    KeyboardCursorShape _cursorShape;
-
-    // custom cursor color.  if this is invalid then the foreground
-    // color of the character under the cursor is used
-    QColor _cursorColor;  
-
-
-    struct InputMethodData
-    {
-        QString preeditString;
-        QRect previousPreeditRect;
-    };
-    InputMethodData _inputMethodData;
-
-    static bool _antialiasText;   // do we antialias or not
-
-    //the delay in milliseconds between redrawing blinking text
-    static const int BLINK_DELAY = 500;
-	static const int DEFAULT_LEFT_MARGIN = 1;
-	static const int DEFAULT_TOP_MARGIN = 1;
-
-public:
-    static void setTransparencyEnabled(bool enable)
-    {
-        HAVE_TRANSPARENCY = enable;
-    }
-};
-
-}
-
-#endif // TERMINALDISPLAY_H
--- a/gui/qtermwidget/lib/Vt102Emulation.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1266 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    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
-
-    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 "Vt102Emulation.h"
-
-//#include <config-konsole.h>
-
-
-#if defined(__osf__) || defined(__APPLE__)
-#define AVOID_XKB
-#endif
-
-// this allows konsole to be compiled without XKB and XTEST extensions
-// even though it might be available on a particular system.
-#if defined(AVOID_XKB)
-#undef HAVE_XKB
-#endif
-
-// Standard 
-#include <stdio.h>
-#include <unistd.h>
-#include <assert.h>
-
-// Qt
-#include <QtCore/QEvent>
-#include <QtGui/QKeyEvent>
-#include <QtCore/QByteRef>
-
-// KDE
-//#include <kdebug.h>
-//#include <klocale.h>
-
-// Konsole
-#include "KeyboardTranslator.h"
-#include "Screen.h"
-
-#if defined(HAVE_XKB)
-void scrolllock_set_off();
-void scrolllock_set_on();
-#endif
-
-using namespace Konsole;
-
-/* VT102 Terminal Emulation
-
-   This class puts together the screens, the pty and the widget to a
-   complete terminal emulation. Beside combining it's componentes, it
-   handles the emulations's protocol.
-
-   This module consists of the following sections:
-
-   - Constructor/Destructor
-   - Incoming Bytes Event pipeline
-   - Outgoing Bytes
-     - Mouse Events
-     - Keyboard Events
-   - Modes and Charset State
-   - Diagnostics
-*/
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                       Constructor / Destructor                            */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-
-Vt102Emulation::Vt102Emulation() 
-    : Emulation(),
-     _titleUpdateTimer(new QTimer(this))
-{
-  _titleUpdateTimer->setSingleShot(true);
-
-  QObject::connect(_titleUpdateTimer , SIGNAL(timeout()) , this , SLOT(updateTitle()));
-
-  initTokenizer();
-  reset();
-}
-
-Vt102Emulation::~Vt102Emulation()
-{
-}
-
-void Vt102Emulation::clearEntireScreen()
-{
-  _currentScreen->clearEntireScreen();
-
-  bufferedUpdate(); 
-}
-
-void Vt102Emulation::reset()
-{
-  //kDebug(1211)<<"Vt102Emulation::reset() resetToken()";
-  resetToken();
-  //kDebug(1211)<<"Vt102Emulation::reset() resetModes()";
-  resetModes();
-  //kDebug(1211)<<"Vt102Emulation::reset() resetCharSet()";
-  resetCharset(0);
-  //kDebug(1211)<<"Vt102Emulation::reset() reset screen0()";
-  _screen[0]->reset();
-  //kDebug(1211)<<"Vt102Emulation::reset() resetCharSet()";
-  resetCharset(1);
-  //kDebug(1211)<<"Vt102Emulation::reset() reset _screen 1";
-  _screen[1]->reset();
-  //kDebug(1211)<<"Vt102Emulation::reset() setCodec()";
-  setCodec(LocaleCodec);
-  //kDebug(1211)<<"Vt102Emulation::reset() done";
- 
-  bufferedUpdate();
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                     Processing the incoming byte stream                   */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/* Incoming Bytes Event pipeline
-
-   This section deals with decoding the incoming character stream.
-   Decoding means here, that the stream is first separated into `tokens'
-   which are then mapped to a `meaning' provided as operations by the
-   `Screen' class or by the emulation class itself.
-
-   The pipeline proceeds as follows:
-
-   - Tokenizing the ESC codes (onReceiveChar)
-   - VT100 code page translation of plain characters (applyCharset)
-   - Interpretation of ESC codes (tau)
-
-   The escape codes and their meaning are described in the
-   technical reference of this program.
-*/
-
-// Tokens ------------------------------------------------------------------ --
-
-/*
-   Since the tokens are the central notion if this section, we've put them
-   in front. They provide the syntactical elements used to represent the
-   terminals operations as byte sequences.
-
-   They are encodes here into a single machine word, so that we can later
-   switch over them easily. Depending on the token itself, additional
-   argument variables are filled with parameter values.
-
-   The tokens are defined below:
-
-   - CHR        - Printable characters     (32..255 but DEL (=127))
-   - CTL        - Control characters       (0..31 but ESC (= 27), DEL)
-   - ESC        - Escape codes of the form <ESC><CHR but `[]()+*#'>
-   - ESC_DE     - Escape codes of the form <ESC><any of `()+*#%'> C
-   - CSI_PN     - Escape codes of the form <ESC>'['     {Pn} ';' {Pn} C
-   - CSI_PS     - Escape codes of the form <ESC>'['     {Pn} ';' ...  C
-   - CSI_PR     - Escape codes of the form <ESC>'[' '?' {Pn} ';' ...  C
-   - CSI_PE     - Escape codes of the form <ESC>'[' '!' {Pn} ';' ...  C
-   - VT52       - VT52 escape codes
-                  - <ESC><Chr>
-                  - <ESC>'Y'{Pc}{Pc}
-   - XTE_HA     - Xterm hacks              <ESC>`]' {Pn} `;' {Text} <BEL>
-                  note that this is handled differently
-
-   The last two forms allow list of arguments. Since the elements of
-   the lists are treated individually the same way, they are passed
-   as individual tokens to the interpretation. Further, because the
-   meaning of the parameters are names (althought represented as numbers),
-   they are includes within the token ('N').
-
-*/
-
-#define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
-
-#define TY_CHR(   )     TY_CONSTR(0,0,0)
-#define TY_CTL(A  )     TY_CONSTR(1,A,0)
-#define TY_ESC(A  )     TY_CONSTR(2,A,0)
-#define TY_ESC_CS(A,B)  TY_CONSTR(3,A,B)
-#define TY_ESC_DE(A  )  TY_CONSTR(4,A,0)
-#define TY_CSI_PS(A,N)  TY_CONSTR(5,A,N)
-#define TY_CSI_PN(A  )  TY_CONSTR(6,A,0)
-#define TY_CSI_PR(A,N)  TY_CONSTR(7,A,N)
-
-#define TY_VT52(A  )    TY_CONSTR(8,A,0)
-
-#define TY_CSI_PG(A  )  TY_CONSTR(9,A,0)
-
-#define TY_CSI_PE(A  )  TY_CONSTR(10,A,0)
-
-// Tokenizer --------------------------------------------------------------- --
-
-/* The tokenizers state
-
-   The state is represented by the buffer (pbuf, ppos),
-   and accompanied by decoded arguments kept in (argv,argc).
-   Note that they are kept internal in the tokenizer.
-*/
-
-void Vt102Emulation::resetToken()
-{
-  ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
-}
-
-void Vt102Emulation::addDigit(int dig)
-{
-  argv[argc] = 10*argv[argc] + dig;
-}
-
-void Vt102Emulation::addArgument()
-{
-  argc = qMin(argc+1,MAXARGS-1);
-  argv[argc] = 0;
-}
-
-void Vt102Emulation::pushToToken(int cc)
-{
-  pbuf[ppos] = cc;
-  ppos = qMin(ppos+1,MAXPBUF-1);
-}
-
-// Character Classes used while decoding
-
-#define CTL  1
-#define CHR  2
-#define CPN  4
-#define DIG  8
-#define SCS 16
-#define GRP 32
-#define CPS 64
-
-void Vt102Emulation::initTokenizer()
-{ int i; quint8* s;
-  for(i =  0;                      i < 256; i++) tbl[ i]  = 0;
-  for(i =  0;                      i <  32; i++) tbl[ i] |= CTL;
-  for(i = 32;                      i < 256; i++) tbl[ i] |= CHR;
-  for(s = (quint8*)"@ABCDGHILMPSTXZcdfry"; *s; s++) tbl[*s] |= CPN;
-// resize = \e[8;<row>;<col>t
-  for(s = (quint8*)"t"; *s; s++) tbl[*s] |= CPS;
-  for(s = (quint8*)"0123456789"        ; *s; s++) tbl[*s] |= DIG;
-  for(s = (quint8*)"()+*%"             ; *s; s++) tbl[*s] |= SCS;
-  for(s = (quint8*)"()+*#[]%"          ; *s; s++) tbl[*s] |= GRP;
-  resetToken();
-}
-
-/* Ok, here comes the nasty part of the decoder.
-
-   Instead of keeping an explicit state, we deduce it from the
-   token scanned so far. It is then immediately combined with
-   the current character to form a scanning decision.
-
-   This is done by the following defines.
-
-   - P is the length of the token scanned so far.
-   - L (often P-1) is the position on which contents we base a decision.
-   - C is a character or a group of characters (taken from 'tbl').
-
-   Note that they need to applied in proper order.
-*/
-
-#define lec(P,L,C) (p == (P) &&                     s[(L)]         == (C))
-#define lun(     ) (p ==  1  &&                       cc           >= 32 )
-#define les(P,L,C) (p == (P) && s[L] < 256  && (tbl[s[(L)]] & (C)) == (C))
-#define eec(C)     (p >=  3  &&        cc                          == (C))
-#define ees(C)     (p >=  3  && cc < 256 &&    (tbl[  cc  ] & (C)) == (C))
-#define eps(C)     (p >=  3  && s[2] != '?' && s[2] != '!' && s[2] != '>' && cc < 256 && (tbl[  cc  ] & (C)) == (C))
-#define epp( )     (p >=  3  && s[2] == '?'                              )
-#define epe( )     (p >=  3  && s[2] == '!'                              )
-#define egt(     ) (p >=  3  && s[2] == '>'                              )
-#define Xpe        (ppos>=2  && pbuf[1] == ']'                           )
-#define Xte        (Xpe                        &&     cc           ==  7 )
-#define ces(C)     (            cc < 256 &&    (tbl[  cc  ] & (C)) == (C) && !Xte)
-
-#define ESC 27
-#define CNTL(c) ((c)-'@')
-
-// process an incoming unicode character
-
-void Vt102Emulation::receiveChar(int cc)
-{ 
-  int i;
-  if (cc == 127) return; //VT100: ignore.
-
-  if (ces(    CTL))
-  { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
-    // This means, they do neither a resetToken nor a pushToToken. Some of them, do
-    // of course. Guess this originates from a weakly layered handling of the X-on
-    // X-off protocol, which comes really below this level.
-    if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
-    if (cc != ESC)    { tau( TY_CTL(cc+'@' ),   0,  0); return; }
-  }
-
-  pushToToken(cc); // advance the state
-
-  int* s = pbuf;
-  int  p = ppos;
-
-  if (getMode(MODE_Ansi)) // decide on proper action
-  {
-    if (lec(1,0,ESC)) {                                                       return; }
-    if (lec(1,0,ESC+128)) { s[0] = ESC; receiveChar('[');                   return; }
-    if (les(2,1,GRP)) {                                                       return; }
-    if (Xte         ) { XtermHack();                            resetToken(); return; }
-    if (Xpe         ) {                                                       return; }
-    if (lec(3,2,'?')) {                                                       return; }
-    if (lec(3,2,'>')) {                                                       return; }
-    if (lec(3,2,'!')) {                                                       return; }
-    if (lun(       )) { tau( TY_CHR(), applyCharset(cc), 0); resetToken(); return; }
-    if (lec(2,0,ESC)) { tau( TY_ESC(s[1]),   0,  0);       resetToken(); return; }
-    if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]),   0,  0);  resetToken(); return; }
-    if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]),   0,  0);       resetToken(); return; }
-    if (eps(    CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]);   resetToken(); return; }
-
-// resize = \e[8;<row>;<col>t
-    if (eps(    CPS)) { tau( TY_CSI_PS(cc, argv[0]), argv[1], argv[2]);   resetToken(); return; }
-
-    if (epe(       )) { tau( TY_CSI_PE(cc),     0,  0);       resetToken(); return; }
-    if (ees(    DIG)) { addDigit(cc-'0');                                     return; }
-    if (eec(    ';')) { addArgument();                                        return; }
-    for (i=0;i<=argc;i++)
-    if ( epp(     ))  { tau( TY_CSI_PR(cc,argv[i]),   0,  0); }
-    else if(egt(    ))   { tau( TY_CSI_PG(cc     ),   0,  0); } // spec. case for ESC]>0c or ESC]>c
-    else if (cc == 'm' && argc - i >= 4 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 2)
-    { // ESC[ ... 48;2;<red>;<green>;<blue> ... m -or- ESC[ ... 38;2;<red>;<green>;<blue> ... m
-      i += 2;
-      tau( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_RGB, (argv[i] << 16) | (argv[i+1] << 8) | argv[i+2]);
-      i += 2;
-    }
-    else if (cc == 'm' && argc - i >= 2 && (argv[i] == 38 || argv[i] == 48) && argv[i+1] == 5)
-    { // ESC[ ... 48;5;<index> ... m -or- ESC[ ... 38;5;<index> ... m
-      i += 2;
-      tau( TY_CSI_PS(cc, argv[i-2]), COLOR_SPACE_256, argv[i]);
-    }
-    else              { tau( TY_CSI_PS(cc,argv[i]),   0,  0); }
-    resetToken();
-  }
-  else // mode VT52
-  {
-    if (lec(1,0,ESC))                                                      return;
-    if (les(1,0,CHR)) { tau( TY_CHR(       ), s[0],  0); resetToken(); return; }
-    if (lec(2,1,'Y'))                                                      return;
-    if (lec(3,1,'Y'))                                                      return;
-    if (p < 4)        { tau( TY_VT52(s[1]   ),   0,  0); resetToken(); return; }
-                        tau( TY_VT52(s[1]   ), s[2],s[3]); resetToken(); return;
-  }
-}
-
-void Vt102Emulation::XtermHack()
-{ int i,arg = 0;
-  for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
-    arg = 10*arg + (pbuf[i]-'0');
-  if (pbuf[i] != ';') { ReportErrorToken(); return; }
-  QChar *str = new QChar[ppos-i-2];
-  for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
-  QString unistr(str,ppos-i-2);
-  
-  // arg == 1 doesn't change the title. In XTerm it only changes the icon name
-  // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
-//  emit changeTitle(arg,unistr);
-  _pendingTitleUpdates[arg] = unistr;
-  _titleUpdateTimer->start(20);
-
-  delete [] str;
-}
-
-void Vt102Emulation::updateTitle()
-{
-	QListIterator<int> iter( _pendingTitleUpdates.keys() );
-	while (iter.hasNext()) {
-		int arg = iter.next();
-		emit titleChanged( arg , _pendingTitleUpdates[arg] );	
-	}
-
-    _pendingTitleUpdates.clear();	
-}
-
-// Interpreting Codes ---------------------------------------------------------
-
-/*
-   Now that the incoming character stream is properly tokenized,
-   meaning is assigned to them. These are either operations of
-   the current _screen, or of the emulation class itself.
-
-   The token to be interpreteted comes in as a machine word
-   possibly accompanied by two parameters.
-
-   Likewise, the operations assigned to, come with up to two
-   arguments. One could consider to make up a proper table
-   from the function below.
-
-   The technical reference manual provides more information
-   about this mapping.
-*/
-
-void Vt102Emulation::tau( int token, int p, int q )
-{
-#if 0
-int N = (token>>0)&0xff;
-int A = (token>>8)&0xff;
-switch( N )
-{
-   case 0: printf("%c", (p < 128) ? p : '?');
-           break;
-   case 1: if (A == 'J') printf("\r");
-           else if (A == 'M') printf("\n");
-           else printf("CTL-%c ", (token>>8)&0xff);
-           break;
-   case 2: printf("ESC-%c ", (token>>8)&0xff);
-           break;
-   case 3: printf("ESC_CS-%c-%c ", (token>>8)&0xff, (token>>16)&0xff);
-           break;
-   case 4: printf("ESC_DE-%c ", (token>>8)&0xff);
-           break;
-   case 5: printf("CSI-PS-%c-%d", (token>>8)&0xff, (token>>16)&0xff );
-           break;
-   case 6: printf("CSI-PN-%c [%d]", (token>>8)&0xff, p);
-           break;
-   case 7: printf("CSI-PR-%c-%d", (token>>8)&0xff, (token>>16)&0xff );
-           break;
-   case 8: printf("VT52-%c", (token>>8)&0xff);
-           break;
-   case 9: printf("CSI-PG-%c", (token>>8)&0xff);
-           break;
-   case 10: printf("CSI-PE-%c", (token>>8)&0xff);
-           break;
-}
-#endif
-
-  switch (token)
-  {
-
-    case TY_CHR(         ) : _currentScreen->ShowCharacter        (p         ); break; //UTF16
-
-    //             127 DEL    : ignored on input
-
-    case TY_CTL('@'      ) : /* NUL: ignored                      */ break;
-    case TY_CTL('A'      ) : /* SOH: ignored                      */ break;
-    case TY_CTL('B'      ) : /* STX: ignored                      */ break;
-    case TY_CTL('C'      ) : /* ETX: ignored                      */ break;
-    case TY_CTL('D'      ) : /* EOT: ignored                      */ break;
-    case TY_CTL('E'      ) :      reportAnswerBack     (          ); break; //VT100
-    case TY_CTL('F'      ) : /* ACK: ignored                      */ break;
-    case TY_CTL('G'      ) : emit stateSet(NOTIFYBELL);
-                                break; //VT100
-    case TY_CTL('H'      ) : _currentScreen->BackSpace            (          ); break; //VT100
-    case TY_CTL('I'      ) : _currentScreen->Tabulate             (          ); break; //VT100
-    case TY_CTL('J'      ) : _currentScreen->NewLine              (          ); break; //VT100
-    case TY_CTL('K'      ) : _currentScreen->NewLine              (          ); break; //VT100
-    case TY_CTL('L'      ) : _currentScreen->NewLine              (          ); break; //VT100
-    case TY_CTL('M'      ) : _currentScreen->Return               (          ); break; //VT100
-
-    case TY_CTL('N'      ) :      useCharset           (         1); break; //VT100
-    case TY_CTL('O'      ) :      useCharset           (         0); break; //VT100
-
-    case TY_CTL('P'      ) : /* DLE: ignored                      */ break;
-    case TY_CTL('Q'      ) : /* DC1: XON continue                 */ break; //VT100
-    case TY_CTL('R'      ) : /* DC2: ignored                      */ break;
-    case TY_CTL('S'      ) : /* DC3: XOFF halt                    */ break; //VT100
-    case TY_CTL('T'      ) : /* DC4: ignored                      */ break;
-    case TY_CTL('U'      ) : /* NAK: ignored                      */ break;
-    case TY_CTL('V'      ) : /* SYN: ignored                      */ break;
-    case TY_CTL('W'      ) : /* ETB: ignored                      */ break;
-    case TY_CTL('X'      ) : _currentScreen->ShowCharacter        (    0x2592); break; //VT100
-    case TY_CTL('Y'      ) : /* EM : ignored                      */ break;
-    case TY_CTL('Z'      ) : _currentScreen->ShowCharacter        (    0x2592); break; //VT100
-    case TY_CTL('['      ) : /* ESC: cannot be seen here.         */ break;
-    case TY_CTL('\\'     ) : /* FS : ignored                      */ break;
-    case TY_CTL(']'      ) : /* GS : ignored                      */ break;
-    case TY_CTL('^'      ) : /* RS : ignored                      */ break;
-    case TY_CTL('_'      ) : /* US : ignored                      */ break;
-
-    case TY_ESC('D'      ) : _currentScreen->index                (          ); break; //VT100
-    case TY_ESC('E'      ) : _currentScreen->NextLine             (          ); break; //VT100
-    case TY_ESC('H'      ) : _currentScreen->changeTabStop        (true      ); break; //VT100
-    case TY_ESC('M'      ) : _currentScreen->reverseIndex         (          ); break; //VT100
-    case TY_ESC('Z'      ) :      reportTerminalType   (          ); break;
-    case TY_ESC('c'      ) :      reset                (          ); break;
-
-    case TY_ESC('n'      ) :      useCharset           (         2); break;
-    case TY_ESC('o'      ) :      useCharset           (         3); break;
-    case TY_ESC('7'      ) :      saveCursor           (          ); break;
-    case TY_ESC('8'      ) :      restoreCursor        (          ); break;
-
-    case TY_ESC('='      ) :          setMode      (MODE_AppKeyPad); break;
-    case TY_ESC('>'      ) :        resetMode      (MODE_AppKeyPad); break;
-    case TY_ESC('<'      ) :          setMode      (MODE_Ansi     ); break; //VT100
-
-    case TY_ESC_CS('(', '0') :      setCharset           (0,    '0'); break; //VT100
-    case TY_ESC_CS('(', 'A') :      setCharset           (0,    'A'); break; //VT100
-    case TY_ESC_CS('(', 'B') :      setCharset           (0,    'B'); break; //VT100
-
-    case TY_ESC_CS(')', '0') :      setCharset           (1,    '0'); break; //VT100
-    case TY_ESC_CS(')', 'A') :      setCharset           (1,    'A'); break; //VT100
-    case TY_ESC_CS(')', 'B') :      setCharset           (1,    'B'); break; //VT100
-
-    case TY_ESC_CS('*', '0') :      setCharset           (2,    '0'); break; //VT100
-    case TY_ESC_CS('*', 'A') :      setCharset           (2,    'A'); break; //VT100
-    case TY_ESC_CS('*', 'B') :      setCharset           (2,    'B'); break; //VT100
-
-    case TY_ESC_CS('+', '0') :      setCharset           (3,    '0'); break; //VT100
-    case TY_ESC_CS('+', 'A') :      setCharset           (3,    'A'); break; //VT100
-    case TY_ESC_CS('+', 'B') :      setCharset           (3,    'B'); break; //VT100
-
-    case TY_ESC_CS('%', 'G') :      setCodec             (Utf8Codec   ); break; //LINUX
-    case TY_ESC_CS('%', '@') :      setCodec             (LocaleCodec ); break; //LINUX
-
-    case TY_ESC_DE('3'      ) : /* Double height line, top half    */ 
-								_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
-								_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
-									break;
-    case TY_ESC_DE('4'      ) : /* Double height line, bottom half */ 
-								_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true );
-								_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , true );
-									break;
-    case TY_ESC_DE('5'      ) : /* Single width, single height line*/
-								_currentScreen->setLineProperty( LINE_DOUBLEWIDTH , false);
-								_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
-								break;
-    case TY_ESC_DE('6'      ) : /* Double width, single height line*/ 
-							    _currentScreen->setLineProperty( LINE_DOUBLEWIDTH , true);	
-								_currentScreen->setLineProperty( LINE_DOUBLEHEIGHT , false);
-								break;
-    case TY_ESC_DE('8'      ) : _currentScreen->helpAlign            (          ); break;
-
-// resize = \e[8;<row>;<col>t
-    case TY_CSI_PS('t',   8) : setImageSize( q /* colums */, p /* lines */ );    break;
-
-// change tab text color : \e[28;<color>t  color: 0-16,777,215
-    case TY_CSI_PS('t',   28) : emit changeTabTextColorRequest      ( p        );          break;
-
-    case TY_CSI_PS('K',   0) : _currentScreen->clearToEndOfLine     (          ); break;
-    case TY_CSI_PS('K',   1) : _currentScreen->clearToBeginOfLine   (          ); break;
-    case TY_CSI_PS('K',   2) : _currentScreen->clearEntireLine      (          ); break;
-    case TY_CSI_PS('J',   0) : _currentScreen->clearToEndOfScreen   (          ); break;
-    case TY_CSI_PS('J',   1) : _currentScreen->clearToBeginOfScreen (          ); break;
-    case TY_CSI_PS('J',   2) : _currentScreen->clearEntireScreen    (          ); break;
-    case TY_CSI_PS('g',   0) : _currentScreen->changeTabStop        (false     ); break; //VT100
-    case TY_CSI_PS('g',   3) : _currentScreen->clearTabStops        (          ); break; //VT100
-    case TY_CSI_PS('h',   4) : _currentScreen->    setMode      (MODE_Insert   ); break;
-    case TY_CSI_PS('h',  20) :          setMode      (MODE_NewLine  ); break;
-    case TY_CSI_PS('i',   0) : /* IGNORE: attached printer          */ break; //VT100
-    case TY_CSI_PS('l',   4) : _currentScreen->  resetMode      (MODE_Insert   ); break;
-    case TY_CSI_PS('l',  20) :        resetMode      (MODE_NewLine  ); break;
-    case TY_CSI_PS('s',   0) :      saveCursor           (          ); break;
-    case TY_CSI_PS('u',   0) :      restoreCursor        (          ); break;
-
-    case TY_CSI_PS('m',   0) : _currentScreen->setDefaultRendition  (          ); break;
-    case TY_CSI_PS('m',   1) : _currentScreen->  setRendition     (RE_BOLD     ); break; //VT100
-    case TY_CSI_PS('m',   4) : _currentScreen->  setRendition     (RE_UNDERLINE); break; //VT100
-    case TY_CSI_PS('m',   5) : _currentScreen->  setRendition     (RE_BLINK    ); break; //VT100
-    case TY_CSI_PS('m',   7) : _currentScreen->  setRendition     (RE_REVERSE  ); break;
-    case TY_CSI_PS('m',  10) : /* IGNORED: mapping related          */ break; //LINUX
-    case TY_CSI_PS('m',  11) : /* IGNORED: mapping related          */ break; //LINUX
-    case TY_CSI_PS('m',  12) : /* IGNORED: mapping related          */ break; //LINUX
-    case TY_CSI_PS('m',  22) : _currentScreen->resetRendition     (RE_BOLD     ); break;
-    case TY_CSI_PS('m',  24) : _currentScreen->resetRendition     (RE_UNDERLINE); break;
-    case TY_CSI_PS('m',  25) : _currentScreen->resetRendition     (RE_BLINK    ); break;
-    case TY_CSI_PS('m',  27) : _currentScreen->resetRendition     (RE_REVERSE  ); break;
-
-    case TY_CSI_PS('m',   30) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  0); break;
-    case TY_CSI_PS('m',   31) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  1); break;
-    case TY_CSI_PS('m',   32) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  2); break;
-    case TY_CSI_PS('m',   33) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  3); break;
-    case TY_CSI_PS('m',   34) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  4); break;
-    case TY_CSI_PS('m',   35) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  5); break;
-    case TY_CSI_PS('m',   36) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  6); break;
-    case TY_CSI_PS('m',   37) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  7); break;
-
-    case TY_CSI_PS('m',   38) : _currentScreen->setForeColor         (p,       q); break;
-
-    case TY_CSI_PS('m',   39) : _currentScreen->setForeColor         (COLOR_SPACE_DEFAULT,  0); break;
-
-    case TY_CSI_PS('m',   40) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  0); break;
-    case TY_CSI_PS('m',   41) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  1); break;
-    case TY_CSI_PS('m',   42) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  2); break;
-    case TY_CSI_PS('m',   43) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  3); break;
-    case TY_CSI_PS('m',   44) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  4); break;
-    case TY_CSI_PS('m',   45) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  5); break;
-    case TY_CSI_PS('m',   46) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  6); break;
-    case TY_CSI_PS('m',   47) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  7); break;
-
-    case TY_CSI_PS('m',   48) : _currentScreen->setBackColor         (p,       q); break;
-
-    case TY_CSI_PS('m',   49) : _currentScreen->setBackColor         (COLOR_SPACE_DEFAULT,  1); break;
-
-    case TY_CSI_PS('m',   90) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  8); break;
-    case TY_CSI_PS('m',   91) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM,  9); break;
-    case TY_CSI_PS('m',   92) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 10); break;
-    case TY_CSI_PS('m',   93) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 11); break;
-    case TY_CSI_PS('m',   94) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 12); break;
-    case TY_CSI_PS('m',   95) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 13); break;
-    case TY_CSI_PS('m',   96) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 14); break;
-    case TY_CSI_PS('m',   97) : _currentScreen->setForeColor         (COLOR_SPACE_SYSTEM, 15); break;
-
-    case TY_CSI_PS('m',  100) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  8); break;
-    case TY_CSI_PS('m',  101) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM,  9); break;
-    case TY_CSI_PS('m',  102) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 10); break;
-    case TY_CSI_PS('m',  103) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 11); break;
-    case TY_CSI_PS('m',  104) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 12); break;
-    case TY_CSI_PS('m',  105) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 13); break;
-    case TY_CSI_PS('m',  106) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 14); break;
-    case TY_CSI_PS('m',  107) : _currentScreen->setBackColor         (COLOR_SPACE_SYSTEM, 15); break;
-
-    case TY_CSI_PS('n',   5) :      reportStatus         (          ); break;
-    case TY_CSI_PS('n',   6) :      reportCursorPosition (          ); break;
-    case TY_CSI_PS('q',   0) : /* IGNORED: LEDs off                 */ break; //VT100
-    case TY_CSI_PS('q',   1) : /* IGNORED: LED1 on                  */ break; //VT100
-    case TY_CSI_PS('q',   2) : /* IGNORED: LED2 on                  */ break; //VT100
-    case TY_CSI_PS('q',   3) : /* IGNORED: LED3 on                  */ break; //VT100
-    case TY_CSI_PS('q',   4) : /* IGNORED: LED4 on                  */ break; //VT100
-    case TY_CSI_PS('x',   0) :      reportTerminalParms  (         2); break; //VT100
-    case TY_CSI_PS('x',   1) :      reportTerminalParms  (         3); break; //VT100
-
-    case TY_CSI_PN('@'      ) : _currentScreen->insertChars          (p         ); break;
-    case TY_CSI_PN('A'      ) : _currentScreen->cursorUp             (p         ); break; //VT100
-    case TY_CSI_PN('B'      ) : _currentScreen->cursorDown           (p         ); break; //VT100
-    case TY_CSI_PN('C'      ) : _currentScreen->cursorRight          (p         ); break; //VT100
-    case TY_CSI_PN('D'      ) : _currentScreen->cursorLeft           (p         ); break; //VT100
-    case TY_CSI_PN('G'      ) : _currentScreen->setCursorX           (p         ); break; //LINUX
-    case TY_CSI_PN('H'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
-    case TY_CSI_PN('I'      ) : _currentScreen->Tabulate             (p         ); break;
-    case TY_CSI_PN('L'      ) : _currentScreen->insertLines          (p         ); break;
-    case TY_CSI_PN('M'      ) : _currentScreen->deleteLines          (p         ); break;
-    case TY_CSI_PN('P'      ) : _currentScreen->deleteChars          (p         ); break;
-    case TY_CSI_PN('S'      ) : _currentScreen->scrollUp             (p         ); break;
-    case TY_CSI_PN('T'      ) : _currentScreen->scrollDown           (p         ); break;
-    case TY_CSI_PN('X'      ) : _currentScreen->eraseChars           (p         ); break;
-    case TY_CSI_PN('Z'      ) : _currentScreen->backTabulate         (p         ); break;
-    case TY_CSI_PN('c'      ) :      reportTerminalType   (          ); break; //VT100
-    case TY_CSI_PN('d'      ) : _currentScreen->setCursorY           (p         ); break; //LINUX
-    case TY_CSI_PN('f'      ) : _currentScreen->setCursorYX          (p,      q); break; //VT100
-    case TY_CSI_PN('r'      ) :      setMargins           (p,      q); break; //VT100
-    case TY_CSI_PN('y'      ) : /* IGNORED: Confidence test          */ break; //VT100
-
-    case TY_CSI_PR('h',   1) :          setMode      (MODE_AppCuKeys); break; //VT100
-    case TY_CSI_PR('l',   1) :        resetMode      (MODE_AppCuKeys); break; //VT100
-    case TY_CSI_PR('s',   1) :         saveMode      (MODE_AppCuKeys); break; //FIXME
-    case TY_CSI_PR('r',   1) :      restoreMode      (MODE_AppCuKeys); break; //FIXME
-
-    case TY_CSI_PR('l',   2) :        resetMode      (MODE_Ansi     ); break; //VT100
-
-    case TY_CSI_PR('h',   3) : clearScreenAndSetColumns(132);          break; //VT100
-    case TY_CSI_PR('l',   3) : clearScreenAndSetColumns(80);           break; //VT100
-
-    case TY_CSI_PR('h',   4) : /* IGNORED: soft scrolling           */ break; //VT100
-    case TY_CSI_PR('l',   4) : /* IGNORED: soft scrolling           */ break; //VT100
-
-    case TY_CSI_PR('h',   5) : _currentScreen->    setMode      (MODE_Screen   ); break; //VT100
-    case TY_CSI_PR('l',   5) : _currentScreen->  resetMode      (MODE_Screen   ); break; //VT100
-
-    case TY_CSI_PR('h',   6) : _currentScreen->    setMode      (MODE_Origin   ); break; //VT100
-    case TY_CSI_PR('l',   6) : _currentScreen->  resetMode      (MODE_Origin   ); break; //VT100
-    case TY_CSI_PR('s',   6) : _currentScreen->   saveMode      (MODE_Origin   ); break; //FIXME
-    case TY_CSI_PR('r',   6) : _currentScreen->restoreMode      (MODE_Origin   ); break; //FIXME
-
-    case TY_CSI_PR('h',   7) : _currentScreen->    setMode      (MODE_Wrap     ); break; //VT100
-    case TY_CSI_PR('l',   7) : _currentScreen->  resetMode      (MODE_Wrap     ); break; //VT100
-    case TY_CSI_PR('s',   7) : _currentScreen->   saveMode      (MODE_Wrap     ); break; //FIXME
-    case TY_CSI_PR('r',   7) : _currentScreen->restoreMode      (MODE_Wrap     ); break; //FIXME
-
-    case TY_CSI_PR('h',   8) : /* IGNORED: autorepeat on            */ break; //VT100
-    case TY_CSI_PR('l',   8) : /* IGNORED: autorepeat off           */ break; //VT100
-    case TY_CSI_PR('s',   8) : /* IGNORED: autorepeat on            */ break; //VT100
-    case TY_CSI_PR('r',   8) : /* IGNORED: autorepeat off           */ break; //VT100
-
-    case TY_CSI_PR('h',   9) : /* IGNORED: interlace                */ break; //VT100
-    case TY_CSI_PR('l',   9) : /* IGNORED: interlace                */ break; //VT100
-    case TY_CSI_PR('s',   9) : /* IGNORED: interlace                */ break; //VT100
-    case TY_CSI_PR('r',   9) : /* IGNORED: interlace                */ break; //VT100
-
-    case TY_CSI_PR('h',  12) : /* IGNORED: Cursor blink             */ break; //att610
-    case TY_CSI_PR('l',  12) : /* IGNORED: Cursor blink             */ break; //att610
-    case TY_CSI_PR('s',  12) : /* IGNORED: Cursor blink             */ break; //att610
-    case TY_CSI_PR('r',  12) : /* IGNORED: Cursor blink             */ break; //att610
-
-    case TY_CSI_PR('h',  25) :          setMode      (MODE_Cursor   ); break; //VT100
-    case TY_CSI_PR('l',  25) :        resetMode      (MODE_Cursor   ); break; //VT100
-    case TY_CSI_PR('s',  25) :         saveMode      (MODE_Cursor   ); break; //VT100
-    case TY_CSI_PR('r',  25) :      restoreMode      (MODE_Cursor   ); break; //VT100
-
-    case TY_CSI_PR('h',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
-    case TY_CSI_PR('l',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
-    case TY_CSI_PR('s',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
-    case TY_CSI_PR('r',  41) : /* IGNORED: obsolete more(1) fix     */ break; //XTERM
-
-    case TY_CSI_PR('h',  47) :          setMode      (MODE_AppScreen); break; //VT100
-    case TY_CSI_PR('l',  47) :        resetMode      (MODE_AppScreen); break; //VT100
-    case TY_CSI_PR('s',  47) :         saveMode      (MODE_AppScreen); break; //XTERM
-    case TY_CSI_PR('r',  47) :      restoreMode      (MODE_AppScreen); break; //XTERM
-
-    case TY_CSI_PR('h',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
-    case TY_CSI_PR('l',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
-    case TY_CSI_PR('s',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
-    case TY_CSI_PR('r',  67) : /* IGNORED: DECBKM                   */ break; //XTERM
-
-    // XTerm defines the following modes:
-    // SET_VT200_MOUSE             1000
-    // SET_VT200_HIGHLIGHT_MOUSE   1001
-    // SET_BTN_EVENT_MOUSE         1002
-    // SET_ANY_EVENT_MOUSE         1003
-    //
-    
-    //Note about mouse modes:
-    //There are four mouse modes which xterm-compatible terminals can support - 1000,1001,1002,1003
-    //Konsole currently supports mode 1000 (basic mouse press and release) and mode 1002 (dragging the mouse).
-    //TODO:  Implementation of mouse modes 1001 (something called hilight tracking) and 
-    //1003 (a slight variation on dragging the mouse)
-    //
- 
-    case TY_CSI_PR('h', 1000) :          setMode      (MODE_Mouse1000); break; //XTERM
-    case TY_CSI_PR('l', 1000) :        resetMode      (MODE_Mouse1000); break; //XTERM
-    case TY_CSI_PR('s', 1000) :         saveMode      (MODE_Mouse1000); break; //XTERM
-    case TY_CSI_PR('r', 1000) :      restoreMode      (MODE_Mouse1000); break; //XTERM
-
-    case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
-    case TY_CSI_PR('l', 1001) :        resetMode      (MODE_Mouse1001); break; //XTERM
-    case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
-    case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking    */ break; //XTERM
-
-    case TY_CSI_PR('h', 1002) :          setMode      (MODE_Mouse1002); break; //XTERM
-    case TY_CSI_PR('l', 1002) :        resetMode      (MODE_Mouse1002); break; //XTERM
-    case TY_CSI_PR('s', 1002) :         saveMode      (MODE_Mouse1002); break; //XTERM
-    case TY_CSI_PR('r', 1002) :      restoreMode      (MODE_Mouse1002); break; //XTERM
-
-    case TY_CSI_PR('h', 1003) :          setMode      (MODE_Mouse1003); break; //XTERM
-    case TY_CSI_PR('l', 1003) :        resetMode      (MODE_Mouse1003); break; //XTERM
-    case TY_CSI_PR('s', 1003) :         saveMode      (MODE_Mouse1003); break; //XTERM
-    case TY_CSI_PR('r', 1003) :      restoreMode      (MODE_Mouse1003); break; //XTERM
-
-    case TY_CSI_PR('h', 1047) :          setMode      (MODE_AppScreen); break; //XTERM
-    case TY_CSI_PR('l', 1047) : _screen[1]->clearEntireScreen(); resetMode(MODE_AppScreen); break; //XTERM
-    case TY_CSI_PR('s', 1047) :         saveMode      (MODE_AppScreen); break; //XTERM
-    case TY_CSI_PR('r', 1047) :      restoreMode      (MODE_AppScreen); break; //XTERM
-
-    //FIXME: Unitoken: save translations
-    case TY_CSI_PR('h', 1048) :      saveCursor           (          ); break; //XTERM
-    case TY_CSI_PR('l', 1048) :      restoreCursor        (          ); break; //XTERM
-    case TY_CSI_PR('s', 1048) :      saveCursor           (          ); break; //XTERM
-    case TY_CSI_PR('r', 1048) :      restoreCursor        (          ); break; //XTERM
-
-    //FIXME: every once new sequences like this pop up in xterm.
-    //       Here's a guess of what they could mean.
-    case TY_CSI_PR('h', 1049) : saveCursor(); _screen[1]->clearEntireScreen(); setMode(MODE_AppScreen); break; //XTERM
-    case TY_CSI_PR('l', 1049) : resetMode(MODE_AppScreen); restoreCursor(); break; //XTERM
-
-    //FIXME: weird DEC reset sequence
-    case TY_CSI_PE('p'      ) : /* IGNORED: reset         (        ) */ break;
-
-    //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
-    case TY_VT52('A'      ) : _currentScreen->cursorUp             (         1); break; //VT52
-    case TY_VT52('B'      ) : _currentScreen->cursorDown           (         1); break; //VT52
-    case TY_VT52('C'      ) : _currentScreen->cursorRight          (         1); break; //VT52
-    case TY_VT52('D'      ) : _currentScreen->cursorLeft           (         1); break; //VT52
-
-    case TY_VT52('F'      ) :      setAndUseCharset     (0,    '0'); break; //VT52
-    case TY_VT52('G'      ) :      setAndUseCharset     (0,    'B'); break; //VT52
-
-    case TY_VT52('H'      ) : _currentScreen->setCursorYX          (1,1       ); break; //VT52
-    case TY_VT52('I'      ) : _currentScreen->reverseIndex         (          ); break; //VT52
-    case TY_VT52('J'      ) : _currentScreen->clearToEndOfScreen   (          ); break; //VT52
-    case TY_VT52('K'      ) : _currentScreen->clearToEndOfLine     (          ); break; //VT52
-    case TY_VT52('Y'      ) : _currentScreen->setCursorYX          (p-31,q-31 ); break; //VT52
-    case TY_VT52('Z'      ) :      reportTerminalType   (           ); break; //VT52
-    case TY_VT52('<'      ) :          setMode      (MODE_Ansi     ); break; //VT52
-    case TY_VT52('='      ) :          setMode      (MODE_AppKeyPad); break; //VT52
-    case TY_VT52('>'      ) :        resetMode      (MODE_AppKeyPad); break; //VT52
-
-    case TY_CSI_PG('c'      ) :  reportSecondaryAttributes(          ); break; //VT100
-
-    default : ReportErrorToken();    break;
-  };
-}
-
-void Vt102Emulation::clearScreenAndSetColumns(int columnCount)
-{
-    setImageSize(_currentScreen->getLines(),columnCount); 
-    clearEntireScreen();
-    setDefaultMargins(); 
-    _currentScreen->setCursorYX(0,0);
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                          Terminal to Host protocol                        */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/* 
-   Outgoing bytes originate from several sources:
-
-   - Replies to Enquieries.
-   - Mouse Events
-   - Keyboard Events
-*/
-
-/*!
-*/
-
-void Vt102Emulation::sendString(const char* s , int length)
-{
-  if ( length >= 0 )
-    emit sendData(s,length);
-  else
-    emit sendData(s,strlen(s));
-}
-
-// Replies ----------------------------------------------------------------- --
-
-// This section copes with replies send as response to an enquiery control code.
-
-/*!
-*/
-
-void Vt102Emulation::reportCursorPosition()
-{ char tmp[20];
-  sprintf(tmp,"\033[%d;%dR",_currentScreen->getCursorY()+1,_currentScreen->getCursorX()+1);
-  sendString(tmp);
-}
-
-/*
-   What follows here is rather obsolete and faked stuff.
-   The correspondent enquieries are neverthenless issued.
-*/
-
-/*!
-*/
-
-void Vt102Emulation::reportTerminalType()
-{
-  // Primary device attribute response (Request was: ^[[0c or ^[[c (from TT321 Users Guide))
-  //   VT220:  ^[[?63;1;2;3;6;7;8c   (list deps on emul. capabilities)
-  //   VT100:  ^[[?1;2c
-  //   VT101:  ^[[?1;0c
-  //   VT102:  ^[[?6v
-  if (getMode(MODE_Ansi))
-    sendString("\033[?1;2c");     // I'm a VT100
-  else
-    sendString("\033/Z");         // I'm a VT52
-}
-
-void Vt102Emulation::reportSecondaryAttributes()
-{
-  // Seconday device attribute response (Request was: ^[[>0c or ^[[>c)
-  if (getMode(MODE_Ansi))
-    sendString("\033[>0;115;0c"); // Why 115?  ;)
-  else
-    sendString("\033/Z");         // FIXME I don't think VT52 knows about it but kept for
-                                  // konsoles backward compatibility.
-}
-
-void Vt102Emulation::reportTerminalParms(int p)
-// DECREPTPARM
-{ char tmp[100];
-  sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
-  sendString(tmp);
-}
-
-/*!
-*/
-
-void Vt102Emulation::reportStatus()
-{
-  sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
-}
-
-/*!
-*/
-
-#define ANSWER_BACK "" // This is really obsolete VT100 stuff.
-
-void Vt102Emulation::reportAnswerBack()
-{
-  sendString(ANSWER_BACK);
-}
-
-// Mouse Handling ---------------------------------------------------------- --
-
-/*!
-    Mouse clicks are possibly reported to the client
-    application if it has issued interest in them.
-    They are normally consumed by the widget for copy
-    and paste, but may be propagated from the widget
-    when gui->setMouseMarks is set via setMode(MODE_Mouse1000).
-
-    `x',`y' are 1-based.
-    `ev' (event) indicates the button pressed (0-2)
-                 or a general mouse release (3).
-
-    eventType represents the kind of mouse action that occurred:
-    	0 = Mouse button press or release
-	1 = Mouse drag
-*/
-
-void Vt102Emulation::sendMouseEvent( int cb, int cx, int cy , int eventType )
-{ char tmp[20];
-  if (  cx<1 || cy<1 ) return;
-  // normal buttons are passed as 0x20 + button,
-  // mouse wheel (buttons 4,5) as 0x5c + button
-  if (cb >= 4) cb += 0x3c;
-
-  //Mouse motion handling
-  if ( (getMode(MODE_Mouse1002) || getMode(MODE_Mouse1003)) && eventType == 1 )
-	  cb += 0x20; //add 32 to signify motion event
-
-  sprintf(tmp,"\033[M%c%c%c",cb+0x20,cx+0x20,cy+0x20);
-  sendString(tmp);
-}
-
-// Keyboard Handling ------------------------------------------------------- --
-
-#define encodeMode(M,B) BITS(B,getMode(M))
-#define encodeStat(M,B) BITS(B,((ev->modifiers() & (M)) == (M)))
-
-void Vt102Emulation::sendText( const QString& text )
-{
-  if (!text.isEmpty()) {
-    QKeyEvent event(QEvent::KeyPress, 
-                    0, 
-                    Qt::NoModifier, 
-                    text);
-    sendKeyEvent(&event); // expose as a big fat keypress event
-  }
-
-}
-
-void Vt102Emulation::sendKeyEvent( QKeyEvent* event )
-{
-    Qt::KeyboardModifiers modifiers = event->modifiers();
-    KeyboardTranslator::States states = KeyboardTranslator::NoState;
-
-    // get current states
-    if ( getMode(MODE_NewLine)  ) states |= KeyboardTranslator::NewLineState;
-    if ( getMode(MODE_Ansi)     ) states |= KeyboardTranslator::AnsiState;
-    if ( getMode(MODE_AppCuKeys)) states |= KeyboardTranslator::CursorKeysState;
-    if ( getMode(MODE_AppScreen)) states |= KeyboardTranslator::AlternateScreenState;
-
-    // lookup key binding
-    if ( _keyTranslator )
-    {
-    KeyboardTranslator::Entry entry = _keyTranslator->findEntry( 
-                                                event->key() , 
-                                                modifiers,
-                                                states );
-
-        // send result to terminal
-        QByteArray textToSend;
-
-        // special handling for the Alt (aka. Meta) modifier.  pressing
-        // Alt+[Character] results in Esc+[Character] being sent
-        // (unless there is an entry defined for this particular combination
-        //  in the keyboard modifier)
-        bool wantsAltModifier = entry.modifiers() & entry.modifierMask() & Qt::AltModifier;
-		bool wantsAnyModifier = entry.state() & entry.stateMask() & KeyboardTranslator::AnyModifierState;
-
-        if ( modifiers & Qt::AltModifier && !(wantsAltModifier || wantsAnyModifier) 
-             && !event->text().isEmpty() )
-        {
-            textToSend.prepend("\033");
-        }
-
-        if ( entry.command() != KeyboardTranslator::NoCommand )
-        {
-			if (entry.command() & KeyboardTranslator::EraseCommand)
-				textToSend += getErase();
-            // TODO command handling
-        }
-        else if ( !entry.text().isEmpty() ) 
-        {
-            textToSend += _codec->fromUnicode(entry.text(true,modifiers));
-        }
-        else
-            textToSend += _codec->fromUnicode(event->text());
-
-        sendData( textToSend.constData() , textToSend.length() );
-    }
-    else
-    {
-        // print an error message to the terminal if no key translator has been
-        // set
-        QString translatorError =  ("No keyboard translator available.  "
-                                         "The information needed to convert key presses "
-                                         "into characters to send to the terminal " 
-                                         "is missing.");
-
-        reset();
-        receiveData( translatorError.toAscii().constData() , translatorError.count() );
-    }
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                                VT100 Charsets                             */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-// Character Set Conversion ------------------------------------------------ --
-
-/* 
-   The processing contains a VT100 specific code translation layer.
-   It's still in use and mainly responsible for the line drawing graphics.
-
-   These and some other glyphs are assigned to codes (0x5f-0xfe)
-   normally occupied by the latin letters. Since this codes also
-   appear within control sequences, the extra code conversion
-   does not permute with the tokenizer and is placed behind it
-   in the pipeline. It only applies to tokens, which represent
-   plain characters.
-
-   This conversion it eventually continued in TerminalDisplay.C, since 
-   it might involve VT100 enhanced fonts, which have these
-   particular glyphs allocated in (0x00-0x1f) in their code page.
-*/
-
-#define CHARSET _charset[_currentScreen==_screen[1]]
-
-// Apply current character map.
-
-unsigned short Vt102Emulation::applyCharset(unsigned short c)
-{
-  if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
-  if (CHARSET.pound                && c == '#' ) return 0xa3; //This mode is obsolete
-  return c;
-}
-
-/*
-   "Charset" related part of the emulation state.
-   This configures the VT100 _charset filter.
-
-   While most operation work on the current _screen,
-   the following two are different.
-*/
-
-void Vt102Emulation::resetCharset(int scrno)
-{
-  _charset[scrno].cu_cs   = 0;
-  strncpy(_charset[scrno].charset,"BBBB",4);
-  _charset[scrno].sa_graphic = false;
-  _charset[scrno].sa_pound   = false;
-  _charset[scrno].graphic = false;
-  _charset[scrno].pound   = false;
-}
-
-void Vt102Emulation::setCharset(int n, int cs) // on both screens.
-{
-  _charset[0].charset[n&3] = cs; useCharset(_charset[0].cu_cs);
-  _charset[1].charset[n&3] = cs; useCharset(_charset[1].cu_cs);
-}
-
-void Vt102Emulation::setAndUseCharset(int n, int cs)
-{
-  CHARSET.charset[n&3] = cs;
-  useCharset(n&3);
-}
-
-void Vt102Emulation::useCharset(int n)
-{
-  CHARSET.cu_cs   = n&3;
-  CHARSET.graphic = (CHARSET.charset[n&3] == '0');
-  CHARSET.pound   = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
-}
-
-void Vt102Emulation::setDefaultMargins()
-{
-	_screen[0]->setDefaultMargins();
-	_screen[1]->setDefaultMargins();
-}
-
-void Vt102Emulation::setMargins(int t, int b)
-{
-  _screen[0]->setMargins(t, b);
-  _screen[1]->setMargins(t, b);
-}
-
-/*! Save the cursor position and the rendition attribute settings. */
-
-void Vt102Emulation::saveCursor()
-{
-  CHARSET.sa_graphic = CHARSET.graphic;
-  CHARSET.sa_pound   = CHARSET.pound; //This mode is obsolete
-  // we are not clear about these
-  //sa_charset = charsets[cScreen->_charset];
-  //sa_charset_num = cScreen->_charset;
-  _currentScreen->saveCursor();
-}
-
-/*! Restore the cursor position and the rendition attribute settings. */
-
-void Vt102Emulation::restoreCursor()
-{
-  CHARSET.graphic = CHARSET.sa_graphic;
-  CHARSET.pound   = CHARSET.sa_pound; //This mode is obsolete
-  _currentScreen->restoreCursor();
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                                Mode Operations                            */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/*
-   Some of the emulations state is either added to the state of the screens.
-
-   This causes some scoping problems, since different emulations choose to
-   located the mode either to the current _screen or to both.
-
-   For strange reasons, the extend of the rendition attributes ranges over
-   all screens and not over the actual _screen.
-
-   We decided on the precise precise extend, somehow.
-*/
-
-// "Mode" related part of the state. These are all booleans.
-
-void Vt102Emulation::resetModes()
-{
-  resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
-  resetMode(MODE_Mouse1001); saveMode(MODE_Mouse1001);
-  resetMode(MODE_Mouse1002); saveMode(MODE_Mouse1002);
-  resetMode(MODE_Mouse1003); saveMode(MODE_Mouse1003);
-
-  resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
-  // here come obsolete modes
-  resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
-  resetMode(MODE_NewLine  );
-    setMode(MODE_Ansi     );
-}
-
-void Vt102Emulation::setMode(int m)
-{
-  _currParm.mode[m] = true;
-  switch (m)
-  {
-    case MODE_Mouse1000:
-    case MODE_Mouse1001:
-    case MODE_Mouse1002:
-    case MODE_Mouse1003:
- 	    emit programUsesMouseChanged(false); 
-    break;
-
-    case MODE_AppScreen : _screen[1]->clearSelection();
-                          setScreen(1);
-    break;
-  }
-  if (m < MODES_SCREEN || m == MODE_NewLine)
-  {
-    _screen[0]->setMode(m);
-    _screen[1]->setMode(m);
-  }
-}
-
-void Vt102Emulation::resetMode(int m)
-{
-  _currParm.mode[m] = false;
-  switch (m)
-  {
-    case MODE_Mouse1000 : 
-    case MODE_Mouse1001 :
-    case MODE_Mouse1002 :
-    case MODE_Mouse1003 :
-	    emit programUsesMouseChanged(true); 
-    break;
-
-    case MODE_AppScreen : _screen[0]->clearSelection();
-                          setScreen(0);
-    break;
-  }
-  if (m < MODES_SCREEN || m == MODE_NewLine)
-  {
-    _screen[0]->resetMode(m);
-    _screen[1]->resetMode(m);
-  }
-}
-
-void Vt102Emulation::saveMode(int m)
-{
-  _saveParm.mode[m] = _currParm.mode[m];
-}
-
-void Vt102Emulation::restoreMode(int m)
-{
-  if (_saveParm.mode[m]) 
-      setMode(m); 
-  else 
-      resetMode(m);
-}
-
-bool Vt102Emulation::getMode(int m)
-{
-  return _currParm.mode[m];
-}
-
-char Vt102Emulation::getErase() const
-{
-  KeyboardTranslator::Entry entry = _keyTranslator->findEntry(
-                                            Qt::Key_Backspace,
-                                            0,
-                                            0);
-  if ( entry.text().count() > 0 )
-      return entry.text()[0];
-  else
-      return '\b';
-}
-
-/* ------------------------------------------------------------------------- */
-/*                                                                           */
-/*                               Diagnostic                                  */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-/*! shows the contents of the scan buffer.
-
-    This functions is used for diagnostics. It is called by \e ReportErrorToken
-    to inform about strings that cannot be decoded or handled by the emulation.
-
-    \sa ReportErrorToken
-*/
-
-static void hexdump(int* s, int len)
-{ int i;
-  for (i = 0; i < len; i++)
-  {
-    if (s[i] == '\\')
-      printf("\\\\");
-    else
-    if ((s[i]) > 32 && s[i] < 127)
-      printf("%c",s[i]);
-    else
-      printf("\\%04x(hex)",s[i]);
-  }
-}
-
-void Vt102Emulation::scan_buffer_report()
-{
-  if (ppos == 0 || ppos == 1 && (pbuf[0] & 0xff) >= 32) return;
-  printf("token: "); hexdump(pbuf,ppos); printf("\n");
-}
-
-/*!
-*/
-
-void Vt102Emulation::ReportErrorToken()
-{
-#ifndef NDEBUG
-  printf("undecodable "); scan_buffer_report();
-#endif
-}
-
-//#include "moc_Vt102Emulation.cpp"
-
--- a/gui/qtermwidget/lib/Vt102Emulation.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-/*
-    This file is part of Konsole, an X terminal.
-    
-    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
-
-    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.
-*/
-
-#ifndef VT102EMULATION_H
-#define VT102EMULATION_H
-
-// Standard Library
-#include <stdio.h>
-
-// Qt 
-#include <QtGui/QKeyEvent>
-#include <QtCore/QHash>
-#include <QtCore/QTimer>
-
-// Konsole
-#include "Emulation.h"
-#include "Screen.h"
-
-#define MODE_AppScreen (MODES_SCREEN+0)
-#define MODE_AppCuKeys (MODES_SCREEN+1)
-#define MODE_AppKeyPad (MODES_SCREEN+2)
-#define MODE_Mouse1000 (MODES_SCREEN+3)
-#define MODE_Mouse1001 (MODES_SCREEN+4)
-#define MODE_Mouse1002 (MODES_SCREEN+5)
-#define MODE_Mouse1003 (MODES_SCREEN+6)
-#define MODE_Ansi      (MODES_SCREEN+7)
-#define MODE_total     (MODES_SCREEN+8)
-
-namespace Konsole
-{
-
-struct DECpar
-{
-  bool mode[MODE_total];
-};
-
-struct CharCodes
-{
-  // coding info
-  char charset[4]; //
-  int  cu_cs;      // actual charset.
-  bool graphic;    // Some VT100 tricks
-  bool pound  ;    // Some VT100 tricks
-  bool sa_graphic; // saved graphic
-  bool sa_pound;   // saved pound
-};
-
-/**
- * Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
- * A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/
- * 
- * In addition, various additional xterm escape sequences are supported to provide 
- * features such as mouse input handling.
- * See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape
- * sequences. 
- *
- */
-class Vt102Emulation : public Emulation
-{ 
-Q_OBJECT
-
-public:
-
-  /** Constructs a new emulation */
-  Vt102Emulation();
-  ~Vt102Emulation();
-  
-  // reimplemented
-  virtual void clearEntireScreen();
-  virtual void reset();
-  
-  // reimplemented
-  virtual char getErase() const;
-  
-public slots: 
-
-  // reimplemented 
-  virtual void sendString(const char*,int length = -1);
-  virtual void sendText(const QString& text);
-  virtual void sendKeyEvent(QKeyEvent*);
-  virtual void sendMouseEvent( int buttons, int column, int line , int eventType );
-  
-protected:
-  // reimplemented
-  virtual void setMode    (int mode);
-  virtual void resetMode  (int mode);
-
-  // reimplemented 
-  virtual void receiveChar(int cc);
-  
-
-private slots:
-		
-  //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
-  //used to buffer multiple title updates
-  void updateTitle();
-
-
-private:
-  unsigned short applyCharset(unsigned short c);
-  void setCharset(int n, int cs);
-  void useCharset(int n);
-  void setAndUseCharset(int n, int cs);
-  void saveCursor();
-  void restoreCursor();
-  void resetCharset(int scrno);
-
-  void setMargins(int top, int bottom);
-  //set margins for all screens back to their defaults
-  void setDefaultMargins();
-
-  // returns true if 'mode' is set or false otherwise
-  bool getMode    (int mode);
-  // saves the current boolean value of 'mode'
-  void saveMode   (int mode);
-  // restores the boolean value of 'mode' 
-  void restoreMode(int mode);
-  // resets all modes
-  void resetModes();
-
-  void resetToken();
-#define MAXPBUF 80
-  void pushToToken(int cc);
-  int pbuf[MAXPBUF]; //FIXME: overflow?
-  int ppos;
-#define MAXARGS 15
-  void addDigit(int dig);
-  void addArgument();
-  int argv[MAXARGS];
-  int argc;
-  void initTokenizer();
-  int tbl[256];
-
-  void scan_buffer_report(); //FIXME: rename
-  void ReportErrorToken();   //FIXME: rename
-
-  void tau(int code, int p, int q);
-  void XtermHack();
-
-  void reportTerminalType();
-  void reportSecondaryAttributes();
-  void reportStatus();
-  void reportAnswerBack();
-  void reportCursorPosition();
-  void reportTerminalParms(int p);
-
-  void onScrollLock();
-  void scrollLock(const bool lock);
-
-  // clears the screen and resizes it to the specified
-  // number of columns
-  void clearScreenAndSetColumns(int columnCount);
-
-  CharCodes _charset[2];
-
-  DECpar _currParm;
-  DECpar _saveParm;
-
-  //hash table and timer for buffering calls to the session instance 
-  //to update the name of the session
-  //or window title.
-  //these calls occur when certain escape sequences are seen in the 
-  //output from the terminal
-  QHash<int,QString> _pendingTitleUpdates;
-  QTimer* _titleUpdateTimer;
-  
-};
-
-}
-
-#endif // VT102EMULATION_H
--- a/gui/qtermwidget/lib/default.keytab	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-# [README.default.Keytab] Buildin Keyboard Table
-#
-# To customize your keyboard, copy this file to something
-# ending with .keytab and change it to meet you needs.
-# Please read the README.KeyTab and the README.keyboard
-# in this case.
-#
-# --------------------------------------------------------------
-
-keyboard "Default (XFree 4)"
-
-# --------------------------------------------------------------
-#
-# Note that this particular table is a "risc" version made to
-# ease customization without bothering with obsolete details.
-# See VT100.keytab for the more hairy stuff.
-#
-# --------------------------------------------------------------
-
-# common keys
-
-key Escape             : "\E"
-
-key Tab   -Shift       : "\t"
-key Tab   +Shift+Ansi  : "\E[Z"
-key Tab   +Shift-Ansi  : "\t"
-key Backtab     +Ansi  : "\E[Z"
-key Backtab     -Ansi  : "\t"
-
-key Return-Shift-NewLine : "\r"
-key Return-Shift+NewLine : "\r\n"
-
-key Return+Shift         : "\EOM"
-
-# Backspace and Delete codes are preserving CTRL-H.
-
-key Backspace      : "\x7f"
-
-# Arrow keys in VT52 mode
-# shift up/down are reserved for scrolling.
-# shift left/right are reserved for switching between tabs (this is hardcoded).
-
-key Up   -Shift-Ansi : "\EA"
-key Down -Shift-Ansi : "\EB"
-key Right-Shift-Ansi : "\EC"
-key Left -Shift-Ansi : "\ED"
-
-# Arrow keys in ANSI mode with Application - and Normal Cursor Mode)
-
-key Up    -Shift-AnyMod+Ansi+AppCuKeys           : "\EOA"
-key Down  -Shift-AnyMod+Ansi+AppCuKeys           : "\EOB"
-key Right -Shift-AnyMod+Ansi+AppCuKeys           : "\EOC"
-key Left  -Shift-AnyMod+Ansi+AppCuKeys           : "\EOD"
-
-key Up    -Shift-AnyMod+Ansi-AppCuKeys           : "\E[A"
-key Down  -Shift-AnyMod+Ansi-AppCuKeys           : "\E[B"
-key Right -Shift-AnyMod+Ansi-AppCuKeys           : "\E[C"
-key Left  -Shift-AnyMod+Ansi-AppCuKeys           : "\E[D"
-
-key Up    -Shift+AnyMod+Ansi                     : "\E[1;*A"
-key Down  -Shift+AnyMod+Ansi                     : "\E[1;*B"
-key Right -Shift+AnyMod+Ansi                     : "\E[1;*C"
-key Left  -Shift+AnyMod+Ansi                     : "\E[1;*D"
-
-# other grey PC keys
-
-key Enter+NewLine : "\r\n"
-key Enter-NewLine : "\r"
-
-key Home        -AnyMod     -AppCuKeys           : "\E[H"  
-key End         -AnyMod     -AppCuKeys           : "\E[F"  
-key Home        -AnyMod     +AppCuKeys           : "\EOH"  
-key End         -AnyMod     +AppCuKeys           : "\EOF"  
-key Home        +AnyMod                          : "\E[1;*H"
-key End         +AnyMod                          : "\E[1;*F"
-
-key Insert      -AnyMod                          : "\E[2~"
-key Delete      -AnyMod                          : "\E[3~"
-key Insert      +AnyMod                          : "\E[2;*~"
-key Delete      +AnyMod                          : "\E[3;*~"
-
-key Prior -Shift-AnyMod                          : "\E[5~"
-key Next  -Shift-AnyMod                          : "\E[6~"
-key Prior -Shift+AnyMod                          : "\E[5;*~"
-key Next  -Shift+AnyMod                          : "\E[6;*~"
-
-# Function keys
-key F1          -AnyMod                          : "\EOP"
-key F2          -AnyMod                          : "\EOQ"
-key F3          -AnyMod                          : "\EOR"
-key F4          -AnyMod                          : "\EOS"
-key F5          -AnyMod                          : "\E[15~"
-key F6          -AnyMod                          : "\E[17~"
-key F7          -AnyMod                          : "\E[18~"
-key F8          -AnyMod                          : "\E[19~"
-key F9          -AnyMod                          : "\E[20~"
-key F10         -AnyMod                          : "\E[21~"
-key F11         -AnyMod                          : "\E[23~"
-key F12         -AnyMod                          : "\E[24~"
-
-key F1          +AnyMod                          : "\EO*P"
-key F2          +AnyMod                          : "\EO*Q"
-key F3          +AnyMod                          : "\EO*R"
-key F4          +AnyMod                          : "\EO*S"
-key F5          +AnyMod                          : "\E[15;*~"
-key F6          +AnyMod                          : "\E[17;*~"
-key F7          +AnyMod                          : "\E[18;*~"
-key F8          +AnyMod                          : "\E[19;*~"
-key F9          +AnyMod                          : "\E[20;*~"
-key F10         +AnyMod                          : "\E[21;*~"
-key F11         +AnyMod                          : "\E[23;*~"
-key F12         +AnyMod                          : "\E[24;*~"
-
-# Work around dead keys
-
-key Space +Control : "\x00"
-
-# Some keys are used by konsole to cause operations.
-# The scroll* operations refer to the history buffer.
-
-key Up    +Shift-AppScreen  : scrollLineUp
-key Prior +Shift-AppScreen  : scrollPageUp
-key Down  +Shift-AppScreen  : scrollLineDown
-key Next  +Shift-AppScreen  : scrollPageDown
-
-key ScrollLock     : scrollLock
-
-# keypad characters are not offered differently by Qt.
--- a/gui/qtermwidget/lib/k3process.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1053 +0,0 @@
-/*
-   This file is part of the KDE libraries
-   Copyright (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
-
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-
-   This library 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public License
-   along with this library; see the file COPYING.LIB.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.
-*/
-
-
-#include "k3process.h"
-//#include <config.h>
-
-#include "k3processcontroller.h"
-#include "kpty.h"
-
-#ifdef __osf__
-#define _OSF_SOURCE
-#include <float.h>
-#endif
-
-#ifdef _AIX
-#define _ALL_SOURCE
-#endif
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include <errno.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <time.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <QtCore/QMap>
-#include <QtCore/QFile>
-#include <QtCore/QSocketNotifier>
-
-//#include <kdebug.h>
-//#include <kstandarddirs.h>
-//#include <kuser.h>
-
-
-//////////////////
-// private data //
-//////////////////
-
-class K3ProcessPrivate {
-public:
-   K3ProcessPrivate() :
-     usePty(K3Process::NoCommunication),
-     addUtmp(false), useShell(false),
-     pty(0),
-     priority(0)
-   {
-   }
-
-   K3Process::Communication usePty;
-   bool addUtmp : 1;
-   bool useShell : 1;
-
-   KPty *pty;
-
-   int priority;
-
-   QMap<QString,QString> env;
-   QString wd;
-   QByteArray shell;
-   QByteArray executable;
-};
-
-/////////////////////////////
-// public member functions //
-/////////////////////////////
-
-K3Process::K3Process( QObject* parent )
-  : QObject( parent ),
-    run_mode(NotifyOnExit),
-    runs(false),
-    pid_(0),
-    status(0),
-    keepPrivs(false),
-    innot(0),
-    outnot(0),
-    errnot(0),
-    communication(NoCommunication),
-    input_data(0),
-    input_sent(0),
-    input_total(0),
-	 d(new K3ProcessPrivate)
-{
-  K3ProcessController::ref();
-  K3ProcessController::instance()->addKProcess(this);
-
-
-  out[0] = out[1] = -1;
-  in[0] = in[1] = -1;
-  err[0] = err[1] = -1;
-}
-
-void
-K3Process::setEnvironment(const QString &name, const QString &value)
-{
-   d->env.insert(name, value);
-}
-
-void
-K3Process::setWorkingDirectory(const QString &dir)
-{
-   d->wd = dir;
-}
-
-void
-K3Process::setupEnvironment()
-{
-   QMap<QString,QString>::Iterator it;
-   for(it = d->env.begin(); it != d->env.end(); ++it)
-   {
-      setenv(QFile::encodeName(it.key()).data(),
-             QFile::encodeName(it.value()).data(), 1);
-   }
-   if (!d->wd.isEmpty())
-   {
-      chdir(QFile::encodeName(d->wd).data());
-   }
-}
-
-void
-K3Process::setRunPrivileged(bool keepPrivileges)
-{
-   keepPrivs = keepPrivileges;
-}
-
-bool
-K3Process::runPrivileged() const
-{
-   return keepPrivs;
-}
-
-bool
-K3Process::setPriority(int prio)
-{
-    if (runs) {
-        if (setpriority(PRIO_PROCESS, pid_, prio))
-            return false;
-    } else {
-        if (prio > 19 || prio < (geteuid() ? getpriority(PRIO_PROCESS, 0) : -20))
-            return false;
-    }
-    d->priority = prio;
-    return true;
-}
-
-K3Process::~K3Process()
-{
-  if (run_mode != DontCare)
-    kill(SIGKILL);
-  detach();
-
-  delete d->pty;
-  delete d;
-
-  K3ProcessController::instance()->removeKProcess(this);
-  K3ProcessController::deref();
-}
-
-void K3Process::detach()
-{
-  if (runs) {
-    K3ProcessController::instance()->addProcess(pid_);
-    runs = false;
-    pid_ = 0; // close without draining
-    commClose(); // Clean up open fd's and socket notifiers.
-  }
-}
-
-void K3Process::setBinaryExecutable(const char *filename)
-{
-   d->executable = filename;
-}
-
-K3Process &K3Process::operator<<(const QStringList& args)
-{
-  QStringList::ConstIterator it = args.begin();
-  for ( ; it != args.end() ; ++it )
-      arguments.append(QFile::encodeName(*it));
-  return *this;
-}
-
-K3Process &K3Process::operator<<(const QByteArray& arg)
-{
-  return operator<< (arg.data());
-}
-
-K3Process &K3Process::operator<<(const char* arg)
-{
-  arguments.append(arg);
-  return *this;
-}
-
-K3Process &K3Process::operator<<(const QString& arg)
-{
-  arguments.append(QFile::encodeName(arg));
-  return *this;
-}
-
-void K3Process::clearArguments()
-{
-  arguments.clear();
-}
-
-bool K3Process::start(RunMode runmode, Communication comm)
-{
-  if (runs) {
-    qDebug() << "Attempted to start an already running process" << endl;
-    return false;
-  }
-
-  uint n = arguments.count();
-  if (n == 0) {
-    qDebug() << "Attempted to start a process without arguments" << endl;
-    return false;
-  }
-  char **arglist;
-  QByteArray shellCmd;
-  if (d->useShell)
-  {
-      if (d->shell.isEmpty()) {
-        qDebug() << "Invalid shell specified" << endl;
-        return false;
-      }
-
-      for (uint i = 0; i < n; i++) {
-          shellCmd += arguments[i];
-          shellCmd += ' '; // CC: to separate the arguments
-      }
-
-      arglist = static_cast<char **>(malloc( 4 * sizeof(char *)));
-      arglist[0] = d->shell.data();
-      arglist[1] = (char *) "-c";
-      arglist[2] = shellCmd.data();
-      arglist[3] = 0;
-  }
-  else
-  {
-      arglist = static_cast<char **>(malloc( (n + 1) * sizeof(char *)));
-      for (uint i = 0; i < n; i++)
-         arglist[i] = arguments[i].data();
-      arglist[n] = 0;
-  }
-
-  run_mode = runmode;
-
-  if (!setupCommunication(comm))
-  {
-      qDebug() << "Could not setup Communication!" << endl;
-      free(arglist);
-      return false;
-  }
-
-  // We do this in the parent because if we do it in the child process
-  // gdb gets confused when the application runs from gdb.
-#ifdef HAVE_INITGROUPS
-  struct passwd *pw = geteuid() ? 0 : getpwuid(getuid());
-#endif
-
-  int fd[2];
-  if (pipe(fd))
-     fd[0] = fd[1] = -1; // Pipe failed.. continue
-
-  // we don't use vfork() because
-  // - it has unclear semantics and is not standardized
-  // - we do way too much magic in the child
-  pid_ = fork();
-  if (pid_ == 0) {
-        // The child process
-
-        close(fd[0]);
-        // Closing of fd[1] indicates that the execvp() succeeded!
-        fcntl(fd[1], F_SETFD, FD_CLOEXEC);
-
-        if (!commSetupDoneC())
-          qDebug() << "Could not finish comm setup in child!" << endl;
-
-        // reset all signal handlers
-        struct sigaction act;
-        sigemptyset(&act.sa_mask);
-        act.sa_handler = SIG_DFL;
-        act.sa_flags = 0;
-        for (int sig = 1; sig < NSIG; sig++)
-          sigaction(sig, &act, 0L);
-
-        if (d->priority)
-            setpriority(PRIO_PROCESS, 0, d->priority);
-
-        if (!runPrivileged())
-        {
-           setgid(getgid());
-#ifdef HAVE_INITGROUPS
-           if (pw)
-              initgroups(pw->pw_name, pw->pw_gid);
-#endif
-	   if (geteuid() != getuid())
-	       setuid(getuid());
-	   if (geteuid() != getuid())
-	       _exit(1);
-        }
-
-        setupEnvironment();
-
-        if (runmode == DontCare || runmode == OwnGroup)
-          setsid();
-
-        const char *executable = arglist[0];
-        if (!d->executable.isEmpty())
-           executable = d->executable.data();
-        execvp(executable, arglist);
-
-        char resultByte = 1;
-        write(fd[1], &resultByte, 1);
-        _exit(-1);
-  } else if (pid_ == -1) {
-        // forking failed
-
-        // commAbort();
-        pid_ = 0;
-        free(arglist);
-        return false;
-  }
-  // the parent continues here
-  free(arglist);
-
-  if (!commSetupDoneP())
-    qDebug() << "Could not finish comm setup in parent!" << endl;
-
-  // Check whether client could be started.
-  close(fd[1]);
-  for(;;)
-  {
-     char resultByte;
-     int n = ::read(fd[0], &resultByte, 1);
-     if (n == 1)
-     {
-         // exec() failed
-         close(fd[0]);
-         waitpid(pid_, 0, 0);
-         pid_ = 0;
-         commClose();
-         return false;
-     }
-     if (n == -1)
-     {
-        if (errno == EINTR)
-           continue; // Ignore
-     }
-     break; // success
-  }
-  close(fd[0]);
-
-  runs = true;
-  switch (runmode)
-  {
-  case Block:
-    for (;;)
-    {
-      commClose(); // drain only, unless obsolete reimplementation
-      if (!runs)
-      {
-        // commClose detected data on the process exit notifification pipe
-        K3ProcessController::instance()->unscheduleCheck();
-        if (waitpid(pid_, &status, WNOHANG) != 0) // error finishes, too
-        {
-          commClose(); // this time for real (runs is false)
-          K3ProcessController::instance()->rescheduleCheck();
-          break;
-        }
-        runs = true; // for next commClose() iteration
-      }
-      else
-      {
-        // commClose is an obsolete reimplementation and waited until
-        // all output channels were closed (or it was interrupted).
-        // there is a chance that it never gets here ...
-        waitpid(pid_, &status, 0);
-        runs = false;
-        break;
-      }
-    }
-    // why do we do this? i think this signal should be emitted _only_
-    // after the process has successfully run _asynchronously_ --ossi
-    emit processExited(this);
-    break;
-  default: // NotifyOnExit & OwnGroup
-    input_data = 0; // Discard any data for stdin that might still be there
-    break;
-  }
-  return true;
-}
-
-
-
-bool K3Process::kill(int signo)
-{
-  if (runs && pid_ > 0 && !::kill(run_mode == OwnGroup ? -pid_ : pid_, signo))
-    return true;
-  return false;
-}
-
-
-
-bool K3Process::isRunning() const
-{
-  return runs;
-}
-
-
-
-pid_t K3Process::pid() const
-{
-  return pid_;
-}
-
-#ifndef timersub
-# define timersub(a, b, result) \
-  do { \
-    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
-    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
-    if ((result)->tv_usec < 0) { \
-      --(result)->tv_sec; \
-      (result)->tv_usec += 1000000; \
-    } \
-  } while (0)
-#endif
-
-bool K3Process::wait(int timeout)
-{
-  if (!runs)
-    return true;
-
-#ifndef __linux__
-  struct timeval etv;
-#endif
-  struct timeval tv, *tvp;
-  if (timeout < 0)
-    tvp = 0;
-  else
-  {
-#ifndef __linux__
-    gettimeofday(&etv, 0);
-    etv.tv_sec += timeout;
-#else
-    tv.tv_sec = timeout;
-    tv.tv_usec = 0;
-#endif
-    tvp = &tv;
-  }
-
-  int fd = K3ProcessController::instance()->notifierFd();
-  for(;;)
-  {
-    fd_set fds;
-    FD_ZERO( &fds );
-    FD_SET( fd, &fds );
-
-#ifndef __linux__
-    if (tvp)
-    {
-      gettimeofday(&tv, 0);
-      timersub(&etv, &tv, &tv);
-      if (tv.tv_sec < 0)
-        tv.tv_sec = tv.tv_usec = 0;
-    }
-#endif
-
-    switch( select( fd+1, &fds, 0, 0, tvp ) )
-    {
-    case -1:
-      if( errno == EINTR )
-        break;
-      // fall through; should happen if tvp->tv_sec < 0
-    case 0:
-      K3ProcessController::instance()->rescheduleCheck();
-      return false;
-    default:
-      K3ProcessController::instance()->unscheduleCheck();
-      if (waitpid(pid_, &status, WNOHANG) != 0) // error finishes, too
-      {
-        processHasExited(status);
-        K3ProcessController::instance()->rescheduleCheck();
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-
-
-bool K3Process::normalExit() const
-{
-  return (pid_ != 0) && !runs && WIFEXITED(status);
-}
-
-
-bool K3Process::signalled() const
-{
-  return (pid_ != 0) && !runs && WIFSIGNALED(status);
-}
-
-
-bool K3Process::coreDumped() const
-{
-#ifdef WCOREDUMP
-  return signalled() && WCOREDUMP(status);
-#else
-  return false;
-#endif
-}
-
-
-int K3Process::exitStatus() const
-{
-  return WEXITSTATUS(status);
-}
-
-
-int K3Process::exitSignal() const
-{
-  return WTERMSIG(status);
-}
-
-
-bool K3Process::writeStdin(const char *buffer, int buflen)
-{
-  // if there is still data pending, writing new data
-  // to stdout is not allowed (since it could also confuse
-  // kprocess ...)
-  if (input_data != 0)
-    return false;
-
-  if (communication & Stdin) {
-    input_data = buffer;
-    input_sent = 0;
-    input_total = buflen;
-    innot->setEnabled(true);
-    if (input_total)
-       slotSendData(0);
-    return true;
-  } else
-    return false;
-}
-
-void K3Process::suspend()
-{
-  if (outnot)
-     outnot->setEnabled(false);
-}
-
-void K3Process::resume()
-{
-  if (outnot)
-     outnot->setEnabled(true);
-}
-
-bool K3Process::closeStdin()
-{
-  if (communication & Stdin) {
-    communication = communication & ~Stdin;
-    delete innot;
-    innot = 0;
-    if (!(d->usePty & Stdin))
-      close(in[1]);
-    in[1] = -1;
-    return true;
-  } else
-    return false;
-}
-
-bool K3Process::closeStdout()
-{
-  if (communication & Stdout) {
-    communication = communication & ~Stdout;
-    delete outnot;
-    outnot = 0;
-    if (!(d->usePty & Stdout))
-      close(out[0]);
-    out[0] = -1;
-    return true;
-  } else
-    return false;
-}
-
-bool K3Process::closeStderr()
-{
-  if (communication & Stderr) {
-    communication = communication & ~Stderr;
-    delete errnot;
-    errnot = 0;
-    if (!(d->usePty & Stderr))
-      close(err[0]);
-    err[0] = -1;
-    return true;
-  } else
-    return false;
-}
-
-bool K3Process::closePty()
-{
-  if (d->pty && d->pty->masterFd() >= 0) {
-    if (d->addUtmp)
-      d->pty->logout();
-    d->pty->close();
-    return true;
-  } else
-    return false;
-}
-
-void K3Process::closeAll()
-{
-  closeStdin();
-  closeStdout();
-  closeStderr();
-  closePty();
-}
-
-/////////////////////////////
-// protected slots         //
-/////////////////////////////
-
-
-
-void K3Process::slotChildOutput(int fdno)
-{
-  if (!childOutput(fdno))
-     closeStdout();
-}
-
-
-void K3Process::slotChildError(int fdno)
-{
-  if (!childError(fdno))
-     closeStderr();
-}
-
-
-void K3Process::slotSendData(int)
-{
-  if (input_sent == input_total) {
-    innot->setEnabled(false);
-    input_data = 0;
-    emit wroteStdin(this);
-  } else {
-    int result = ::write(in[1], input_data+input_sent, input_total-input_sent);
-    if (result >= 0)
-    {
-       input_sent += result;
-    }
-    else if ((errno != EAGAIN) && (errno != EINTR))
-    {
-       qDebug() << "Error writing to stdin of child process" << endl;
-       closeStdin();
-    }
-  }
-}
-
-void K3Process::setUseShell(bool useShell, const char *shell)
-{
-  d->useShell = useShell;
-  if (shell && *shell)
-    d->shell = shell;
-  else
-// #ifdef NON_FREE // ... as they ship non-POSIX /bin/sh
-#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__GNU__) && !defined(__DragonFly__)
-  // Solaris POSIX ...
-  if (!access( "/usr/xpg4/bin/sh", X_OK ))
-    d->shell = "/usr/xpg4/bin/sh";
-  else
-  // ... which links here anyway
-  if (!access( "/bin/ksh", X_OK ))
-    d->shell = "/bin/ksh";
-  else
-  // dunno, maybe superfluous?
-  if (!access( "/usr/ucb/sh", X_OK ))
-    d->shell = "/usr/ucb/sh";
-  else
-#endif
-    d->shell = "/bin/sh";
-}
-
-void K3Process::setUsePty(Communication usePty, bool addUtmp)
-{
-  d->usePty = usePty;
-  d->addUtmp = addUtmp;
-  if (usePty) {
-    if (!d->pty)
-      d->pty = new KPty;
-  } else {
-    delete d->pty;
-    d->pty = 0;
-  }
-}
-
-KPty *K3Process::pty() const
-{
-  return d->pty;
-}
-
-QString K3Process::quote(const QString &arg)
-{
-    QChar q('\'');
-    return QString(arg).replace(q, "'\\''").prepend(q).append(q);
-}
-
-
-//////////////////////////////
-// private member functions //
-//////////////////////////////
-
-
-void K3Process::processHasExited(int state)
-{
-    // only successfully run NotifyOnExit processes ever get here
-
-    status = state;
-    runs = false; // do this before commClose, so it knows we're dead
-
-    commClose(); // cleanup communication sockets
-
-    if (run_mode != DontCare)
-      emit processExited(this);
-}
-
-
-
-int K3Process::childOutput(int fdno)
-{
-  if (communication & NoRead) {
-     int len = -1;
-     emit receivedStdout(fdno, len);
-     errno = 0; // Make sure errno doesn't read "EAGAIN"
-     return len;
-  }
-  else
-  {
-     char buffer[1025];
-     int len;
-
-     len = ::read(fdno, buffer, 1024);
-
-     if (len > 0) {
-        buffer[len] = 0; // Just in case.
-        emit receivedStdout(this, buffer, len);
-     }
-     return len;
-  }
-}
-
-int K3Process::childError(int fdno)
-{
-  char buffer[1025];
-  int len;
-
-  len = ::read(fdno, buffer, 1024);
-
-  if (len > 0) {
-     buffer[len] = 0; // Just in case.
-     emit receivedStderr(this, buffer, len);
-  }
-  return len;
-}
-
-
-int K3Process::setupCommunication(Communication comm)
-{
-  // PTY stuff //
-  if (d->usePty)
-  {
-    // cannot communicate on both stderr and stdout if they are both on the pty
-    if (!(~(comm & d->usePty) & (Stdout | Stderr))) {
-       qWarning() << "Invalid usePty/communication combination (" << d->usePty << "/" << comm << ")" << endl;
-       return 0;
-    }
-    if (!d->pty->open())
-       return 0;
-
-    int rcomm = comm & d->usePty;
-    int mfd = d->pty->masterFd();
-    if (rcomm & Stdin)
-      in[1] = mfd;
-    if (rcomm & Stdout)
-      out[0] = mfd;
-    if (rcomm & Stderr)
-      err[0] = mfd;
-  }
-
-  communication = comm;
-
-  comm = comm & ~d->usePty;
-  if (comm & Stdin) {
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, in))
-      goto fail0;
-    fcntl(in[0], F_SETFD, FD_CLOEXEC);
-    fcntl(in[1], F_SETFD, FD_CLOEXEC);
-  }
-  if (comm & Stdout) {
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, out))
-      goto fail1;
-    fcntl(out[0], F_SETFD, FD_CLOEXEC);
-    fcntl(out[1], F_SETFD, FD_CLOEXEC);
-  }
-  if (comm & Stderr) {
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, err))
-      goto fail2;
-    fcntl(err[0], F_SETFD, FD_CLOEXEC);
-    fcntl(err[1], F_SETFD, FD_CLOEXEC);
-  }
-  return 1; // Ok
- fail2:
-  if (comm & Stdout)
-  {
-    close(out[0]);
-    close(out[1]);
-    out[0] = out[1] = -1;
-  }
- fail1:
-  if (comm & Stdin)
-  {
-    close(in[0]);
-    close(in[1]);
-    in[0] = in[1] = -1;
-  }
- fail0:
-  communication = NoCommunication;
-  return 0; // Error
-}
-
-
-
-int K3Process::commSetupDoneP()
-{
-  int rcomm = communication & ~d->usePty;
-  if (rcomm & Stdin)
-    close(in[0]);
-  if (rcomm & Stdout)
-    close(out[1]);
-  if (rcomm & Stderr)
-    close(err[1]);
-  in[0] = out[1] = err[1] = -1;
-
-  // Don't create socket notifiers if no interactive comm is to be expected
-  if (run_mode != NotifyOnExit && run_mode != OwnGroup)
-    return 1;
-
-  if (communication & Stdin) {
-    fcntl(in[1], F_SETFL, O_NONBLOCK | fcntl(in[1], F_GETFL));
-    innot =  new QSocketNotifier(in[1], QSocketNotifier::Write, this);
-    Q_CHECK_PTR(innot);
-    innot->setEnabled(false); // will be enabled when data has to be sent
-    QObject::connect(innot, SIGNAL(activated(int)),
-                     this, SLOT(slotSendData(int)));
-  }
-
-  if (communication & Stdout) {
-    outnot = new QSocketNotifier(out[0], QSocketNotifier::Read, this);
-    Q_CHECK_PTR(outnot);
-    QObject::connect(outnot, SIGNAL(activated(int)),
-                     this, SLOT(slotChildOutput(int)));
-    if (communication & NoRead)
-        suspend();
-  }
-
-  if (communication & Stderr) {
-    errnot = new QSocketNotifier(err[0], QSocketNotifier::Read, this );
-    Q_CHECK_PTR(errnot);
-    QObject::connect(errnot, SIGNAL(activated(int)),
-                     this, SLOT(slotChildError(int)));
-  }
-
-  return 1;
-}
-
-
-
-int K3Process::commSetupDoneC()
-{
-  int ok = 1;
-  if (d->usePty & Stdin) {
-    if (dup2(d->pty->slaveFd(), STDIN_FILENO) < 0) ok = 0;
-  } else if (communication & Stdin) {
-    if (dup2(in[0], STDIN_FILENO) < 0) ok = 0;
-  } else {
-    int null_fd = open( "/dev/null", O_RDONLY );
-    if (dup2( null_fd, STDIN_FILENO ) < 0) ok = 0;
-    close( null_fd );
-  }
-  struct linger so;
-  memset(&so, 0, sizeof(so));
-  if (d->usePty & Stdout) {
-    if (dup2(d->pty->slaveFd(), STDOUT_FILENO) < 0) ok = 0;
-  } else if (communication & Stdout) {
-    if (dup2(out[1], STDOUT_FILENO) < 0 ||
-        setsockopt(out[1], SOL_SOCKET, SO_LINGER, (char *)&so, sizeof(so)))
-      ok = 0;
-    if (communication & MergedStderr) {
-      if (dup2(out[1], STDERR_FILENO) < 0)
-        ok = 0;
-    }
-  }
-  if (d->usePty & Stderr) {
-    if (dup2(d->pty->slaveFd(), STDERR_FILENO) < 0) ok = 0;
-  } else if (communication & Stderr) {
-    if (dup2(err[1], STDERR_FILENO) < 0 ||
-        setsockopt(err[1], SOL_SOCKET, SO_LINGER, (char *)&so, sizeof(so)))
-      ok = 0;
-  }
-
-  // don't even think about closing all open fds here or anywhere else
-
-  // PTY stuff //
-  if (d->usePty) {
-    d->pty->setCTty();
-    if (d->addUtmp)
-      d->pty->login(getenv("USER"), getenv("DISPLAY"));
-  }
-
-  return ok;
-}
-
-
-
-void K3Process::commClose()
-{
-  closeStdin();
-
-  if (pid_) { // detached, failed, and killed processes have no output. basta. :)
-    // If both channels are being read we need to make sure that one socket
-    // buffer doesn't fill up whilst we are waiting for data on the other
-    // (causing a deadlock). Hence we need to use select.
-
-    int notfd = K3ProcessController::instance()->notifierFd();
-
-    while ((communication & (Stdout | Stderr)) || runs) {
-      fd_set rfds;
-      FD_ZERO(&rfds);
-      struct timeval timeout, *p_timeout;
-
-      int max_fd = 0;
-      if (communication & Stdout) {
-        FD_SET(out[0], &rfds);
-        max_fd = out[0];
-      }
-      if (communication & Stderr) {
-        FD_SET(err[0], &rfds);
-        if (err[0] > max_fd)
-          max_fd = err[0];
-      }
-      if (runs) {
-        FD_SET(notfd, &rfds);
-        if (notfd > max_fd)
-          max_fd = notfd;
-        // If the process is still running we block until we
-        // receive data or the process exits.
-        p_timeout = 0; // no timeout
-      } else {
-        // If the process has already exited, we only check
-        // the available data, we don't wait for more.
-        timeout.tv_sec = timeout.tv_usec = 0; // timeout immediately
-        p_timeout = &timeout;
-      }
-
-      int fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout);
-      if (fds_ready < 0) {
-        if (errno == EINTR)
-          continue;
-        break;
-      } else if (!fds_ready)
-        break;
-
-      if ((communication & Stdout) && FD_ISSET(out[0], &rfds))
-        slotChildOutput(out[0]);
-
-      if ((communication & Stderr) && FD_ISSET(err[0], &rfds))
-        slotChildError(err[0]);
-
-      if (runs && FD_ISSET(notfd, &rfds)) {
-        runs = false; // hack: signal potential exit
-        return; // don't close anything, we will be called again
-      }
-    }
-  }
-
-  closeStdout();
-  closeStderr();
-
-  closePty();
-}
-
-
-
-///////////////////////////
-// CC: Class K3ShellProcess
-///////////////////////////
-
-K3ShellProcess::K3ShellProcess(const char *shellname):
-  K3Process(), d(0)
-{
-  setUseShell( true, shellname ? shellname : getenv("SHELL") );
-}
-
-K3ShellProcess::~K3ShellProcess() {
-}
-
-QString K3ShellProcess::quote(const QString &arg)
-{
-    return K3Process::quote(arg);
-}
-
-bool K3ShellProcess::start(RunMode runmode, Communication comm)
-{
-  return K3Process::start(runmode, comm);
-}
-
-
-//#include "moc_k3process.cpp"
--- a/gui/qtermwidget/lib/k3process.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,890 +0,0 @@
-/* This file is part of the KDE libraries
-    Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
-
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#ifndef K3PROCESS_H
-#define K3PROCESS_H
-
-#include <QtCore/QObject>
-
-#include <sys/types.h> // for pid_t
-#include <sys/wait.h>
-#include <signal.h>
-#include <unistd.h>
-
-class QSocketNotifier;
-class K3ProcessPrivate;
-class KPty;
-
-/**
- * @obsolete Use KProcess and KPtyProcess instead.
- *
- * Child process invocation, monitoring and control.
- * This class works only in the application's main thread.
- *
- * <b>General usage and features:</b>\n
- *
- * This class allows a KDE application to start child processes without having
- * to worry about UN*X signal handling issues and zombie process reaping.
- *
- * @see K3ProcIO
- *
- * Basically, this class distinguishes three different ways of running
- * child processes:
- *
- * @li  DontCare -- The child process is invoked and both the child
- * process and the parent process continue concurrently.
- *
- * The process is started in an own session (see setsid(2)).
- *
- * @li  NotifyOnExit -- The child process is invoked and both the
- * child and the parent process run concurrently.
- *
- * When the child process exits, the K3Process instance
- * corresponding to it emits the Qt signal processExited().
- * Since this signal is @em not emitted from within a UN*X
- * signal handler, arbitrary function calls can be made.
- *
- * Be aware: When the K3Process object gets destructed, the child
- * process will be killed if it is still running!
- * This means in particular, that it usually makes no sense to use
- * a K3Process on the stack with NotifyOnExit.
- *
- * @li  OwnGroup -- like NotifyOnExit, but the child process is started
- * in an own process group (and an own session, FWIW). The behavior of
- * kill() changes to killing the whole process group - this makes
- * this mode useful for implementing primitive job management. It can be
- * used to work around broken wrapper scripts that don't propagate signals
- * to the "real" program. However, use this with care, as you disturb the
- * shell's job management if your program is started from the command line.
- *
- * @li  Block -- The child process starts and the parent process
- * is suspended until the child process exits. (@em Really not recommended
- * for programs with a GUI.)
- * In this mode the parent can read the child's output, but can't send it any
- * input.
- *
- * K3Process also provides several functions for determining the exit status
- * and the pid of the child process it represents.
- *
- * Furthermore it is possible to supply command-line arguments to the process
- * in a clean fashion (no null-terminated stringlists and such...)
- *
- * A small usage example:
- * \code
- *   K3Process *proc = new K3Process;
- *
- *   *proc << "my_executable";
- *   *proc << "These" << "are" << "the" << "command" << "line" << "args";
- *   QApplication::connect(proc, SIGNAL(processExited(K3Process *)),
- *                         pointer_to_my_object, SLOT(my_objects_slot(K3Process *)));
- *   proc->start();
- * \endcode
- *
- * This will start "my_executable" with the commandline arguments "These"...
- *
- * When the child process exits, the slot will be invoked.
- *
- * <b>Communication with the child process:</b>\n
- *
- * K3Process supports communication with the child process through
- * stdin/stdout/stderr.
- *
- * The following functions are provided for getting data from the child
- * process or sending data to the child's stdin (For more information,
- * have a look at the documentation of each function):
- *
- * @li writeStdin()
- *  -- Transmit data to the child process' stdin. When all data was sent, the
- * signal wroteStdin() is emitted.
- *
- * @li When data arrives at stdout or stderr, the signal receivedStdout()
- * resp. receivedStderr() is emitted.
- *
- * @li You can shut down individual communication channels with
- * closeStdin(), closeStdout(), and closeStderr(), resp.
- *
- * @author Christian Czezatke e9025461@student.tuwien.ac.at
- *
- **/
-class K3Process : public QObject
-{
-  Q_OBJECT
-
-public:
-
-  /**
-   * Modes in which the communication channels can be opened.
-   *
-   * If communication for more than one channel is required,
-   * the values should be or'ed together, for example to get
-   * communication with stdout as well as with stdin, you would
-   * specify @p Stdin | @p Stdout
-   *
-   */
-  enum CommunicationFlag {
-       NoCommunication = 0, /**< No communication with the process. */
-       Stdin = 1, /**< Connect to write to the process with writeStdin(). */
-       Stdout = 2, /**< Connect to read from the process' output. */
-       Stderr = 4, /**< Connect to read from the process' stderr. */
-       AllOutput = 6, /**< Connects to all output channels. */
-       All = 7, /**< Connects to all channels. */
-       NoRead = 8, /**< If specified with Stdout, no data is actually read from stdout,
-                    * only the signal receivedStdout(int fd, int &len) is emitted. */
-       CTtyOnly = NoRead, /**< Tells setUsePty() to create a PTY for the process
-                           * and make it the process' controlling TTY, but does not
-                           * redirect any I/O channel to the PTY. */
-       MergedStderr = 16  /**< If specified with Stdout, the process' stderr will be
-                           * redirected onto the same file handle as its stdout, i.e.,
-                           * all error output will be signalled with receivedStdout().
-                           * Don't specify Stderr if you specify MergedStderr. */
-  };
-
-  Q_DECLARE_FLAGS(Communication, CommunicationFlag)
-
-  /**
-   * Run-modes for a child process.
-   */
-  enum RunMode {
-      /**
-       * The application does not receive notifications from the subprocess when
-       * it is finished or aborted.
-       */
-       DontCare,
-       /**
-        * The application is notified when the subprocess dies.
-        */
-       NotifyOnExit,
-       /**
-        * The application is suspended until the started process is finished.
-        */
-       Block,
-       /**
-        * Same as NotifyOnExit, but the process is run in an own session,
-        * just like with DontCare.
-        */
-       OwnGroup
-  };
-
-  /**
-   * Constructor
-   */
-  explicit K3Process( QObject* parent=0L );
-
-  /**
-   *Destructor:
-   *
-   *  If the process is running when the destructor for this class
-   *  is called, the child process is killed with a SIGKILL, but
-   *  only if the run mode is not of type @p DontCare.
-   *  Processes started as @p DontCare keep running anyway.
-  */
-  virtual ~K3Process();
-
-  /**
-   * Sets the executable and the command line argument list for this process.
-   *
-   * For example, doing an "ls -l /usr/local/bin" can be achieved by:
-   *  \code
-   *  K3Process p;
-   *  ...
-   *  p << "ls" << "-l" << "/usr/local/bin"
-   *  \endcode
-   *
-   * @param arg the argument to add
-   * @return a reference to this K3Process
-   **/
-  K3Process &operator<<(const QString& arg);
-  /**
-   * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
-   */
-  K3Process &operator<<(const char * arg);
-  /**
-   * Similar to previous method, takes a QByteArray, supposed to be in locale 8 bit already.
-   * @param arg the argument to add
-   * @return a reference to this K3Process
-   */
-  K3Process &operator<<(const QByteArray & arg);
-
-  /**
-   * Sets the executable and the command line argument list for this process,
-   * in a single method call, or add a list of arguments.
-   * @param args the arguments to add
-   * @return a reference to this K3Process
-   **/
-  K3Process &operator<<(const QStringList& args);
-
-  /**
-   * Clear a command line argument list that has been set by using
-   * operator<<.
-  */
-  void clearArguments();
-
-  /**
-   *  Starts the process.
-   *  For a detailed description of the
-   *  various run modes and communication semantics, have a look at the
-   *  general description of the K3Process class. Note that if you use
-   * setUsePty( Stdout | Stderr, \<bool\> ), you cannot use Stdout | Stderr
-   *  here - instead, use Stdout only to receive the mixed output.
-   *
-   *  The following problems could cause this function to
-   *    return false:
-   *
-   *  @li The process is already running.
-   *  @li The command line argument list is empty.
-   *  @li The the @p comm parameter is incompatible with the selected pty usage.
-   *  @li The starting of the process failed (could not fork).
-   *  @li The executable was not found.
-   *
-   *  @param runmode The Run-mode for the process.
-   *  @param comm  Specifies which communication channels should be
-   *  established to the child process (stdin/stdout/stderr). By default,
-   *  no communication takes place and the respective communication
-   *  signals will never get emitted.
-   *
-   *  @return true on success, false on error
-   *  (see above for error conditions)
-   **/
-  virtual bool start(RunMode  runmode = NotifyOnExit,
-                     Communication comm = NoCommunication);
-
-  /**
-   * Stop the process (by sending it a signal).
-   *
-   * @param signo The signal to send. The default is SIGTERM.
-   * @return true if the signal was delivered successfully.
-  */
-  virtual bool kill(int signo = SIGTERM);
-
-  /**
-   * Checks whether the process is running.
-   * @return true if the process is (still) considered to be running
-  */
-  bool isRunning() const;
-
-  /** Returns the process id of the process.
-   *
-   * If it is called after
-   * the process has exited, it returns the process id of the last
-   *  child process that was created by this instance of K3Process.
-   *
-   *  Calling it before any child process has been started by this
-   *  K3Process instance causes pid() to return 0.
-   * @return the pid of the process or 0 if no process has been started yet.
-   **/
-  pid_t pid() const;
-
-  /**
-   * Suspend processing of data from stdout of the child process.
-   */
-  void suspend();
-
-  /**
-   * Resume processing of data from stdout of the child process.
-   */
-  void resume();
-
-  /**
-   * Suspend execution of the current thread until the child process dies
-   * or the timeout hits. This function is not recommended for programs
-   * with a GUI.
-   * @param timeout timeout in seconds. -1 means wait indefinitely.
-   * @return true if the process exited, false if the timeout hit.
-   */
-  bool wait(int timeout = -1);
-
-  /**
-   * Checks whether the process exited cleanly.
-   *
-   * @return true if the process has already finished and has exited
-   *  "voluntarily", ie: it has not been killed by a signal.
-   */
-  bool normalExit() const;
-
-  /**
-   * Checks whether the process was killed by a signal.
-   *
-   * @return true if the process has already finished and has not exited
-   * "voluntarily", ie: it has been killed by a signal.
-   */
-  bool signalled() const;
-
-  /**
-   * Checks whether a killed process dumped core.
-   *
-   * @return true if signalled() returns true and the process
-   * dumped core. Note that on systems that don't define the
-   * WCOREDUMP macro, the return value is always false.
-   */
-  bool coreDumped() const;
-
-  /**
-   * Returns the exit status of the process.
-   *
-   * @return the exit status of the process. Note that this value
-   * is not valid if normalExit() returns false.
-   */
-  int exitStatus() const;
-
-  /**
-   * Returns the signal the process was killed by.
-   *
-   * @return the signal number that caused the process to exit.
-   * Note that this value is not valid if signalled() returns false.
-   */
-  int exitSignal() const;
-
-  /**
-   *	 Transmit data to the child process' stdin.
-   *
-   * This function may return false in the following cases:
-   *
-   *     @li The process is not currently running.
-   * This implies that you cannot use this function in Block mode.
-   *
-   *     @li Communication to stdin has not been requested in the start() call.
-   *
-   *     @li Transmission of data to the child process by a previous call to
-   * writeStdin() is still in progress.
-   *
-   * Please note that the data is sent to the client asynchronously,
-   * so when this function returns, the data might not have been
-   * processed by the child process.
-   * That means that you must not free @p buffer or call writeStdin()
-   * again until either a wroteStdin() signal indicates that the
-   * data has been sent or a processExited() signal shows that
-   * the child process is no longer alive.
-   *
-   * If all the data has been sent to the client, the signal
-   * wroteStdin() will be emitted.
-   *
-   * This function does not work when the process is start()ed in Block mode.
-   *
-   * @param buffer the buffer to write
-   * @param buflen the length of the buffer
-   * @return false if an error has occurred
-   **/
-  bool writeStdin(const char *buffer, int buflen);
-
-  /**
-   * Shuts down the Stdin communication link. If no pty is used, this
-   * causes "EOF" to be indicated on the child's stdin file descriptor.
-   *
-   * @return false if no Stdin communication link exists (any more).
-   */
-  bool closeStdin();
-
-  /**
-   * Shuts down the Stdout communication link. If no pty is used, any further
-   * attempts by the child to write to its stdout file descriptor will cause
-   * it to receive a SIGPIPE.
-   *
-   * @return false if no Stdout communication link exists (any more).
-   */
-  bool closeStdout();
-
-  /**
-   * Shuts down the Stderr communication link. If no pty is used, any further
-   * attempts by the child to write to its stderr file descriptor will cause
-   * it to receive a SIGPIPE.
-   *
-   * @return false if no Stderr communication link exists (any more).
-   */
-  bool closeStderr();
-
-  /**
-   * Deletes the optional utmp entry and closes the pty.
-   *
-   * Make sure to shut down any communication links that are using the pty
-   * before calling this function.
-   *
-   * @return false if the pty is not open (any more).
-   */
-  bool closePty();
-
-  /**
-   * @brief Close stdin, stdout, stderr and the pty
-   *
-   * This is the same that calling all close* functions in a row:
-   * @see closeStdin, @see closeStdout, @see closeStderr and @see closePty
-   */
-  void closeAll();
-
-  /**
-   * Lets you see what your arguments are for debugging.
-   * @return the list of arguments
-   */
-  const QList<QByteArray> &args() /* const */ { return arguments; }
-
-  /**
-   * Controls whether the started process should drop any
-   * setuid/setgid privileges or whether it should keep them.
-   * Note that this function is mostly a dummy, as the KDE libraries
-   * currently refuse to run with setuid/setgid privileges.
-   *
-   * The default is false: drop privileges
-   * @param keepPrivileges true to keep the privileges
-   */
-  void setRunPrivileged(bool keepPrivileges);
-
-  /**
-   * Returns whether the started process will drop any
-   * setuid/setgid privileges or whether it will keep them.
-   * @return true if the process runs privileged
-   */
-  bool runPrivileged() const;
-
-  /**
-   * Adds the variable @p name to the process' environment.
-   * This function must be called before starting the process.
-   * @param name the name of the environment variable
-   * @param value the new value for the environment variable
-   */
-  void setEnvironment(const QString &name, const QString &value);
-
-  /**
-   * Changes the current working directory (CWD) of the process
-   * to be started.
-   * This function must be called before starting the process.
-   * @param dir the new directory
-   */
-  void setWorkingDirectory(const QString &dir);
-
-  /**
-   * Specify whether to start the command via a shell or directly.
-   * The default is to start the command directly.
-   * If @p useShell is true @p shell will be used as shell, or
-   * if shell is empty, /bin/sh will be used.
-   *
-   * When using a shell, the caller should make sure that all filenames etc.
-   * are properly quoted when passed as argument.
-   * @see quote()
-   * @param useShell true if the command should be started via a shell
-   * @param shell the path to the shell that will execute the process, or
-   *              0 to use /bin/sh. Use getenv("SHELL") to use the user's
-   *              default shell, but note that doing so is usually a bad idea
-   *              for shell compatibility reasons.
-   */
-  void setUseShell(bool useShell, const char *shell = 0);
-
-  /**
-   * This function can be used to quote an argument string such that
-   * the shell processes it properly. This is e. g. necessary for
-   * user-provided file names which may contain spaces or quotes.
-   * It also prevents expansion of wild cards and environment variables.
-   * @param arg the argument to quote
-   * @return the quoted argument
-   */
-  static QString quote(const QString &arg);
-
-  /**
-   * Detaches K3Process from child process. All communication is closed.
-   * No exit notification is emitted any more for the child process.
-   * Deleting the K3Process will no longer kill the child process.
-   * Note that the current process remains the parent process of the
-   * child process.
-   */
-  void detach();
-
-  /**
-   * Specify whether to create a pty (pseudo-terminal) for running the
-   * command.
-   * This function should be called before starting the process.
-   *
-   * @param comm for which stdio handles to use a pty. Note that it is not
-   *  allowed to specify Stdout and Stderr at the same time both here and to
-   * start (there is only one pty, so they cannot be distinguished).
-   * @param addUtmp true if a utmp entry should be created for the pty
-   */
-  void setUsePty(Communication comm, bool addUtmp);
-
-  /**
-   * Obtains the pty object used by this process. The return value is
-   * valid only after setUsePty() was used with a non-zero argument.
-   * The pty is open only while the process is running.
-   * @return a pointer to the pty object
-   */
-  KPty *pty() const;
-
-  /**
-   * More or less intuitive constants for use with setPriority().
-   */
-  enum { PrioLowest = 20, PrioLow = 10, PrioLower = 5, PrioNormal = 0,
-    PrioHigher = -5, PrioHigh = -10, PrioHighest = -19 };
-
-  /**
-   * Sets the scheduling priority of the process.
-   * @param prio the new priority in the range -20 (high) to 19 (low).
-   * @return false on error; see setpriority(2) for possible reasons.
-   */
-  bool setPriority(int prio);
-
-Q_SIGNALS:
-  /**
-   * Emitted after the process has terminated when
-   * the process was run in the @p NotifyOnExit  (==default option to
-   * start() ) or the Block mode.
-   * @param proc a pointer to the process that has exited
-   **/
-  void processExited(K3Process *proc);
-
-
-  /**
-   * Emitted, when output from the child process has
-   * been received on stdout.
-   *
-   * To actually get this signal, the Stdout communication link
-   * has to be turned on in start().
-   *
-   * @param proc a pointer to the process that has received the output
-   * @param buffer The data received.
-   * @param buflen The number of bytes that are available.
-   *
-   * You should copy the information contained in @p buffer to your private
-   * data structures before returning from the slot.
-   * Example:
-   * \code
-   *     QString myBuf = QLatin1String(buffer, buflen);
-   * \endcode
-   **/
-  void receivedStdout(K3Process *proc, char *buffer, int buflen);
-
-  /**
-   * Emitted when output from the child process has
-   * been received on stdout.
-   *
-   * To actually get this signal, the Stdout communication link
-   * has to be turned on in start() and the
-   * NoRead flag must have been passed.
-   *
-   * You will need to explicitly call resume() after your call to start()
-   * to begin processing data from the child process' stdout.  This is
-   * to ensure that this signal is not emitted when no one is connected
-   * to it, otherwise this signal will not be emitted.
-   *
-   * The data still has to be read from file descriptor @p fd.
-   * @param fd the file descriptor that provides the data
-   * @param len the number of bytes that have been read from @p fd must
-   *  be written here
-   **/
-  void receivedStdout(int fd, int &len); // KDE4: change, broken API
-
-
-  /**
-   * Emitted, when output from the child process has
-   * been received on stderr.
-   *
-   * To actually get this signal, the Stderr communication link
-   * has to be turned on in start().
-   *
-   * You should copy the information contained in @p buffer to your private
-   * data structures before returning from the slot.
-   *
-   * @param proc a pointer to the process that has received the data
-   * @param buffer The data received.
-   * @param buflen The number of bytes that are available.
-   **/
-  void receivedStderr(K3Process *proc, char *buffer, int buflen);
-
-  /**
-   * Emitted after all the data that has been
-   * specified by a prior call to writeStdin() has actually been
-   * written to the child process.
-   * @param proc a pointer to the process
-   **/
-  void wroteStdin(K3Process *proc);
-
-
-protected Q_SLOTS:
-
- /**
-  * This slot gets activated when data from the child's stdout arrives.
-  * It usually calls childOutput().
-  * @param fdno the file descriptor for the output
-  */
-  void slotChildOutput(int fdno);
-
- /**
-  * This slot gets activated when data from the child's stderr arrives.
-  * It usually calls childError().
-  * @param fdno the file descriptor for the output
-  */
-  void slotChildError(int fdno);
-
-  /**
-   * Called when another bulk of data can be sent to the child's
-   * stdin. If there is no more data to be sent to stdin currently
-   * available, this function must disable the QSocketNotifier innot.
-   * @param dummy ignore this argument
-   */
-  void slotSendData(int dummy);	// KDE 4: remove dummy
-
-protected:
-
-  /**
-   * Sets up the environment according to the data passed via
-   * setEnvironment()
-   */
-  void setupEnvironment();
-
-  /**
-   * The list of the process' command line arguments. The first entry
-   * in this list is the executable itself.
-   */
-  QList<QByteArray> arguments;
-  /**
-   * How to run the process (Block, NotifyOnExit, DontCare). You should
-   *  not modify this data member directly from derived classes.
-   */
-  RunMode run_mode;
-  /**
-   * true if the process is currently running. You should not
-   * modify this data member directly from derived classes. Please use
-   * isRunning() for reading the value of this data member since it
-   * will probably be made private in later versions of K3Process.
-   */
-  bool runs;
-
-  /**
-   * The PID of the currently running process.
-   * You should not modify this data member in derived classes.
-   * Please use pid() instead of directly accessing this
-   * member since it will probably be made private in
-   * later versions of K3Process.
-   */
-  pid_t pid_;
-
-  /**
-   * The process' exit status as returned by waitpid(). You should not
-   * modify the value of this data member from derived classes. You should
-   * rather use exitStatus() than accessing this data member directly
-   * since it will probably be made private in further versions of
-   * K3Process.
-   */
-  int status;
-
-
-  /**
-   * If false, the child process' effective uid & gid will be reset to the
-   * real values.
-   * @see setRunPrivileged()
-   */
-  bool keepPrivs;
-
-  /**
-   * This function is called from start() right before a fork() takes
-   * place. According to the @p comm parameter this function has to initialize
-   * the in, out and err data members of K3Process.
-   *
-   * This function should return 1 if setting the needed communication channels
-   * was successful.
-   *
-   * The default implementation is to create UNIX STREAM sockets for the
-   * communication, but you could reimplement this function to establish a
-   * TCP/IP communication for network communication, for example.
-   */
-  virtual int setupCommunication(Communication comm);
-
-  /**
-   * Called right after a (successful) fork() on the parent side. This function
-   * will usually do some communications cleanup, like closing in[0],
-   * out[1] and out[1].
-   *
-   * Furthermore, it must also create the QSocketNotifiers innot,
-   * outnot and errnot and connect their Qt signals to the respective
-   * K3Process slots.
-   *
-   * For a more detailed explanation, it is best to have a look at the default
-   * implementation in kprocess.cpp.
-   */
-  virtual int commSetupDoneP();
-
-  /**
-   * Called right after a (successful) fork(), but before an exec() on the child
-   * process' side. It usually duplicates the in[0], out[1] and
-   * err[1] file handles to the respective standard I/O handles.
-   */
-  virtual int commSetupDoneC();
-
-
-  /**
-   * Immediately called after a successfully started process in NotifyOnExit
-   * mode has exited. This function normally calls commClose()
-   * and emits the processExited() signal.
-   * @param state the exit code of the process as returned by waitpid()
-   */
-  virtual void processHasExited(int state);
-
-  /**
-   * Cleans up the communication links to the child after it has exited.
-   * This function should act upon the values of pid() and runs.
-   * See the kprocess.cpp source for details.
-   * @li If pid() returns zero, the communication links should be closed
-   *  only.
-   * @li if pid() returns non-zero and runs is false, all data
-   *  immediately available from the communication links should be processed
-   *  before closing them.
-   * @li if pid() returns non-zero and runs is true, the communication
-   *  links should be monitored for data until the file handle returned by
-   *  K3ProcessController::theKProcessController->notifierFd() becomes ready
-   *  for reading - when it triggers, runs should be reset to false, and
-   *  the function should be immediately left without closing anything.
-   *
-   * The previous semantics of this function are forward-compatible, but should
-   * be avoided, as they are prone to race conditions and can cause K3Process
-   * (and thus the whole program) to lock up under certain circumstances. At the
-   * end the function closes the communication links in any case. Additionally
-   * @li if runs is true, the communication links are monitored for data
-   *  until all of them have returned EOF. Note that if any system function is
-   *  interrupted (errno == EINTR) the polling loop should be aborted.
-   * @li if runs is false, all data immediately available from the
-   *  communication links is processed.
-   */
-  virtual void commClose();
-
-  /* KDE 4 - commClose will be changed to perform cleanup only in all cases *
-   * If @p notfd is -1, all data immediately available from the
-   *  communication links should be processed.
-   * If @p notfd is not -1, the communication links should be monitored
-   *  for data until the file handle @p notfd becomes ready for reading.
-   */
-//  virtual void commDrain(int notfd);
-
-  /**
-   * Specify the actual executable that should be started (first argument to execve)
-   * Normally the the first argument is the executable but you can
-   * override that with this function.
-   */
-  void setBinaryExecutable(const char *filename);
-
-  /**
-   * The socket descriptors for stdout.
-   */
-  int out[2];
-  /**
-   * The socket descriptors for stdin.
-   */
-  int in[2];
-  /**
-   * The socket descriptors for stderr.
-   */
-  int err[2];
-
-  /**
-   * The socket notifier for in[1].
-   */
-  QSocketNotifier *innot;
-  /**
-   * The socket notifier for out[0].
-   */
-  QSocketNotifier *outnot;
-  /**
-   * The socket notifier for err[0].
-   */
-  QSocketNotifier *errnot;
-
-  /**
-   * Lists the communication links that are activated for the child
-   * process.  Should not be modified from derived classes.
-   */
-  Communication communication;
-
-  /**
-   * Called by slotChildOutput() this function copies data arriving from
-   * the child process' stdout to the respective buffer and emits the signal
-   * receivedStdout().
-   */
-  int childOutput(int fdno);
-
-  /**
-   * Called by slotChildError() this function copies data arriving from
-   * the child process' stderr to the respective buffer and emits the signal
-   * receivedStderr().
-   */
-  int childError(int fdno);
-
-  /**
-   * The buffer holding the data that has to be sent to the child
-   */
-  const char *input_data;
-  /**
-   * The number of bytes already transmitted
-   */
-  int input_sent;
-  /**
-   * The total length of input_data
-   */
-  int input_total;
-
-  /**
-   * K3ProcessController is a friend of K3Process because it has to have
-   * access to various data members.
-   */
-  friend class K3ProcessController;
-
-private:
-  K3ProcessPrivate* const d;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(K3Process::Communication)
-
-class K3ShellProcessPrivate;
-
-/**
-* @obsolete
-*
-* Use K3Process and K3Process::setUseShell(true) instead.
-*
-*   @short A class derived from K3Process to start child
-*   	processes through a shell.
-*   @author Christian Czezatke <e9025461@student.tuwien.ac.at>
-*/
-class K3ShellProcess : public K3Process
-{
-  Q_OBJECT
-
-public:
-
-  /**
-   * Constructor
-   *
-   * If no shellname is specified, the user's default shell is used.
-   */
-  explicit K3ShellProcess(const char *shellname=0);
-
-  /**
-   * Destructor.
-   */
-  ~K3ShellProcess();
-
-  virtual bool start(RunMode  runmode = NotifyOnExit,
-		  Communication comm = NoCommunication);
-
-  static QString quote(const QString &arg);
-
-private:
-  K3ShellProcessPrivate* const d;
-};
-
-
-
-#endif
-
--- a/gui/qtermwidget/lib/k3processcontroller.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-/* This file is part of the KDE libraries
-    Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
-
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#include "k3processcontroller.h"
-#include "k3process.h"
-
-//#include <config.h>
-
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <QtCore/QSocketNotifier>
-
-class K3ProcessController::Private
-{
-public:
-    Private()
-        : needcheck( false ),
-          notifier( 0 )
-    {
-    }
-
-    ~Private()
-    {
-        delete notifier;
-    }
-
-    int fd[2];
-    bool needcheck;
-    QSocketNotifier *notifier;
-    QList<K3Process*> kProcessList;
-    QList<int> unixProcessList;
-    static struct sigaction oldChildHandlerData;
-    static bool handlerSet;
-    static int refCount;
-    static K3ProcessController* instance;
-};
-
-K3ProcessController *K3ProcessController::Private::instance = 0;
-int K3ProcessController::Private::refCount = 0;
-
-void K3ProcessController::ref()
-{
-    if ( !Private::refCount ) {
-        Private::instance = new K3ProcessController;
-        setupHandlers();
-    }
-    Private::refCount++;
-}
-
-void K3ProcessController::deref()
-{
-    Private::refCount--;
-    if( !Private::refCount ) {
-        resetHandlers();
-        delete Private::instance;
-        Private::instance = 0;
-    }
-}
-
-K3ProcessController* K3ProcessController::instance()
-{
-    /*
-     * there were no safety guards in previous revisions, is that ok?
-    if ( !Private::instance ) {
-        ref();
-    }
-     */
-
-    return Private::instance;
-}
-
-K3ProcessController::K3ProcessController()
-  : d( new Private )
-{
-  if( pipe( d->fd ) )
-  {
-    perror( "pipe" );
-    abort();
-  }
-
-  fcntl( d->fd[0], F_SETFL, O_NONBLOCK ); // in case slotDoHousekeeping is called without polling first
-  fcntl( d->fd[1], F_SETFL, O_NONBLOCK ); // in case it fills up
-  fcntl( d->fd[0], F_SETFD, FD_CLOEXEC );
-  fcntl( d->fd[1], F_SETFD, FD_CLOEXEC );
-
-  d->notifier = new QSocketNotifier( d->fd[0], QSocketNotifier::Read );
-  d->notifier->setEnabled( true );
-  QObject::connect( d->notifier, SIGNAL(activated(int)),
-                    SLOT(slotDoHousekeeping()));
-}
-
-K3ProcessController::~K3ProcessController()
-{
-#ifndef Q_OS_MAC
-/* not sure why, but this is causing lockups */
-  close( d->fd[0] );
-  close( d->fd[1] );
-#else
-#warning FIXME: why does close() freeze up destruction?
-#endif
-
-  delete d;
-}
-
-
-extern "C" {
-static void theReaper( int num )
-{
-  K3ProcessController::theSigCHLDHandler( num );
-}
-}
-
-#ifdef Q_OS_UNIX
-struct sigaction K3ProcessController::Private::oldChildHandlerData;
-#endif
-bool K3ProcessController::Private::handlerSet = false;
-
-void K3ProcessController::setupHandlers()
-{
-  if( Private::handlerSet )
-      return;
-  Private::handlerSet = true;
-
-#ifdef Q_OS_UNIX
-  struct sigaction act;
-  sigemptyset( &act.sa_mask );
-
-  act.sa_handler = SIG_IGN;
-  act.sa_flags = 0;
-  sigaction( SIGPIPE, &act, 0L );
-
-  act.sa_handler = theReaper;
-  act.sa_flags = SA_NOCLDSTOP;
-  // CC: take care of SunOS which automatically restarts interrupted system
-  // calls (and thus does not have SA_RESTART)
-#ifdef SA_RESTART
-  act.sa_flags |= SA_RESTART;
-#endif
-  sigaction( SIGCHLD, &act, &Private::oldChildHandlerData );
-
-  sigaddset( &act.sa_mask, SIGCHLD );
-  // Make sure we don't block this signal. gdb tends to do that :-(
-  sigprocmask( SIG_UNBLOCK, &act.sa_mask, 0 );
-#else
-  //TODO: win32
-#endif
-}
-
-void K3ProcessController::resetHandlers()
-{
-  if( !Private::handlerSet )
-      return;
-  Private::handlerSet = false;
-
-#ifdef Q_OS_UNIX
-  sigset_t mask, omask;
-  sigemptyset( &mask );
-  sigaddset( &mask, SIGCHLD );
-  sigprocmask( SIG_BLOCK, &mask, &omask );
-
-  struct sigaction act;
-  sigaction( SIGCHLD, &Private::oldChildHandlerData, &act );
-  if (act.sa_handler != theReaper) {
-     sigaction( SIGCHLD, &act, 0 );
-     Private::handlerSet = true;
-  }
-
-  sigprocmask( SIG_SETMASK, &omask, 0 );
-#else
-  //TODO: win32
-#endif
-  // there should be no problem with SIGPIPE staying SIG_IGN
-}
-
-// the pipe is needed to sync the child reaping with our event processing,
-// as otherwise there are race conditions, locking requirements, and things
-// generally get harder
-void K3ProcessController::theSigCHLDHandler( int arg )
-{
-  int saved_errno = errno;
-
-  char dummy = 0;
-  ::write( instance()->d->fd[1], &dummy, 1 );
-
-#ifdef Q_OS_UNIX
-    if ( Private::oldChildHandlerData.sa_handler != SIG_IGN &&
-         Private::oldChildHandlerData.sa_handler != SIG_DFL ) {
-        Private::oldChildHandlerData.sa_handler( arg ); // call the old handler
-    }
-#else
-  //TODO: win32
-#endif
-
-  errno = saved_errno;
-}
-
-int K3ProcessController::notifierFd() const
-{
-  return d->fd[0];
-}
-
-void K3ProcessController::unscheduleCheck()
-{
-  char dummy[16]; // somewhat bigger - just in case several have queued up
-  if( ::read( d->fd[0], dummy, sizeof(dummy) ) > 0 )
-    d->needcheck = true;
-}
-
-void
-K3ProcessController::rescheduleCheck()
-{
-  if( d->needcheck )
-  {
-    d->needcheck = false;
-    char dummy = 0;
-    ::write( d->fd[1], &dummy, 1 );
-  }
-}
-
-void K3ProcessController::slotDoHousekeeping()
-{
-  char dummy[16]; // somewhat bigger - just in case several have queued up
-  ::read( d->fd[0], dummy, sizeof(dummy) );
-
-  int status;
- again:
-  QList<K3Process*>::iterator it( d->kProcessList.begin() );
-  QList<K3Process*>::iterator eit( d->kProcessList.end() );
-  while( it != eit )
-  {
-    K3Process *prc = *it;
-    if( prc->runs && waitpid( prc->pid_, &status, WNOHANG ) > 0 )
-    {
-      prc->processHasExited( status );
-      // the callback can nuke the whole process list and even 'this'
-      if (!instance())
-        return;
-      goto again;
-    }
-    ++it;
-  }
-  QList<int>::iterator uit( d->unixProcessList.begin() );
-  QList<int>::iterator ueit( d->unixProcessList.end() );
-  while( uit != ueit )
-  {
-    if( waitpid( *uit, 0, WNOHANG ) > 0 )
-    {
-      uit = d->unixProcessList.erase( uit );
-      deref(); // counterpart to addProcess, can invalidate 'this'
-    } else
-      ++uit;
-  }
-}
-
-bool K3ProcessController::waitForProcessExit( int timeout )
-{
-#ifdef Q_OS_UNIX
-  for(;;)
-  {
-    struct timeval tv, *tvp;
-    if (timeout < 0)
-      tvp = 0;
-    else
-    {
-      tv.tv_sec = timeout;
-      tv.tv_usec = 0;
-      tvp = &tv;
-    }
-
-    fd_set fds;
-    FD_ZERO( &fds );
-    FD_SET( d->fd[0], &fds );
-
-    switch( select( d->fd[0]+1, &fds, 0, 0, tvp ) )
-    {
-    case -1:
-      if( errno == EINTR )
-        continue;
-      // fall through; should never happen
-    case 0:
-      return false;
-    default:
-      slotDoHousekeeping();
-      return true;
-    }
-  }
-#else
-  //TODO: win32
-  return false;
-#endif
-}
-
-void K3ProcessController::addKProcess( K3Process* p )
-{
-  d->kProcessList.append( p );
-}
-
-void K3ProcessController::removeKProcess( K3Process* p )
-{
-  d->kProcessList.removeAll( p );
-}
-
-void K3ProcessController::addProcess( int pid )
-{
-  d->unixProcessList.append( pid );
-  ref(); // make sure we stay around when the K3Process goes away
-}
-
-//#include "moc_k3processcontroller.cpp"
--- a/gui/qtermwidget/lib/k3processcontroller.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/* This file is part of the KDE libraries
-    Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
-
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#ifndef K3PROCCTRL_H
-#define K3PROCCTRL_H
-
-#include <QtCore/QList>
-#include <k3process.h>
-
-
-/**
- * @short Used internally by K3Process
- * @internal
- * @author Christian Czezatke <e9025461@student.tuwien.ac.at>
- *
- *  A class for internal use by K3Process only. -- Exactly one instance
- *  of this class is created by KApplication.
- *
- * This class takes care of the actual (UN*X) signal handling.
- */
-class K3ProcessController : public QObject
-{
-  Q_OBJECT
-
-public:
-  /**
-   * Create an instance if none exists yet.
-   * Called by KApplication::KApplication()
-   */
-  static void ref();
-
-  /**
-   * Destroy the instance if one exists and it is not referenced any more.
-   * Called by KApplication::~KApplication()
-   */
-  static void deref();
-
-  /**
-   * Only a single instance of this class is allowed at a time.
-   * This method provides access to that instance.
-   */
-  static K3ProcessController *instance();
-
-  /**
-   * Automatically called upon SIGCHLD. Never call it directly.
-   * If your application (or some library it uses) redirects SIGCHLD,
-   * the new signal handler (and only it) should call the old handler
-   * returned by sigaction().
-   * @internal
-   */
-  static void theSigCHLDHandler(int signal); // KDE4: private
-
-  /**
-   * Wait for any process to exit and handle their exit without
-   * starting an event loop.
-   * This function may cause K3Process to emit any of its signals.
-   *
-   * @param timeout the timeout in seconds. -1 means no timeout.
-   * @return true if a process exited, false
-   *         if no process exited within @p timeout seconds.
-   */
-  bool waitForProcessExit(int timeout);
-
-  /**
-   * Call this function to defer processing of the data that became available
-   * on notifierFd().
-   */
-  void unscheduleCheck();
-
-  /**
-   * This function @em must be called at some point after calling
-   * unscheduleCheck().
-   */
-  void rescheduleCheck();
-
-  /*
-   * Obtain the file descriptor K3ProcessController uses to get notified
-   * about process exits. select() or poll() on it if you create a custom
-   * event loop that needs to act upon SIGCHLD.
-   * @return the file descriptor of the reading end of the notification pipe
-   */
-  int notifierFd() const;
-
-  /**
-   * @internal
-   */
-  void addKProcess( K3Process* );
-  /**
-   * @internal
-   */
-  void removeKProcess( K3Process* );
-  /**
-   * @internal
-   */
-  void addProcess( int pid );
-
-private Q_SLOTS:
-  void slotDoHousekeeping();
-
-private:
-  friend class I_just_love_gcc;
-
-  static void setupHandlers();
-  static void resetHandlers();
-
-  // Disallow instantiation
-  K3ProcessController();
-  ~K3ProcessController();
-
-  // Disallow assignment and copy-construction
-  K3ProcessController( const K3ProcessController& );
-  K3ProcessController& operator= ( const K3ProcessController& );
-
-  class Private;
-  Private * const d;
-};
-
-#endif
-
--- a/gui/qtermwidget/lib/kb-layouts/CVS/Entries	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-/default.keytab/1.1.1.1/Sat May 10 21:27:57 2008//
-/linux.keytab/1.1.1.1/Sat May 10 21:27:57 2008//
-/vt420pc.keytab/1.1.1.1/Sat May 10 21:27:57 2008//
-D
--- a/gui/qtermwidget/lib/kb-layouts/CVS/Repository	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-qtermwidget/lib/kb-layouts
--- a/gui/qtermwidget/lib/kb-layouts/CVS/Root	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-:ext:e_k@qtermwidget.cvs.sourceforge.net:/cvsroot/qtermwidget
--- a/gui/qtermwidget/lib/kb-layouts/default.keytab	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-# [README.default.Keytab] Buildin Keyboard Table
-#
-# To customize your keyboard, copy this file to something
-# ending with .keytab and change it to meet you needs.
-# Please read the README.KeyTab and the README.keyboard
-# in this case.
-#
-# --------------------------------------------------------------
-
-keyboard "Default (XFree 4)"
-
-# --------------------------------------------------------------
-#
-# Note that this particular table is a "risc" version made to
-# ease customization without bothering with obsolete details.
-# See VT100.keytab for the more hairy stuff.
-#
-# --------------------------------------------------------------
-
-# common keys
-
-key Escape             : "\E"
-
-key Tab   -Shift       : "\t"
-key Tab   +Shift+Ansi  : "\E[Z"
-key Tab   +Shift-Ansi  : "\t"
-key Backtab     +Ansi  : "\E[Z"
-key Backtab     -Ansi  : "\t"
-
-key Return-Shift-NewLine : "\r"
-key Return-Shift+NewLine : "\r\n"
-
-key Return+Shift         : "\EOM"
-
-# Backspace and Delete codes are preserving CTRL-H.
-
-key Backspace      : "\x7f"
-
-# Arrow keys in VT52 mode
-# shift up/down are reserved for scrolling.
-# shift left/right are reserved for switching between tabs (this is hardcoded).
-
-key Up   -Shift-Ansi : "\EA"
-key Down -Shift-Ansi : "\EB"
-key Right-Shift-Ansi : "\EC"
-key Left -Shift-Ansi : "\ED"
-
-# Arrow keys in ANSI mode with Application - and Normal Cursor Mode)
-
-key Up    -Shift-AnyMod+Ansi+AppCuKeys           : "\EOA"
-key Down  -Shift-AnyMod+Ansi+AppCuKeys           : "\EOB"
-key Right -Shift-AnyMod+Ansi+AppCuKeys           : "\EOC"
-key Left  -Shift-AnyMod+Ansi+AppCuKeys           : "\EOD"
-
-key Up    -Shift-AnyMod+Ansi-AppCuKeys           : "\E[A"
-key Down  -Shift-AnyMod+Ansi-AppCuKeys           : "\E[B"
-key Right -Shift-AnyMod+Ansi-AppCuKeys           : "\E[C"
-key Left  -Shift-AnyMod+Ansi-AppCuKeys           : "\E[D"
-
-key Up    -Shift+AnyMod+Ansi                     : "\E[1;*A"
-key Down  -Shift+AnyMod+Ansi                     : "\E[1;*B"
-key Right -Shift+AnyMod+Ansi                     : "\E[1;*C"
-key Left  -Shift+AnyMod+Ansi                     : "\E[1;*D"
-
-# other grey PC keys
-
-key Enter+NewLine : "\r\n"
-key Enter-NewLine : "\r"
-
-key Home        -AnyMod     -AppCuKeys           : "\E[H"  
-key End         -AnyMod     -AppCuKeys           : "\E[F"  
-key Home        -AnyMod     +AppCuKeys           : "\EOH"  
-key End         -AnyMod     +AppCuKeys           : "\EOF"  
-key Home        +AnyMod                          : "\E[1;*H"
-key End         +AnyMod                          : "\E[1;*F"
-
-key Insert      -AnyMod                          : "\E[2~"
-key Delete      -AnyMod                          : "\E[3~"
-key Insert      +AnyMod                          : "\E[2;*~"
-key Delete      +AnyMod                          : "\E[3;*~"
-
-key Prior -Shift-AnyMod                          : "\E[5~"
-key Next  -Shift-AnyMod                          : "\E[6~"
-key Prior -Shift+AnyMod                          : "\E[5;*~"
-key Next  -Shift+AnyMod                          : "\E[6;*~"
-
-# Function keys
-key F1          -AnyMod                          : "\EOP"
-key F2          -AnyMod                          : "\EOQ"
-key F3          -AnyMod                          : "\EOR"
-key F4          -AnyMod                          : "\EOS"
-key F5          -AnyMod                          : "\E[15~"
-key F6          -AnyMod                          : "\E[17~"
-key F7          -AnyMod                          : "\E[18~"
-key F8          -AnyMod                          : "\E[19~"
-key F9          -AnyMod                          : "\E[20~"
-key F10         -AnyMod                          : "\E[21~"
-key F11         -AnyMod                          : "\E[23~"
-key F12         -AnyMod                          : "\E[24~"
-
-key F1          +AnyMod                          : "\EO*P"
-key F2          +AnyMod                          : "\EO*Q"
-key F3          +AnyMod                          : "\EO*R"
-key F4          +AnyMod                          : "\EO*S"
-key F5          +AnyMod                          : "\E[15;*~"
-key F6          +AnyMod                          : "\E[17;*~"
-key F7          +AnyMod                          : "\E[18;*~"
-key F8          +AnyMod                          : "\E[19;*~"
-key F9          +AnyMod                          : "\E[20;*~"
-key F10         +AnyMod                          : "\E[21;*~"
-key F11         +AnyMod                          : "\E[23;*~"
-key F12         +AnyMod                          : "\E[24;*~"
-
-# Work around dead keys
-
-key Space +Control : "\x00"
-
-# Some keys are used by konsole to cause operations.
-# The scroll* operations refer to the history buffer.
-
-key Up    +Shift-AppScreen  : scrollLineUp
-key Prior +Shift-AppScreen  : scrollPageUp
-key Down  +Shift-AppScreen  : scrollLineDown
-key Next  +Shift-AppScreen  : scrollPageDown
-
-#key Up    +Shift  : scrollLineUp
-#key Prior +Shift  : scrollPageUp
-#key Down  +Shift  : scrollLineDown
-#key Next  +Shift  : scrollPageDown
-
-key ScrollLock     : scrollLock
-
-# keypad characters are not offered differently by Qt.
--- a/gui/qtermwidget/lib/kb-layouts/linux.keytab	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-# [linux.keytab] Konsole Keyboard Table (Linux console keys)
-#
-# --------------------------------------------------------------
-
-# NOT TESTED, MAY NEED SOME CLEANUPS
-keyboard "Linux console"
-
-# --------------------------------------------------------------
-#
-# This configuration table allows to customize the
-# meaning of the keys.
-#
-# The syntax is that each entry has the form : 
-#
-#   "key" Keyname { ("+"|"-") Modename } ":" (String|Operation)
-#
-# Keynames are those defined in <qnamespace.h> with the
-# "Qt::Key_" removed. (We'd better insert the list here)
-#
-# Mode names are : 
-#
-# - Shift
-# - Alt
-# - Control
-#
-#   The VT100 emulation has two modes that can affect the
-#   sequences emitted by certain keys. These modes are
-#   under control of the client program.
-#   
-# - Newline     : effects Return and Enter key.
-# - Application : effects Up and Down key.
-#
-# - Ansi        : effects Up and Down key (This is for VT52, really).
-#
-# Operations are
-#
-# - scrollUpLine
-# - scrollUpPage
-# - scrollDownLine
-# - scrollDownPage
-#
-# - emitSelection
-#
-# If the key is not found here, the text of the
-# key event as provided by QT is emitted, possibly
-# preceeded by ESC if the Alt key is pressed.
-#
-# --------------------------------------------------------------
-
-key Escape : "\E"
-key Tab    : "\t"
-
-# VT100 can add an extra \n after return.
-# The NewLine mode is set by an escape sequence.
-
-key Return-NewLine : "\r"  
-key Return+NewLine : "\r\n"
-
-# Some desperately try to save the ^H.
-
-key Backspace : "\x7f"
-key Delete    : "\E[3~"
-
-# These codes are for the VT52 mode of VT100
-# The Ansi mode (i.e. VT100 mode) is set by
-# an escape sequence
-
-key Up   -Shift-Ansi : "\EA"
-key Down -Shift-Ansi : "\EB"
-key Right-Shift-Ansi : "\EC"
-key Left -Shift-Ansi : "\ED"
-
-# VT100 emits a mode bit together
-# with the arrow keys.The AppCuKeys
-# mode is set by an escape sequence.
-
-key Up   -Shift+Ansi+AppCuKeys : "\EOA"
-key Down -Shift+Ansi+AppCuKeys : "\EOB"
-key Right-Shift+Ansi+AppCuKeys : "\EOC"
-key Left -Shift+Ansi+AppCuKeys : "\EOD"
-
-key Up   -Shift+Ansi-AppCuKeys : "\E[A"
-key Down -Shift+Ansi-AppCuKeys : "\E[B"
-key Right-Shift+Ansi-AppCuKeys : "\E[C"
-key Left -Shift+Ansi-AppCuKeys : "\E[D"
-
-# linux functions keys F1-F5 differ from xterm
-
-key F1 : "\E[[A" 
-key F2 : "\E[[B" 
-key F3 : "\E[[C" 
-key F4 : "\E[[D" 
-key F5 : "\E[[E" 
-
-key F6     : "\E[17~" 
-key F7     : "\E[18~" 
-key F8     : "\E[19~" 
-key F9     : "\E[20~" 
-key F10    : "\E[21~" 
-key F11    : "\E[23~" 
-key F12    : "\E[24~" 
-
-key Home   : "\E[1~"  
-key End    : "\E[4~"  
-
-key Prior -Shift : "\E[5~"  
-key Next  -Shift : "\E[6~"  
-key Insert-Shift : "\E[2~"  
-
-# Keypad-Enter. See comment on Return above.
-
-key Enter+NewLine : "\r\n"
-key Enter-NewLine : "\r"  
-
-key Space +Control : "\x00"
-
-# some of keys are used by konsole.
-
-key Up    +Shift   : scrollLineUp
-key Prior +Shift   : scrollPageUp
-key Down  +Shift   : scrollLineDown
-key Next  +Shift   : scrollPageDown
-
-key ScrollLock     : scrollLock
-
-#----------------------------------------------------------
-
-# keypad characters as offered by Qt
-# cannot be recognized as such.
-
-#----------------------------------------------------------
-
-# Following other strings as emitted by konsole.
--- a/gui/qtermwidget/lib/kb-layouts/vt420pc.keytab	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-# [vt420pc.keytab] Konsole Keyboard Table (VT420pc keys)
-# adapted by ferdinand gassauer f.gassauer@aon.at
-# Nov 2000
-#
-################################################################
-#
-# The escape sequences emmited by the 
-# keys Shift+F1 to Shift+F12 might not fit your needs
-#
-################# IMPORTANT NOTICE #############################
-# the key bindings (Kcontrol -> look and feel -> keybindgs) 
-# overrule the settings in this file. The key bindings might be 
-# changed by the user WITHOUT notification of the maintainer of
-# the keytab file. Konsole will not work as expected by 
-# the maintainer of the keytab file.
-################################################################
-#
-# --------------------------------------------------------------
-
-keyboard "DEC VT420 Terminal"
-
-# --------------------------------------------------------------
-#
-# This configuration table allows to customize the
-# meaning of the keys.
-#
-# The syntax is that each entry has the form : 
-#
-#   "key" Keyname { ("+"|"-") Modename } ":" (String|Operation)
-#
-# Keynames are those defined in <qnamespace.h> with the
-# "Qt::Key_" removed. (We'd better insert the list here)
-#
-# Mode names are : 
-#
-# - Shift
-# - Alt
-# - Control
-#
-#   The VT100 emulation has two modes that can affect the
-#   sequences emitted by certain keys. These modes are
-#   under control of the client program.
-#   
-# - Newline     : effects Return and Enter key.
-# - Application : effects Up and Down key.
-#
-# - Ansi        : effects Up and Down key (This is for VT52, really).
-#
-# Operations are
-#
-# - scrollUpLine
-# - scrollUpPage
-# - scrollDownLine
-# - scrollDownPage
-#
-# - emitSelection
-#
-# If the key is not found here, the text of the
-# key event as provided by QT is emitted, possibly
-# preceeded by ESC if the Alt key is pressed.
-#
-# --------------------------------------------------------------
-
-key Escape : "\E"
-key Tab    : "\t"
-key Backtab: "\E[Z"
-
-# VT100 can add an extra \n after return.
-# The NewLine mode is set by an escape sequence.
-
-key Return-NewLine : "\r"  
-key Return+NewLine : "\r\n"
-
-# Some desperately try to save the ^H.
-# may be not everyone wants this
-
-key Backspace : "\x08"  # Control H
-key Delete    : "\x7f"
-
-# These codes are for the VT420pc
-# The Ansi mode (i.e. VT100 mode) is set by
-# an escape sequence
-
-key Up   -Shift-Ansi : "\EA"
-key Down -Shift-Ansi : "\EB"
-key Right-Shift-Ansi : "\EC"
-key Left -Shift-Ansi : "\ED"
-
-# VT100 emits a mode bit together
-# with the arrow keys.The AppCuKeys
-# mode is set by an escape sequence.
-
-key Up   -Shift+Ansi+AppCuKeys : "\EOA"
-key Down -Shift+Ansi+AppCuKeys : "\EOB"
-key Right-Shift+Ansi+AppCuKeys : "\EOC"
-key Left -Shift+Ansi+AppCuKeys : "\EOD"
-
-key Up   -Shift+Ansi-AppCuKeys : "\E[A"
-key Down -Shift+Ansi-AppCuKeys : "\E[B"
-key Right-Shift+Ansi-AppCuKeys : "\E[C"
-key Left -Shift+Ansi-AppCuKeys : "\E[D"
-
-# function keys 
-
-key F1 -Shift    : "\E[11~"  
-key F2 -Shift    : "\E[12~"
-key F3 -Shift    : "\E[13~"
-key F4 -Shift    : "\E[14~"
-key F5 -Shift    : "\E[15~"
-key F6 -Shift    : "\E[17~"
-key F7 -Shift    : "\E[18~"
-key F8 -Shift    : "\E[19~"
-key F9 -Shift    : "\E[20~"
-key F10-Shift    : "\E[21~"
-key F11-Shift    : "\E[23~"
-key F12-Shift    : "\E[24~"  
-#
-# Shift F1-F12
-#
-key F1 +Shift    : "\E[11;2~"
-key F2 +Shift    : "\E[12;2~"
-key F3 +Shift    : "\E[13;2~"
-key F4 +Shift    : "\E[14;2~"
-key F5 +Shift    : "\E[15;2~"
-key F6 +Shift    : "\E[17;2~" 
-key F7 +Shift    : "\E[18;2~" 
-key F8 +Shift    : "\E[19;2~" 
-key F9 +Shift    : "\E[20;2~" 
-key F10+Shift    : "\E[21;2~" 
-key F11+Shift    : "\E[23;2~" 
-key F12+Shift    : "\E[24;2~" 
-
-key Home   : "\E[H"  
-key End    : "\E[F"  
-
-key Prior -Shift : "\E[5~"  
-key Next  -Shift : "\E[6~"  
-key Insert-Shift : "\E[2~"  
-
-# Keypad-Enter. See comment on Return above.
-
-key Enter+NewLine : "\r\n"
-key Enter-NewLine : "\r"  
-
-key Space +Control : "\x00"
-
-# some of keys are used by konsole.
-
-key Up    +Shift   : scrollLineUp
-key Prior +Shift   : scrollPageUp
-key Down  +Shift   : scrollLineDown
-key Next  +Shift   : scrollPageDown
-
-key ScrollLock     : scrollLock
-
-#----------------------------------------------------------
-
-# keypad characters as offered by Qt
-# cannot be recognized as such.
-
-#----------------------------------------------------------
-
-# Following other strings as emitted by konsole.
--- a/gui/qtermwidget/lib/konsole_wcwidth.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/* $XFree86: xc/programs/xterm/wcwidth.character,v 1.3 2001/07/29 22:08:16 tsi Exp $ */
-/*
- * This is an implementation of wcwidth() and wcswidth() as defined in
- * "The Single UNIX Specification, Version 2, The Open Group, 1997"
- * <http://www.UNIX-systems.org/online.html>
- *
- * Markus Kuhn -- 2001-01-12 -- public domain
- */
-
-#include "konsole_wcwidth.h"
-
-struct interval {
-  unsigned short first;
-  unsigned short last;
-};
-
-/* auxiliary function for binary search in interval table */
-static int bisearch(quint16 ucs, const struct interval *table, int max) {
-  int min = 0;
-  int mid;
-
-  if (ucs < table[0].first || ucs > table[max].last)
-    return 0;
-  while (max >= min) {
-    mid = (min + max) / 2;
-    if (ucs > table[mid].last)
-      min = mid + 1;
-    else if (ucs < table[mid].first)
-      max = mid - 1;
-    else
-      return 1;
-  }
-
-  return 0;
-}
-
-
-/* The following functions define the column width of an ISO 10646
- * character as follows:
- *
- *    - The null character (U+0000) has a column width of 0.
- *
- *    - Other C0/C1 control characters and DEL will lead to a return
- *      value of -1.
- *
- *    - Non-spacing and enclosing combining characters (general
- *      category code Mn or Me in the Unicode database) have a
- *      column width of 0.
- *
- *    - Other format characters (general category code Cf in the Unicode
- *      database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
- *
- *    - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
- *      have a column width of 0.
- *
- *    - Spacing characters in the East Asian Wide (W) or East Asian
- *      FullWidth (F) category as defined in Unicode Technical
- *      Report #11 have a column width of 2.
- *
- *    - All remaining characters (including all printable
- *      ISO 8859-1 and WGL4 characters, Unicode control characters,
- *      etc.) have a column width of 1.
- *
- * This implementation assumes that quint16 characters are encoded
- * in ISO 10646.
- */
-
-int konsole_wcwidth(quint16 ucs)
-{
-  /* sorted list of non-overlapping intervals of non-spacing characters */
-  static const struct interval combining[] = {
-    { 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 },
-    { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 },
-    { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
-    { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 },
-    { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
-    { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
-    { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C },
-    { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 },
-    { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC },
-    { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 },
-    { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 },
-    { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 },
-    { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 },
-    { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 },
-    { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 },
-    { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 },
-    { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 },
-    { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 },
-    { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
-    { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA },
-    { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 },
-    { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 },
-    { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD },
-    { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 },
-    { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 },
-    { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC },
-    { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 },
-    { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 },
-    { 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 },
-    { 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 },
-    { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F },
-    { 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A },
-    { 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF },
-    { 0xFFF9, 0xFFFB }
-  };
-
-  /* test for 8-bit control characters */
-  if (ucs == 0)
-    return 0;
-  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
-    return -1;
-
-  /* binary search in table of non-spacing characters */
-  if (bisearch(ucs, combining,
-	       sizeof(combining) / sizeof(struct interval) - 1))
-    return 0;
-
-  /* if we arrive here, ucs is not a combining or C0/C1 control character */
-
-  return 1 +
-    (ucs >= 0x1100 &&
-     (ucs <= 0x115f ||                    /* Hangul Jamo init. consonants */
-      (ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&
-       ucs != 0x303f) ||                  /* CJK ... Yi */
-      (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
-      (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
-      (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
-      (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */
-      (ucs >= 0xffe0 && ucs <= 0xffe6) /* do not compare UINT16 with 0x20000 ||
-      (ucs >= 0x20000 && ucs <= 0x2ffff) */));
-}
-
-#if 0
-/*
- * The following function is the same as konsole_wcwidth(), except that
- * spacing characters in the East Asian Ambiguous (A) category as
- * defined in Unicode Technical Report #11 have a column width of 2.
- * This experimental variant might be useful for users of CJK legacy
- * encodings who want to migrate to UCS. It is not otherwise
- * recommended for general use.
- */
-int konsole_wcwidth_cjk(quint16 ucs)
-{
-  /* sorted list of non-overlapping intervals of East Asian Ambiguous
-   * characters */
-  static const struct interval ambiguous[] = {
-    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
-    { 0x00AA, 0x00AA }, { 0x00AD, 0x00AD }, { 0x00B0, 0x00B4 },
-    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
-    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
-    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
-    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
-    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
-    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
-    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
-    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
-    { 0x0148, 0x014A }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
-    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
-    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
-    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
-    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
-    { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, { 0x02CD, 0x02CD },
-    { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, { 0x02DD, 0x02DD },
-    { 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 },
-    { 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, { 0x0410, 0x044F },
-    { 0x0451, 0x0451 }, { 0x2010, 0x2010 }, { 0x2013, 0x2016 },
-    { 0x2018, 0x2019 }, { 0x201C, 0x201D }, { 0x2020, 0x2021 },
-    { 0x2025, 0x2027 }, { 0x2030, 0x2030 }, { 0x2032, 0x2033 },
-    { 0x2035, 0x2035 }, { 0x203B, 0x203B }, { 0x2074, 0x2074 },
-    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
-    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
-    { 0x2113, 0x2113 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 },
-    { 0x212B, 0x212B }, { 0x2154, 0x2155 }, { 0x215B, 0x215B },
-    { 0x215E, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
-    { 0x2190, 0x2199 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 },
-    { 0x2200, 0x2200 }, { 0x2202, 0x2203 }, { 0x2207, 0x2208 },
-    { 0x220B, 0x220B }, { 0x220F, 0x220F }, { 0x2211, 0x2211 },
-    { 0x2215, 0x2215 }, { 0x221A, 0x221A }, { 0x221D, 0x2220 },
-    { 0x2223, 0x2223 }, { 0x2225, 0x2225 }, { 0x2227, 0x222C },
-    { 0x222E, 0x222E }, { 0x2234, 0x2237 }, { 0x223C, 0x223D },
-    { 0x2248, 0x2248 }, { 0x224C, 0x224C }, { 0x2252, 0x2252 },
-    { 0x2260, 0x2261 }, { 0x2264, 0x2267 }, { 0x226A, 0x226B },
-    { 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 },
-    { 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 },
-    { 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF },
-    { 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 },
-    { 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 },
-    { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 },
-    { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 },
-    { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 },
-    { 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, { 0x2609, 0x2609 },
-    { 0x260E, 0x260F }, { 0x261C, 0x261C }, { 0x261E, 0x261E },
-    { 0x2640, 0x2640 }, { 0x2642, 0x2642 }, { 0x2660, 0x2661 },
-    { 0x2663, 0x2665 }, { 0x2667, 0x266A }, { 0x266C, 0x266D },
-    { 0x266F, 0x266F }, { 0x300A, 0x300B }, { 0x301A, 0x301B },
-    { 0xE000, 0xF8FF }, { 0xFFFD, 0xFFFD }
-  };
-
-  /* binary search in table of non-spacing characters */
-  if (bisearch(ucs, ambiguous,
-	       sizeof(ambiguous) / sizeof(struct interval) - 1))
-    return 2;
-
-  return konsole_wcwidth(ucs);
-}
-#endif
-
-// single byte char: +1, multi byte char: +2
-int string_width( const QString &txt )
-{
-  int w = 0;
-  for ( int i = 0; i < txt.length(); ++i )
-     w += konsole_wcwidth( txt[ i ].unicode() );
- return w;
-}
--- a/gui/qtermwidget/lib/konsole_wcwidth.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/* $XFree86: xc/programs/xterm/wcwidth.h,v 1.2 2001/06/18 19:09:27 dickey Exp $ */
-
-/* Markus Kuhn -- 2001-01-12 -- public domain */
-/* Adaptions for KDE by Waldo Bastian <bastian@kde.org> */
-/*
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>
-*/
-
-
-#ifndef	_KONSOLE_WCWIDTH_H_
-#define	_KONSOLE_WCWIDTH_H_
-
-// Qt
-#include <QtCore/QBool>
-#include <QtCore/QString>
-
-int konsole_wcwidth(quint16 ucs);
-#if 0
-int konsole_wcwidth_cjk(Q_UINT16 ucs);
-#endif
-
-int string_width( const QString &txt );
-
-#endif
--- a/gui/qtermwidget/lib/kpty.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,624 +0,0 @@
-/*
-
-   This file is part of the KDE libraries
-   Copyright (C) 2002 Waldo Bastian <bastian@kde.org>
-   Copyright (C) 2002-2003,2007 Oswald Buddenhagen <ossi@kde.org>
-
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-
-   This library 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public License
-   along with this library; see the file COPYING.LIB.  If not, write to
-   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.
-*/
-
-#include "kpty_p.h"
-
-#ifdef __sgi
-#define __svr4__
-#endif
-
-#ifdef __osf__
-#define _OSF_SOURCE
-#include <float.h>
-#endif
-
-#ifdef _AIX
-#define _ALL_SOURCE
-#endif
-
-// __USE_XOPEN isn't defined by default in ICC
-// (needed for ptsname(), grantpt() and unlockpt())
-#ifdef __INTEL_COMPILER
-#  ifndef __USE_XOPEN
-#    define __USE_XOPEN
-#  endif
-#endif
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <grp.h>
-
-#if defined(HAVE_PTY_H)
-# include <pty.h>
-#endif
-
-#ifdef HAVE_LIBUTIL_H
-# include <libutil.h>
-#elif defined(HAVE_UTIL_H)
-# include <util.h>
-#endif
-
-#ifdef HAVE_UTEMPTER
-extern "C" {
-# include <utempter.h>
-}
-#else
-# include <utmp.h>
-# ifdef HAVE_UTMPX
-#  include <utmpx.h>
-# endif
-# if !defined(_PATH_UTMPX) && defined(_UTMPX_FILE)
-#  define _PATH_UTMPX _UTMPX_FILE
-# endif
-# if !defined(_PATH_WTMPX) && defined(_WTMPX_FILE)
-#  define _PATH_WTMPX _WTMPX_FILE
-# endif
-#endif
-
-/* for HP-UX (some versions) the extern C is needed, and for other
-   platforms it doesn't hurt */
-extern "C" {
-#include <termios.h>
-#if defined(HAVE_TERMIO_H)
-# include <termio.h> // struct winsize on some systems
-#endif
-}
-
-#if defined (_HPUX_SOURCE)
-# define _TERMIOS_INCLUDED
-# include <bsdtty.h>
-#endif
-
-#ifdef HAVE_SYS_STROPTS_H
-# include <sys/stropts.h>	// Defines I_PUSH
-# define _NEW_TTY_CTRL
-#endif
-
-#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
-# define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode)
-#else
-# if defined(_HPUX_SOURCE) || defined(__Lynx__) || defined (__CYGWIN__)
-#  define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode)
-# else
-#  define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode)
-# endif
-#endif
-
-#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
-# define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode)
-#else
-# if defined(_HPUX_SOURCE) || defined(__CYGWIN__)
-#  define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode)
-# else
-#  define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode)
-# endif
-#endif
-
-//#include <kdebug.h>
-//#include <kstandarddirs.h>	// findExe
-
-#include <QtCore>
-
-// not defined on HP-UX for example
-#ifndef CTRL
-# define CTRL(x) ((x) & 037)
-#endif
-
-#define TTY_GROUP "tty"
-
-///////////////////////
-// private functions //
-///////////////////////
-
-//////////////////
-// private data //
-//////////////////
-
-KPtyPrivate::KPtyPrivate() :
-    masterFd(-1), slaveFd(-1)
-{
-}
-
-bool KPtyPrivate::chownpty(bool)
-{
-//    return !QProcess::execute(KStandardDirs::findExe("kgrantpty"),
-//        QStringList() << (grant?"--grant":"--revoke") << QString::number(masterFd));
-    return true;
-}
-
-/////////////////////////////
-// public member functions //
-/////////////////////////////
-
-KPty::KPty() :
-    d_ptr(new KPtyPrivate)
-{
-    d_ptr->q_ptr = this;
-}
-
-KPty::KPty(KPtyPrivate *d) :
-    d_ptr(d)
-{
-    d_ptr->q_ptr = this;
-}
-
-KPty::~KPty()
-{
-    close();
-    delete d_ptr;
-}
-
-bool KPty::open()
-{
-  Q_D(KPty);
-
-  if (d->masterFd >= 0)
-    return true;
-
-  QByteArray ptyName;
-
-  // Find a master pty that we can open ////////////////////////////////
-
-  // Because not all the pty animals are created equal, they want to
-  // be opened by several different methods.
-
-  // We try, as we know them, one by one.
-
-#ifdef HAVE_OPENPTY
-
-  char ptsn[PATH_MAX];
-  if (::openpty( &d->masterFd, &d->slaveFd, ptsn, 0, 0))
-  {
-    d->masterFd = -1;
-    d->slaveFd = -1;
-    kWarning(175) << "Can't open a pseudo teletype";
-    return false;
-  }
-  d->ttyName = ptsn;
-
-#else
-
-#ifdef HAVE__GETPTY // irix
-
-  char *ptsn = _getpty(&d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
-  if (ptsn) {
-    d->ttyName = ptsn;
-    goto grantedpt;
-  }
-
-#elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)
-
-#ifdef HAVE_POSIX_OPENPT
-  d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
-#elif defined(HAVE_GETPT)
-  d->masterFd = ::getpt();
-#elif defined(PTM_DEVICE)
-  d->masterFd = ::open(PTM_DEVICE, O_RDWR|O_NOCTTY);
-#else
-# error No method to open a PTY master detected.
-#endif
-
-  if (d->masterFd >= 0)
-  {
- 
-#ifdef HAVE_PTSNAME
-    char *ptsn = ptsname(d->masterFd);
-    if (ptsn) {
-        d->ttyName = ptsn;
-#else
-    int ptyno;
-    if (!ioctl(d->masterFd, TIOCGPTN, &ptyno)) {
-        d->ttyName = QByteArray("/dev/pts/") + QByteArray::number(ptyno);
-#endif
-#ifdef HAVE_GRANTPT
-        if (!grantpt(d->masterFd))
-           goto grantedpt;
-#else
-
-        goto gotpty;
-#endif
-    }
-    ::close(d->masterFd);
-    d->masterFd = -1;
-  }
-#endif // HAVE_PTSNAME || TIOCGPTN
-
-  // Linux device names, FIXME: Trouble on other systems?
-  for (const char* s3 = "pqrstuvwxyzabcde"; *s3; s3++)
-  {
-    for (const char* s4 = "0123456789abcdef"; *s4; s4++)
-    {
-      ptyName = QString().sprintf("/dev/pty%c%c", *s3, *s4).toAscii();
-      d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toAscii();
-
-      d->masterFd = ::open(ptyName.data(), O_RDWR);
-      if (d->masterFd >= 0)
-      {
-#ifdef Q_OS_SOLARIS
-        /* Need to check the process group of the pty.
-         * If it exists, then the slave pty is in use,
-         * and we need to get another one.
-         */
-        int pgrp_rtn;
-        if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
-          ::close(d->masterFd);
-          d->masterFd = -1;
-          continue;
-        }
-#endif /* Q_OS_SOLARIS */
-        if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits
-        {
-          if (!geteuid())
-          {
-            struct group* p = getgrnam(TTY_GROUP);
-            if (!p)
-              p = getgrnam("wheel");
-            gid_t gid = p ? p->gr_gid : getgid ();
-
-            chown(d->ttyName.data(), getuid(), gid);
-            chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
-          }
-          goto gotpty;
-        }
-        ::close(d->masterFd);
-        d->masterFd = -1;
-      }
-    }
-  }
-
-  qWarning() << "Can't open a pseudo teletype";
-  return false;
-
- gotpty:
-  struct stat st;
-  if (stat(d->ttyName.data(), &st)) {
-    return false; // this just cannot happen ... *cough*  Yeah right, I just
-                  // had it happen when pty #349 was allocated.  I guess
-                  // there was some sort of leak?  I only had a few open.
-    }
-  if (((st.st_uid != getuid()) ||
-       (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
-      !d->chownpty(true))
-  {
-    qWarning()
-      << "chownpty failed for device " << ptyName << "::" << d->ttyName
-      << "\nThis means the communication can be eavesdropped." << endl;
-  }
-
-#if defined (HAVE__GETPTY) || defined (HAVE_GRANTPT)
- grantedpt:
-#endif 
-
-#ifdef HAVE_REVOKE
-  revoke(d->ttyName.data());
-#endif
-
-#ifdef HAVE_UNLOCKPT
-  unlockpt(d->masterFd);
-#elif defined(TIOCSPTLCK)
-  int flag = 0;
-  ioctl(d->masterFd, TIOCSPTLCK, &flag);
-#endif
-
-  d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
-  if (d->slaveFd < 0)
-  {
-    qWarning() << "Can't open slave pseudo teletype";
-    ::close(d->masterFd);
-    d->masterFd = -1;
-    return false;
-  }
-
-#if (defined(__svr4__) || defined(__sgi__))
-  // Solaris
-  ioctl(d->slaveFd, I_PUSH, "ptem");
-  ioctl(d->slaveFd, I_PUSH, "ldterm");
-#endif
-
-#endif /* HAVE_OPENPTY */
-
-  fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
-  fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
-
-  return true;
-}
-
-void KPty::closeSlave()
-{
-    Q_D(KPty);
-
-    if (d->slaveFd < 0)
-        return;
-    ::close(d->slaveFd);
-    d->slaveFd = -1;
-}
-
-void KPty::close()
-{
-   Q_D(KPty);
-
-   if (d->masterFd < 0)
-      return;
-   closeSlave();
-   // don't bother resetting unix98 pty, it will go away after closing master anyway.
-   if (memcmp(d->ttyName.data(), "/dev/pts/", 9)) {
-      if (!geteuid()) {
-         struct stat st;
-         if (!stat(d->ttyName.data(), &st)) {
-            chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1);
-            chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
-         }
-      } else {
-         fcntl(d->masterFd, F_SETFD, 0);
-         d->chownpty(false);
-      }
-   }
-   ::close(d->masterFd);
-   d->masterFd = -1;
-}
-
-void KPty::setCTty()
-{
-    Q_D(KPty);
-
-    // Setup job control //////////////////////////////////
-
-    // Become session leader, process group leader,
-    // and get rid of the old controlling terminal.
-    setsid();
-
-    // make our slave pty the new controlling terminal.
-#ifdef TIOCSCTTY
-    ioctl(d->slaveFd, TIOCSCTTY, 0);
-#else
-    // __svr4__ hack: the first tty opened after setsid() becomes controlling tty
-    ::close(::open(d->ttyName, O_WRONLY, 0));
-#endif
-
-    // make our new process group the foreground group on the pty
-    int pgrp = getpid();
-#if defined(_POSIX_VERSION) || defined(__svr4__)
-    tcsetpgrp(d->slaveFd, pgrp);
-#elif defined(TIOCSPGRP)
-    ioctl(d->slaveFd, TIOCSPGRP, (char *)&pgrp);
-#endif
-}
-
-void KPty::login(const char *user, const char *remotehost)
-{
-#ifdef HAVE_UTEMPTER
-    Q_D(KPty);
-
-    addToUtmp(d->ttyName, remotehost, d->masterFd);
-    Q_UNUSED(user);
-#else
-# ifdef HAVE_UTMPX
-    struct utmpx l_struct;
-# else
-    struct utmp l_struct;
-# endif
-    memset(&l_struct, 0, sizeof(l_struct));
-    // note: strncpy without terminators _is_ correct here. man 4 utmp
-
-    if (user)
-      strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name));
-
-    if (remotehost) {
-      strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host));
-# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
-      l_struct.ut_syslen = qMin(strlen(remotehost), sizeof(l_struct.ut_host));
-# endif
-    }
-
-# ifndef __GLIBC__
-    Q_D(KPty);
-    const char *str_ptr = d->ttyName.data();
-    if (!memcmp(str_ptr, "/dev/", 5))
-        str_ptr += 5;
-    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
-#  ifdef HAVE_STRUCT_UTMP_UT_ID
-    strncpy(l_struct.ut_id,
-            str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id),
-            sizeof(l_struct.ut_id));
-#  endif
-# endif
-
-# ifdef HAVE_UTMPX
-    gettimeofday(&l_struct.ut_tv, 0);
-# else
-    l_struct.ut_time = time(0);
-# endif
-
-# ifdef HAVE_LOGIN
-#  ifdef HAVE_LOGINX
-    ::loginx(&l_struct);
-#  else
-    ::login(&l_struct);
-#  endif
-# else
-#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
-    l_struct.ut_type = USER_PROCESS;
-#  endif
-#  ifdef HAVE_STRUCT_UTMP_UT_PID
-    l_struct.ut_pid = getpid();
-#   ifdef HAVE_STRUCT_UTMP_UT_SESSION
-    l_struct.ut_session = getsid(0);
-#   endif
-#  endif
-#  ifdef HAVE_UTMPX
-    utmpxname(_PATH_UTMPX);
-    setutxent();
-    pututxline(&l_struct);
-    endutxent();
-    updwtmpx(_PATH_WTMPX, &l_struct);
-#  else
-    utmpname(_PATH_UTMP);
-    setutent();
-    pututline(&l_struct);
-    endutent();
-    updwtmp(_PATH_WTMP, &l_struct);
-#  endif
-# endif
-#endif
-}
-
-void KPty::logout()
-{
-#ifdef HAVE_UTEMPTER
-    Q_D(KPty);
-
-    removeLineFromUtmp(d->ttyName, d->masterFd);
-#else
-    Q_D(KPty);
-
-    const char *str_ptr = d->ttyName.data();
-    if (!memcmp(str_ptr, "/dev/", 5))
-        str_ptr += 5;
-# ifdef __GLIBC__
-    else {
-        const char *sl_ptr = strrchr(str_ptr, '/');
-        if (sl_ptr)
-            str_ptr = sl_ptr + 1;
-    }
-# endif
-# ifdef HAVE_LOGIN
-#  ifdef HAVE_LOGINX
-    ::logoutx(str_ptr, 0, DEAD_PROCESS);
-#  else
-    ::logout(str_ptr);
-#  endif
-# else
-#  ifdef HAVE_UTMPX
-    struct utmpx l_struct, *ut;
-#  else
-    struct utmp l_struct, *ut;
-#  endif
-    memset(&l_struct, 0, sizeof(l_struct));
-
-    strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
-
-#  ifdef HAVE_UTMPX
-    utmpxname(_PATH_UTMPX);
-    setutxent();
-    if ((ut = getutxline(&l_struct))) {
-#  else
-    utmpname(_PATH_UTMP);
-    setutent();
-    if ((ut = getutline(&l_struct))) {
-#  endif
-        memset(ut->ut_name, 0, sizeof(*ut->ut_name));
-        memset(ut->ut_host, 0, sizeof(*ut->ut_host));
-#  ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
-        ut->ut_syslen = 0;
-#  endif
-#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
-        ut->ut_type = DEAD_PROCESS;
-#  endif
-#  ifdef HAVE_UTMPX
-        gettimeofday(ut->ut_tv, 0);
-        pututxline(ut);
-    }
-    endutxent();
-#  else
-        ut->ut_time = time(0);
-        pututline(ut);
-    }
-    endutent();
-#  endif
-# endif
-#endif
-}
-
-// XXX Supposedly, tc[gs]etattr do not work with the master on Solaris.
-// Please verify.
-
-bool KPty::tcGetAttr(struct ::termios *ttmode) const
-{
-    Q_D(const KPty);
-
-    return _tcgetattr(d->masterFd, ttmode) == 0;
-}
-
-bool KPty::tcSetAttr(struct ::termios *ttmode)
-{
-    Q_D(KPty);
-
-    return _tcsetattr(d->masterFd, ttmode) == 0;
-}
-
-bool KPty::setWinSize(int lines, int columns)
-{
-    Q_D(KPty);
-
-    struct winsize winSize;
-    memset(&winSize, 0, sizeof(winSize));
-    winSize.ws_row = (unsigned short)lines;
-    winSize.ws_col = (unsigned short)columns;
-    return ioctl(d->masterFd, TIOCSWINSZ, (char *)&winSize) == 0;
-}
-
-bool KPty::setEcho(bool echo)
-{
-    struct ::termios ttmode;
-    if (!tcGetAttr(&ttmode))
-        return false;
-    if (!echo)
-        ttmode.c_lflag &= ~ECHO;
-    else
-        ttmode.c_lflag |= ECHO;
-    return tcSetAttr(&ttmode);
-}
-
-const char *KPty::ttyName() const
-{
-    Q_D(const KPty);
-
-    return d->ttyName.data();
-}
-
-int KPty::masterFd() const
-{
-    Q_D(const KPty);
-
-    return d->masterFd;
-}
-
-int KPty::slaveFd() const
-{
-    Q_D(const KPty);
-
-    return d->slaveFd;
-}
--- a/gui/qtermwidget/lib/kpty.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/* This file is part of the KDE libraries
-
-    Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
-
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#ifndef kpty_h
-#define kpty_h
-
-#include <QtCore>
-
-struct KPtyPrivate;
-struct termios;
-
-/**
- * Provides primitives for opening & closing a pseudo TTY pair, assigning the
- * controlling TTY, utmp registration and setting various terminal attributes.
- */
-class KPty {
-    Q_DECLARE_PRIVATE(KPty)
-
-public:
-
-  /**
-   * Constructor
-   */
-  KPty();
-
-  /**
-   * Destructor:
-   *
-   *  If the pty is still open, it will be closed. Note, however, that
-   *  an utmp registration is @em not undone.
-  */
-  ~KPty();
-
-  /**
-   * Create a pty master/slave pair.
-   *
-   * @return true if a pty pair was successfully opened
-   */
-  bool open();
-
-  /**
-   * Close the pty master/slave pair.
-   */
-  void close();
-
-  /**
-   * Close the pty slave descriptor.
-   *
-   * When creating the pty, KPty also opens the slave and keeps it open.
-   * Consequently the master will never receive an EOF notification.
-   * Usually this is the desired behavior, as a closed pty slave can be
-   * reopened any time - unlike a pipe or socket. However, in some cases
-   * pipe-alike behavior might be desired.
-   *
-   * After this function was called, slaveFd() and setCTty() cannot be
-   * used.
-   */
-  void closeSlave();
-
-  /**
-   * Creates a new session and process group and makes this pty the
-   * controlling tty.
-   */
-  void setCTty();
-
-  /**
-   * Creates an utmp entry for the tty.
-   * This function must be called after calling setCTty and
-   * making this pty the stdin.
-   * @param user the user to be logged on
-   * @param remotehost the host from which the login is coming. This is
-   *  @em not the local host. For remote logins it should be the hostname
-   *  of the client. For local logins from inside an X session it should
-   *  be the name of the X display. Otherwise it should be empty.
-   */
-  void login(const char *user = 0, const char *remotehost = 0);
-
-  /**
-   * Removes the utmp entry for this tty.
-   */
-  void logout();
-
-  /**
-   * Wrapper around tcgetattr(3).
-   *
-   * This function can be used only while the PTY is open.
-   * You will need an #include &lt;termios.h&gt; to do anything useful
-   * with it.
-   *
-   * @param ttmode a pointer to a termios structure.
-   *  Note: when declaring ttmode, @c struct @c ::termios must be used -
-   *  without the '::' some version of HP-UX thinks, this declares
-   *  the struct in your class, in your method.
-   * @return @c true on success, false otherwise
-   */
-  bool tcGetAttr(struct ::termios *ttmode) const;
-
-  /**
-   * Wrapper around tcsetattr(3) with mode TCSANOW.
-   *
-   * This function can be used only while the PTY is open.
-   *
-   * @param ttmode a pointer to a termios structure.
-   * @return @c true on success, false otherwise. Note that success means
-   *  that @em at @em least @em one attribute could be set.
-   */
-  bool tcSetAttr(struct ::termios *ttmode);
-
-  /**
-   * Change the logical (screen) size of the pty.
-   * The default is 24 lines by 80 columns.
-   *
-   * This function can be used only while the PTY is open.
-   *
-   * @param lines the number of rows
-   * @param columns the number of columns
-   * @return @c true on success, false otherwise
-   */
-  bool setWinSize(int lines, int columns);
-
-  /**
-   * Set whether the pty should echo input.
-   *
-   * Echo is on by default.
-   * If the output of automatically fed (non-interactive) PTY clients
-   * needs to be parsed, disabling echo often makes it much simpler.
-   *
-   * This function can be used only while the PTY is open.
-   *
-   * @param echo true if input should be echoed.
-   * @return @c true on success, false otherwise
-   */
-  bool setEcho(bool echo);
-
-  /**
-   * @return the name of the slave pty device.
-   *
-   * This function should be called only while the pty is open.
-   */
-  const char *ttyName() const;
-
-  /**
-   * @return the file descriptor of the master pty
-   *
-   * This function should be called only while the pty is open.
-   */
-  int masterFd() const;
-
-  /**
-   * @return the file descriptor of the slave pty
-   *
-   * This function should be called only while the pty slave is open.
-   */
-  int slaveFd() const;
-
-protected:
-  /**
-   * @internal
-   */
-  KPty(KPtyPrivate *d);
-
-  /**
-   * @internal
-   */
-  KPtyPrivate * const d_ptr;
-};
-
-#endif
-
--- a/gui/qtermwidget/lib/kpty_p.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/* This file is part of the KDE libraries
-
-    Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
-
-    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#ifndef kpty_p_h
-#define kpty_p_h
-
-#include "kpty.h"
-
-#include <QtCore/QByteArray>
-
-struct KPtyPrivate {
-    Q_DECLARE_PUBLIC(KPty)
-
-    KPtyPrivate();
-    bool chownpty(bool grant);
-
-    int masterFd;
-    int slaveFd;
-
-    QByteArray ttyName;
-
-    KPty *q_ptr;
-};
-
-#endif
--- a/gui/qtermwidget/lib/lib.pro	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-TEMPLATE	= lib
-VERSION		= 0.1.0
-DESTDIR 	= ..
-
-TARGET		= qtermwidget
-
-CONFIG		+= qt debug_and_release warn_on build_all staticlib #dll
-
-QT += core gui
-
-MOC_DIR 	= ../.moc
-
-CONFIG(debug, debug|release) {
-    OBJECTS_DIR = ../.objs_d
-    TARGET 	= qtermwidget_d
-} else {
-    OBJECTS_DIR = ../.objs
-    TARGET 	= qtermwidget
-}
-
-DEFINES 	+= HAVE_POSIX_OPENPT	    
-#or DEFINES 	+= HAVE_GETPT
-
-HEADERS 	= TerminalCharacterDecoder.h Character.h CharacterColor.h \
-		KeyboardTranslator.h \
-		ExtendedDefaultTranslator.h \
-		Screen.h History.h BlockArray.h konsole_wcwidth.h \
-		ScreenWindow.h \
-		Emulation.h \
-		Vt102Emulation.h TerminalDisplay.h Filter.h LineFont.h \
-		Pty.h kpty.h kpty_p.h k3process.h k3processcontroller.h \
-		Session.h ShellCommand.h \
-		qtermwidget.h
-
-SOURCES 	= TerminalCharacterDecoder.cpp \
-		KeyboardTranslator.cpp \
-		Screen.cpp History.cpp BlockArray.cpp konsole_wcwidth.cpp \
-		ScreenWindow.cpp \
-		Emulation.cpp \
-		Vt102Emulation.cpp TerminalDisplay.cpp Filter.cpp \
-		Pty.cpp kpty.cpp k3process.cpp k3processcontroller.cpp \
-		Session.cpp ShellCommand.cpp \
-		qtermwidget.cpp
-
-	    
-
-
-	
\ No newline at end of file
--- a/gui/qtermwidget/lib/qtermwidget.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*  Copyright (C) 2008 e_k (e_k@users.sourceforge.net)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-		
-    This library 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
-    Library General Public License for more details.
-				
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-						
-
-#include "qtermwidget.h"
-
-#include "Session.h"
-#include "TerminalDisplay.h"
-
-using namespace Konsole;
-
-void *createTermWidget(int startnow, void *parent)
-{ 
-    return (void*) new QTermWidget(startnow, (QWidget*)parent); 
-}
-
-struct TermWidgetImpl
-{
-    TermWidgetImpl(QWidget* parent = 0);
-
-    TerminalDisplay *m_terminalDisplay;
-    Session *m_session;
-    
-    Session* createSession();
-    TerminalDisplay* createTerminalDisplay(Session *session, QWidget* parent);
-};
-
-TermWidgetImpl::TermWidgetImpl(QWidget* parent)
-{
-    this->m_session = createSession();
-    this->m_terminalDisplay = createTerminalDisplay(this->m_session, parent);
-}
-
-
-Session *TermWidgetImpl::createSession()
-{
-    Session *session = new Session();
-
-    session->setTitle(Session::NameRole, "QTermWidget");
-    session->setProgram("/bin/bash");
-    QStringList args("");
-    session->setArguments(args);
-    session->setAutoClose(true);
-		    
-    session->setCodec(QTextCodec::codecForName("UTF-8"));
-			
-    session->setFlowControlEnabled(true);
-    session->setHistoryType(HistoryTypeBuffer(1000));
-    
-    session->setDarkBackground(true);
-	    
-    session->setKeyBindings("");	    
-    return session;
-}
-
-TerminalDisplay *TermWidgetImpl::createTerminalDisplay(Session *session, QWidget* parent)
-{
-//    TerminalDisplay* display = new TerminalDisplay(this);
-    TerminalDisplay* display = new TerminalDisplay(parent);
-    
-    display->setBellMode(TerminalDisplay::NotifyBell);
-    display->setTerminalSizeHint(true);
-    display->setTripleClickMode(TerminalDisplay::SelectWholeLine);
-    display->setTerminalSizeStartup(true);
-
-    display->setRandomSeed(session->sessionId() * 31);
-    
-    return display;
-}
-
-
-QTermWidget::QTermWidget(int startnow, QWidget *parent)
-:QWidget(parent)
-{
-    m_impl = new TermWidgetImpl(this);
-    
-    init();
-
-    if (startnow && m_impl->m_session) {
-	m_impl->m_session->run();
-    }
-    
-    this->setFocus( Qt::OtherFocusReason );
-    m_impl->m_terminalDisplay->resize(this->size());
-    
-    this->setFocusProxy(m_impl->m_terminalDisplay);
-}
-
-void QTermWidget::startShellProgram()
-{
-    if ( m_impl->m_session->isRunning() )
-	return;
-	
-    m_impl->m_session->run();
-}
-
-void QTermWidget::init()
-{    
-    m_impl->m_terminalDisplay->setSize(80, 40);
-    
-    QFont font = QApplication::font(); 
-    font.setFamily("Monospace");
-    font.setPointSize(10);
-    font.setStyleHint(QFont::TypeWriter);
-    setTerminalFont(font);
-    setScrollBarPosition(NoScrollBar);    
-        
-    m_impl->m_session->addView(m_impl->m_terminalDisplay);
-    
-    connect(m_impl->m_session, SIGNAL(finished()), this, SLOT(sessionFinished()));
-}
-
-
-QTermWidget::~QTermWidget()
-{
-    emit destroyed();
-}
-
-
-void QTermWidget::setTerminalFont(QFont &font)
-{
-    if (!m_impl->m_terminalDisplay)
-	return;
-    m_impl->m_terminalDisplay->setVTFont(font);
-}
-
-void QTermWidget::setShellProgram(QString &progname)
-{
-    if (!m_impl->m_session)
-	return;
-    m_impl->m_session->setProgram(progname);	
-}
-
-void QTermWidget::setArgs(QStringList &args)
-{
-    if (!m_impl->m_session)
-	return;
-    m_impl->m_session->setArguments(args);	
-}
-
-void QTermWidget::setTextCodec(QTextCodec *codec)
-{
-    if (!m_impl->m_session)
-	return;
-    m_impl->m_session->setCodec(codec);	
-}
-
-void QTermWidget::setColorScheme(int scheme)
-{
-    switch(scheme) {
-	case COLOR_SCHEME_WHITE_ON_BLACK:
-		m_impl->m_terminalDisplay->setColorTable(whiteonblack_color_table);
-		break;		
-	case COLOR_SCHEME_GREEN_ON_BLACK:
-		m_impl->m_terminalDisplay->setColorTable(greenonblack_color_table);
-		break;
-	case COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW:
-		m_impl->m_terminalDisplay->setColorTable(blackonlightyellow_color_table);
-		break;
-	default: //do nothing
-	    break;
-    };
-}
-
-void QTermWidget::setSize(int h, int v)
-{
-    if (!m_impl->m_terminalDisplay)
-	return;
-    m_impl->m_terminalDisplay->setSize(h, v);
-}
-
-void QTermWidget::setHistorySize(int lines)
-{
-    if (lines < 0)
-        m_impl->m_session->setHistoryType(HistoryTypeFile());
-    else
-	m_impl->m_session->setHistoryType(HistoryTypeBuffer(lines));
-}
-
-void QTermWidget::setScrollBarPosition(ScrollBarPosition pos)
-{
-    if (!m_impl->m_terminalDisplay)
-	return;
-    m_impl->m_terminalDisplay->setScrollBarPosition((TerminalDisplay::ScrollBarPosition)pos);
-}
-
-void QTermWidget::sendText(QString &text)
-{
-    m_impl->m_session->sendText(text); 
-}
-
-void QTermWidget::resizeEvent(QResizeEvent*)
-{
-//qDebug("global window resizing...with %d %d", this->size().width(), this->size().height());
-    m_impl->m_terminalDisplay->resize(this->size());
-}
-
-
-
-void QTermWidget::sessionFinished()
-{
-    emit finished();
-}
-
-	
-//#include "moc_consoleq.cpp"
-
--- a/gui/qtermwidget/lib/qtermwidget.h	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*  Copyright (C) 2008 e_k (e_k@users.sourceforge.net)
-    
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-		    
-    This library 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
-    Library General Public License for more details.
-			    
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-						    
-
-#ifndef _Q_TERM_WIDGET
-#define _Q_TERM_WIDGET
-
-#include <QtGui>
-
-struct TermWidgetImpl;
-
-enum COLOR_SCHEME {     COLOR_SCHEME_WHITE_ON_BLACK	= 1,
-		        COLOR_SCHEME_GREEN_ON_BLACK,
-		        COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW };
-
-class QTermWidget : public QWidget
-{
-    Q_OBJECT
-public:
-    
-    enum ScrollBarPosition
-    {
-        /** Do not show the scroll bar. */
-        NoScrollBar=0,
-        /** Show the scroll bar on the left side of the display. */
-        ScrollBarLeft=1,
-        /** Show the scroll bar on the right side of the display. */
-        ScrollBarRight=2
-    };
-
-
-    //Creation of widget
-    QTermWidget(int startnow = 1, //start shell programm immediatelly
-		QWidget *parent = 0);
-    ~QTermWidget();
-
-    //start shell program if it was not started in constructor
-    void startShellProgram();
-    
-    //look-n-feel, if you don`t like defaults
-
-    //	Terminal font
-    // Default is application font with family Monospace, size 10
-    void setTerminalFont(QFont &font); 
-    
-    //	Shell program, default is /bin/bash
-    void setShellProgram(QString &progname);
-    
-    // Shell program args, default is none
-    void setArgs(QStringList &args);
-    
-    //Text codec, default is UTF-8
-    void setTextCodec(QTextCodec *codec);
-
-    //Color scheme, default is white on black
-    void setColorScheme(int scheme);
-    
-    //set size
-    void setSize(int h, int v);
-    
-    // History size for scrolling 
-    void setHistorySize(int lines); //infinite if lines < 0
-
-    // Presence of scrollbar
-    void setScrollBarPosition(ScrollBarPosition);
-    
-    // Send some text to terminal
-    void sendText(QString &text);
-            
-signals:
-    void finished();
-        
-protected: 
-    virtual void resizeEvent(QResizeEvent *);
-    
-protected slots:
-    void sessionFinished();        
-    
-private:
-    void init();    
-    TermWidgetImpl *m_impl;
-};
-
-
-//Maybe useful, maybe not
-
-#ifdef __cplusplus
-extern "C"
-#endif
-void *createTermWidget(int startnow, void *parent); 
-
-#endif
-
--- a/gui/qtermwidget/qtermwidget.pro	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-TEMPLATE 	= subdirs
-SUBDIRS 	= lib src
-
-OPTIONS 	+= ordered
\ No newline at end of file
--- a/gui/qtermwidget/src/CVS/Entries	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-/README/1.1.1.1/Sat May 10 21:27:57 2008//
-/src.pro/1.1.1.1/Sat May 10 21:27:57 2008//
-/main.cpp/1.7/Wed Jul 30 21:32:00 2008//
-D
--- a/gui/qtermwidget/src/CVS/Repository	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-qtermwidget/src
--- a/gui/qtermwidget/src/CVS/Root	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-:ext:e_k@qtermwidget.cvs.sourceforge.net:/cvsroot/qtermwidget
--- a/gui/qtermwidget/src/README	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-here is sample program which uses QTermWidet for displaying a terminal
\ No newline at end of file
--- a/gui/qtermwidget/src/main.cpp	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*  Copyright (C) 2008 e_k (e_k@users.sourceforge.net)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-		
-    This library 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
-    Library General Public License for more details.
-				
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-						
-
-#include <QtCore>
-#include <QtGui>
-#include <QApplication>
-
-#include "qtermwidget.h"
-
-int main(int argc, char *argv[])
-{
-    QApplication app(argc, argv);
-    QMainWindow *mainWindow = new QMainWindow();
-
-    QTermWidget *console = new QTermWidget();
-    
-    QFont font = QApplication::font();
-    font.setFamily("Terminus");
-    font.setPointSize(12);
-    
-    console->setTerminalFont(font);
-    
-    //console->setColorScheme(COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW);
-    console->setScrollBarPosition(QTermWidget::ScrollBarRight);
-    
-    mainWindow->setCentralWidget(console);
-    mainWindow->resize(802, 610);
-    
-    QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close()));
-
-    mainWindow->show();    
-    return app.exec();
-} 
-
-  
--- a/gui/qtermwidget/src/src.pro	Sat Jan 21 11:26:36 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-TEMPLATE	= app
-DESTDIR 	= ..
-
-CONFIG		+= qt debug_and_release warn_on build_all
-
-QT += core gui
-
-MOC_DIR 	= ../.moc
-
-CONFIG(debug, debug|release) {
-    OBJECTS_DIR = ../.objs_d
-    TARGET 	= consoleq_d
-    LIBS 	+= -L.. ../libqtermwidget_d.a
-} else {
-    OBJECTS_DIR = ../.objs
-    TARGET 	= consoleq
-    LIBS 	+= -L.. ../libqtermwidget.a
-}
-
-SOURCES 	= main.cpp 
-
-INCLUDEPATH 	= ../lib
-
-#LIBS 		+= -L.. -lqtermwidget
-
-
-	
\ No newline at end of file