mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 10:52:49 +00:00
566 lines
15 KiB
C++
566 lines
15 KiB
C++
/* This file is part of the KDE project
|
|
Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library 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
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
|
|
#include "kactionselector.h"
|
|
|
|
#include <klocale.h>
|
|
#include <kicon.h>
|
|
#include <kdebug.h>
|
|
#include <QtGui/QApplication>
|
|
#include <QtGui/QToolButton>
|
|
#include <QtGui/QLabel>
|
|
#include <QtGui/QLayout>
|
|
#include <QtGui/qevent.h>
|
|
#include <QListWidget>
|
|
|
|
class KActionSelectorPrivate {
|
|
public:
|
|
KActionSelectorPrivate(KActionSelector *q): q(q) {}
|
|
|
|
KActionSelector *q;
|
|
QListWidget *availableListWidget, *selectedListWidget;
|
|
QToolButton *btnAdd, *btnRemove, *btnUp, *btnDown;
|
|
QLabel *lAvailable, *lSelected;
|
|
bool moveOnDoubleClick : 1;
|
|
bool keyboardEnabled : 1;
|
|
bool showUpDownButtons : 1;
|
|
QString addIcon, removeIcon, upIcon, downIcon;
|
|
KActionSelector::InsertionPolicy availableInsertionPolicy, selectedInsertionPolicy;
|
|
|
|
/**
|
|
Move item @p item to the other listbox
|
|
*/
|
|
void moveItem( QListWidgetItem *item );
|
|
|
|
/**
|
|
loads the icons for the move buttons.
|
|
*/
|
|
void loadIcons();
|
|
|
|
/**
|
|
@return the index to insert an item into listbox @p lb,
|
|
given InsertionPolicy @p policy.
|
|
|
|
Note that if policy is Sorted, this will return -1.
|
|
Sort the listbox after inserting the item in that case.
|
|
*/
|
|
int insertionIndex( QListWidget *lb, KActionSelector::InsertionPolicy policy );
|
|
|
|
/**
|
|
@return the index of the first selected item in listbox @p lb.
|
|
If no item is selected, it will return -1.
|
|
*/
|
|
int selectedRowIndex( QListWidget *lb );
|
|
|
|
void buttonAddClicked();
|
|
void buttonRemoveClicked();
|
|
void buttonUpClicked();
|
|
void buttonDownClicked();
|
|
void itemDoubleClicked( QListWidgetItem *item );
|
|
void slotCurrentChanged( QListWidgetItem * )
|
|
{ q->setButtonsEnabled(); }
|
|
};
|
|
|
|
//BEGIN Constructor/destructor
|
|
|
|
KActionSelector::KActionSelector( QWidget *parent )
|
|
: QWidget( parent )
|
|
, d( new KActionSelectorPrivate(this) )
|
|
{
|
|
d->moveOnDoubleClick = true;
|
|
d->keyboardEnabled = true;
|
|
d->addIcon = QApplication::isRightToLeft()? "go-previous" : "go-next";
|
|
d->removeIcon = QApplication::isRightToLeft()? "go-next" : "go-previous";
|
|
d->upIcon = "go-up";
|
|
d->downIcon = "go-down";
|
|
d->availableInsertionPolicy = Sorted;
|
|
d->selectedInsertionPolicy = BelowCurrent;
|
|
d->showUpDownButtons = true;
|
|
|
|
QHBoxLayout *lo = new QHBoxLayout( this );
|
|
lo->setMargin( 0 );
|
|
|
|
QVBoxLayout *loAv = new QVBoxLayout();
|
|
lo->addLayout( loAv );
|
|
d->lAvailable = new QLabel( i18n("&Available:"), this );
|
|
loAv->addWidget( d->lAvailable );
|
|
d->availableListWidget = new QListWidget( this );
|
|
loAv->addWidget( d->availableListWidget );
|
|
d->lAvailable->setBuddy( d->availableListWidget );
|
|
|
|
QVBoxLayout *loHBtns = new QVBoxLayout();
|
|
lo->addLayout( loHBtns );
|
|
loHBtns->addStretch( 1 );
|
|
d->btnAdd = new QToolButton( this );
|
|
loHBtns->addWidget( d->btnAdd );
|
|
d->btnRemove = new QToolButton( this );
|
|
loHBtns->addWidget( d->btnRemove );
|
|
loHBtns->addStretch( 1 );
|
|
|
|
QVBoxLayout *loS = new QVBoxLayout();
|
|
lo->addLayout( loS );
|
|
d->lSelected = new QLabel( i18n("&Selected:"), this );
|
|
loS->addWidget( d->lSelected );
|
|
d->selectedListWidget = new QListWidget( this );
|
|
loS->addWidget( d->selectedListWidget );
|
|
d->lSelected->setBuddy( d->selectedListWidget );
|
|
|
|
QVBoxLayout *loVBtns = new QVBoxLayout();
|
|
lo->addLayout( loVBtns );
|
|
loVBtns->addStretch( 1 );
|
|
d->btnUp = new QToolButton( this );
|
|
d->btnUp->setAutoRepeat( true );
|
|
loVBtns->addWidget( d->btnUp );
|
|
d->btnDown = new QToolButton( this );
|
|
d->btnDown->setAutoRepeat( true );
|
|
loVBtns->addWidget( d->btnDown );
|
|
loVBtns->addStretch( 1 );
|
|
|
|
d->loadIcons();
|
|
|
|
connect( d->btnAdd, SIGNAL(clicked()), this, SLOT(buttonAddClicked()) );
|
|
connect( d->btnRemove, SIGNAL(clicked()), this, SLOT(buttonRemoveClicked()) );
|
|
connect( d->btnUp, SIGNAL(clicked()), this, SLOT(buttonUpClicked()) );
|
|
connect( d->btnDown, SIGNAL(clicked()), this, SLOT(buttonDownClicked()) );
|
|
connect( d->availableListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
|
|
this, SLOT(itemDoubleClicked(QListWidgetItem*)) );
|
|
connect( d->selectedListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
|
|
this, SLOT(itemDoubleClicked(QListWidgetItem*)) );
|
|
connect( d->availableListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(polish()) );
|
|
connect( d->selectedListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(polish()) );
|
|
|
|
d->availableListWidget->installEventFilter( this );
|
|
d->selectedListWidget->installEventFilter( this );
|
|
setButtonsEnabled();
|
|
}
|
|
|
|
KActionSelector::~KActionSelector()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
//END Constructor/destroctor
|
|
|
|
//BEGIN Public Methods
|
|
|
|
QListWidget *KActionSelector::availableListWidget() const
|
|
{
|
|
return d->availableListWidget;
|
|
}
|
|
|
|
QListWidget *KActionSelector::selectedListWidget() const
|
|
{
|
|
return d->selectedListWidget;
|
|
}
|
|
|
|
void KActionSelector::setButtonIcon( const QString &icon, MoveButton button )
|
|
{
|
|
switch ( button )
|
|
{
|
|
case ButtonAdd:
|
|
d->addIcon = icon;
|
|
d->btnAdd->setIcon( KIcon( icon ) );
|
|
break;
|
|
case ButtonRemove:
|
|
d->removeIcon = icon;
|
|
d->btnRemove->setIcon( KIcon( icon ) );
|
|
break;
|
|
case ButtonUp:
|
|
d->upIcon = icon;
|
|
d->btnUp->setIcon( KIcon( icon ) );
|
|
break;
|
|
case ButtonDown:
|
|
d->downIcon = icon;
|
|
d->btnDown->setIcon( KIcon( icon ) );
|
|
break;
|
|
default:
|
|
kDebug(13001)<<"KActionSelector::setButtonIcon: DAINBREAD!";
|
|
}
|
|
}
|
|
|
|
void KActionSelector::setButtonIconSet( const QIcon &iconset, MoveButton button )
|
|
{
|
|
switch ( button )
|
|
{
|
|
case ButtonAdd:
|
|
d->btnAdd->setIcon( iconset );
|
|
break;
|
|
case ButtonRemove:
|
|
d->btnRemove->setIcon( iconset );
|
|
break;
|
|
case ButtonUp:
|
|
d->btnUp->setIcon( iconset );
|
|
break;
|
|
case ButtonDown:
|
|
d->btnDown->setIcon( iconset );
|
|
break;
|
|
default:
|
|
kDebug(13001)<<"KActionSelector::setButtonIconSet: DAINBREAD!";
|
|
}
|
|
}
|
|
|
|
void KActionSelector::setButtonTooltip( const QString &tip, MoveButton button )
|
|
{
|
|
switch ( button )
|
|
{
|
|
case ButtonAdd:
|
|
d->btnAdd->setText( tip );
|
|
d->btnAdd->setToolTip( tip );
|
|
break;
|
|
case ButtonRemove:
|
|
d->btnRemove->setText( tip );
|
|
d->btnRemove->setToolTip( tip );
|
|
break;
|
|
case ButtonUp:
|
|
d->btnUp->setText( tip );
|
|
d->btnUp->setToolTip( tip );
|
|
break;
|
|
case ButtonDown:
|
|
d->btnDown->setText( tip );
|
|
d->btnDown->setToolTip( tip );
|
|
break;
|
|
default:
|
|
kDebug(13001)<<"KActionSelector::setButtonToolTip: DAINBREAD!";
|
|
}
|
|
}
|
|
|
|
void KActionSelector::setButtonWhatsThis( const QString &text, MoveButton button )
|
|
{
|
|
switch ( button )
|
|
{
|
|
case ButtonAdd:
|
|
d->btnAdd->setWhatsThis(text );
|
|
break;
|
|
case ButtonRemove:
|
|
d->btnRemove->setWhatsThis(text );
|
|
break;
|
|
case ButtonUp:
|
|
d->btnUp->setWhatsThis(text );
|
|
break;
|
|
case ButtonDown:
|
|
d->btnDown->setWhatsThis(text );
|
|
break;
|
|
default:
|
|
kDebug(13001)<<"KActionSelector::setButtonWhatsThis: DAINBREAD!";
|
|
}
|
|
}
|
|
|
|
void KActionSelector::setButtonsEnabled()
|
|
{
|
|
d->btnAdd->setEnabled( d->selectedRowIndex(d->availableListWidget) > -1 );
|
|
d->btnRemove->setEnabled( d->selectedRowIndex(d->selectedListWidget) > -1 );
|
|
d->btnUp->setEnabled( d->selectedRowIndex(d->selectedListWidget) > 0 );
|
|
d->btnDown->setEnabled( d->selectedRowIndex(d->selectedListWidget) > -1 &&
|
|
d->selectedRowIndex(d->selectedListWidget) < d->selectedListWidget->count() - 1 );
|
|
}
|
|
|
|
//END Public Methods
|
|
|
|
//BEGIN Properties
|
|
|
|
bool KActionSelector::moveOnDoubleClick() const
|
|
{
|
|
return d->moveOnDoubleClick;
|
|
}
|
|
|
|
void KActionSelector::setMoveOnDoubleClick( bool b )
|
|
{
|
|
d->moveOnDoubleClick = b;
|
|
}
|
|
|
|
bool KActionSelector::keyboardEnabled() const
|
|
{
|
|
return d->keyboardEnabled;
|
|
}
|
|
|
|
void KActionSelector::setKeyboardEnabled( bool b )
|
|
{
|
|
d->keyboardEnabled = b;
|
|
}
|
|
|
|
QString KActionSelector::availableLabel() const
|
|
{
|
|
return d->lAvailable->text();
|
|
}
|
|
|
|
void KActionSelector::setAvailableLabel( const QString &text )
|
|
{
|
|
d->lAvailable->setText( text );
|
|
}
|
|
|
|
QString KActionSelector::selectedLabel() const
|
|
{
|
|
return d->lSelected->text();
|
|
}
|
|
|
|
void KActionSelector::setSelectedLabel( const QString &text )
|
|
{
|
|
d->lSelected->setText( text );
|
|
}
|
|
|
|
KActionSelector::InsertionPolicy KActionSelector::availableInsertionPolicy() const
|
|
{
|
|
return d->availableInsertionPolicy;
|
|
}
|
|
|
|
void KActionSelector::setAvailableInsertionPolicy( InsertionPolicy p )
|
|
{
|
|
d->availableInsertionPolicy = p;
|
|
}
|
|
|
|
KActionSelector::InsertionPolicy KActionSelector::selectedInsertionPolicy() const
|
|
{
|
|
return d->selectedInsertionPolicy;
|
|
}
|
|
|
|
void KActionSelector::setSelectedInsertionPolicy( InsertionPolicy p )
|
|
{
|
|
d->selectedInsertionPolicy = p;
|
|
}
|
|
|
|
bool KActionSelector::showUpDownButtons() const
|
|
{
|
|
return d->showUpDownButtons;
|
|
}
|
|
|
|
void KActionSelector::setShowUpDownButtons( bool show )
|
|
{
|
|
d->showUpDownButtons = show;
|
|
if ( show )
|
|
{
|
|
d->btnUp->show();
|
|
d->btnDown->show();
|
|
}
|
|
else
|
|
{
|
|
d->btnUp->hide();
|
|
d->btnDown->hide();
|
|
}
|
|
}
|
|
|
|
//END Properties
|
|
|
|
//BEGIN Public Slots
|
|
|
|
void KActionSelector::polish()
|
|
{
|
|
setButtonsEnabled();
|
|
}
|
|
|
|
//END Public Slots
|
|
|
|
//BEGIN Protected
|
|
void KActionSelector::keyPressEvent( QKeyEvent *e )
|
|
{
|
|
if ( ! d->keyboardEnabled ) return;
|
|
if ( (e->modifiers() & Qt::ControlModifier) )
|
|
{
|
|
switch ( e->key() )
|
|
{
|
|
case Qt::Key_Right:
|
|
d->buttonAddClicked();
|
|
break;
|
|
case Qt::Key_Left:
|
|
d->buttonRemoveClicked();
|
|
break;
|
|
case Qt::Key_Up:
|
|
d->buttonUpClicked();
|
|
break;
|
|
case Qt::Key_Down:
|
|
d->buttonDownClicked();
|
|
break;
|
|
default:
|
|
e->ignore();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool KActionSelector::eventFilter( QObject *o, QEvent *e )
|
|
{
|
|
if ( d->keyboardEnabled && e->type() == QEvent::KeyPress )
|
|
{
|
|
if ( (((QKeyEvent*)e)->modifiers() & Qt::ControlModifier) )
|
|
{
|
|
switch ( ((QKeyEvent*)e)->key() )
|
|
{
|
|
case Qt::Key_Right:
|
|
d->buttonAddClicked();
|
|
break;
|
|
case Qt::Key_Left:
|
|
d->buttonRemoveClicked();
|
|
break;
|
|
case Qt::Key_Up:
|
|
d->buttonUpClicked();
|
|
break;
|
|
case Qt::Key_Down:
|
|
d->buttonDownClicked();
|
|
break;
|
|
default:
|
|
return QWidget::eventFilter( o, e );
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
else if ( QListWidget *lb = qobject_cast<QListWidget*>(o) )
|
|
{
|
|
switch ( ((QKeyEvent*)e)->key() )
|
|
{
|
|
case Qt::Key_Return:
|
|
case Qt::Key_Enter:
|
|
int index = lb->currentRow();
|
|
if ( index < 0 ) break;
|
|
d->moveItem( lb->item( index ) );
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return QWidget::eventFilter( o, e );
|
|
}
|
|
|
|
//END Protected
|
|
|
|
//BEGIN Private Slots
|
|
|
|
void KActionSelectorPrivate::buttonAddClicked()
|
|
{
|
|
// move all selected items from available to selected listbox
|
|
QList<QListWidgetItem *> list = availableListWidget->selectedItems();
|
|
foreach (QListWidgetItem* item, list) {
|
|
availableListWidget->takeItem( availableListWidget->row( item ) );
|
|
selectedListWidget->insertItem( insertionIndex( selectedListWidget, selectedInsertionPolicy ), item );
|
|
selectedListWidget->setCurrentItem( item );
|
|
emit q->added( item );
|
|
}
|
|
if ( selectedInsertionPolicy == KActionSelector::Sorted )
|
|
selectedListWidget->sortItems();
|
|
selectedListWidget->setFocus();
|
|
}
|
|
|
|
void KActionSelectorPrivate::buttonRemoveClicked()
|
|
{
|
|
// move all selected items from selected to available listbox
|
|
QList<QListWidgetItem *> list = selectedListWidget->selectedItems();
|
|
foreach (QListWidgetItem* item, list) {
|
|
selectedListWidget->takeItem( selectedListWidget->row( item ) );
|
|
availableListWidget->insertItem( insertionIndex( availableListWidget, availableInsertionPolicy ), item );
|
|
availableListWidget->setCurrentItem( item );
|
|
emit q->removed( item );
|
|
}
|
|
if ( availableInsertionPolicy == KActionSelector::Sorted )
|
|
availableListWidget->sortItems();
|
|
availableListWidget->setFocus();
|
|
}
|
|
|
|
void KActionSelectorPrivate::buttonUpClicked()
|
|
{
|
|
int c = selectedRowIndex(selectedListWidget);
|
|
if ( c < 1 ) return;
|
|
QListWidgetItem *item = selectedListWidget->item( c );
|
|
selectedListWidget->takeItem( c );
|
|
selectedListWidget->insertItem( c-1, item );
|
|
selectedListWidget->setCurrentItem( item );
|
|
emit q->movedUp( item );
|
|
}
|
|
|
|
void KActionSelectorPrivate::buttonDownClicked()
|
|
{
|
|
int c = selectedRowIndex(selectedListWidget);
|
|
if ( c < 0 || c == selectedListWidget->count() - 1 ) return;
|
|
QListWidgetItem *item = selectedListWidget->item( c );
|
|
selectedListWidget->takeItem( c );
|
|
selectedListWidget->insertItem( c+1, item );
|
|
selectedListWidget->setCurrentItem( item );
|
|
emit q->movedDown( item );
|
|
}
|
|
|
|
void KActionSelectorPrivate::itemDoubleClicked( QListWidgetItem *item )
|
|
{
|
|
if ( moveOnDoubleClick )
|
|
moveItem( item );
|
|
}
|
|
|
|
//END Private Slots
|
|
|
|
//BEGIN Private Methods
|
|
|
|
void KActionSelectorPrivate::loadIcons()
|
|
{
|
|
btnAdd->setIcon( KIcon( addIcon ) );
|
|
btnRemove->setIcon( KIcon( removeIcon ) );
|
|
btnUp->setIcon( KIcon( upIcon ) );
|
|
btnDown->setIcon( KIcon( downIcon ) );
|
|
}
|
|
|
|
void KActionSelectorPrivate::moveItem( QListWidgetItem *item )
|
|
{
|
|
QListWidget *lbFrom = item->listWidget();
|
|
QListWidget *lbTo;
|
|
if ( lbFrom == availableListWidget )
|
|
lbTo = selectedListWidget;
|
|
else if ( lbFrom == selectedListWidget )
|
|
lbTo = availableListWidget;
|
|
else //?! somewhat unlikely...
|
|
return;
|
|
|
|
KActionSelector::InsertionPolicy p = ( lbTo == availableListWidget ) ?
|
|
availableInsertionPolicy : selectedInsertionPolicy;
|
|
|
|
lbFrom->takeItem( lbFrom->row( item ) );
|
|
lbTo->insertItem( insertionIndex( lbTo, p ), item );
|
|
lbTo->setFocus();
|
|
lbTo->setCurrentItem( item );
|
|
|
|
if ( p == KActionSelector::Sorted )
|
|
lbTo->sortItems();
|
|
if ( lbTo == selectedListWidget )
|
|
emit q->added( item );
|
|
else
|
|
emit q->removed( item );
|
|
}
|
|
|
|
int KActionSelectorPrivate::insertionIndex( QListWidget *lb, KActionSelector::InsertionPolicy policy )
|
|
{
|
|
int index;
|
|
switch ( policy )
|
|
{
|
|
case KActionSelector::BelowCurrent:
|
|
index = lb->currentRow();
|
|
if ( index > -1 ) index += 1;
|
|
break;
|
|
case KActionSelector::AtTop:
|
|
index = 0;
|
|
break;
|
|
default:
|
|
index = -1;
|
|
}
|
|
return index;
|
|
}
|
|
|
|
int KActionSelectorPrivate::selectedRowIndex( QListWidget *lb )
|
|
{
|
|
QList<QListWidgetItem *> list = lb->selectedItems();
|
|
if (list.isEmpty()) {
|
|
return -1;
|
|
}
|
|
return lb->row(list.at(0));
|
|
}
|
|
|
|
//END Private Methods
|
|
#include "moc_kactionselector.cpp"
|