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.
466 lines
16 KiB
466 lines
16 KiB
// -*- 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 <pfeiffer@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; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
#include <tqlabel.h>
|
|
#include <tqlayout.h>
|
|
#include <tqlistview.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqwhatsthis.h>
|
|
#include <tqvbuttongroup.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( TQString::null, "klipper" );
|
|
|
|
TQFrame *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);
|
|
TQSize s1 = sizeHint();
|
|
TQSize 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( TQWidget *parent, const char *name )
|
|
: TQVBox( parent, name )
|
|
{
|
|
setSpacing(KDialog::spacingHint());
|
|
|
|
cbMousePos = new TQCheckBox( i18n("&Popup menu at mouse-cursor position"),
|
|
this );
|
|
cbSaveContents = new TQCheckBox( i18n("Save clipboard contents on e&xit"),
|
|
this );
|
|
cbStripWhitespace = new TQCheckBox( i18n("Remove whitespace when executing actions"), this );
|
|
TQWhatsThis::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 TQCheckBox( i18n("&Replay actions on an item selected from history"),
|
|
this );
|
|
|
|
cbNoNull = new TQCheckBox( i18n("Pre&vent empty clipboard"), this );
|
|
TQWhatsThis::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 TQCheckBox( i18n("&Ignore selection"), this );
|
|
TQWhatsThis::add( cbIgnoreSelection,
|
|
i18n("This option prevents the selection being recorded "
|
|
"in the clipboard history. Only explicit clipboard "
|
|
"changes are recorded.") );
|
|
|
|
TQVButtonGroup *group = new TQVButtonGroup( i18n("Clipboard/Selection Behavior"), this );
|
|
group->setExclusive( true );
|
|
|
|
TQWhatsThis::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 TQRadioButton(
|
|
i18n("Sy&nchronize contents of the clipboard and the selection"),
|
|
group );
|
|
TQWhatsThis::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 TQRadioButton(
|
|
i18n("Separate clipboard and selection"), group );
|
|
TQWhatsThis::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" ) );
|
|
TQToolTip::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, TQT_SIGNAL( valueChanged( int )),
|
|
TQT_SLOT( historySizeChanged( int ) ));
|
|
|
|
connect( group, TQT_SIGNAL( clicked( int )),
|
|
TQT_SLOT( slotClipConfigChanged() ));
|
|
slotClipConfigChanged();
|
|
|
|
// Add some spacing at the end
|
|
TQWidget *dummy = new TQWidget( 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( TQListViewItem* 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<TQDialog>( "KRegExpEditor/KRegExpEditor", TQString(), TQT_TQOBJECT(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, TQWidget *parent,
|
|
const char *name )
|
|
: TQVBox( parent, name ),
|
|
advancedWidget( 0L )
|
|
{
|
|
Q_ASSERT( list != 0L );
|
|
|
|
TQLabel *lblAction = new TQLabel(
|
|
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/tqregexp.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( TQListView::Single );
|
|
connect( listView, TQT_SIGNAL(executed( TQListViewItem*, const TQPoint&, int )),
|
|
TQT_SLOT( slotItemChanged( TQListViewItem*, const TQPoint& , int ) ));
|
|
connect( listView, TQT_SIGNAL( selectionChanged ( TQListViewItem * )),
|
|
TQT_SLOT(selectionChanged ( TQListViewItem * )));
|
|
connect(listView,
|
|
TQT_SIGNAL(contextMenu(KListView *, TQListViewItem *, const TQPoint&)),
|
|
TQT_SLOT( slotContextMenu(KListView*, TQListViewItem*, const TQPoint&)));
|
|
|
|
ClipAction *action = 0L;
|
|
ClipCommand *command = 0L;
|
|
TQListViewItem *item = 0L;
|
|
TQListViewItem *child = 0L;
|
|
TQListViewItem *after = 0L; // QListView's default inserting really sucks
|
|
ActionListIterator it( *list );
|
|
|
|
const TQPixmap& doc = SmallIcon( "misc" );
|
|
const TQPixmap& exec = SmallIcon( "exec" );
|
|
|
|
for ( action = it.current(); action; action = ++it ) {
|
|
item = new TQListViewItem( listView, after,
|
|
action->regExp(), action->description() );
|
|
item->setPixmap( 0, doc );
|
|
|
|
TQPtrListIterator<ClipCommand> it2( action->commands() );
|
|
for ( command = it2.current(); command; command = ++it2 ) {
|
|
child = new TQListViewItem( 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 TQCheckBox( i18n("&Use graphical editor for editing regular expressions" ), this );
|
|
if ( KTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() )
|
|
{
|
|
cbUseGUIRegExpEditor->hide();
|
|
cbUseGUIRegExpEditor->setChecked( false );
|
|
}
|
|
|
|
TQHBox *box = new TQHBox( this );
|
|
box->setSpacing( KDialog::spacingHint() );
|
|
TQPushButton *button = new TQPushButton( i18n("&Add Action"), box );
|
|
connect( button, TQT_SIGNAL( clicked() ), TQT_SLOT( slotAddAction() ));
|
|
|
|
delActionButton = new TQPushButton( i18n("&Delete Action"), box );
|
|
connect( delActionButton, TQT_SIGNAL( clicked() ), TQT_SLOT( slotDeleteAction() ));
|
|
|
|
TQLabel *label = new TQLabel(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 TQHBox( this );
|
|
TQPushButton *advanced = new TQPushButton( i18n("Advanced..."), box );
|
|
advanced->setFixedSize( advanced->sizeHint() );
|
|
connect( advanced, TQT_SIGNAL( clicked() ), TQT_SLOT( slotAdvanced() ));
|
|
(void) new TQWidget( box ); // spacer
|
|
|
|
delActionButton->setEnabled(listView->currentItem () !=0);
|
|
}
|
|
|
|
ActionWidget::~ActionWidget()
|
|
{
|
|
}
|
|
|
|
void ActionWidget::selectionChanged ( TQListViewItem * item)
|
|
{
|
|
delActionButton->setEnabled(item!=0);
|
|
}
|
|
|
|
void ActionWidget::slotContextMenu( KListView *, TQListViewItem *item,
|
|
const TQPoint& 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 ) {
|
|
TQListViewItem *p = item->parent() ? item->parent() : item;
|
|
TQListViewItem *cmdItem = new TQListViewItem( 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( TQListViewItem *item, const TQPoint&, 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()
|
|
{
|
|
TQListViewItem *item = new TQListViewItem( 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()
|
|
{
|
|
TQListViewItem *item = listView->currentItem();
|
|
if ( item && item->parent() )
|
|
item = item->parent();
|
|
delete item;
|
|
}
|
|
|
|
|
|
ActionList * ActionWidget::actionList()
|
|
{
|
|
TQListViewItem *item = listView->firstChild();
|
|
TQListViewItem *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 );
|
|
TQVBox *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() == TQDialog::Accepted ) {
|
|
m_wmClasses = widget->wmClasses();
|
|
}
|
|
}
|
|
|
|
AdvancedWidget::AdvancedWidget( TQWidget *parent, const char *name )
|
|
: TQVBox( parent, name )
|
|
{
|
|
editListBox = new KEditListBox( i18n("D&isable Actions for Windows of Type WM_CLASS"), this, "editlistbox", true, KEditListBox::Add | KEditListBox::Remove );
|
|
|
|
TQWhatsThis::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 TQStringList& items )
|
|
{
|
|
editListBox->clear();
|
|
editListBox->insertStringList( items );
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
//////////
|
|
|
|
/*
|
|
KeysWidget::KeysWidget( KAccelActions &keyMap, TQWidget *parent, const char *name)
|
|
: TQVBox( parent, name )
|
|
{
|
|
keyChooser = new KKeyChooser( keyMap, this );
|
|
}
|
|
|
|
KeysWidget::~KeysWidget()
|
|
{
|
|
}
|
|
*/
|
|
|
|
#include "configdialog.moc"
|