From 2a1109196ff3fd2cf9b580b43045397cf88c481f Mon Sep 17 00:00:00 2001 From: Robert Knight Date: Sat, 23 Jun 2007 02:09:21 +0000 Subject: [PATCH] Save and load environment variables as part of the profile. Defaults to just 'TERM=xterm'. Allow editing of the environment in the profile editor (not just the TERM variable). Separate out the tab-related options into their own tab in the profile editor and rename 'Keyboard Setup' to 'Input' as that seems a more obvious name. svn path=/trunk/KDE/kdebase/apps/konsole/; revision=679103 --- src/EditProfileDialog.cpp | 98 ++++++++++++++++++++++++++++----------- src/EditProfileDialog.h | 6 ++- src/EditProfileDialog.ui | 98 ++++++++++++++++++++++++++++----------- src/Profile.cpp | 5 +- src/Pty.cpp | 29 ++++++++++-- src/Pty.h | 11 +++-- src/Session.cpp | 12 ++--- src/Session.h | 18 ++----- src/SessionManager.cpp | 3 ++ 9 files changed, 201 insertions(+), 79 deletions(-) diff --git a/src/EditProfileDialog.cpp b/src/EditProfileDialog.cpp index 3d3802501..0c420bf8e 100644 --- a/src/EditProfileDialog.cpp +++ b/src/EditProfileDialog.cpp @@ -27,7 +27,7 @@ #include #include #include - +#include #include #include @@ -140,9 +140,13 @@ void EditProfileDialog::setProfile(const QString& key) _tempProfile = new Profile; } } +const Profile* EditProfileDialog::lookupProfile() const +{ + return SessionManager::instance()->profile(_profileKey); +} void EditProfileDialog::ensurePageLoaded(int page) { - const Profile* info = SessionManager::instance()->profile(_profileKey); + const Profile* info = lookupProfile(); Q_ASSERT( _pageNeedsUpdate.count() > page ); Q_ASSERT( info ); @@ -153,6 +157,8 @@ void EditProfileDialog::ensurePageLoaded(int 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 ) @@ -169,6 +175,8 @@ void EditProfileDialog::ensurePageLoaded(int page) } void EditProfileDialog::setupGeneralPage(const Profile* info) { + + // basic profile options _ui->profileNameEdit->setText( info->name() ); ShellCommand command( info->command() , info->arguments() ); @@ -183,6 +191,49 @@ void EditProfileDialog::setupGeneralPage(const Profile* info) _ui->dirSelectButton->setIcon( KIcon("folder-open") ); _ui->iconSelectButton->setIcon( KIcon(info->icon()) ); + // window options + _ui->showMenuBarButton->setChecked( info->property(Profile::ShowMenuBar).value() ); + + // signals and slots + connect( _ui->dirSelectButton , SIGNAL(clicked()) , this , SLOT(selectInitialDir()) ); + connect( _ui->iconSelectButton , SIGNAL(clicked()) , this , SLOT(selectIcon()) ); + + 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->environmentEditButton , SIGNAL(clicked()) , this , + SLOT(showEnvironmentEditor()) ); +} +void EditProfileDialog::showEnvironmentEditor() +{ + const Profile* info = lookupProfile(); + + KDialog* dialog = new KDialog(this); + QTextEdit* edit = new QTextEdit(dialog); + + QStringList currentEnvironment = info->property(Profile::Environment).value(); + + 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* info) +{ // tab title format _ui->tabTitleEdit->setClearButtonShown(true); _ui->remoteTabTitleEdit->setClearButtonShown(true); @@ -208,29 +259,17 @@ void EditProfileDialog::setupGeneralPage(const Profile* info) _ui->tabBarPositionCombo->setCurrentIndex(tabPosition); + // signals and slots connect( _ui->tabBarVisibilityCombo , SIGNAL(activated(int)) , this , SLOT(tabBarVisibilityChanged(int)) ); connect( _ui->tabBarPositionCombo , SIGNAL(activated(int)) , this , SLOT(tabBarPositionChanged(int)) ); - _ui->showMenuBarButton->setChecked( info->property(Profile::ShowMenuBar).value() ); - - // signals and slots - connect( _ui->dirSelectButton , SIGNAL(clicked()) , this , SLOT(selectInitialDir()) ); - connect( _ui->iconSelectButton , SIGNAL(clicked()) , this , SLOT(selectIcon()) ); - - 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->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); @@ -243,9 +282,6 @@ void EditProfileDialog::setupGeneralPage(const Profile* info) _ui->remoteTabTitleEditButton->setMenu(remoteTabTitleAction->menu()); connect( remoteTabTitleAction , SIGNAL(dynamicElementSelected(const QString&)) , this , SLOT(insertRemoteTabTitleText(const QString&)) ); - - connect(_ui->showMenuBarButton , SIGNAL(toggled(bool)) , this , - SLOT(showMenuBar(bool)) ); } void EditProfileDialog::tabBarVisibilityChanged(int newValue) { @@ -314,7 +350,7 @@ void EditProfileDialog::selectInitialDir() void EditProfileDialog::setupAppearancePage(const Profile* info) { // setup color list - updateColorSchemeList(); + updateColorSchemeList(true); ColorSchemeViewDelegate* delegate = new ColorSchemeViewDelegate(this); @@ -367,17 +403,19 @@ void EditProfileDialog::updateFontPreviewLabel(const QFont& font) _ui->fontPreviewLabel->setFont(font); _ui->fontPreviewLabel->setText(i18n("%1, size %2",font.family(),font.pointSize())); } -void EditProfileDialog::updateColorSchemeList() +void EditProfileDialog::updateColorSchemeList(bool selectCurrentScheme) { delete _ui->colorSchemeList->model(); - const QString& name = SessionManager::instance()->profile(_profileKey)->colorScheme(); + const QString& name = lookupProfile()->colorScheme(); const ColorScheme* currentScheme = ColorSchemeManager::instance()->findColorScheme(name); QStandardItemModel* model = new QStandardItemModel(this); QList schemeList = ColorSchemeManager::instance()->allColorSchemes(); QListIterator schemeIter(schemeList); + QStandardItem* selectedItem = 0; + while (schemeIter.hasNext()) { const ColorScheme* colors = schemeIter.next(); @@ -386,7 +424,10 @@ void EditProfileDialog::updateColorSchemeList() item->setFlags( item->flags() | Qt::ItemIsUserCheckable ); if ( colors == currentScheme ) + { item->setCheckState( Qt::Checked ); + selectedItem = item; + } else item->setCheckState( Qt::Unchecked ); @@ -397,6 +438,11 @@ void EditProfileDialog::updateColorSchemeList() _ui->colorSchemeList->setModel(model); + /*if ( selectCurrentScheme ) + _ui->colorSchemeList->selectionModel()->select( + selectedItem->index() , QItemSelectionModel::Select + );*/ + } void EditProfileDialog::updateKeyBindingsList() { @@ -404,7 +450,7 @@ void EditProfileDialog::updateKeyBindingsList() delete _ui->keyBindingList->model(); - const QString& name = SessionManager::instance()->profile(_profileKey) + const QString& name = lookupProfile() ->property(Profile::KeyBindings).value(); const KeyboardTranslator* currentTranslator = keyManager->findTranslator(name); @@ -487,7 +533,7 @@ void EditProfileDialog::preview(int property , const QVariant& value) QHash map; map.insert((Profile::Property)property,value); - const Profile* original = SessionManager::instance()->profile(_profileKey); + const Profile* original = lookupProfile(); if (!_previewedProperties.contains(property)) _previewedProperties.insert(property , original->property((Profile::Property)property) ); @@ -551,7 +597,7 @@ void EditProfileDialog::showColorSchemeEditor(bool isNewScheme) updateColorSchemeList(); - Profile* profile = SessionManager::instance()->profile(_profileKey); + const Profile* profile = lookupProfile(); const QString& currentScheme = profile->colorScheme(); // the next couple of lines may seem slightly odd, @@ -684,7 +730,7 @@ void EditProfileDialog::showKeyBindingEditor(bool isNewTranslator) updateKeyBindingsList(); - const QString& currentTranslator = SessionManager::instance()->profile(_profileKey) + const QString& currentTranslator = lookupProfile() ->property(Profile::KeyBindings).value(); if ( newTranslator->name() == currentTranslator ) diff --git a/src/EditProfileDialog.h b/src/EditProfileDialog.h index 133e30752..4874b86fb 100644 --- a/src/EditProfileDialog.h +++ b/src/EditProfileDialog.h @@ -109,6 +109,7 @@ private slots: void insertRemoteTabTitleText(const QString& text); void showMenuBar(bool); + void showEnvironmentEditor(); void tabBarVisibilityChanged(int); void tabBarPositionChanged(int); @@ -158,12 +159,13 @@ private slots: private: // initialize various pages of the dialog void setupGeneralPage(const Profile* info); + void setupTabsPage(const Profile* info); void setupAppearancePage(const Profile* info); void setupKeyboardPage(const Profile* info); void setupScrollingPage(const Profile* info); void setupAdvancedPage(const Profile* info); - void updateColorSchemeList(); + void updateColorSchemeList(bool selectCurrentScheme = false); void updateKeyBindingsList(); void updateFontPreviewLabel(const QFont& font); @@ -191,6 +193,8 @@ private: }; void setupCombo(ComboOption* options , const Profile* profile); + const Profile* lookupProfile() const; + Ui::EditProfileDialog* _ui; Profile* _tempProfile; QString _profileKey; diff --git a/src/EditProfileDialog.ui b/src/EditProfileDialog.ui index 651f32749..7ffa68321 100644 --- a/src/EditProfileDialog.ui +++ b/src/EditProfileDialog.ui @@ -5,13 +5,10 @@ 0 0 - 521 - 596 + 441 + 505 - - Form - 0 @@ -165,15 +162,80 @@ - 40 + 20 20 + + + + Environment: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Edit... + + + + + + + Window Options + + + true + + + + + + + 0 + 0 + + + + Show or hide the menu bar in terminal windows using this profile + + + Show menu bar in new windows created from this profile + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + Tabs + + @@ -243,28 +305,12 @@ - Window && Tab Bar Options + Tab Bar Options true - - - - - 0 - 0 - - - - Show or hide the menu bar in terminal windows using this profile - - - Show menu bar in new windows created from this profile - - - @@ -309,8 +355,8 @@ - 95 - 20 + 20 + 40 @@ -664,7 +710,7 @@ - Keyboard Setup + Input diff --git a/src/Profile.cpp b/src/Profile.cpp index 957003e03..74db9369b 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -115,12 +115,14 @@ FallbackProfile::FallbackProfile() setProperty(Command,getenv("SHELL")); setProperty(Icon,"konsole"); setProperty(Arguments,QStringList() << getenv("SHELL")); + setProperty(Environment,QStringList() << "TERM=xterm"); setProperty(LocalTabTitleFormat,"%d : %n"); setProperty(RemoteTabTitleFormat,"%H (%u)"); setProperty(TabBarMode,AlwaysShowTabBar); setProperty(TabBarPosition,TabBarBottom); setProperty(ShowMenuBar,true); + setProperty(KeyBindings,"default"); setProperty(Font,QFont("Monospace")); @@ -275,6 +277,7 @@ bool KDE4ProfileWriter::writeProfile(const QString& path , const Profile* profil if ( profile->isPropertySet(Profile::Directory) ) general.writeEntry("Directory",profile->defaultWorkingDirectory()); + writeStandardElement( general , profile , Profile::Environment ); writeStandardElement( general , profile , Profile::Icon ); // Tab Titles @@ -359,7 +362,7 @@ bool KDE4ProfileReader::readProfile(const QString& path , Profile* profile , QSt } readStandardElement(general,profile,Profile::Directory); - + readStandardElement(general,profile,Profile::Environment); readStandardElement(general,profile,Profile::Icon); readStandardElement(general,profile,Profile::LocalTabTitleFormat); readStandardElement(general,profile,Profile::RemoteTabTitleFormat); diff --git a/src/Pty.cpp b/src/Pty.cpp index 953c398de..7973a1667 100644 --- a/src/Pty.cpp +++ b/src/Pty.cpp @@ -103,9 +103,32 @@ void Pty::setErase(char erase) } } +void Pty::addEnvironmentVariables(const QStringList& environment) +{ + QListIterator 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); + + qDebug() << "Setting environment pair" << variable << + " set to " << value; + + setEnvironment(variable,value); + } + } +} + int Pty::start(const QString& program, const QStringList& programArguments, - const QString& term, + const QStringList& environment, ulong winid, bool addToUtmp, const QString& dbusService, @@ -115,12 +138,12 @@ int Pty::start(const QString& program, setBinaryExecutable(program.toLatin1()); + addEnvironmentVariables(environment); + QStringListIterator it( programArguments ); while (it.hasNext()) arguments.append( it.next().toUtf8() ); - if ( !term.isEmpty() ) - setEnvironment("TERM",term); if ( !dbusService.isEmpty() ) setEnvironment("KONSOLE_DBUS_SERVICE",dbusService); if ( !dbusSession.isEmpty() ) diff --git a/src/Pty.h b/src/Pty.h index 9f2a86ecc..b5d6b36c4 100644 --- a/src/Pty.h +++ b/src/Pty.h @@ -73,8 +73,9 @@ Q_OBJECT * * @param program Path to the program to start * @param arguments Arguments to pass to the program being started - * @param term Specifies the value of the TERM environment variable - * in the process's environment. + * @param environment A list of key=value pairs which will be added + * to the environemnt 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 @@ -86,7 +87,7 @@ Q_OBJECT */ int start( const QString& program, const QStringList& arguments, - const QString& term, + const QStringList& environment, ulong winid, bool addToUtmp, const QString& dbusService, @@ -187,6 +188,10 @@ Q_OBJECT 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); diff --git a/src/Session.cpp b/src/Session.cpp index ef19c18b5..38d00f65a 100644 --- a/src/Session.cpp +++ b/src/Session.cpp @@ -1,5 +1,5 @@ /* - This file is part of Konsole, an X _terminal. + This file is part of Konsole Copyright (C) 2006-2007 by Robert Knight Copyright (C) 1997,1998 by Lars Doelle @@ -276,7 +276,7 @@ void Session::run() int result = _shellProcess->start(QFile::encodeName(_program), arguments, - _term, + _environment, _winId, _addToUtmp, dbusService, @@ -565,14 +565,14 @@ QString Session::keyBindings() const return _emulation->keyBindings(); } -QString Session::terminalType() const +QStringList Session::environment() const { - return _term; + return _environment; } -void Session::setTerminalType(const QString& _terminalType) +void Session::setEnvironment(const QStringList& environment) { - _term = _terminalType; + _environment = environment; } int Session::sessionId() const diff --git a/src/Session.h b/src/Session.h index c5c5c650d..219e35471 100644 --- a/src/Session.h +++ b/src/Session.h @@ -132,21 +132,13 @@ public: Emulation* emulation() const; /** - * Returns the value of the TERM environment variable which will - * be used in the session's environment when it is started using - * the run() method. - * - * Defaults to "xterm". + * TODO: Document me */ - QString terminalType() const; + QStringList environment() const; /** - * Sets the value of the TERM variable which will be used in the - * session's environment when it is started using the run() method. - * Changing this once the session has been started using run() has no effect. - * - * Defaults to "xterm" if not set explicitly + * TODO: Document me */ - void setTerminalType(const QString& terminalType); + void setEnvironment(const QStringList& environment); /** Returns the unique ID for this session. */ int sessionId() const; @@ -485,7 +477,7 @@ private: QString _program; QStringList _arguments; - QString _term; + QStringList _environment; ulong _winId; int _sessionId; diff --git a/src/SessionManager.cpp b/src/SessionManager.cpp index 615beaefa..ac47e4097 100644 --- a/src/SessionManager.cpp +++ b/src/SessionManager.cpp @@ -383,6 +383,9 @@ void SessionManager::applyProfile(Session* session, const Profile* info , bool m if ( !modifiedPropertiesOnly || info->isPropertySet(Profile::Directory) ) session->setInitialWorkingDirectory(info->defaultWorkingDirectory()); + if ( !modifiedPropertiesOnly || info->isPropertySet(Profile::Environment) ) + session->setEnvironment(info->property(Profile::Environment).value()); + if ( !modifiedPropertiesOnly || info->isPropertySet(Profile::Icon) ) session->setIconName(info->icon());