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