kactionselector.cpp
00001 /* This file is part of the KDE project 00002 Copyright (C) 2002 Anders Lund <anders.lund@lund.tdcadsl.dk> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #include "kactionselector.h" 00021 00022 #include <klocale.h> 00023 #include <kiconloader.h> 00024 #include <kdialog.h> // for spacingHint() 00025 #include <kdebug.h> 00026 #include <tqapplication.h> 00027 #include <tqlistbox.h> 00028 #include <tqtoolbutton.h> 00029 #include <tqlabel.h> 00030 #include <tqlayout.h> 00031 #include <tqevent.h> 00032 #include <tqwhatsthis.h> 00033 00034 class KActionSelectorPrivate { 00035 public: 00036 TQListBox *availableListBox, *selectedListBox; 00037 TQToolButton *btnAdd, *btnRemove, *btnUp, *btnDown; 00038 TQLabel *lAvailable, *lSelected; 00039 bool moveOnDoubleClick, keyboardEnabled; 00040 KActionSelector::ButtonIconSize iconSize; 00041 TQString addIcon, removeIcon, upIcon, downIcon; 00042 KActionSelector::InsertionPolicy availableInsertionPolicy, selectedInsertionPolicy; 00043 bool showUpDownButtons; 00044 }; 00045 00046 //BEGIN Constructor/destructor 00047 00048 KActionSelector::KActionSelector( TQWidget *parent, const char *name ) 00049 : TQWidget( parent, name ) 00050 { 00051 d = new KActionSelectorPrivate(); 00052 d->moveOnDoubleClick = true; 00053 d->keyboardEnabled = true; 00054 d->iconSize = SmallIcon; 00055 d->addIcon = TQApplication::reverseLayout()? "back" : "forward"; 00056 d->removeIcon = TQApplication::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 //int isz = IconSize( KIcon::Small ); 00064 00065 TQHBoxLayout *lo = new TQHBoxLayout( this ); 00066 lo->setSpacing( KDialog::spacingHint() ); 00067 00068 TQVBoxLayout *loAv = new TQVBoxLayout( lo ); 00069 d->lAvailable = new TQLabel( i18n("&Available:"), this ); 00070 loAv->addWidget( d->lAvailable ); 00071 d->availableListBox = new TQListBox( this ); 00072 loAv->addWidget( d->availableListBox ); 00073 d->lAvailable->setBuddy( d->availableListBox ); 00074 00075 TQVBoxLayout *loHBtns = new TQVBoxLayout( lo ); 00076 loHBtns->addStretch( 1 ); 00077 d->btnAdd = new TQToolButton( this ); 00078 loHBtns->addWidget( d->btnAdd ); 00079 d->btnRemove = new TQToolButton( this ); 00080 loHBtns->addWidget( d->btnRemove ); 00081 loHBtns->addStretch( 1 ); 00082 00083 TQVBoxLayout *loS = new TQVBoxLayout( lo ); 00084 d->lSelected = new TQLabel( i18n("&Selected:"), this ); 00085 loS->addWidget( d->lSelected ); 00086 d->selectedListBox = new TQListBox( this ); 00087 loS->addWidget( d->selectedListBox ); 00088 d->lSelected->setBuddy( d->selectedListBox ); 00089 00090 TQVBoxLayout *loVBtns = new TQVBoxLayout( lo ); 00091 loVBtns->addStretch( 1 ); 00092 d->btnUp = new TQToolButton( this ); 00093 d->btnUp->setAutoRepeat( true ); 00094 loVBtns->addWidget( d->btnUp ); 00095 d->btnDown = new TQToolButton( this ); 00096 d->btnDown->setAutoRepeat( true ); 00097 loVBtns->addWidget( d->btnDown ); 00098 loVBtns->addStretch( 1 ); 00099 00100 loadIcons(); 00101 00102 connect( d->btnAdd, TQT_SIGNAL(clicked()), this, TQT_SLOT(buttonAddClicked()) ); 00103 connect( d->btnRemove, TQT_SIGNAL(clicked()), this, TQT_SLOT(buttonRemoveClicked()) ); 00104 connect( d->btnUp, TQT_SIGNAL(clicked()), this, TQT_SLOT(buttonUpClicked()) ); 00105 connect( d->btnDown, TQT_SIGNAL(clicked()), this, TQT_SLOT(buttonDownClicked()) ); 00106 connect( d->availableListBox, TQT_SIGNAL(doubleClicked(TQListBoxItem*)), 00107 this, TQT_SLOT(itemDoubleClicked(TQListBoxItem*)) ); 00108 connect( d->selectedListBox, TQT_SIGNAL(doubleClicked(TQListBoxItem*)), 00109 this, TQT_SLOT(itemDoubleClicked(TQListBoxItem*)) ); 00110 connect( d->availableListBox, TQT_SIGNAL(currentChanged(TQListBoxItem*)), 00111 this, TQT_SLOT(slotCurrentChanged(TQListBoxItem *)) ); 00112 connect( d->selectedListBox, TQT_SIGNAL(currentChanged(TQListBoxItem*)), 00113 this, TQT_SLOT(slotCurrentChanged(TQListBoxItem *)) ); 00114 00115 d->availableListBox->installEventFilter( this ); 00116 d->selectedListBox->installEventFilter( this ); 00117 } 00118 00119 KActionSelector::~KActionSelector() 00120 { 00121 delete d; 00122 } 00123 00124 //END Constructor/destroctor 00125 00126 //BEGIN Public Methods 00127 00128 TQListBox *KActionSelector::availableListBox() const 00129 { 00130 return d->availableListBox; 00131 } 00132 00133 TQListBox *KActionSelector::selectedListBox() const 00134 { 00135 return d->selectedListBox; 00136 } 00137 00138 void KActionSelector::setButtonIcon( const TQString &icon, MoveButton button ) 00139 { 00140 switch ( button ) 00141 { 00142 case ButtonAdd: 00143 d->addIcon = icon; 00144 d->btnAdd->setIconSet( SmallIconSet( icon, d->iconSize ) ); 00145 break; 00146 case ButtonRemove: 00147 d->removeIcon = icon; 00148 d->btnRemove->setIconSet( SmallIconSet( icon, d->iconSize ) ); 00149 break; 00150 case ButtonUp: 00151 d->upIcon = icon; 00152 d->btnUp->setIconSet( SmallIconSet( icon, d->iconSize ) ); 00153 break; 00154 case ButtonDown: 00155 d->downIcon = icon; 00156 d->btnDown->setIconSet( SmallIconSet( icon, d->iconSize ) ); 00157 break; 00158 default: 00159 kdDebug(13001)<<"KActionSelector::setButtonIcon: DAINBREAD!"<<endl; 00160 } 00161 } 00162 00163 void KActionSelector::setButtonIconSet( const TQIconSet &iconset, MoveButton button ) 00164 { 00165 switch ( button ) 00166 { 00167 case ButtonAdd: 00168 d->btnAdd->setIconSet( iconset ); 00169 break; 00170 case ButtonRemove: 00171 d->btnRemove->setIconSet( iconset ); 00172 break; 00173 case ButtonUp: 00174 d->btnUp->setIconSet( iconset ); 00175 break; 00176 case ButtonDown: 00177 d->btnDown->setIconSet( iconset ); 00178 break; 00179 default: 00180 kdDebug(13001)<<"KActionSelector::setButtonIconSet: DAINBREAD!"<<endl; 00181 } 00182 } 00183 00184 void KActionSelector::setButtonTooltip( const TQString &tip, MoveButton button ) 00185 { 00186 switch ( button ) 00187 { 00188 case ButtonAdd: 00189 d->btnAdd->setTextLabel( tip ); 00190 break; 00191 case ButtonRemove: 00192 d->btnRemove->setTextLabel( tip ); 00193 break; 00194 case ButtonUp: 00195 d->btnUp->setTextLabel( tip ); 00196 break; 00197 case ButtonDown: 00198 d->btnDown->setTextLabel( tip ); 00199 break; 00200 default: 00201 kdDebug(13001)<<"KActionSelector::setButtonToolTip: DAINBREAD!"<<endl; 00202 } 00203 } 00204 00205 void KActionSelector::setButtonWhatsThis( const TQString &text, MoveButton button ) 00206 { 00207 switch ( button ) 00208 { 00209 case ButtonAdd: 00210 TQWhatsThis::add( d->btnAdd, text ); 00211 break; 00212 case ButtonRemove: 00213 TQWhatsThis::add( d->btnRemove, text ); 00214 break; 00215 case ButtonUp: 00216 TQWhatsThis::add( d->btnUp, text ); 00217 break; 00218 case ButtonDown: 00219 TQWhatsThis::add( d->btnDown, text ); 00220 break; 00221 default: 00222 kdDebug(13001)<<"KActionSelector::setButtonWhatsThis: DAINBREAD!"<<endl; 00223 } 00224 } 00225 00226 void KActionSelector::setButtonsEnabled() 00227 { 00228 d->btnAdd->setEnabled( d->availableListBox->currentItem() > -1 ); 00229 d->btnRemove->setEnabled( d->selectedListBox->currentItem() > -1 ); 00230 d->btnUp->setEnabled( d->selectedListBox->currentItem() > 0 ); 00231 d->btnDown->setEnabled( d->selectedListBox->currentItem() > -1 && 00232 d->selectedListBox->currentItem() < (int)d->selectedListBox->count() - 1 ); 00233 } 00234 00235 //END Public Methods 00236 00237 //BEGIN Properties 00238 00239 bool KActionSelector::moveOnDoubleClick() const 00240 { 00241 return d->moveOnDoubleClick; 00242 } 00243 00244 void KActionSelector::setMoveOnDoubleClick( bool b ) 00245 { 00246 d->moveOnDoubleClick = b; 00247 } 00248 00249 bool KActionSelector::keyboardEnabled() const 00250 { 00251 return d->keyboardEnabled; 00252 } 00253 00254 void KActionSelector::setKeyboardEnabled( bool b ) 00255 { 00256 d->keyboardEnabled = b; 00257 } 00258 00259 TQString KActionSelector::availableLabel() const 00260 { 00261 return d->lAvailable->text(); 00262 } 00263 00264 void KActionSelector::setAvailableLabel( const TQString &text ) 00265 { 00266 d->lAvailable->setText( text ); 00267 } 00268 00269 TQString KActionSelector::selectedLabel() const 00270 { 00271 return d->lSelected->text(); 00272 } 00273 00274 void KActionSelector::setSelectedLabel( const TQString &text ) 00275 { 00276 d->lSelected->setText( text ); 00277 } 00278 00279 KActionSelector::ButtonIconSize KActionSelector::buttonIconSize() const 00280 { 00281 return d->iconSize; 00282 } 00283 00284 void KActionSelector::setButtonIconSize( ButtonIconSize size ) 00285 { 00286 d->iconSize = size; 00287 // reload icons 00288 loadIcons(); 00289 } 00290 00291 KActionSelector::InsertionPolicy KActionSelector::availableInsertionPolicy() const 00292 { 00293 return d->availableInsertionPolicy; 00294 } 00295 00296 void KActionSelector::setAvailableInsertionPolicy( InsertionPolicy p ) 00297 { 00298 d->availableInsertionPolicy = p; 00299 } 00300 00301 KActionSelector::InsertionPolicy KActionSelector::selectedInsertionPolicy() const 00302 { 00303 return d->selectedInsertionPolicy; 00304 } 00305 00306 void KActionSelector::setSelectedInsertionPolicy( InsertionPolicy p ) 00307 { 00308 d->selectedInsertionPolicy = p; 00309 } 00310 00311 bool KActionSelector::showUpDownButtons() const 00312 { 00313 return d->showUpDownButtons; 00314 } 00315 00316 void KActionSelector::setShowUpDownButtons( bool show ) 00317 { 00318 d->showUpDownButtons = show; 00319 if ( show ) 00320 { 00321 d->btnUp->show(); 00322 d->btnDown->show(); 00323 } 00324 else 00325 { 00326 d->btnUp->hide(); 00327 d->btnDown->hide(); 00328 } 00329 } 00330 00331 //END Properties 00332 00333 //BEGIN Public Slots 00334 00335 void KActionSelector::polish() 00336 { 00337 setButtonsEnabled(); 00338 } 00339 00340 //END Public Slots 00341 00342 //BEGIN Protected 00343 void KActionSelector::keyPressEvent( TQKeyEvent *e ) 00344 { 00345 if ( ! d->keyboardEnabled ) return; 00346 if ( (e->state() & TQt::ControlButton) ) 00347 { 00348 switch ( e->key() ) 00349 { 00350 case Key_Right: 00351 buttonAddClicked(); 00352 break; 00353 case Key_Left: 00354 buttonRemoveClicked(); 00355 break; 00356 case Key_Up: 00357 buttonUpClicked(); 00358 break; 00359 case Key_Down: 00360 buttonDownClicked(); 00361 break; 00362 default: 00363 e->ignore(); 00364 return; 00365 } 00366 } 00367 } 00368 00369 bool KActionSelector::eventFilter( TQObject *o, TQEvent *e ) 00370 { 00371 if ( d->keyboardEnabled && e->type() == TQEvent::KeyPress ) 00372 { 00373 if ( (((TQKeyEvent*)e)->state() & TQt::ControlButton) ) 00374 { 00375 switch ( ((TQKeyEvent*)e)->key() ) 00376 { 00377 case Key_Right: 00378 buttonAddClicked(); 00379 break; 00380 case Key_Left: 00381 buttonRemoveClicked(); 00382 break; 00383 case Key_Up: 00384 buttonUpClicked(); 00385 break; 00386 case Key_Down: 00387 buttonDownClicked(); 00388 break; 00389 default: 00390 return TQWidget::eventFilter( o, e ); 00391 break; 00392 } 00393 return true; 00394 } 00395 else if ( o->inherits( TQLISTBOX_OBJECT_NAME_STRING ) ) 00396 { 00397 switch ( ((TQKeyEvent*)e)->key() ) 00398 { 00399 case Key_Return: 00400 case Key_Enter: 00401 TQListBox *lb = (TQListBox*)o; 00402 int index = lb->currentItem(); 00403 if ( index < 0 ) break; 00404 moveItem( lb->item( index ) ); 00405 return true; 00406 } 00407 } 00408 } 00409 return TQWidget::eventFilter( o, e ); 00410 } 00411 00412 //END Protected 00413 00414 //BEGIN Private Slots 00415 00416 void KActionSelector::buttonAddClicked() 00417 { 00418 // move all selected items from available to selected listbox 00419 TQListBoxItem *item = d->availableListBox->firstItem(); 00420 while ( item ) { 00421 if ( item->isSelected() ) { 00422 d->availableListBox->takeItem( item ); 00423 d->selectedListBox->insertItem( item, insertionIndex( d->selectedListBox, d->selectedInsertionPolicy ) ); 00424 d->selectedListBox->setCurrentItem( item ); 00425 emit added( item ); 00426 item = d->availableListBox->firstItem(); 00427 } else 00428 item = item->next(); 00429 } 00430 if ( d->selectedInsertionPolicy == Sorted ) 00431 d->selectedListBox->sort(); 00432 d->selectedListBox->setFocus(); 00433 } 00434 00435 void KActionSelector::buttonRemoveClicked() 00436 { 00437 // move all selected items from selected to available listbox 00438 TQListBoxItem *item = d->selectedListBox->firstItem(); 00439 while ( item ) { 00440 if ( item->isSelected() ) { 00441 d->selectedListBox->takeItem( item ); 00442 d->availableListBox->insertItem( item, insertionIndex( d->availableListBox, d->availableInsertionPolicy ) ); 00443 d->availableListBox->setCurrentItem( item ); 00444 emit removed( item ); 00445 item = d->selectedListBox->firstItem(); 00446 } else 00447 item = item->next(); 00448 } 00449 if ( d->availableInsertionPolicy == Sorted ) 00450 d->availableListBox->sort(); 00451 d->availableListBox->setFocus(); 00452 } 00453 00454 void KActionSelector::buttonUpClicked() 00455 { 00456 int c = d->selectedListBox->currentItem(); 00457 if ( c < 1 ) return; 00458 TQListBoxItem *item = d->selectedListBox->item( c ); 00459 d->selectedListBox->takeItem( item ); 00460 d->selectedListBox->insertItem( item, c-1 ); 00461 d->selectedListBox->setCurrentItem( item ); 00462 emit movedUp( item ); 00463 } 00464 00465 void KActionSelector::buttonDownClicked() 00466 { 00467 int c = d->selectedListBox->currentItem(); 00468 if ( c < 0 || c == int( d->selectedListBox->count() ) - 1 ) return; 00469 TQListBoxItem *item = d->selectedListBox->item( c ); 00470 d->selectedListBox->takeItem( item ); 00471 d->selectedListBox->insertItem( item, c+1 ); 00472 d->selectedListBox->setCurrentItem( item ); 00473 emit movedDown( item ); 00474 } 00475 00476 void KActionSelector::itemDoubleClicked( TQListBoxItem *item ) 00477 { 00478 if ( d->moveOnDoubleClick ) 00479 moveItem( item ); 00480 } 00481 00482 //END Private Slots 00483 00484 //BEGIN Private Methods 00485 00486 void KActionSelector::loadIcons() 00487 { 00488 d->btnAdd->setIconSet( SmallIconSet( d->addIcon, d->iconSize ) ); 00489 d->btnRemove->setIconSet( SmallIconSet( d->removeIcon, d->iconSize ) ); 00490 d->btnUp->setIconSet( SmallIconSet( d->upIcon, d->iconSize ) ); 00491 d->btnDown->setIconSet( SmallIconSet( d->downIcon, d->iconSize ) ); 00492 } 00493 00494 void KActionSelector::moveItem( TQListBoxItem *item ) 00495 { 00496 TQListBox *lbFrom = item->listBox(); 00497 TQListBox *lbTo; 00498 if ( lbFrom == d->availableListBox ) 00499 lbTo = d->selectedListBox; 00500 else if ( lbFrom == d->selectedListBox ) 00501 lbTo = d->availableListBox; 00502 else //?! somewhat unlikely... 00503 return; 00504 00505 InsertionPolicy p = ( lbTo == d->availableListBox ) ? 00506 d->availableInsertionPolicy : d->selectedInsertionPolicy; 00507 00508 lbFrom->takeItem( item ); 00509 lbTo->insertItem( item, insertionIndex( lbTo, p ) ); 00510 lbTo->setFocus(); 00511 lbTo->setCurrentItem( item ); 00512 00513 if ( p == Sorted ) 00514 lbTo->sort(); 00515 if ( lbTo == d->selectedListBox ) 00516 emit added( item ); 00517 else 00518 emit removed( item ); 00519 } 00520 00521 int KActionSelector::insertionIndex( TQListBox *lb, InsertionPolicy policy ) 00522 { 00523 int index; 00524 switch ( policy ) 00525 { 00526 case BelowCurrent: 00527 index = lb->currentItem(); 00528 if ( index > -1 ) index += 1; 00529 break; 00530 case AtTop: 00531 index = 0; 00532 break; 00533 default: 00534 index = -1; 00535 } 00536 return index; 00537 } 00538 00539 //END Private Methods 00540 #include "kactionselector.moc"