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