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