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/kmenuedit/basictab.cpp

501 lines
17 KiB

/*
* Copyright (C) 2000 Matthias Elter <elter@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 <tqcheckbox.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqfileinfo.h>
#include <tqgroupbox.h>
#include <tqhbox.h>
#include <tqwhatsthis.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kglobal.h>
#include <kdialog.h>
#include <kkeybutton.h>
#include <klineedit.h>
#include <kmessagebox.h>
#include <kicondialog.h>
#include <kdesktopfile.h>
#include <kurlrequester.h>
#include <kfiledialog.h>
#include <kcombobox.h>
#include <kkeydialog.h>
#include <kprocess.h>
#include "khotkeys.h"
#include "menuinfo.h"
#include "basictab.h"
#include "basictab.moc"
BasicTab::BasicTab( TQWidget *parent, const char *name )
: TQWidget(parent, name)
{
_menuFolderInfo = 0;
_menuEntryInfo = 0;
TQGridLayout *layout = new TQGridLayout(this, 6, 2,
KDialog::marginHint(),
KDialog::spacingHint());
// general group
TQGroupBox *general_group = new TQGroupBox(this);
TQGridLayout *grid = new TQGridLayout(general_group, 5, 2,
KDialog::marginHint(),
KDialog::spacingHint());
general_group->setAcceptDrops(false);
// setup line inputs
_nameEdit = new KLineEdit(general_group);
_nameEdit->setAcceptDrops(false);
_descriptionEdit = new KLineEdit(general_group);
_descriptionEdit->setAcceptDrops(false);
_commentEdit = new KLineEdit(general_group);
_commentEdit->setAcceptDrops(false);
_execEdit = new KURLRequester(general_group);
_execEdit->lineEdit()->setAcceptDrops(false);
TQWhatsThis::add(_execEdit,i18n(
"Following the command, you can have several place holders which will be replaced "
"with the actual values when the actual program is run:\n"
"%f - a single file name\n"
"%F - a list of files; use for applications that can open several local files at once\n"
"%u - a single URL\n"
"%U - a list of URLs\n"
"%d - the folder of the file to open\n"
"%D - a list of folders\n"
"%i - the icon\n"
"%m - the mini-icon\n"
"%c - the caption"));
_launchCB = new TQCheckBox(i18n("Enable &launch feedback"), general_group);
_systrayCB = new TQCheckBox(i18n("&Place in system tray"), general_group);
// setup labels
_nameLabel = new TQLabel(_nameEdit, i18n("&Name:"), general_group);
_descriptionLabel = new TQLabel(_descriptionEdit, i18n("&Description:"), general_group);
_commentLabel = new TQLabel(_commentEdit, i18n("&Comment:"), general_group);
_execLabel = new TQLabel(_execEdit, i18n("Co&mmand:"), general_group);
grid->addWidget(_nameLabel, 0, 0);
grid->addWidget(_descriptionLabel, 1, 0);
grid->addWidget(_commentLabel, 2, 0);
grid->addWidget(_execLabel, 3, 0);
// connect line inputs
connect(_nameEdit, TQT_SIGNAL(textChanged(const TQString&)),
TQT_SLOT(slotChanged()));
connect(_descriptionEdit, TQT_SIGNAL(textChanged(const TQString&)),
TQT_SLOT(slotChanged()));
connect(_commentEdit, TQT_SIGNAL(textChanged(const TQString&)),
TQT_SLOT(slotChanged()));
connect(_execEdit, TQT_SIGNAL(textChanged(const TQString&)),
TQT_SLOT(slotChanged()));
connect(_execEdit, TQT_SIGNAL(urlSelected(const TQString&)),
TQT_SLOT(slotExecSelected()));
connect(_launchCB, TQT_SIGNAL(clicked()), TQT_SLOT(launchcb_clicked()));
connect(_systrayCB, TQT_SIGNAL(clicked()), TQT_SLOT(systraycb_clicked()));
// add line inputs to the grid
grid->addMultiCellWidget(_nameEdit, 0, 0, 1, 1);
grid->addMultiCellWidget(_descriptionEdit, 1, 1, 1, 1);
grid->addMultiCellWidget(_commentEdit, 2, 2, 1, 2);
grid->addMultiCellWidget(_execEdit, 3, 3, 1, 2);
grid->addMultiCellWidget(_launchCB, 4, 4, 0, 2);
grid->addMultiCellWidget(_systrayCB, 5, 5, 0, 2);
// setup icon button
_iconButton = new KIconButton(general_group);
_iconButton->setFixedSize(56,56);
_iconButton->setIconSize(48);
connect(_iconButton, TQT_SIGNAL(iconChanged(TQString)), TQT_SLOT(slotChanged()));
grid->addMultiCellWidget(_iconButton, 0, 1, 2, 2);
// add the general group to the main layout
layout->addMultiCellWidget(general_group, 0, 0, 0, 1);
// path group
_path_group = new TQGroupBox(this);
TQVBoxLayout *vbox = new TQVBoxLayout(_path_group, KDialog::marginHint(),
KDialog::spacingHint());
TQHBox *hbox = new TQHBox(_path_group);
hbox->setSpacing(KDialog::spacingHint());
_pathLabel = new TQLabel(i18n("&Work path:"), hbox);
_pathEdit = new KURLRequester(hbox);
_pathEdit->setMode(KFile::Directory | KFile::LocalOnly);
_pathEdit->lineEdit()->setAcceptDrops(false);
_pathLabel->setBuddy(_pathEdit);
connect(_pathEdit, TQT_SIGNAL(textChanged(const TQString&)),
TQT_SLOT(slotChanged()));
vbox->addWidget(hbox);
layout->addMultiCellWidget(_path_group, 1, 1, 0, 1);
// terminal group
_term_group = new TQGroupBox(this);
vbox = new TQVBoxLayout(_term_group, KDialog::marginHint(),
KDialog::spacingHint());
_terminalCB = new TQCheckBox(i18n("Run in term&inal"), _term_group);
connect(_terminalCB, TQT_SIGNAL(clicked()), TQT_SLOT(termcb_clicked()));
vbox->addWidget(_terminalCB);
hbox = new TQHBox(_term_group);
hbox->setSpacing(KDialog::spacingHint());
_termOptLabel = new TQLabel(i18n("Terminal &options:"), hbox);
_termOptEdit = new KLineEdit(hbox);
_termOptEdit->setAcceptDrops(false);
_termOptLabel->setBuddy(_termOptEdit);
connect(_termOptEdit, TQT_SIGNAL(textChanged(const TQString&)),
TQT_SLOT(slotChanged()));
vbox->addWidget(hbox);
layout->addMultiCellWidget(_term_group, 2, 2, 0, 1);
_termOptEdit->setEnabled(false);
// uid group
_uid_group = new TQGroupBox(this);
vbox = new TQVBoxLayout(_uid_group, KDialog::marginHint(),
KDialog::spacingHint());
_uidCB = new TQCheckBox(i18n("&Run as a different user"), _uid_group);
connect(_uidCB, TQT_SIGNAL(clicked()), TQT_SLOT(uidcb_clicked()));
vbox->addWidget(_uidCB);
hbox = new TQHBox(_uid_group);
hbox->setSpacing(KDialog::spacingHint());
_uidLabel = new TQLabel(i18n("&Username:"), hbox);
_uidEdit = new KLineEdit(hbox);
_uidEdit->setAcceptDrops(false);
_uidLabel->setBuddy(_uidEdit);
connect(_uidEdit, TQT_SIGNAL(textChanged(const TQString&)),
TQT_SLOT(slotChanged()));
vbox->addWidget(hbox);
layout->addMultiCellWidget(_uid_group, 3, 3, 0, 1);
_uidEdit->setEnabled(false);
layout->setRowStretch(0, 2);
// key binding group
general_group_keybind = new TQGroupBox(this);
layout->addMultiCellWidget( general_group_keybind, 4, 4, 0, 1 );
// dummy widget in order to make it look a bit better
layout->addWidget( new TQWidget(this), 5, 0 );
layout->setRowStretch( 5, 4 );
TQGridLayout *grid_keybind = new TQGridLayout(general_group_keybind, 3, 1,
KDialog::marginHint(),
KDialog::spacingHint());
//_keyEdit = new KLineEdit(general_group_keybind);
//_keyEdit->setReadOnly( true );
//_keyEdit->setText( "" );
//TQPushButton* _keyButton = new TQPushButton( i18n( "Change" ),
// general_group_keybind );
//connect( _keyButton, TQT_SIGNAL( clicked()), this, TQT_SLOT( keyButtonPressed()));
_keyEdit = new KKeyButton(general_group_keybind);
grid_keybind->addWidget(new TQLabel(_keyEdit, i18n("Current shortcut &key:"), general_group_keybind), 0, 0);
connect( _keyEdit, TQT_SIGNAL(capturedShortcut(const KShortcut&)),
this, TQT_SLOT(slotCapturedShortcut(const KShortcut&)));
grid_keybind->addWidget(_keyEdit, 0, 1);
//grid_keybind->addWidget(_keyButton, 0, 2 );
if (!KHotKeys::present())
general_group_keybind->hide();
slotDisableAction();
}
void BasicTab::slotDisableAction()
{
//disable all group at the begining.
//because there is not file selected.
_nameEdit->setEnabled(false);
_descriptionEdit->setEnabled(false);
_commentEdit->setEnabled(false);
_execEdit->setEnabled(false);
_launchCB->setEnabled(false);
_systrayCB->setEnabled(false);
_nameLabel->setEnabled(false);
_descriptionLabel->setEnabled(false);
_commentLabel->setEnabled(false);
_execLabel->setEnabled(false);
_path_group->setEnabled(false);
_term_group->setEnabled(false);
_uid_group->setEnabled(false);
_iconButton->setEnabled(false);
// key binding part
general_group_keybind->setEnabled( false );
}
void BasicTab::enableWidgets(bool isDF, bool isDeleted)
{
// set only basic attributes if it is not a .desktop file
_nameEdit->setEnabled(!isDeleted);
_descriptionEdit->setEnabled(!isDeleted);
_commentEdit->setEnabled(!isDeleted);
_iconButton->setEnabled(!isDeleted);
_execEdit->setEnabled(isDF && !isDeleted);
_launchCB->setEnabled(isDF && !isDeleted);
_systrayCB->setEnabled(isDF && !isDeleted);
_nameLabel->setEnabled(!isDeleted);
_descriptionLabel->setEnabled(!isDeleted);
_commentLabel->setEnabled(!isDeleted);
_execLabel->setEnabled(isDF && !isDeleted);
_path_group->setEnabled(isDF && !isDeleted);
_term_group->setEnabled(isDF && !isDeleted);
_uid_group->setEnabled(isDF && !isDeleted);
general_group_keybind->setEnabled( isDF && !isDeleted );
_termOptEdit->setEnabled(isDF && !isDeleted && _terminalCB->isChecked());
_termOptLabel->setEnabled(isDF && !isDeleted && _terminalCB->isChecked());
_uidEdit->setEnabled(isDF && !isDeleted && _uidCB->isChecked());
_uidLabel->setEnabled(isDF && !isDeleted && _uidCB->isChecked());
}
void BasicTab::setFolderInfo(MenuFolderInfo *folderInfo)
{
blockSignals(true);
_menuFolderInfo = folderInfo;
_menuEntryInfo = 0;
_nameEdit->setText(folderInfo->caption);
_descriptionEdit->setText(folderInfo->genericname);
_descriptionEdit->setCursorPosition(0);
_commentEdit->setText(folderInfo->comment);
_commentEdit->setCursorPosition(0);
_iconButton->setIcon(folderInfo->icon);
// clean all disabled fields and return
_execEdit->lineEdit()->setText("");
_pathEdit->lineEdit()->setText("");
_termOptEdit->setText("");
_uidEdit->setText("");
_launchCB->setChecked(false);
_systrayCB->setChecked(false);
_terminalCB->setChecked(false);
_uidCB->setChecked(false);
_keyEdit->setShortcut(0, false);
enableWidgets(false, folderInfo->hidden);
blockSignals(false);
}
void BasicTab::setEntryInfo(MenuEntryInfo *entryInfo)
{
blockSignals(true);
_menuFolderInfo = 0;
_menuEntryInfo = entryInfo;
if (!entryInfo)
{
_nameEdit->setText(TQString::null);
_descriptionEdit->setText(TQString::null);
_commentEdit->setText(TQString::null);
_iconButton->setIcon(TQString::null);
// key binding part
_keyEdit->setShortcut( KShortcut(), false );
_execEdit->lineEdit()->setText(TQString::null);
_systrayCB->setChecked(false);
_pathEdit->lineEdit()->setText(TQString::null);
_termOptEdit->setText(TQString::null);
_uidEdit->setText(TQString::null);
_launchCB->setChecked(false);
_terminalCB->setChecked(false);
_uidCB->setChecked(false);
enableWidgets(true, true);
blockSignals(false);
return;
}
KDesktopFile *df = entryInfo->desktopFile();
_nameEdit->setText(df->readName());
_descriptionEdit->setText(df->readGenericName());
_descriptionEdit->setCursorPosition(0);
_commentEdit->setText(df->readComment());
_commentEdit->setCursorPosition(0);
_iconButton->setIcon(df->readIcon());
// key binding part
if( KHotKeys::present())
{
_keyEdit->setShortcut( entryInfo->shortcut(), false );
}
TQString temp = df->readPathEntry("Exec");
if (temp.left(12) == "ksystraycmd ")
{
_execEdit->lineEdit()->setText(temp.right(temp.length()-12));
_systrayCB->setChecked(true);
}
else
{
_execEdit->lineEdit()->setText(temp);
_systrayCB->setChecked(false);
}
_pathEdit->lineEdit()->setText(df->readPath());
_termOptEdit->setText(df->readEntry("TerminalOptions"));
_uidEdit->setText(df->readEntry("X-KDE-Username"));
if( df->hasKey( "StartupNotify" ))
_launchCB->setChecked(df->readBoolEntry("StartupNotify", true));
else // backwards comp.
_launchCB->setChecked(df->readBoolEntry("X-KDE-StartupNotify", true));
if(df->readNumEntry("Terminal", 0) == 1)
_terminalCB->setChecked(true);
else
_terminalCB->setChecked(false);
_uidCB->setChecked(df->readBoolEntry("X-KDE-SubstituteUID", false));
enableWidgets(true, entryInfo->hidden);
blockSignals(false);
}
void BasicTab::apply()
{
if (_menuEntryInfo)
{
_menuEntryInfo->setDirty();
_menuEntryInfo->setCaption(_nameEdit->text());
_menuEntryInfo->setDescription(_descriptionEdit->text());
_menuEntryInfo->setIcon(_iconButton->icon());
KDesktopFile *df = _menuEntryInfo->desktopFile();
df->writeEntry("Comment", _commentEdit->text());
if (_systrayCB->isChecked())
df->writePathEntry("Exec", _execEdit->lineEdit()->text().prepend("ksystraycmd "));
else
df->writePathEntry("Exec", _execEdit->lineEdit()->text());
df->writePathEntry("Path", _pathEdit->lineEdit()->text());
if (_terminalCB->isChecked())
df->writeEntry("Terminal", 1);
else
df->writeEntry("Terminal", 0);
df->writeEntry("TerminalOptions", _termOptEdit->text());
df->writeEntry("X-KDE-SubstituteUID", _uidCB->isChecked());
df->writeEntry("X-KDE-Username", _uidEdit->text());
df->writeEntry("StartupNotify", _launchCB->isChecked());
}
else
{
_menuFolderInfo->setCaption(_nameEdit->text());
_menuFolderInfo->setGenericName(_descriptionEdit->text());
_menuFolderInfo->setComment(_commentEdit->text());
_menuFolderInfo->setIcon(_iconButton->icon());
}
}
void BasicTab::slotChanged()
{
if (signalsBlocked())
return;
apply();
if (_menuEntryInfo)
emit changed( _menuEntryInfo );
else
emit changed( _menuFolderInfo );
}
void BasicTab::launchcb_clicked()
{
slotChanged();
}
void BasicTab::systraycb_clicked()
{
slotChanged();
}
void BasicTab::termcb_clicked()
{
_termOptEdit->setEnabled(_terminalCB->isChecked());
_termOptLabel->setEnabled(_terminalCB->isChecked());
slotChanged();
}
void BasicTab::uidcb_clicked()
{
_uidEdit->setEnabled(_uidCB->isChecked());
_uidLabel->setEnabled(_uidCB->isChecked());
slotChanged();
}
void BasicTab::slotExecSelected()
{
TQString path = _execEdit->lineEdit()->text();
if (!path.startsWith("'"))
_execEdit->lineEdit()->setText(KProcess::quote(path));
}
void BasicTab::slotCapturedShortcut(const KShortcut& cut)
{
if (signalsBlocked())
return;
if( KKeyChooser::checkGlobalShortcutsConflict( cut, true, topLevelWidget())
|| KKeyChooser::checkStandardShortcutsConflict( cut, true, topLevelWidget()))
return;
if ( KHotKeys::present() )
{
if (!_menuEntryInfo->isShortcutAvailable( cut ) )
{
KService::Ptr service;
emit findServiceShortcut(cut, service);
if (!service)
service = KHotKeys::findMenuEntry(cut.toString());
if (service)
{
KMessageBox::sorry(this, i18n("<qt>The key <b>%1</b> can not be used here because it is already used to activate <b>%2</b>.").arg(cut.toString(), service->name()));
return;
}
else
{
KMessageBox::sorry(this, i18n("<qt>The key <b>%1</b> can not be used here because it is already in use.").arg(cut.toString()));
return;
}
}
_menuEntryInfo->setShortcut( cut );
}
_keyEdit->setShortcut(cut, false);
if (_menuEntryInfo)
emit changed( _menuEntryInfo );
}