You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebase/kcontrol/konsole/sessioneditor.cpp

384 lines
12 KiB

/***************************************************************************
sessioneditor.cpp - description
-------------------
begin : oct 28 2001
copyright : (C) 2001 by Stephan Binner
email : binner@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. *
* *
***************************************************************************/
#include "sessioneditor.h"
#include "sessioneditor.moc"
#include <tqlineedit.h>
#include <tqcombobox.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include <tdelocale.h>
#include <tdefiledialog.h>
#include <kinputdialog.h>
#include <kicondialog.h>
#include <tdemessagebox.h>
#include <kurlrequester.h>
#include <klineedit.h>
#include <kiconloader.h>
#include <krun.h>
#include <kshell.h>
// SessionListBoxText is a list box text item with session filename
class SessionListBoxText : public TQListBoxText
{
public:
SessionListBoxText(const TQString &title, const TQString &filename): TQListBoxText(title)
{
m_filename = filename;
};
const TQString filename() { return m_filename; };
private:
TQString m_filename;
};
SessionEditor::SessionEditor(TQWidget * parent, const char *name)
:SessionDialog(parent, name)
{
sesMod=false;
oldSession=-1;
loaded=false;
TDEGlobal::locale()->insertCatalogue("konsole"); // For schema and keytab translations
TDEGlobal::iconLoader()->addAppDir( "konsole" );
directoryLine->setMode(KFile::Directory);
connect(sessionList, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(readSession(int)));
connect(saveButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(saveCurrent()));
connect(removeButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(removeCurrent()));
connect(nameLine, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(sessionModified()));
connect(directoryLine, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(sessionModified()));
connect(executeLine, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(sessionModified()));
connect(termLine, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(sessionModified()));
connect(previewIcon, TQT_SIGNAL(iconChanged(TQString)), this, TQT_SLOT(sessionModified()));
connect(fontCombo, TQT_SIGNAL(activated(int)), this, TQT_SLOT(sessionModified()));
connect(keytabCombo, TQT_SIGNAL(activated(int)), this, TQT_SLOT(sessionModified()));
connect(schemaCombo, TQT_SIGNAL(activated(int)), this, TQT_SLOT(sessionModified()));
}
SessionEditor::~SessionEditor()
{
keytabFilename.setAutoDelete(true);
schemaFilename.setAutoDelete(true);
}
void SessionEditor::show()
{
removeButton->setEnabled(sessionList->count()>1);
if (! loaded) {
loadAllKeytab();
loadAllSession();
readSession(0);
sessionList->setCurrentItem(0);
loaded = true;
}
SessionDialog::show();
}
void SessionEditor::loadAllKeytab()
{
TQStringList lst = TDEGlobal::dirs()->findAllResources("data", "konsole/*.keytab");
keytabCombo->clear();
keytabFilename.clear();
keytabCombo->insertItem(i18n("XTerm (XFree 4.x.x)"),0);
keytabFilename.append(new TQString(""));
int i=1;
for(TQStringList::Iterator it = lst.begin(); it != lst.end(); ++it )
{
TQString name = (*it);
TQString title = readKeymapTitle(name);
name = name.section('/',-1);
name = name.section('.',0);
keytabFilename.append(new TQString(name));
if (title.isNull() || title.isEmpty())
title=i18n("untitled");
keytabCombo->insertItem(title,i);
i++;
}
}
TQString SessionEditor::readKeymapTitle(const TQString & file)
{
TQString fPath = locate("data", "konsole/" + file);
if (fPath.isNull())
fPath = locate("data", file);
removeButton->setEnabled( TQFileInfo (fPath).isWritable () );
if (fPath.isNull())
return 0;
FILE *sysin = fopen(TQFile::encodeName(fPath), "r");
if (!sysin)
return 0;
char line[100];
int len;
while (fscanf(sysin, "%80[^\n]\n", line) > 0)
if ((len = strlen(line)) > 8)
if (!strncmp(line, "keyboard", 8)) {
fclose(sysin);
if(line[len-1] == '"')
line[len-1] = '\000';
TQString temp;
if(line[9] == '"')
temp=i18n(line+10);
else
temp=i18n(line+9);
return temp;
}
return 0;
}
void SessionEditor::loadAllSession(TQString currentFile)
{
TQStringList list = TDEGlobal::dirs()->findAllResources("data", "konsole/*.desktop", false, true);
sessionList->clear();
TQListBoxItem* currentItem = 0;
for (TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
TQString name = (*it);
KSimpleConfig* co = new KSimpleConfig(name,true);
co->setDesktopGroup();
TQString sesname = co->readEntry("Name",i18n("Unnamed"));
delete co;
sessionList->insertItem(new SessionListBoxText(sesname, name));
if (currentFile==name.section('/',-1))
currentItem = sessionList->item( sessionList->count()-1 );
}
sessionList->sort();
sessionList->setCurrentItem(0); // select the first added item correctly too
sessionList->setCurrentItem(currentItem);
emit getList();
}
void SessionEditor::readSession(int num)
{
int i,counter;
TQString str;
KSimpleConfig* co;
if(sesMod) {
disconnect(sessionList, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(readSession(int)));
sessionList->setCurrentItem(oldSession);
querySave();
sessionList->setCurrentItem(num);
connect(sessionList, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(readSession(int)));
sesMod=false;
}
if( sessionList->item(num) )
{
removeButton->setEnabled( TQFileInfo ( ((SessionListBoxText *)sessionList->item(num))->filename() ).isWritable () );
co = new KSimpleConfig( ((SessionListBoxText *)sessionList->item(num))->filename(),true);
co->setDesktopGroup();
str = co->readEntry("Name");
nameLine->setText(str);
str = co->readPathEntry("Cwd");
directoryLine->lineEdit()->setText(str);
str = co->readPathEntry("Exec");
executeLine->setText(str);
str = co->readEntry("Icon","konsole");
previewIcon->setIcon(str);
i = co->readUnsignedNumEntry("Font",(unsigned int)-1);
fontCombo->setCurrentItem(i+1);
str = co->readEntry("Term","xterm");
termLine->setText(str);
str = co->readEntry("KeyTab","");
i=0;
counter=0;
for (TQString *it = keytabFilename.first(); it != 0; it = keytabFilename.next()) {
if (str == (*it))
i = counter;
counter++;
}
keytabCombo->setCurrentItem(i);
str = co->readEntry("Schema","");
i=0;
counter=0;
for (TQString *it = schemaFilename.first(); it != 0; it = schemaFilename.next()) {
if (str == (*it))
i = counter;
counter++;
}
schemaCombo->setCurrentItem(i);
delete co;
}
sesMod=false;
oldSession=num;
}
void SessionEditor::querySave()
{
int result = KMessageBox::questionYesNo(this,
i18n("The session has been modified.\n"
"Do you want to save the changes?"),
i18n("Session Modified"),
KStdGuiItem::save(),
KStdGuiItem::discard());
if (result == KMessageBox::Yes)
{
saveCurrent();
}
}
void SessionEditor::schemaListChanged(const TQStringList &titles, const TQStringList &filenames)
{
const TQString text = schemaCombo->currentText();
schemaCombo->clear();
schemaFilename.clear();
schemaCombo->insertItem(i18n("Konsole Default"),0);
schemaFilename.append(new TQString(""));
schemaCombo->insertStringList(titles, 1);
for (TQStringList::const_iterator it = filenames.begin(); it != filenames.end(); ++it)
schemaFilename.append(new TQString(*it));
// Restore current item
int item = 0;
for (int i = 0; i < schemaCombo->count(); i++)
if (schemaCombo->text(i) == text) {
item = i;
break;
}
schemaCombo->setCurrentItem(item);
}
void SessionEditor::saveCurrent()
{
// Verify Execute entry is valid; otherwise Konsole will ignore it.
// This code is take from konsole.cpp; if you change one, change both.
TQString exec = executeLine->text();
if ( !exec.isEmpty() ) // If Execute field is empty, default shell is used.
{
if ( exec.startsWith( "su -c \'" ) )
exec = exec.mid( 7, exec.length() - 8 );
exec = KRun::binaryName( exec, false );
exec = KShell::tildeExpand( exec );
TQString pexec = TDEGlobal::dirs()->findExe( exec );
if ( pexec.isEmpty() )
{
int result = KMessageBox::warningContinueCancel( this,
i18n( "The Execute entry is not a valid command.\n"
"You can still save this session, but it will not show up in Konsole's Session list." ),
i18n( "Invalid Execute Entry" ),
KStdGuiItem::save() );
if ( result != KMessageBox::Continue )
return;
}
}
TQString fullpath;
if (sessionList->currentText() == nameLine->text()) {
fullpath = ( ((SessionListBoxText *)sessionList->item( sessionList->currentItem() ))->filename() ).section('/',-1);
}
else {
// Only ask for a name for changed nameLine, considered a "save as"
fullpath = nameLine->text().stripWhiteSpace().simplifyWhiteSpace()+".desktop";
bool ok;
fullpath = KInputDialog::getText( i18n( "Save Session" ),
i18n( "File name:" ), fullpath, &ok, this );
if (!ok) return;
}
if (fullpath[0] != '/')
fullpath = TDEGlobal::dirs()->saveLocation("data", "konsole/") + fullpath;
KSimpleConfig* co = new KSimpleConfig(fullpath);
co->setDesktopGroup();
co->writeEntry("Type","KonsoleApplication");
co->writeEntry("Name",nameLine->text());
co->writePathEntry("Cwd",directoryLine->lineEdit()->text());
co->writePathEntry("Exec",executeLine->text());
co->writeEntry("Icon",previewIcon->icon());
if (fontCombo->currentItem()==0)
co->writeEntry("Font","");
else
co->writeEntry("Font",fontCombo->currentItem()-1);
co->writeEntry("Term",termLine->text());
co->writeEntry("KeyTab",*keytabFilename.at(keytabCombo->currentItem()));
co->writeEntry("Schema",*schemaFilename.at(schemaCombo->currentItem()));
co->sync();
delete co;
sesMod=false;
loadAllSession(fullpath.section('/',-1));
removeButton->setEnabled(sessionList->count()>1);
}
void SessionEditor::removeCurrent()
{
TQString base = ((SessionListBoxText *)sessionList->item( sessionList->currentItem() ))->filename();
// Query if system sessions should be removed
if (locateLocal("data", "konsole/" + base.section('/', -1)) != base) {
int code = KMessageBox::warningContinueCancel(this,
i18n("You are trying to remove a system session. Are you sure?"),
i18n("Removing System Session"),
KGuiItem(i18n("&Delete"),"edit-delete"));
if (code != KMessageBox::Continue)
return;
}
if (!TQFile::remove(base)) {
KMessageBox::error(this,
i18n("Cannot remove the session.\nMaybe it is a system session.\n"),
i18n("Error Removing Session"));
return;
}
removeButton->setEnabled(sessionList->count()>1);
loadAllSession();
readSession(0);
sessionList->setCurrentItem(0);
}
void SessionEditor::sessionModified()
{
saveButton->setEnabled(nameLine->text().length() != 0);
sesMod=true;
emit changed();
}