00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "kactionselector.h"
00021
00022
#include <klocale.h>
00023
#include <kiconloader.h>
00024
#include <kdialog.h>
00025
#include <kdebug.h>
00026
#include <qapplication.h>
00027
#include <qlistbox.h>
00028
#include <qtoolbutton.h>
00029
#include <qlabel.h>
00030
#include <qlayout.h>
00031
#include <qevent.h>
00032
#include <qwhatsthis.h>
00033
00034
class KActionSelectorPrivate {
00035
public:
00036 QListBox *availableListBox, *selectedListBox;
00037 QToolButton *btnAdd, *btnRemove, *btnUp, *btnDown;
00038 QLabel *lAvailable, *lSelected;
00039
bool moveOnDoubleClick, keyboardEnabled;
00040
KActionSelector::ButtonIconSize iconSize;
00041 QString addIcon, removeIcon, upIcon, downIcon;
00042
KActionSelector::InsertionPolicy availableInsertionPolicy, selectedInsertionPolicy;
00043
bool showUpDownButtons;
00044 };
00045
00046
00047
00048 KActionSelector::KActionSelector( QWidget *parent,
const char *name )
00049 : QWidget( parent, name )
00050 {
00051 d =
new KActionSelectorPrivate();
00052 d->moveOnDoubleClick =
true;
00053 d->keyboardEnabled =
true;
00054 d->iconSize = SmallIcon;
00055 d->addIcon = QApplication::reverseLayout()?
"back" :
"forward";
00056 d->removeIcon = QApplication::reverseLayout()?
"forward" :
"back";
00057 d->upIcon =
"up";
00058 d->downIcon =
"down";
00059 d->availableInsertionPolicy = Sorted;
00060 d->selectedInsertionPolicy = BelowCurrent;
00061 d->showUpDownButtons =
true;
00062
00063
00064
00065 QHBoxLayout *lo =
new QHBoxLayout(
this );
00066 lo->setSpacing( KDialog::spacingHint() );
00067
00068 QVBoxLayout *loAv =
new QVBoxLayout( lo );
00069 d->lAvailable =
new QLabel( i18n(
"&Available:"),
this );
00070 loAv->addWidget( d->lAvailable );
00071 d->availableListBox =
new QListBox(
this );
00072 loAv->addWidget( d->availableListBox );
00073 d->lAvailable->setBuddy( d->availableListBox );
00074
00075 QVBoxLayout *loHBtns =
new QVBoxLayout( lo );
00076 loHBtns->addStretch( 1 );
00077 d->btnAdd =
new QToolButton(
this );
00078 loHBtns->addWidget( d->btnAdd );
00079 d->btnRemove =
new QToolButton(
this );
00080 loHBtns->addWidget( d->btnRemove );
00081 loHBtns->addStretch( 1 );
00082
00083 QVBoxLayout *loS =
new QVBoxLayout( lo );
00084 d->lSelected =
new QLabel( i18n(
"&Selected:"),
this );
00085 loS->addWidget( d->lSelected );
00086 d->selectedListBox =
new QListBox(
this );
00087 loS->addWidget( d->selectedListBox );
00088 d->lSelected->setBuddy( d->selectedListBox );
00089
00090 QVBoxLayout *loVBtns =
new QVBoxLayout( lo );
00091 loVBtns->addStretch( 1 );
00092 d->btnUp =
new QToolButton(
this );
00093 loVBtns->addWidget( d->btnUp );
00094 d->btnDown =
new QToolButton(
this );
00095 loVBtns->addWidget( d->btnDown );
00096 loVBtns->addStretch( 1 );
00097
00098 loadIcons();
00099
00100 connect( d->btnAdd, SIGNAL(clicked()),
this, SLOT(buttonAddClicked()) );
00101 connect( d->btnRemove, SIGNAL(clicked()),
this, SLOT(buttonRemoveClicked()) );
00102 connect( d->btnUp, SIGNAL(clicked()),
this, SLOT(buttonUpClicked()) );
00103 connect( d->btnDown, SIGNAL(clicked()),
this, SLOT(buttonDownClicked()) );
00104 connect( d->availableListBox, SIGNAL(doubleClicked(QListBoxItem*)),
00105
this, SLOT(itemDoubleClicked(QListBoxItem*)) );
00106 connect( d->selectedListBox, SIGNAL(doubleClicked(QListBoxItem*)),
00107
this, SLOT(itemDoubleClicked(QListBoxItem*)) );
00108 connect( d->availableListBox, SIGNAL(currentChanged(QListBoxItem*)),
00109
this, SLOT(slotCurrentChanged(QListBoxItem *)) );
00110 connect( d->selectedListBox, SIGNAL(currentChanged(QListBoxItem*)),
00111
this, SLOT(slotCurrentChanged(QListBoxItem *)) );
00112
00113 d->availableListBox->installEventFilter(
this );
00114 d->selectedListBox->installEventFilter(
this );
00115 }
00116
00117 KActionSelector::~KActionSelector()
00118 {
00119 }
00120
00121
00122
00123
00124
00125 QListBox *
KActionSelector::availableListBox()
const
00126
{
00127
return d->availableListBox;
00128 }
00129
00130 QListBox *
KActionSelector::selectedListBox()
const
00131
{
00132
return d->selectedListBox;
00133 }
00134
00135 void KActionSelector::setButtonIcon(
const QString &icon, MoveButton button )
00136 {
00137
switch ( button )
00138 {
00139
case ButtonAdd:
00140 d->addIcon = icon;
00141 d->btnAdd->setIconSet( SmallIconSet( icon, d->iconSize ) );
00142
break;
00143
case ButtonRemove:
00144 d->removeIcon = icon;
00145 d->btnRemove->setIconSet( SmallIconSet( icon, d->iconSize ) );
00146
break;
00147
case ButtonUp:
00148 d->upIcon = icon;
00149 d->btnUp->setIconSet( SmallIconSet( icon, d->iconSize ) );
00150
break;
00151
case ButtonDown:
00152 d->downIcon = icon;
00153 d->btnDown->setIconSet( SmallIconSet( icon, d->iconSize ) );
00154
break;
00155
default:
00156 kdDebug(13001)<<
"KActionSelector::setButtonIcon: DAINBREAD!"<<endl;
00157 }
00158 }
00159
00160 void KActionSelector::setButtonIconSet(
const QIconSet &iconset, MoveButton button )
00161 {
00162
switch ( button )
00163 {
00164
case ButtonAdd:
00165 d->btnAdd->setIconSet( iconset );
00166
break;
00167
case ButtonRemove:
00168 d->btnRemove->setIconSet( iconset );
00169
break;
00170
case ButtonUp:
00171 d->btnUp->setIconSet( iconset );
00172
break;
00173
case ButtonDown:
00174 d->btnDown->setIconSet( iconset );
00175
break;
00176
default:
00177 kdDebug(13001)<<
"KActionSelector::setButtonIconSet: DAINBREAD!"<<endl;
00178 }
00179 }
00180
00181 void KActionSelector::setButtonTooltip(
const QString &tip, MoveButton button )
00182 {
00183
switch ( button )
00184 {
00185
case ButtonAdd:
00186 d->btnAdd->setTextLabel( tip );
00187
break;
00188
case ButtonRemove:
00189 d->btnRemove->setTextLabel( tip );
00190
break;
00191
case ButtonUp:
00192 d->btnUp->setTextLabel( tip );
00193
break;
00194
case ButtonDown:
00195 d->btnDown->setTextLabel( tip );
00196
break;
00197
default:
00198 kdDebug(13001)<<
"KActionSelector::setButtonToolTip: DAINBREAD!"<<endl;
00199 }
00200 }
00201
00202 void KActionSelector::setButtonWhatsThis(
const QString &text, MoveButton button )
00203 {
00204
switch ( button )
00205 {
00206
case ButtonAdd:
00207 QWhatsThis::add( d->btnAdd, text );
00208
break;
00209
case ButtonRemove:
00210 QWhatsThis::add( d->btnRemove, text );
00211
break;
00212
case ButtonUp:
00213 QWhatsThis::add( d->btnUp, text );
00214
break;
00215
case ButtonDown:
00216 QWhatsThis::add( d->btnDown, text );
00217
break;
00218
default:
00219 kdDebug(13001)<<
"KActionSelector::setButtonWhatsThis: DAINBREAD!"<<endl;
00220 }
00221 }
00222
00223 void KActionSelector::setButtonsEnabled()
00224 {
00225 d->btnAdd->setEnabled( d->availableListBox->currentItem() > -1 );
00226 d->btnRemove->setEnabled( d->selectedListBox->currentItem() > -1 );
00227 d->btnUp->setEnabled( d->selectedListBox->currentItem() > 0 );
00228 d->btnDown->setEnabled( d->selectedListBox->currentItem() > -1 &&
00229 d->selectedListBox->currentItem() < (
int)d->selectedListBox->count() - 1 );
00230 }
00231
00232
00233
00234
00235
00236
bool KActionSelector::moveOnDoubleClick()
const
00237
{
00238
return d->moveOnDoubleClick;
00239 }
00240
00241 void KActionSelector::setMoveOnDoubleClick(
bool b )
00242 {
00243 d->moveOnDoubleClick = b;
00244 }
00245
00246
bool KActionSelector::keyboardEnabled()
const
00247
{
00248
return d->keyboardEnabled;
00249 }
00250
00251 void KActionSelector::setKeyboardEnabled(
bool b )
00252 {
00253 d->keyboardEnabled = b;
00254 }
00255
00256 QString
KActionSelector::availableLabel()
const
00257
{
00258
return d->lAvailable->text();
00259 }
00260
00261 void KActionSelector::setAvailableLabel(
const QString &text )
00262 {
00263 d->lAvailable->setText( text );
00264 }
00265
00266 QString
KActionSelector::selectedLabel()
const
00267
{
00268
return d->lSelected->text();
00269 }
00270
00271 void KActionSelector::setSelectedLabel(
const QString &text )
00272 {
00273 d->lSelected->setText( text );
00274 }
00275
00276 KActionSelector::ButtonIconSize
KActionSelector::buttonIconSize()
const
00277
{
00278
return d->iconSize;
00279 }
00280
00281 void KActionSelector::setButtonIconSize( ButtonIconSize size )
00282 {
00283 d->iconSize = size;
00284
00285 loadIcons();
00286 }
00287
00288 KActionSelector::InsertionPolicy
KActionSelector::availableInsertionPolicy()
const
00289
{
00290
return d->availableInsertionPolicy;
00291 }
00292
00293 void KActionSelector::setAvailableInsertionPolicy( InsertionPolicy p )
00294 {
00295 d->availableInsertionPolicy = p;
00296 }
00297
00298 KActionSelector::InsertionPolicy
KActionSelector::selectedInsertionPolicy()
const
00299
{
00300
return d->selectedInsertionPolicy;
00301 }
00302
00303 void KActionSelector::setSelectedInsertionPolicy( InsertionPolicy p )
00304 {
00305 d->selectedInsertionPolicy = p;
00306 }
00307
00308
bool KActionSelector::showUpDownButtons()
const
00309
{
00310
return d->showUpDownButtons;
00311 }
00312
00313 void KActionSelector::setShowUpDownButtons(
bool show )
00314 {
00315 d->showUpDownButtons = show;
00316
if ( show )
00317 {
00318 d->btnUp->show();
00319 d->btnDown->show();
00320 }
00321
else
00322 {
00323 d->btnUp->hide();
00324 d->btnDown->hide();
00325 }
00326 }
00327
00328
00329
00330
00331
00332 void KActionSelector::polish()
00333 {
00334
setButtonsEnabled();
00335 }
00336
00337
00338
00339
00340 void KActionSelector::keyPressEvent( QKeyEvent *e )
00341 {
00342
if ( ! d->keyboardEnabled )
return;
00343
if ( (e->state() & Qt::ControlButton) )
00344 {
00345
switch ( e->key() )
00346 {
00347
case Key_Right:
00348 buttonAddClicked();
00349
break;
00350
case Key_Left:
00351 buttonRemoveClicked();
00352
break;
00353
case Key_Up:
00354 buttonUpClicked();
00355
break;
00356
case Key_Down:
00357 buttonDownClicked();
00358
break;
00359
default:
00360 e->ignore();
00361
return;
00362 }
00363 }
00364 }
00365
00366 bool KActionSelector::eventFilter( QObject *o, QEvent *e )
00367 {
00368
if ( d->keyboardEnabled && e->type() == QEvent::KeyPress )
00369 {
00370
if ( (((QKeyEvent*)e)->state() & Qt::ControlButton) )
00371 {
00372
switch ( ((QKeyEvent*)e)->key() )
00373 {
00374
case Key_Right:
00375 buttonAddClicked();
00376
break;
00377
case Key_Left:
00378 buttonRemoveClicked();
00379
break;
00380
case Key_Up:
00381 buttonUpClicked();
00382
break;
00383
case Key_Down:
00384 buttonDownClicked();
00385
break;
00386
default:
00387
return QWidget::eventFilter( o, e );
00388
break;
00389 }
00390
return true;
00391 }
00392
else if ( o->inherits(
"QListBox" ) )
00393 {
00394
switch ( ((QKeyEvent*)e)->key() )
00395 {
00396
case Key_Return:
00397
case Key_Enter:
00398 QListBox *lb = (QListBox*)o;
00399
int index = lb->currentItem();
00400
if ( index < 0 )
break;
00401 moveItem( lb->item( index ) );
00402
return true;
00403 }
00404 }
00405 }
00406
return QWidget::eventFilter( o, e );
00407 }
00408
00409
00410
00411
00412
00413
void KActionSelector::buttonAddClicked()
00414 {
00415
00416 QListBoxItem *item = d->availableListBox->firstItem();
00417
while ( item ) {
00418
if ( item->isSelected() ) {
00419 d->availableListBox->takeItem( item );
00420 d->selectedListBox->insertItem( item, insertionIndex( d->selectedListBox, d->selectedInsertionPolicy ) );
00421 d->selectedListBox->setCurrentItem( item );
00422 emit added( item );
00423 }
00424 item = item->next();
00425 }
00426
if ( d->selectedInsertionPolicy == Sorted )
00427 d->selectedListBox->sort();
00428 d->selectedListBox->setFocus();
00429 }
00430
00431
void KActionSelector::buttonRemoveClicked()
00432 {
00433
00434 QListBoxItem *item = d->selectedListBox->firstItem();
00435
while ( item ) {
00436
if ( item->isSelected() ) {
00437 d->selectedListBox->takeItem( item );
00438 d->availableListBox->insertItem( item, insertionIndex( d->availableListBox, d->availableInsertionPolicy ) );
00439 d->availableListBox->setCurrentItem( item );
00440 emit
removed( item );
00441 }
00442 item = item->next();
00443 }
00444
if ( d->availableInsertionPolicy == Sorted )
00445 d->availableListBox->sort();
00446 d->availableListBox->setFocus();
00447 }
00448
00449
void KActionSelector::buttonUpClicked()
00450 {
00451
int c = d->selectedListBox->currentItem();
00452
if ( c < 0 )
return;
00453 QListBoxItem *item = d->selectedListBox->item( c );
00454 d->selectedListBox->takeItem( item );
00455 d->selectedListBox->insertItem( item, c-1 );
00456 d->selectedListBox->setCurrentItem( item );
00457 emit
movedUp( item );
00458 }
00459
00460
void KActionSelector::buttonDownClicked()
00461 {
00462
int c = d->selectedListBox->currentItem();
00463
if ( c < 0 )
return;
00464 QListBoxItem *item = d->selectedListBox->item( c );
00465 d->selectedListBox->takeItem( item );
00466 d->selectedListBox->insertItem( item, c+1 );
00467 d->selectedListBox->setCurrentItem( item );
00468 emit
movedDown( item );
00469 }
00470
00471
void KActionSelector::itemDoubleClicked( QListBoxItem *item )
00472 {
00473
if ( d->moveOnDoubleClick )
00474 moveItem( item );
00475 }
00476
00477
00478
00479
00480
00481
void KActionSelector::loadIcons()
00482 {
00483 d->btnAdd->setIconSet( SmallIconSet( d->addIcon, d->iconSize ) );
00484 d->btnRemove->setIconSet( SmallIconSet( d->removeIcon, d->iconSize ) );
00485 d->btnUp->setIconSet( SmallIconSet( d->upIcon, d->iconSize ) );
00486 d->btnDown->setIconSet( SmallIconSet( d->downIcon, d->iconSize ) );
00487 }
00488
00489
void KActionSelector::moveItem( QListBoxItem *item )
00490 {
00491 QListBox *lbFrom = item->listBox();
00492 QListBox *lbTo;
00493
if ( lbFrom == d->availableListBox )
00494 lbTo = d->selectedListBox;
00495
else if ( lbFrom == d->selectedListBox )
00496 lbTo = d->availableListBox;
00497
else
00498
return;
00499
00500
InsertionPolicy p = ( lbTo == d->availableListBox ) ?
00501 d->availableInsertionPolicy : d->selectedInsertionPolicy;
00502
00503 lbFrom->takeItem( item );
00504 lbTo->insertItem( item, insertionIndex( lbTo, p ) );
00505 lbTo->setFocus();
00506 lbTo->setCurrentItem( item );
00507
00508
if ( p == Sorted )
00509 lbTo->sort();
00510
if ( lbTo == d->selectedListBox )
00511 emit
added( item );
00512
else
00513 emit
removed( item );
00514 }
00515
00516
int KActionSelector::insertionIndex( QListBox *lb, InsertionPolicy policy )
00517 {
00518
int index;
00519
switch ( policy )
00520 {
00521
case BelowCurrent:
00522 index = lb->currentItem();
00523
if ( index > -1 ) index += 1;
00524
break;
00525
case AtTop:
00526 index = 0;
00527
break;
00528
default:
00529 index = -1;
00530 }
00531
return index;
00532 }
00533
00534
00535
#include "kactionselector.moc"