Commit c5ab0f3c authored by Robert Knight's avatar Robert Knight

Add basic code to associate shortcuts with profiles and load/save those...

Add basic code to associate shortcuts with profiles and load/save those shortcut/profile pairs.  Move Profile class into its own source file.  Move old TODO list into the 'old' directory.

svn path=/trunk/KDE/kdebase/apps/konsole/; revision=664308
parent ecdb2781
......@@ -72,6 +72,7 @@ set(konsole_KDEINIT_SRCS
ScreenWindow.cpp
SessionController.cpp
ShellCommand.cpp
Profile.cpp
ProfileList.cpp
ProfileListWidget.cpp
SessionManager.cpp
......@@ -145,6 +146,7 @@ set(konsolepart_PART_SRCS
MainWindow.cpp
Part.cpp
ProcessInfo.cpp
Profile.cpp
Pty.cpp
RemoteConnectionDialog.cpp
Screen.cpp
......
......@@ -40,6 +40,7 @@
#include "ui_EditProfileDialog.h"
#include "KeyBindingEditor.h"
#include "KeyboardTranslator.h"
#include "Profile.h"
#include "SessionManager.h"
#include "ShellCommand.h"
#include "TabTitleFormatAction.h"
......@@ -49,7 +50,7 @@ using namespace Konsole;
EditProfileDialog::EditProfileDialog(QWidget* parent)
: KDialog(parent)
{
setCaption("Edit Profile");
setCaption(i18n("Edit Profile"));
setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply | KDialog::Default );
connect( this , SIGNAL(applyClicked()) , this , SLOT(save()) );
......@@ -102,7 +103,7 @@ void EditProfileDialog::setProfile(const QString& key)
Q_ASSERT( info );
// update caption
setCaption( QString("Edit Profile \"%1\"").arg(info->name()) );
setCaption( i18n("Edit Profile \"%1\"",info->name()) );
// setup each page of the dialog
setupGeneralPage(info);
......
......@@ -58,20 +58,14 @@ MainWindow::MainWindow()
_bookmarkHandler(0),
_pluggedController(0)
{
// add a small amount of space between the top of the window and the main widget
// to prevent the menu bar and main widget borders touching (which looks very ugly) in styles
// where the menu bar has a lower border
//setContentsMargins(0,2,0,0);
// create actions for menus
// the directory ('konsole') is included in the path here so that the XML
// file can be found when this code is being used in the Konsole part.
setXMLFile("konsole/konsoleui.rc");
setupActions();
// create view manager
// the directory ('konsole') is included in the path here so that the XML
// file can be found when this code is being used in the Konsole part.
//setXMLFile("konsole/konsoleui.rc");
_viewManager = new ViewManager(this,actionCollection());
_viewManager = new ViewManager(this,actionCollection());
connect( _viewManager , SIGNAL(empty()) , this , SLOT(close()) );
connect( _viewManager , SIGNAL(activeViewChanged(SessionController*)) , this ,
SLOT(activeViewChanged(SessionController*)) );
......@@ -256,27 +250,6 @@ void MainWindow::showRemoteConnectionDialog()
emit requestSession(dialog.sessionKey(),_viewManager);
}
void MainWindow::mergeWindows()
{
// merges all of the open Konsole windows into this window
// by merging the view manager associated with the other Konsole windows
// into this window's view manager
QListIterator<QWidget*> topLevelIter( QApplication::topLevelWidgets() );
while (topLevelIter.hasNext())
{
QWidget* w = topLevelIter.next();
qDebug() << "Top level widget: " << w->metaObject()->className();
MainWindow* window = qobject_cast<MainWindow*>(w);
if ( window && window != this )
{
_viewManager->merge( window->_viewManager );
//window->close();
}
}
}
void MainWindow::setupWidgets()
{
QWidget* widget = new QWidget(this);
......
......@@ -79,19 +79,11 @@ class MainWindow : public KXmlGuiWindow
*/
BookmarkHandler* bookmarkHandler() const;
public slots:
/**
* Merges all of the MainWindow widgets in the application into this window.
* Note: Only the active container in other MainWindow widgets are considered,
* other containers are currently just deleted
*/
void mergeWindows();
signals:
/**
* Emitted by the main window to request the creation of a new session.
*
* @param key Specifies the type of session to create
* @param key The key for the profile to use to create the new session.
* @param view The view manager owned by this main window
*/
void requestSession(const QString& key , ViewManager* view);
......
......@@ -39,7 +39,7 @@ using namespace Konsole;
ManageProfilesDialog::ManageProfilesDialog(QWidget* parent)
: KDialog(parent)
{
setCaption("Manage Profiles");
setCaption(i18n("Manage Profiles"));
_ui = new Ui::ManageProfilesDialog();
_ui->setupUi(mainWidget());
......@@ -76,16 +76,32 @@ ManageProfilesDialog::~ManageProfilesDialog()
{
delete _ui;
}
void ManageProfilesDialog::itemDataChanged(QStandardItem* item)
{
static const int ShortcutColumn = 2;
if ( item->column() == ShortcutColumn )
{
QKeySequence sequence = QKeySequence::fromString(item->text());
qDebug() << "New key sequence: " << item->text();
SessionManager::instance()->setShortcut(item->data(Qt::UserRole+1).value<QString>(),
sequence);
}
}
void ManageProfilesDialog::updateTableModel()
{
// 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();
// setup session table
_sessionModel = new QStandardItemModel(this);
_sessionModel->setHorizontalHeaderLabels( QStringList() << "Name"
<< "Show in Menu"
<< "Shortcut" );
_sessionModel->setHorizontalHeaderLabels( QStringList() << i18n("Name")
<< i18n("Show in Menu")
<< i18n("Shortcut") );
QListIterator<QString> keyIter( SessionManager::instance()->availableProfiles() );
while ( keyIter.hasNext() )
{
......@@ -105,6 +121,7 @@ void ManageProfilesDialog::updateTableModel()
const bool isFavorite = SessionManager::instance()->findFavorites().contains(key);
// favorite column
QStandardItem* favoriteItem = new QStandardItem();
if ( isFavorite )
favoriteItem->setData(KIcon("favorites"),Qt::DecorationRole);
......@@ -113,11 +130,22 @@ void ManageProfilesDialog::updateTableModel()
favoriteItem->setData(key,Qt::UserRole+1);
itemList << item << favoriteItem;
// shortcut column
QStandardItem* shortcutItem = new QStandardItem();
QString shortcut = SessionManager::instance()->shortcut(key).
toString();
shortcutItem->setText(shortcut);
shortcutItem->setData(key,Qt::UserRole+1);
itemList << item << favoriteItem << shortcutItem;
_sessionModel->appendRow(itemList);
}
updateDefaultItem();
connect( _sessionModel , SIGNAL(itemChanged(QStandardItem*)) , this ,
SLOT(itemDataChanged(QStandardItem*)) );
_ui->sessionTable->setModel(_sessionModel);
// listen for changes in the table selection and update the state of the form's buttons
......
......@@ -58,6 +58,8 @@ private slots:
void newType();
void editSelected();
void itemDataChanged(QStandardItem* item);
// enables or disables Edit/Delete/Set as Default buttons when the
// selection changes
void tableSelectionChanged(const QItemSelection&);
......
/*
This source file is part of Konsole, a terminal emulator.
Copyright (C) 2006-7 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>
// KDE
#include <KConfigGroup>
#include <KDesktopFile>
#include <KGlobal>
#include <KLocale>
#include <KStandardDirs>
// Konsole
#include "ShellCommand.h"
using namespace Konsole;
QHash<QString,Profile::Property> Profile::_propertyNames;
FallbackProfile::FallbackProfile()
: Profile(0)
{
// Fallback settings
setProperty(Name,i18n("Shell"));
setProperty(Command,getenv("SHELL"));
setProperty(Icon,"konsole");
setProperty(Arguments,QStringList() << getenv("SHELL"));
setProperty(LocalTabTitleFormat,"%d : %n");
setProperty(RemoteTabTitleFormat,"%H : %u");
setProperty(TabBarMode,AlwaysShowTabBar);
setProperty(ShowMenuBar,true);
setProperty(KeyBindings,"default");
setProperty(Font,QFont("Monospace"));
setProperty(HistoryMode,FixedSizeHistory);
setProperty(HistorySize,1000);
setProperty(ScrollBarPosition,ScrollBarRight);
setProperty(FlowControlEnabled,true);
setProperty(AllowProgramsToResizeWindow,true);
setProperty(BlinkingTextEnabled,true);
setProperty(BlinkingCursorEnabled,false);
setProperty(CursorShape,BlockCursor);
setProperty(UseCustomCursorColor,false);
setProperty(CustomCursorColor,Qt::black);
// default taken from KDE 3
setProperty(WordCharacters,":@-./_~?&=%+#");
// Fallback should not be shown in menus
setHidden(true);
}
Profile::Profile(Profile* parent)
: _parent(parent)
,_hidden(false)
{
}
bool Profile::isHidden() const { return _hidden; }
void Profile::setHidden(bool hidden) { _hidden = hidden; }
void Profile::setParent(Profile* parent) { _parent = parent; }
const Profile* Profile::parent() const { return _parent; }
bool Profile::isEmpty() const
{
return _propertyValues.isEmpty();
}
QHash<Profile::Property,QVariant> Profile::setProperties() const
{
return _propertyValues;
}
QVariant Profile::property(Property property) const
{
if ( _propertyValues.contains(property) )
return _propertyValues[property];
else if ( _parent )
return _parent->property(property);
else
return QVariant();
}
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)
{
return _propertyNames.contains(name);
}
Profile::Property Profile::lookupByName(const QString& name)
{
return _propertyNames[name];
}
QList<QString> Profile::namesForProperty(Property property)
{
return _propertyNames.keys(property);
}
void Profile::registerName(Property property , const QString& name)
{
_propertyNames.insert(name,property);
}
QString KDE4ProfileWriter::getPath(const Profile* info)
{
QString newPath;
if ( info->isPropertySet(Profile::Path) )
newPath=info->path();
// if the path is not specified, use the profile name + ".profile"
if ( newPath.isEmpty() )
newPath = info->name() + ".profile";
QFileInfo fileInfo(newPath);
if (!fileInfo.isAbsolute())
newPath = KGlobal::dirs()->saveLocation("data","konsole/") + newPath;
qDebug() << "Saving profile under name: " << newPath;
return newPath;
}
void KDE4ProfileWriter::writeStandardElement(KConfigGroup& group , char* name , const Profile* profile ,
Profile::Property attribute)
{
if ( profile->isPropertySet(attribute) )
group.writeEntry(name,profile->property(attribute));
}
bool KDE4ProfileWriter::writeProfile(const QString& path , const Profile* profile)
{
KConfig config(path,KConfig::NoGlobals);
// Basic Profile Settings
KConfigGroup general = config.group("General");
if ( profile->isPropertySet(Profile::Name) )
general.writeEntry("Name",profile->name());
if ( profile->isPropertySet(Profile::Command)
|| profile->isPropertySet(Profile::Arguments) )
general.writeEntry("Command",
ShellCommand(profile->command(),profile->arguments()).fullCommand());
if ( profile->isPropertySet(Profile::Directory) )
general.writeEntry("Directory",profile->defaultWorkingDirectory());
writeStandardElement( general , "Icon" , profile , Profile::Icon );
// Tab Titles
writeStandardElement( general , "LocalTabTitleFormat" , profile , Profile::LocalTabTitleFormat );
writeStandardElement( general , "RemoteTabTitleFormat" , profile , Profile::RemoteTabTitleFormat );
// Menu and Tab Bar
writeStandardElement( general , "TabBarMode" , profile , Profile::TabBarMode );
writeStandardElement( general , "ShowMenuBar" , profile , Profile::ShowMenuBar );
// Keyboard
KConfigGroup keyboard = config.group("Keyboard");
writeStandardElement( keyboard , "KeyBindings" , profile , Profile::KeyBindings );
// Appearance
KConfigGroup appearance = config.group("Appearance");
writeStandardElement( appearance , "ColorScheme" , profile , Profile::ColorScheme );
writeStandardElement( appearance , "Font" , profile , Profile::Font );
// Scrolling
KConfigGroup scrolling = config.group("Scrolling");
writeStandardElement( scrolling , "HistoryMode" , profile , Profile::HistoryMode );
writeStandardElement( scrolling , "HistorySize" , profile , Profile::HistorySize );
writeStandardElement( scrolling , "ScrollBarPosition" , profile , Profile::ScrollBarPosition );
// Terminal Features
KConfigGroup terminalFeatures = config.group("Terminal Features");
writeStandardElement( terminalFeatures , "FlowControl" , profile , Profile::FlowControlEnabled );
writeStandardElement( terminalFeatures , "BlinkingCursor" , profile , Profile::BlinkingCursorEnabled );
// Cursor
KConfigGroup cursorOptions = config.group("Cursor Options");
writeStandardElement( cursorOptions , "UseCustomCursorColor" , profile , Profile::UseCustomCursorColor );
writeStandardElement( cursorOptions , "CustomCursorColor" , profile , Profile::CustomCursorColor );
writeStandardElement( cursorOptions , "CursorShape" , profile , Profile::CursorShape );
// Interaction
KConfigGroup interactionOptions = config.group("Interaction Options");
writeStandardElement( interactionOptions , "WordCharacters" , profile , Profile::WordCharacters );
return true;
}
QStringList KDE4ProfileReader::findProfiles()
{
return KGlobal::dirs()->findAllResources("data","konsole/*.profile",
KStandardDirs::NoDuplicates);
}
bool KDE4ProfileReader::readProfile(const QString& path , Profile* profile)
{
qDebug() << "KDE 4 Profile Reader:" << path;
KConfig config(path,KConfig::NoGlobals);
// general
KConfigGroup general = config.group("General");
if ( general.hasKey("Name") )
profile->setProperty(Profile::Name,general.readEntry("Name"));
else
return false;
if ( general.hasKey("Command") )
{
ShellCommand shellCommand(general.readEntry("Command"));
profile->setProperty(Profile::Command,shellCommand.command());
profile->setProperty(Profile::Arguments,shellCommand.arguments());
}
readStandardElement<QString>(general,"Directory",profile,Profile::Directory);
readStandardElement<QString>(general,"Icon",profile,Profile::Icon);
readStandardElement<QString>(general,"LocalTabTitleFormat",profile,Profile::LocalTabTitleFormat);
readStandardElement<QString>(general,"RemoteTabTitleFormat",profile,Profile::RemoteTabTitleFormat);
readStandardElement<int>(general,"TabBarMode",profile,Profile::TabBarMode);
readStandardElement<bool>(general,"ShowMenuBar",profile,Profile::ShowMenuBar);
// keyboard
KConfigGroup keyboard = config.group("Keyboard");
readStandardElement<QString>(keyboard,"KeyBindings",profile,Profile::KeyBindings);
// appearence
KConfigGroup appearance = config.group("Appearance");
readStandardElement<QString>(appearance,"ColorScheme",profile,Profile::ColorScheme);
readStandardElement<QFont>(appearance,"Font",profile,Profile::Font);
// scrolling
KConfigGroup scrolling = config.group("Scrolling");
readStandardElement<int>(scrolling,"HistoryMode",profile,Profile::HistoryMode);
readStandardElement<int>(scrolling,"HistorySize",profile,Profile::HistorySize);
readStandardElement<int>(scrolling,"ScrollBarPosition",profile,Profile::ScrollBarPosition);
// terminal features
KConfigGroup terminalFeatures = config.group("Terminal Features");
readStandardElement<bool>(terminalFeatures,"FlowControl",profile,Profile::FlowControlEnabled);
readStandardElement<bool>(terminalFeatures,"BlinkingCursor",profile,Profile::BlinkingCursorEnabled);
// cursor settings
KConfigGroup cursorOptions = config.group("Cursor Options");
readStandardElement<bool>(cursorOptions,"UseCustomCursorColor",profile,Profile::UseCustomCursorColor);
readStandardElement<QColor>(cursorOptions,"CustomCursorColor",profile,Profile::CustomCursorColor);
readStandardElement<int>(cursorOptions,"CursorShape",profile,Profile::CursorShape);
// interaction options
KConfigGroup interactionOptions = config.group("Interaction Options");
readStandardElement<QString>(interactionOptions,"WordCharacters",profile,Profile::WordCharacters);
return true;
}
template <typename T>
void KDE4ProfileReader::readStandardElement(const KConfigGroup& group ,
char* name ,
Profile* info ,
Profile::Property property)
{
if ( group.hasKey(name) )
info->setProperty(property,group.readEntry(name,T()));
}
QStringList KDE3ProfileReader::findProfiles()
{
return KGlobal::dirs()->findAllResources("data", "konsole/*.desktop",
KStandardDirs::NoDuplicates);
}
bool KDE3ProfileReader::readProfile(const QString& path , Profile* profile)
{
if (!QFile::exists(path))
return false;
KDesktopFile* desktopFile = new KDesktopFile(path);
KConfigGroup* config = new KConfigGroup( desktopFile->desktopGroup() );
if ( config->hasKey("Name") )
profile->setProperty(Profile::Name,config->readEntry("Name"));
qDebug() << "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;
}
#include "Profile.moc"
/*
This source file is part of Konsole, a terminal emulator.
Copyright (C) 2006-7 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>
class KConfigGroup;
namespace Konsole
{
/**
* Represents a terminal set-up which can be used to
* set the initial state of new terminal sessions or applied
* to existing sessions.
*
* Profiles can be loaded from disk using ProfileReader instances
* and saved to disk using ProfileWriter instances.
*/
class Profile : public QObject