diff options
Diffstat (limited to 'klipper/configdialog.cpp')
-rw-r--r-- | klipper/configdialog.cpp | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/klipper/configdialog.cpp b/klipper/configdialog.cpp new file mode 100644 index 000000000..a195a2332 --- /dev/null +++ b/klipper/configdialog.cpp @@ -0,0 +1,465 @@ +// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- +/* This file is part of the KDE project + Copyright (C) 2000 by Carsten Pfeiffer <[email protected]> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include <qlabel.h> +#include <qlayout.h> +#include <qlistview.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qvbuttongroup.h> +#include <assert.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kwinmodule.h> +#include <kregexpeditorinterface.h> +#include <kparts/componentfactory.h> + +#include "configdialog.h" + +ConfigDialog::ConfigDialog( const ActionList *list, KGlobalAccel *accel, + bool isApplet ) + : KDialogBase( Tabbed, i18n("Configure"), + Ok | Cancel | Help, + Ok, 0L, "config dialog" ) +{ + if ( isApplet ) + setHelp( QString::null, "klipper" ); + + QFrame *w = 0L; // the parent for the widgets + + w = addVBoxPage( i18n("&General") ); + generalWidget = new GeneralWidget( w, "general widget" ); + + w = addVBoxPage( i18n("Ac&tions") ); + actionWidget = new ActionWidget( list, this, w, "actions widget" ); + + w = addVBoxPage( i18n("Global &Shortcuts") ); + keysWidget = new KKeyChooser( accel, w ); +} + + +ConfigDialog::~ConfigDialog() +{ +} + +// prevent huge size due to long regexps in the action-widget +void ConfigDialog::show() +{ + if ( !isVisible() ) { + KWinModule module(0, KWinModule::INFO_DESKTOP); + QSize s1 = sizeHint(); + QSize s2 = module.workArea().size(); + int w = s1.width(); + int h = s1.height(); + + if ( s1.width() >= s2.width() ) + w = s2.width(); + if ( s1.height() >= s2.height() ) + h = s2.height(); + + resize( w, h ); + } + + KDialogBase::show(); +} + +void ConfigDialog::commitShortcuts() +{ + keysWidget->commitChanges(); +} + +///////////////////////////////////////// +//// + + +GeneralWidget::GeneralWidget( QWidget *parent, const char *name ) + : QVBox( parent, name ) +{ + setSpacing(KDialog::spacingHint()); + + cbMousePos = new QCheckBox( i18n("&Popup menu at mouse-cursor position"), + this ); + cbSaveContents = new QCheckBox( i18n("Save clipboard contents on e&xit"), + this ); + cbStripWhitespace = new QCheckBox( i18n("Remove whitespace when executing actions"), this ); + QWhatsThis::add( cbStripWhitespace, + i18n("Sometimes, the selected text has some whitespace at the end, which, if loaded as URL in a browser would cause an error. Enabling this option removes any whitespace at the beginning or end of the selected string (the original clipboard contents will not be modified).") ); + + cbReplayAIH = new QCheckBox( i18n("&Replay actions on an item selected from history"), + this ); + + cbNoNull = new QCheckBox( i18n("Pre&vent empty clipboard"), this ); + QWhatsThis::add( cbNoNull, + i18n("Selecting this option has the effect, that the " + "clipboard can never be emptied. E.g. when an " + "application exits, the clipboard would usually be " + "emptied.") ); + + cbIgnoreSelection = new QCheckBox( i18n("&Ignore selection"), this ); + QWhatsThis::add( cbIgnoreSelection, + i18n("This option prevents the selection being recorded " + "in the clipboard history. Only explicit clipboard " + "changes are recorded.") ); + + QVButtonGroup *group = new QVButtonGroup( i18n("Clipboard/Selection Behavior"), this ); + group->setExclusive( true ); + + QWhatsThis::add( group, + i18n("<qt>There are two different clipboard buffers available:<br><br>" + "<b>Clipboard</b> is filled by selecting something " + "and pressing Ctrl+C, or by clicking \"Copy\" in a toolbar or " + "menubar.<br><br>" + "<b>Selection</b> is available immediately after " + "selecting some text. The only way to access the selection " + "is to press the middle mouse button.<br><br>" + "You can configure the relationship between Clipboard and Selection." + "</qt>" )); + + cbSynchronize = new QRadioButton( + i18n("Sy&nchronize contents of the clipboard and the selection"), + group ); + QWhatsThis::add( cbSynchronize, + i18n("Selecting this option synchronizes these two buffers, so they " + "work the same way as in KDE 1.x and 2.x.") ); + + cbSeparate = new QRadioButton( + i18n("Separate clipboard and selection"), group ); + QWhatsThis::add( + cbSeparate, + i18n("Using this option will only set the selection when highlighting " + "something and the clipboard when choosing e.g. \"Copy\" " + "in a menubar.") ); + + cbSeparate->setChecked( !cbSynchronize->isChecked() ); + + popupTimeout = new KIntNumInput( this ); + popupTimeout->setLabel( i18n( "Tim&eout for action popups:" ) ); + popupTimeout->setRange( 0, 200, 1, true ); + popupTimeout->setSuffix( i18n( " sec" ) ); + QToolTip::add( popupTimeout, i18n("A value of 0 disables the timeout") ); + + maxItems = new KIntNumInput( this ); + maxItems->setLabel( i18n( "C&lipboard history size:" ) ); + maxItems->setRange( 2, 2048, 1, true ); + connect( maxItems, SIGNAL( valueChanged( int )), + SLOT( historySizeChanged( int ) )); + + connect( group, SIGNAL( clicked( int )), + SLOT( slotClipConfigChanged() )); + slotClipConfigChanged(); + + // Add some spacing at the end + QWidget *dummy = new QWidget( this ); + setStretchFactor( dummy, 1 ); +} + +GeneralWidget::~GeneralWidget() +{ +} + +void GeneralWidget::historySizeChanged( int value ) +{ + // Note there is no %n in this string, because value is not supposed + // to be put into the suffix of the spinbox. + maxItems->setSuffix( i18n( " entry", " entries", value ) ); +} + +void GeneralWidget::slotClipConfigChanged() +{ + cbIgnoreSelection->setEnabled( !cbSynchronize->isChecked() ); +} + +///////////////////////////////////////// +//// + +void ListView::rename( QListViewItem* item, int c ) +{ + bool gui = false; + if ( item->childCount() != 0 && c == 0) { + // This is the regular expression + if ( _configWidget->useGUIRegExpEditor() ) { + gui = true; + } + } + + if ( gui ) { + if ( ! _regExpEditor ) + _regExpEditor = KParts::ComponentFactory::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString::null, this ); + KRegExpEditorInterface *iface = static_cast<KRegExpEditorInterface *>( _regExpEditor->qt_cast( "KRegExpEditorInterface" ) ); + assert( iface ); + iface->setRegExp( item->text( 0 ) ); + + bool ok = _regExpEditor->exec(); + if ( ok ) + item->setText( 0, iface->regExp() ); + + } + else + KListView::rename( item ,c ); +} + + +ActionWidget::ActionWidget( const ActionList *list, ConfigDialog* configWidget, QWidget *parent, + const char *name ) + : QVBox( parent, name ), + advancedWidget( 0L ) +{ + Q_ASSERT( list != 0L ); + + QLabel *lblAction = new QLabel( + i18n("Action &list (right click to add/remove commands):"), this ); + + listView = new ListView( configWidget, this, "list view" ); + lblAction->setBuddy( listView ); + listView->addColumn( i18n("Regular Expression (see http://doc.trolltech.com/qregexp.html#details)") ); + listView->addColumn( i18n("Description") ); + + listView->setRenameable(0); + listView->setRenameable(1); + listView->setItemsRenameable( true ); + listView->setItemsMovable( false ); +// listView->setAcceptDrops( true ); +// listView->setDropVisualizer( true ); +// listView->setDragEnabled( true ); + + listView->setRootIsDecorated( true ); + listView->setMultiSelection( false ); + listView->setAllColumnsShowFocus( true ); + listView->setSelectionMode( QListView::Single ); + connect( listView, SIGNAL(executed( QListViewItem*, const QPoint&, int )), + SLOT( slotItemChanged( QListViewItem*, const QPoint& , int ) )); + connect( listView, SIGNAL( selectionChanged ( QListViewItem * )), + SLOT(selectionChanged ( QListViewItem * ))); + connect(listView, + SIGNAL(contextMenu(KListView *, QListViewItem *, const QPoint&)), + SLOT( slotContextMenu(KListView*, QListViewItem*, const QPoint&))); + + ClipAction *action = 0L; + ClipCommand *command = 0L; + QListViewItem *item = 0L; + QListViewItem *child = 0L; + QListViewItem *after = 0L; // QListView's default inserting really sucks + ActionListIterator it( *list ); + + const QPixmap& doc = SmallIcon( "misc" ); + const QPixmap& exec = SmallIcon( "exec" ); + + for ( action = it.current(); action; action = ++it ) { + item = new QListViewItem( listView, after, + action->regExp(), action->description() ); + item->setPixmap( 0, doc ); + + QPtrListIterator<ClipCommand> it2( action->commands() ); + for ( command = it2.current(); command; command = ++it2 ) { + child = new QListViewItem( item, after, + command->command, command->description); + if ( command->pixmap.isEmpty() ) + child->setPixmap( 0, exec ); + else + child->setPixmap( 0, SmallIcon( command->pixmap ) ); + after = child; + } + after = item; + } + + listView->setSorting( -1 ); // newly inserted items just append unsorted + + cbUseGUIRegExpEditor = new QCheckBox( i18n("&Use graphical editor for editing regular expressions" ), this ); + if ( KTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() ) + { + cbUseGUIRegExpEditor->hide(); + cbUseGUIRegExpEditor->setChecked( false ); + } + + QHBox *box = new QHBox( this ); + box->setSpacing( KDialog::spacingHint() ); + QPushButton *button = new QPushButton( i18n("&Add Action"), box ); + connect( button, SIGNAL( clicked() ), SLOT( slotAddAction() )); + + delActionButton = new QPushButton( i18n("&Delete Action"), box ); + connect( delActionButton, SIGNAL( clicked() ), SLOT( slotDeleteAction() )); + + QLabel *label = new QLabel(i18n("Click on a highlighted item's column to change it. \"%s\" in a command will be replaced with the clipboard contents."), box); + label->setAlignment( WordBreak | AlignLeft | AlignVCenter ); + + box->setStretchFactor( label, 5 ); + + box = new QHBox( this ); + QPushButton *advanced = new QPushButton( i18n("Advanced..."), box ); + advanced->setFixedSize( advanced->sizeHint() ); + connect( advanced, SIGNAL( clicked() ), SLOT( slotAdvanced() )); + (void) new QWidget( box ); // spacer + + delActionButton->setEnabled(listView->currentItem () !=0); +} + +ActionWidget::~ActionWidget() +{ +} + +void ActionWidget::selectionChanged ( QListViewItem * item) +{ + delActionButton->setEnabled(item!=0); +} + +void ActionWidget::slotContextMenu( KListView *, QListViewItem *item, + const QPoint& pos ) +{ + if ( !item ) + return; + + int addCmd = 0, rmCmd = 0; + KPopupMenu *menu = new KPopupMenu; + addCmd = menu->insertItem( i18n("Add Command") ); + rmCmd = menu->insertItem( i18n("Remove Command") ); + if ( !item->parent() ) {// no "command" item + menu->setItemEnabled( rmCmd, false ); + item->setOpen( true ); + } + + int id = menu->exec( pos ); + if ( id == addCmd ) { + QListViewItem *p = item->parent() ? item->parent() : item; + QListViewItem *cmdItem = new QListViewItem( p, item, + i18n("Click here to set the command to be executed"), + i18n("<new command>") ); + cmdItem->setPixmap( 0, SmallIcon( "exec" ) ); + } + else if ( id == rmCmd ) + delete item; + + delete menu; +} + +void ActionWidget::slotItemChanged( QListViewItem *item, const QPoint&, int col ) +{ + if ( !item->parent() || col != 0 ) + return; + ClipCommand command( item->text(0), item->text(1) ); + item->setPixmap( 0, SmallIcon( command.pixmap.isEmpty() ? + "exec" : command.pixmap ) ); +} + +void ActionWidget::slotAddAction() +{ + QListViewItem *item = new QListViewItem( listView ); + item->setPixmap( 0, SmallIcon( "misc" )); + item->setText( 0, i18n("Click here to set the regexp")); + item->setText( 1, i18n("<new action>")); +} + + +void ActionWidget::slotDeleteAction() +{ + QListViewItem *item = listView->currentItem(); + if ( item && item->parent() ) + item = item->parent(); + delete item; +} + + +ActionList * ActionWidget::actionList() +{ + QListViewItem *item = listView->firstChild(); + QListViewItem *child = 0L; + ClipAction *action = 0L; + ActionList *list = new ActionList; + list->setAutoDelete( true ); + while ( item ) { + action = new ClipAction( item->text( 0 ), item->text( 1 ) ); + child = item->firstChild(); + + // add the commands + while ( child ) { + action->addCommand( child->text( 0 ), child->text( 1 ), true ); + child = child->nextSibling(); + } + + list->append( action ); + item = item->nextSibling(); + } + + return list; +} + +void ActionWidget::slotAdvanced() +{ + KDialogBase dlg( 0L, "advanced dlg", true, + i18n("Advanced Settings"), + KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok ); + QVBox *box = dlg.makeVBoxMainWidget(); + AdvancedWidget *widget = new AdvancedWidget( box ); + widget->setWMClasses( m_wmClasses ); + + dlg.resize( dlg.sizeHint().width(), + dlg.sizeHint().height() +40); // or we get an ugly scrollbar :( + + if ( dlg.exec() == QDialog::Accepted ) { + m_wmClasses = widget->wmClasses(); + } +} + +AdvancedWidget::AdvancedWidget( QWidget *parent, const char *name ) + : QVBox( parent, name ) +{ + editListBox = new KEditListBox( i18n("D&isable Actions for Windows of Type WM_CLASS"), this, "editlistbox", true, KEditListBox::Add | KEditListBox::Remove ); + + QWhatsThis::add( editListBox, + i18n("<qt>This lets you specify windows in which Klipper should " + "not invoke \"actions\". Use<br><br>" + "<center><b>xprop | grep WM_CLASS</b></center><br>" + "in a terminal to find out the WM_CLASS of a window. " + "Next, click on the window you want to examine. The " + "first string it outputs after the equal sign is the one " + "you need to enter here.</qt>")); + + editListBox->setFocus(); +} + +AdvancedWidget::~AdvancedWidget() +{ +} + +void AdvancedWidget::setWMClasses( const QStringList& items ) +{ + editListBox->clear(); + editListBox->insertStringList( items ); +} + + + +/////////////////////////////////////////////////////// +////////// + +/* +KeysWidget::KeysWidget( KAccelActions &keyMap, QWidget *parent, const char *name) + : QVBox( parent, name ) +{ + keyChooser = new KKeyChooser( keyMap, this ); +} + +KeysWidget::~KeysWidget() +{ +} +*/ + +#include "configdialog.moc" |