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