KDEUI
khistorycombobox.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "khistorycombobox.h"
00024
00025 #include <QtGui/QAbstractItemView>
00026 #include <QtGui/QApplication>
00027 #include <QtGui/QKeyEvent>
00028 #include <QtGui/QMenu>
00029 #include <QtGui/QWheelEvent>
00030
00031 #include <klocale.h>
00032 #include <knotification.h>
00033 #include <kpixmapprovider.h>
00034 #include <kstandardshortcut.h>
00035 #include <kicontheme.h>
00036 #include <kicon.h>
00037
00038 #include <kdebug.h>
00039
00040 class KHistoryComboBox::Private
00041 {
00042 public:
00043 Private(KHistoryComboBox *q): q(q), myPixProvider(0) {}
00044
00045 KHistoryComboBox *q;
00046
00050 int myIterateIndex;
00051
00055 QString myText;
00056
00061 bool myRotated;
00062 KPixmapProvider *myPixProvider;
00063 };
00064
00065
00066 KHistoryComboBox::KHistoryComboBox( QWidget *parent )
00067 : KComboBox( true, parent ), d(new Private(this))
00068 {
00069 init( true );
00070 }
00071
00072
00073 KHistoryComboBox::KHistoryComboBox( bool useCompletion,
00074 QWidget *parent )
00075 : KComboBox( true, parent ), d(new Private(this))
00076 {
00077 init( useCompletion );
00078 }
00079
00080 void KHistoryComboBox::init( bool useCompletion )
00081 {
00082
00083 setMaxCount( 50 );
00084
00085 if ( useCompletion )
00086 completionObject()->setOrder( KCompletion::Weighted );
00087
00088 setInsertPolicy( NoInsert );
00089 d->myIterateIndex = -1;
00090 d->myRotated = false;
00091 d->myPixProvider = 0L;
00092
00093
00094 QByteArray histControl = qgetenv("HISTCONTROL");
00095 if ( histControl == "ignoredups" || histControl == "ignoreboth" )
00096 setDuplicatesEnabled( false );
00097
00098 connect(this, SIGNAL(aboutToShowContextMenu(QMenu*)), SLOT(addContextMenuItems(QMenu*)));
00099 connect(this, SIGNAL(activated(int)), SLOT(slotReset()));
00100 connect(this, SIGNAL(returnPressed(QString)), SLOT(slotReset()));
00101
00102
00103
00104 connect(this, SIGNAL(returnPressed(QString)), SLOT(slotSimulateActivated(QString)), Qt::QueuedConnection);
00105 }
00106
00107 KHistoryComboBox::~KHistoryComboBox()
00108 {
00109 delete d->myPixProvider;
00110 delete d;
00111 }
00112
00113 void KHistoryComboBox::setHistoryItems( const QStringList &items )
00114 {
00115 setHistoryItems(items, false);
00116 }
00117
00118 void KHistoryComboBox::setHistoryItems( const QStringList &items,
00119 bool setCompletionList )
00120 {
00121 QStringList insertingItems = items;
00122 KComboBox::clear();
00123
00124
00125 const int itemCount = insertingItems.count();
00126 const int toRemove = itemCount - maxCount();
00127
00128 if (toRemove >= itemCount) {
00129 insertingItems.clear();
00130 } else {
00131 for (int i = 0; i < toRemove; ++i)
00132 insertingItems.pop_front();
00133 }
00134
00135 insertItems( insertingItems );
00136
00137 if ( setCompletionList && useCompletion() ) {
00138
00139 KCompletion *comp = completionObject();
00140 comp->setOrder( KCompletion::Insertion );
00141 comp->setItems( insertingItems );
00142 comp->setOrder( KCompletion::Weighted );
00143 }
00144
00145 clearEditText();
00146 }
00147
00148 QStringList KHistoryComboBox::historyItems() const
00149 {
00150 QStringList list;
00151 const int itemCount = count();
00152 for ( int i = 0; i < itemCount; ++i )
00153 list.append( itemText( i ) );
00154
00155 return list;
00156 }
00157
00158 bool KHistoryComboBox::useCompletion() const
00159 {
00160 return compObj();
00161 }
00162
00163 void KHistoryComboBox::clearHistory()
00164 {
00165 const QString temp = currentText();
00166 KComboBox::clear();
00167 if ( useCompletion() )
00168 completionObject()->clear();
00169 setEditText( temp );
00170 }
00171
00172 void KHistoryComboBox::addContextMenuItems( QMenu* menu )
00173 {
00174 if ( menu )
00175 {
00176 menu->addSeparator();
00177 QAction* clearHistory = menu->addAction( KIcon("edit-clear-history"), i18n("Clear &History"), this, SLOT( slotClear()));
00178 if (!count())
00179 clearHistory->setEnabled(false);
00180 }
00181 }
00182
00183 void KHistoryComboBox::addToHistory( const QString& item )
00184 {
00185 if ( item.isEmpty() || (count() > 0 && item == itemText(0) )) {
00186 return;
00187 }
00188
00189 bool wasCurrent = false;
00190
00191 if ( !duplicatesEnabled() ) {
00192 int i = 0;
00193 int itemCount = count();
00194 while ( i < itemCount ) {
00195 if ( itemText( i ) == item ) {
00196 if ( !wasCurrent )
00197 wasCurrent = ( i == currentIndex() );
00198 removeItem( i );
00199 --itemCount;
00200 } else {
00201 ++i;
00202 }
00203 }
00204 }
00205
00206
00207 if ( d->myPixProvider )
00208 insertItem( 0, d->myPixProvider->pixmapFor(item, KIconLoader::SizeSmall), item);
00209 else
00210 insertItem( 0, item );
00211
00212 if ( wasCurrent )
00213 setCurrentIndex( 0 );
00214
00215 const bool useComp = useCompletion();
00216
00217 const int last = count() - 1;
00218 const int mc = maxCount();
00219 const int stopAt = qMax(mc, 0);
00220
00221 for (int rmIndex = last; rmIndex >= stopAt; --rmIndex) {
00222
00223
00224
00225 const QString rmItem = itemText( rmIndex );
00226 removeItem( rmIndex );
00227 if ( useComp && !contains( rmItem ) )
00228 completionObject()->removeItem( rmItem );
00229 }
00230
00231 if ( useComp )
00232 completionObject()->addItem( item );
00233 }
00234
00235 bool KHistoryComboBox::removeFromHistory( const QString& item )
00236 {
00237 if ( item.isEmpty() )
00238 return false;
00239
00240 bool removed = false;
00241 const QString temp = currentText();
00242 int i = 0;
00243 int itemCount = count();
00244 while ( i < itemCount ) {
00245 if ( item == itemText( i ) ) {
00246 removed = true;
00247 removeItem( i );
00248 --itemCount;
00249 } else {
00250 ++i;
00251 }
00252 }
00253
00254 if ( removed && useCompletion() )
00255 completionObject()->removeItem( item );
00256
00257 setEditText( temp );
00258 return removed;
00259 }
00260
00261 void KHistoryComboBox::rotateUp()
00262 {
00263
00264 if ( d->myIterateIndex == -1 )
00265 d->myText = currentText();
00266
00267 ++d->myIterateIndex;
00268
00269
00270 const int last = count() - 1;
00271 const QString currText = currentText();
00272
00273 while ( d->myIterateIndex < last &&
00274 (currText == itemText( d->myIterateIndex ) ||
00275 itemText( d->myIterateIndex ).isEmpty()) )
00276 ++d->myIterateIndex;
00277
00278 if ( d->myIterateIndex >= count() ) {
00279 d->myRotated = true;
00280 d->myIterateIndex = -1;
00281
00282
00283 if ( count() > 0 && d->myText == itemText(0) )
00284 d->myIterateIndex = 0;
00285
00286 setEditText( d->myText );
00287 }
00288 else
00289 setEditText( itemText( d->myIterateIndex ));
00290 }
00291
00292 void KHistoryComboBox::rotateDown()
00293 {
00294
00295 if ( d->myIterateIndex == -1 )
00296 d->myText = currentText();
00297
00298 --d->myIterateIndex;
00299
00300 const QString currText = currentText();
00301
00302 while ( d->myIterateIndex >= 0 &&
00303 (currText == itemText( d->myIterateIndex ) ||
00304 itemText( d->myIterateIndex ).isEmpty()) )
00305 --d->myIterateIndex;
00306
00307
00308 if ( d->myIterateIndex < 0 ) {
00309 if ( d->myRotated && d->myIterateIndex == -2 ) {
00310 d->myRotated = false;
00311 d->myIterateIndex = count() - 1;
00312 setEditText( itemText(d->myIterateIndex) );
00313 }
00314 else {
00315 if ( d->myIterateIndex == -2 ) {
00316 KNotification::event( "Textcompletion: No Match" ,
00317 i18n("No further item in the history."),
00318 QPixmap() , this, KNotification::DefaultEvent);
00319 }
00320
00321 d->myIterateIndex = -1;
00322 if ( currentText() != d->myText )
00323 setEditText( d->myText );
00324 }
00325 }
00326 else
00327 setEditText( itemText( d->myIterateIndex ));
00328
00329 }
00330
00331 void KHistoryComboBox::keyPressEvent( QKeyEvent *e )
00332 {
00333 int event_key = e->key() | e->modifiers();
00334
00335
00336 if ( KStandardShortcut::rotateUp().contains(event_key) )
00337 rotateUp();
00338
00339
00340
00341 else if ( KStandardShortcut::rotateDown().contains(event_key) )
00342 rotateDown();
00343 else
00344 KComboBox::keyPressEvent( e );
00345 }
00346
00347 void KHistoryComboBox::wheelEvent( QWheelEvent *ev )
00348 {
00349
00350 QAbstractItemView* const iv = view();
00351 if ( iv && iv->isVisible() )
00352 {
00353 QApplication::sendEvent( iv, ev );
00354 return;
00355 }
00356
00357 if ( ev->delta() > 0 ) {
00358 rotateUp();
00359 } else {
00360 rotateDown();
00361 }
00362 ev->accept();
00363 }
00364
00365 void KHistoryComboBox::slotReset()
00366 {
00367 d->myIterateIndex = -1;
00368 d->myRotated = false;
00369 }
00370
00371
00372 void KHistoryComboBox::setPixmapProvider( KPixmapProvider *prov )
00373 {
00374 if ( d->myPixProvider == prov )
00375 return;
00376
00377 delete d->myPixProvider;
00378 d->myPixProvider = prov;
00379
00380
00381
00382
00383 if ( count() > 0 ) {
00384 QStringList items( historyItems() );
00385 clear();
00386 insertItems( items );
00387 }
00388 }
00389
00390 void KHistoryComboBox::insertItems( const QStringList& items )
00391 {
00392 QStringList::ConstIterator it = items.constBegin();
00393 const QStringList::ConstIterator itEnd = items.constEnd();
00394
00395 while ( it != itEnd ) {
00396 const QString item = *it;
00397 if ( !item.isEmpty() ) {
00398 if ( d->myPixProvider )
00399 addItem( d->myPixProvider->pixmapFor(item, KIconLoader::SizeSmall),
00400 item );
00401 else
00402 addItem( item );
00403 }
00404 ++it;
00405 }
00406 }
00407
00408 void KHistoryComboBox::slotClear()
00409 {
00410 clearHistory();
00411 emit cleared();
00412 }
00413
00414 void KHistoryComboBox::slotSimulateActivated( const QString& text )
00415 {
00416
00417
00418
00419
00420 if ((insertPolicy() == NoInsert && findText(text, Qt::MatchFixedString|Qt::MatchCaseSensitive) == -1)) {
00421 emit activated(text);
00422 }
00423
00424
00425
00426
00427
00428 else if (insertPolicy() != InsertAtCurrent && count() >= maxCount()) {
00429 emit activated(text);
00430 }
00431 }
00432
00433 KPixmapProvider *KHistoryComboBox::pixmapProvider() const
00434 {
00435 return d->myPixProvider;
00436 }
00437
00438 void KHistoryComboBox::reset()
00439 {
00440 slotReset();
00441 }
00442
00443 #include "khistorycombobox.moc"