00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <qclipboard.h>
00036 #include <qlistbox.h>
00037 #include <qpopupmenu.h>
00038
00039
00040
00041 #include <opie2/ocompletionbox.h>
00042 #include <opie2/olineedit.h>
00043 #include <opie2/opixmapprovider.h>
00044 #include <opie2/ocombobox.h>
00045
00046
00047
00048
00049
00050 class OComboBox::OComboBoxPrivate
00051 {
00052 public:
00053 OComboBoxPrivate()
00054 {
00055 olineEdit = 0L;
00056 }
00057 ~OComboBoxPrivate()
00058 {
00059 }
00060
00061 OLineEdit *olineEdit;
00062 };
00063
00064
00065
00066
00067
00068 OComboBox::OComboBox( QWidget *parent, const char *name )
00069 : QComboBox( parent, name )
00070 {
00071 init();
00072 }
00073
00074 OComboBox::OComboBox( bool rw, QWidget *parent, const char *name )
00075 : QComboBox( rw, parent, name )
00076 {
00077 init();
00078
00079 if ( rw )
00080 {
00081 OLineEdit *edit = new OLineEdit( this, "combo lineedit" );
00082 setLineEdit( edit );
00083 }
00084 }
00085
00086 OComboBox::~OComboBox()
00087 {
00088 delete d;
00089 }
00090
00091 void OComboBox::init()
00092 {
00093 d = new OComboBoxPrivate;
00094
00095
00096 QComboBox::setAutoCompletion( false );
00097
00098
00099
00100
00101 m_bEnableMenu = false;
00102
00103 m_trapReturnKey = false;
00104
00105
00106
00107 setContextMenuEnabled( true );
00108
00109
00110 installEventFilter( this );
00111 if ( lineEdit() )
00112 lineEdit()->installEventFilter( this );
00113 }
00114
00115
00116 bool OComboBox::contains( const QString& _text ) const
00117 {
00118 if ( _text.isEmpty() )
00119 return false;
00120
00121 for (int i = 0; i < count(); i++ ) {
00122 if ( text(i) == _text )
00123 return true;
00124 }
00125 return false;
00126 }
00127
00128 void OComboBox::setAutoCompletion( bool autocomplete )
00129 {
00130 if ( d->olineEdit )
00131 {
00132 if ( autocomplete )
00133 {
00134 d->olineEdit->setCompletionMode( OGlobalSettings::CompletionAuto );
00135 setCompletionMode( OGlobalSettings::CompletionAuto );
00136 }
00137 else
00138 {
00139 d->olineEdit->setCompletionMode( OGlobalSettings::completionMode() );
00140 setCompletionMode( OGlobalSettings::completionMode() );
00141 }
00142 }
00143 }
00144
00145 void OComboBox::setContextMenuEnabled( bool showMenu )
00146 {
00147 if( d->olineEdit )
00148 {
00149 d->olineEdit->setContextMenuEnabled( showMenu );
00150 m_bEnableMenu = showMenu;
00151 }
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 void OComboBox::setCompletedText( const QString& text, bool marked )
00168 {
00169 if ( d->olineEdit )
00170 d->olineEdit->setCompletedText( text, marked );
00171 }
00172
00173 void OComboBox::setCompletedText( const QString& text )
00174 {
00175 if ( d->olineEdit )
00176 d->olineEdit->setCompletedText( text );
00177 }
00178
00179 void OComboBox::makeCompletion( const QString& text )
00180 {
00181 if( d->olineEdit )
00182 d->olineEdit->makeCompletion( text );
00183
00184 else
00185 {
00186 if( text.isNull() || !listBox() )
00187 return;
00188
00189 int index = listBox()->index( listBox()->findItem( text ) );
00190 if( index >= 0 ) {
00191 setCurrentItem( index );
00192 }
00193 }
00194 }
00195
00196 void OComboBox::rotateText( OCompletionBase::KeyBindingType type )
00197 {
00198 if ( d->olineEdit )
00199 d->olineEdit->rotateText( type );
00200 }
00201
00202 bool OComboBox::eventFilter( QObject* o, QEvent* ev )
00203 {
00204 QLineEdit *edit = lineEdit();
00205
00206 int type = ev->type();
00207
00208 if ( o == edit )
00209 {
00210
00211
00212 if ( type == QEvent::KeyPress )
00213 {
00214 QKeyEvent *e = static_cast<QKeyEvent *>( ev );
00215
00216 if ( e->key() == Key_Return || e->key() == Key_Enter)
00217 {
00218
00219
00220 emit returnPressed();
00221 emit returnPressed( currentText() );
00222 if ( d->olineEdit && d->olineEdit->completionBox(false) &&
00223 d->olineEdit->completionBox()->isVisible() )
00224 d->olineEdit->completionBox()->hide();
00225
00226 return m_trapReturnKey;
00227 }
00228 }
00229 }
00230
00231
00232
00233 if ( type == QEvent::Wheel ) {
00234 if ( !listBox() || listBox()->isHidden() ) {
00235 QWheelEvent *e = static_cast<QWheelEvent*>( ev );
00236 static const int WHEEL_DELTA = 120;
00237 int skipItems = e->delta() / WHEEL_DELTA;
00238 if ( e->state() & ControlButton )
00239 skipItems *= 10;
00240
00241 int newItem = currentItem() - skipItems;
00242
00243 if ( newItem < 0 )
00244 newItem = 0;
00245 else if ( newItem >= count() )
00246 newItem = count() -1;
00247
00248 setCurrentItem( newItem );
00249 if ( !text( newItem ).isNull() )
00250 emit activated( text( newItem ) );
00251 emit activated( newItem );
00252 e->accept();
00253 return true;
00254 }
00255 }
00256
00257 return QComboBox::eventFilter( o, ev );
00258 }
00259
00260 void OComboBox::setTrapReturnKey( bool grab )
00261 {
00262 m_trapReturnKey = grab;
00263 }
00264
00265 bool OComboBox::trapReturnKey() const
00266 {
00267 return m_trapReturnKey;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 void OComboBox::setCompletedItems( const QStringList& items )
00299 {
00300 if ( d->olineEdit )
00301 d->olineEdit->setCompletedItems( items );
00302 }
00303
00304
00305 OCompletionBox * OComboBox::completionBox( bool create )
00306 {
00307 if ( d->olineEdit )
00308 return d->olineEdit->completionBox( create );
00309 return 0;
00310 }
00311
00312
00313 void OComboBox::create( WId id, bool initializeWindow, bool destroyOldWindow )
00314 {
00315 QComboBox::create( id, initializeWindow, destroyOldWindow );
00316
00317 }
00318
00319 void OComboBox::setLineEdit( OLineEdit *edit )
00320 {
00321 #if QT_VERSION >= 0x030000
00322 QComboBox::setLineEdit( edit );
00323 if ( !edit->inherits( "OLineEdit" ) )
00324 d->olineEdit = 0;
00325 else
00326 d->olineEdit = static_cast<OLineEdit*>( edit );
00327 setDelegate( d->olineEdit );
00328
00329
00330 if ( d->olineEdit ) {
00331 connect( d->olineEdit, SIGNAL( completion(const QString&)),
00332 SIGNAL( completion(const QString&)) );
00333 connect( d->olineEdit, SIGNAL( substringCompletion(const QString&)),
00334 SIGNAL( substringCompletion(const QString&)) );
00335 connect( d->olineEdit,
00336 SIGNAL( textRotation(OCompletionBase::KeyBindingType)),
00337 SIGNAL( textRotation(OCompletionBase::KeyBindingType)) );
00338 connect( d->olineEdit,
00339 SIGNAL( completionModeChanged(OGlobalSettings::Completion)),
00340 SIGNAL( completionModeChanged(OGlobalSettings::Completion)));
00341
00342 connect( d->olineEdit,
00343 SIGNAL( aboutToShowContextMenu(QPopupMenu*)),
00344 SIGNAL( aboutToShowContextMenu(QPopupMenu*)) );
00345 }
00346 #else
00347 #warning OComboBox is not fully functional with Qt2
00348 #endif
00349 }
00350
00351
00352 void OComboBox::deleteWordForward()
00353 {
00354 lineEdit()->cursorWordForward(TRUE);
00355 #if QT_VERSION >= 0x030000
00356 if ( lineEdit()->hasSelectedText() )
00357 #else
00358 if ( lineEdit()->hasMarkedText() )
00359 #endif
00360 {
00361 lineEdit()->del();
00362 }
00363 }
00364
00365 void OComboBox::deleteWordBack()
00366 {
00367 lineEdit()->cursorWordBackward(TRUE);
00368 #if QT_VERSION >= 0x030000
00369 if ( lineEdit()->hasSelectedText() )
00370 #else
00371 if ( lineEdit()->hasMarkedText() )
00372 #endif
00373 {
00374 lineEdit()->del();
00375 }
00376 }
00377
00378 void OComboBox::setCurrentItem( const QString& item, bool insert, int index )
00379 {
00380 int sel = -1;
00381 for (int i = 0; i < count(); ++i)
00382 if (text(i) == item)
00383 {
00384 sel = i;
00385 break;
00386 }
00387 if (sel == -1 && insert)
00388 {
00389 insertItem(item, index);
00390 if (index >= 0)
00391 sel = index;
00392 else
00393 sel = count() - 1;
00394 }
00395 setCurrentItem(sel);
00396 }
00397
00398 void OComboBox::setCurrentItem(int index)
00399 {
00400 QComboBox::setCurrentItem(index);
00401 }
00402
00403
00404
00405
00406
00407
00408
00409 OHistoryCombo::OHistoryCombo( QWidget *parent, const char *name )
00410 : OComboBox( true, parent, name )
00411 {
00412 init( true );
00413 }
00414
00415
00416 OHistoryCombo::OHistoryCombo( bool useCompletion,
00417 QWidget *parent, const char *name )
00418 : OComboBox( true, parent, name )
00419 {
00420 init( useCompletion );
00421 }
00422
00423 void OHistoryCombo::init( bool useCompletion )
00424 {
00425 if ( useCompletion )
00426 completionObject()->setOrder( OCompletion::Weighted );
00427
00428 setInsertionPolicy( NoInsertion );
00429 myIterateIndex = -1;
00430 myRotated = false;
00431 myPixProvider = 0L;
00432
00433 connect( this, SIGNAL(aboutToShowContextMenu(QPopupMenu*)),
00434 SLOT(addContextMenuItems(QPopupMenu*)) );
00435 connect( this, SIGNAL( activated(int) ), SLOT( slotReset() ));
00436 connect( this, SIGNAL( returnPressed(const QString&) ), SLOT(slotReset()));
00437 }
00438
00439 OHistoryCombo::~OHistoryCombo()
00440 {
00441 delete myPixProvider;
00442 }
00443
00444 void OHistoryCombo::setHistoryItems( QStringList items,
00445 bool setCompletionList )
00446 {
00447 OComboBox::clear();
00448
00449
00450 while ( (int) items.count() > maxCount() && !items.isEmpty() )
00451 items.remove( items.begin() );
00452
00453 insertItems( items );
00454
00455 if ( setCompletionList && useCompletion() ) {
00456
00457 OCompletion *comp = completionObject();
00458 comp->setOrder( OCompletion::Insertion );
00459 comp->setItems( items );
00460 comp->setOrder( OCompletion::Weighted );
00461 }
00462
00463 clearEdit();
00464 }
00465
00466 QStringList OHistoryCombo::historyItems() const
00467 {
00468 QStringList list;
00469 for ( int i = 0; i < count(); i++ )
00470 list.append( text( i ) );
00471
00472 return list;
00473 }
00474
00475 void OHistoryCombo::clearHistory()
00476 {
00477 OComboBox::clear();
00478 if ( useCompletion() )
00479 completionObject()->clear();
00480 }
00481
00482 void OHistoryCombo::addContextMenuItems( QPopupMenu* menu )
00483 {
00484 if ( menu &&!lineEdit()->text().isEmpty())
00485 {
00486 menu->insertSeparator();
00487 menu->insertItem( tr("Empty Contents"), this, SLOT( slotClear()));
00488 }
00489 }
00490
00491 void OHistoryCombo::addToHistory( const QString& item )
00492 {
00493 if ( item.isEmpty() || (count() > 0 && item == text(0) ))
00494 return;
00495
00496
00497 if ( !duplicatesEnabled() ) {
00498 for ( int i = 0; i < count(); i++ ) {
00499 if ( text( i ) == item )
00500 removeItem( i );
00501 }
00502 }
00503
00504
00505 if ( myPixProvider )
00506
00507 insertItem( myPixProvider->pixmapFor(item, 16), item, 0);
00508 else
00509 insertItem( item, 0 );
00510
00511 int last;
00512 QString rmItem;
00513
00514 bool useComp = useCompletion();
00515 while ( count() > maxCount() && count() > 0 ) {
00516
00517
00518
00519 last = count() - 1;
00520 rmItem = text( last );
00521 removeItem( last );
00522 if ( useComp && !contains( rmItem ) )
00523 completionObject()->removeItem( rmItem );
00524 }
00525
00526 if ( useComp )
00527 completionObject()->addItem( item );
00528 }
00529
00530 bool OHistoryCombo::removeFromHistory( const QString& item )
00531 {
00532 if ( item.isEmpty() )
00533 return false;
00534
00535 bool removed = false;
00536 QString temp = currentText();
00537 for ( int i = 0; i < count(); i++ ) {
00538 while ( item == text( i ) ) {
00539 removed = true;
00540 removeItem( i );
00541 }
00542 }
00543
00544 if ( removed && useCompletion() )
00545 completionObject()->removeItem( item );
00546
00547 setEditText( temp );
00548 return removed;
00549 }
00550
00551 void OHistoryCombo::keyPressEvent( QKeyEvent *e )
00552 {
00553
00554 if ( myIterateIndex == -1 )
00555 myText = currentText();
00556
00557
00558
00559 if ( e->key() == Qt::Key_Up ) {
00560 myIterateIndex++;
00561
00562
00563 while ( myIterateIndex < count()-1 &&
00564 (currentText() == text( myIterateIndex ) ||
00565 text( myIterateIndex ).isEmpty()) )
00566 myIterateIndex++;
00567
00568 if ( myIterateIndex >= count() ) {
00569 myRotated = true;
00570 myIterateIndex = -1;
00571
00572
00573 if ( myText == text(0) )
00574 myIterateIndex = 0;
00575
00576 setEditText( myText );
00577 }
00578 else
00579 setEditText( text( myIterateIndex ));
00580 }
00581
00582
00583
00584
00585
00586 else if ( e->key() == Qt::Key_Down ) {
00587 myIterateIndex--;
00588
00589
00590 while ( myIterateIndex >= 0 &&
00591 (currentText() == text( myIterateIndex ) ||
00592 text( myIterateIndex ).isEmpty()) )
00593 myIterateIndex--;
00594
00595
00596 if ( myIterateIndex < 0 ) {
00597 if ( myRotated && myIterateIndex == -2 ) {
00598 myRotated = false;
00599 myIterateIndex = count() - 1;
00600 setEditText( text(myIterateIndex) );
00601 }
00602 else {
00603 if ( myIterateIndex == -2 ) {
00604 qDebug( "ONotifyClient is not implemented yet." );
00605
00606
00607 }
00608
00609 myIterateIndex = -1;
00610 if ( currentText() != myText )
00611 setEditText( myText );
00612 }
00613 }
00614 else
00615 setEditText( text( myIterateIndex ));
00616 }
00617
00618 else
00619 OComboBox::keyPressEvent( e );
00620 }
00621
00622 void OHistoryCombo::slotReset()
00623 {
00624 myIterateIndex = -1;
00625 myRotated = false;
00626 }
00627
00628
00629 void OHistoryCombo::setPixmapProvider( OPixmapProvider *prov )
00630 {
00631 if ( myPixProvider == prov )
00632 return;
00633
00634 delete myPixProvider;
00635 myPixProvider = prov;
00636
00637
00638
00639
00640 if ( count() > 0 ) {
00641 QStringList items( historyItems() );
00642 clear();
00643 insertItems( items );
00644 }
00645 }
00646
00647 void OHistoryCombo::insertItems( const QStringList& items )
00648 {
00649 QStringList::ConstIterator it = items.begin();
00650 QString item;
00651 while ( it != items.end() ) {
00652 item = *it;
00653 if ( !item.isEmpty() ) {
00654 if ( myPixProvider )
00655
00656 insertItem( myPixProvider->pixmapFor(item, 16), item );
00657 else
00658 insertItem( item );
00659 }
00660 ++it;
00661 }
00662 }
00663
00664 void OHistoryCombo::slotClear()
00665 {
00666 clearHistory();
00667 emit cleared();
00668 }
00669