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"