• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • widgets
khistorycombobox.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2
3 Copyright (c) 2000,2001 Dawit Alemayehu <adawit@kde.org>
4 Copyright (c) 2000,2001 Carsten Pfeiffer <pfeiffer@kde.org>
5 Copyright (c) 2000 Stefan Schimanski <1Stein@gmx.de>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License (LGPL) as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "khistorycombobox.h"
24
25#include <QtGui/QAbstractItemView>
26#include <QtGui/QApplication>
27#include <QtGui/QKeyEvent>
28#include <QtGui/QMenu>
29#include <QtGui/QWheelEvent>
30
31#include <klocale.h>
32#include <knotification.h>
33#include <kpixmapprovider.h>
34#include <kstandardshortcut.h>
35#include <kicontheme.h>
36#include <kicon.h>
37
38#include <kdebug.h>
39
40class KHistoryComboBox::Private
41{
42public:
43 Private(KHistoryComboBox *q): q(q), myPixProvider(0) {}
44
45 KHistoryComboBox *q;
46
50 int myIterateIndex;
51
55 QString myText;
56
61 bool myRotated;
62 KPixmapProvider *myPixProvider;
63};
64
65// we are always read-write
66KHistoryComboBox::KHistoryComboBox( QWidget *parent )
67 : KComboBox( true, parent ), d(new Private(this))
68{
69 init( true ); // using completion
70}
71
72// we are always read-write
73KHistoryComboBox::KHistoryComboBox( bool useCompletion,
74 QWidget *parent )
75 : KComboBox( true, parent ), d(new Private(this))
76{
77 init( useCompletion );
78}
79
80void KHistoryComboBox::init( bool useCompletion )
81{
82 // Set a default history size to something reasonable, Qt sets it to INT_MAX by default
83 setMaxCount( 50 );
84
85 if ( useCompletion )
86 completionObject()->setOrder( KCompletion::Weighted );
87
88 setInsertPolicy( NoInsert );
89 d->myIterateIndex = -1;
90 d->myRotated = false;
91 d->myPixProvider = 0L;
92
93 // obey HISTCONTROL setting
94 QByteArray histControl = qgetenv("HISTCONTROL");
95 if ( histControl == "ignoredups" || histControl == "ignoreboth" )
96 setDuplicatesEnabled( false );
97
98 connect(this, SIGNAL(aboutToShowContextMenu(QMenu*)), SLOT(addContextMenuItems(QMenu*)));
99 connect(this, SIGNAL(activated(int)), SLOT(slotReset()));
100 connect(this, SIGNAL(returnPressed(QString)), SLOT(slotReset()));
101 // We want slotSimulateActivated to be called _after_ QComboBoxPrivate::_q_returnPressed
102 // otherwise there's a risk of emitting activated twice (slotSimulateActivated will find
103 // the item, after some app's slotActivated inserted the item into the combo).
104 connect(this, SIGNAL(returnPressed(QString)), SLOT(slotSimulateActivated(QString)), Qt::QueuedConnection);
105}
106
107KHistoryComboBox::~KHistoryComboBox()
108{
109 delete d->myPixProvider;
110 delete d;
111}
112
113void KHistoryComboBox::setHistoryItems( const QStringList &items )
114{
115 setHistoryItems(items, false);
116}
117
118void KHistoryComboBox::setHistoryItems( const QStringList &items,
119 bool setCompletionList )
120{
121 QStringList insertingItems = items;
122 KComboBox::clear();
123
124 // limit to maxCount()
125 const int itemCount = insertingItems.count();
126 const int toRemove = itemCount - maxCount();
127
128 if (toRemove >= itemCount) {
129 insertingItems.clear();
130 } else {
131 for (int i = 0; i < toRemove; ++i)
132 insertingItems.pop_front();
133 }
134
135 insertItems( insertingItems );
136
137 if ( setCompletionList && useCompletion() ) {
138 // we don't have any weighting information here ;(
139 KCompletion *comp = completionObject();
140 comp->setOrder( KCompletion::Insertion );
141 comp->setItems( insertingItems );
142 comp->setOrder( KCompletion::Weighted );
143 }
144
145 clearEditText();
146}
147
148QStringList KHistoryComboBox::historyItems() const
149{
150 QStringList list;
151 const int itemCount = count();
152 for ( int i = 0; i < itemCount; ++i )
153 list.append( itemText( i ) );
154
155 return list;
156}
157
158bool KHistoryComboBox::useCompletion() const
159{
160 return compObj();
161}
162
163void KHistoryComboBox::clearHistory()
164{
165 const QString temp = currentText();
166 KComboBox::clear();
167 if ( useCompletion() )
168 completionObject()->clear();
169 setEditText( temp );
170}
171
172void KHistoryComboBox::addContextMenuItems( QMenu* menu )
173{
174 if ( menu )
175 {
176 menu->addSeparator();
177 QAction* clearHistory = menu->addAction( KIcon("edit-clear-history"), i18n("Clear &History"), this, SLOT(slotClear()));
178 if (!count())
179 clearHistory->setEnabled(false);
180 }
181}
182
183void KHistoryComboBox::addToHistory( const QString& item )
184{
185 if ( item.isEmpty() || (count() > 0 && item == itemText(0) )) {
186 return;
187 }
188
189 bool wasCurrent = false;
190 // remove all existing items before adding
191 if ( !duplicatesEnabled() ) {
192 int i = 0;
193 int itemCount = count();
194 while ( i < itemCount ) {
195 if ( itemText( i ) == item ) {
196 if ( !wasCurrent )
197 wasCurrent = ( i == currentIndex() );
198 removeItem( i );
199 --itemCount;
200 } else {
201 ++i;
202 }
203 }
204 }
205
206 // now add the item
207 if ( d->myPixProvider )
208 insertItem( 0, d->myPixProvider->pixmapFor(item, iconSize().height()), item);
209 else
210 insertItem( 0, item );
211
212 if ( wasCurrent )
213 setCurrentIndex( 0 );
214
215 const bool useComp = useCompletion();
216
217 const int last = count() - 1; // last valid index
218 const int mc = maxCount();
219 const int stopAt = qMax(mc, 0);
220
221 for (int rmIndex = last; rmIndex >= stopAt; --rmIndex) {
222 // remove the last item, as long as we are longer than maxCount()
223 // remove the removed item from the completionObject if it isn't
224 // anymore available at all in the combobox.
225 const QString rmItem = itemText( rmIndex );
226 removeItem( rmIndex );
227 if ( useComp && !contains( rmItem ) )
228 completionObject()->removeItem( rmItem );
229 }
230
231 if ( useComp )
232 completionObject()->addItem( item );
233}
234
235bool KHistoryComboBox::removeFromHistory( const QString& item )
236{
237 if ( item.isEmpty() )
238 return false;
239
240 bool removed = false;
241 const QString temp = currentText();
242 int i = 0;
243 int itemCount = count();
244 while ( i < itemCount ) {
245 if ( item == itemText( i ) ) {
246 removed = true;
247 removeItem( i );
248 --itemCount;
249 } else {
250 ++i;
251 }
252 }
253
254 if ( removed && useCompletion() )
255 completionObject()->removeItem( item );
256
257 setEditText( temp );
258 return removed;
259}
260
261// going up in the history, rotating when reaching QListBox::count()
262//
263// Note: this differs from QComboBox because "up" means ++index here,
264// to simulate the way shell history works (up goes to the most
265// recent item). In QComboBox "down" means ++index, to match the popup...
266//
267void KHistoryComboBox::rotateUp()
268{
269 // save the current text in the lineedit
270 // (This is also where this differs from standard up/down in QComboBox,
271 // where a single keypress can make you lose your typed text)
272 if ( d->myIterateIndex == -1 )
273 d->myText = currentText();
274
275 ++d->myIterateIndex;
276
277 // skip duplicates/empty items
278 const int last = count() - 1; // last valid index
279 const QString currText = currentText();
280
281 while ( d->myIterateIndex < last &&
282 (currText == itemText( d->myIterateIndex ) ||
283 itemText( d->myIterateIndex ).isEmpty()) )
284 ++d->myIterateIndex;
285
286 if ( d->myIterateIndex >= count() ) {
287 d->myRotated = true;
288 d->myIterateIndex = -1;
289
290 // if the typed text is the same as the first item, skip the first
291 if ( count() > 0 && d->myText == itemText(0) )
292 d->myIterateIndex = 0;
293
294 setEditText( d->myText );
295 } else {
296 setCurrentIndex(d->myIterateIndex);
297 }
298}
299
300// going down in the history, no rotation possible. Last item will be
301// the text that was in the lineedit before Up was called.
302void KHistoryComboBox::rotateDown()
303{
304 // save the current text in the lineedit
305 if ( d->myIterateIndex == -1 )
306 d->myText = currentText();
307
308 --d->myIterateIndex;
309
310 const QString currText = currentText();
311 // skip duplicates/empty items
312 while ( d->myIterateIndex >= 0 &&
313 (currText == itemText( d->myIterateIndex ) ||
314 itemText( d->myIterateIndex ).isEmpty()) )
315 --d->myIterateIndex;
316
317
318 if ( d->myIterateIndex < 0 ) {
319 if ( d->myRotated && d->myIterateIndex == -2 ) {
320 d->myRotated = false;
321 d->myIterateIndex = count() - 1;
322 setEditText( itemText(d->myIterateIndex) );
323 }
324 else { // bottom of history
325 if ( d->myIterateIndex == -2 ) {
326 KNotification::event( "Textcompletion: No Match" ,
327 i18n("No further items in the history."),
328 QPixmap() , this, KNotification::DefaultEvent);
329 }
330
331 d->myIterateIndex = -1;
332 if ( currentText() != d->myText )
333 setEditText( d->myText );
334 }
335 } else {
336 setCurrentIndex(d->myIterateIndex);
337 }
338}
339
340void KHistoryComboBox::keyPressEvent( QKeyEvent *e )
341{
342 int event_key = e->key() | e->modifiers();
343
344 if ( KStandardShortcut::rotateUp().contains(event_key) )
345 rotateUp();
346 else if ( KStandardShortcut::rotateDown().contains(event_key) )
347 rotateDown();
348 else
349 KComboBox::keyPressEvent( e );
350}
351
352void KHistoryComboBox::wheelEvent( QWheelEvent *ev )
353{
354 // Pass to poppable listbox if it's up
355 QAbstractItemView* const iv = view();
356 if ( iv && iv->isVisible() )
357 {
358 QApplication::sendEvent( iv, ev );
359 return;
360 }
361 // Otherwise make it change the text without emitting activated
362 if ( ev->delta() > 0 ) {
363 rotateUp();
364 } else {
365 rotateDown();
366 }
367 ev->accept();
368}
369
370void KHistoryComboBox::slotReset()
371{
372 d->myIterateIndex = -1;
373 d->myRotated = false;
374}
375
376
377void KHistoryComboBox::setPixmapProvider( KPixmapProvider *prov )
378{
379 if ( d->myPixProvider == prov )
380 return;
381
382 delete d->myPixProvider;
383 d->myPixProvider = prov;
384
385 // re-insert all the items with/without pixmap
386 // I would prefer to use changeItem(), but that doesn't honor the pixmap
387 // when using an editable combobox (what we do)
388 if ( count() > 0 ) {
389 QStringList items( historyItems() );
390 clear();
391 insertItems( items );
392 }
393}
394
395void KHistoryComboBox::insertItems( const QStringList& items )
396{
397 QStringList::ConstIterator it = items.constBegin();
398 const QStringList::ConstIterator itEnd = items.constEnd();
399
400 while ( it != itEnd ) {
401 const QString item = *it;
402 if ( !item.isEmpty() ) { // only insert non-empty items
403 if ( d->myPixProvider )
404 addItem( d->myPixProvider->pixmapFor(item, iconSize().height()),
405 item );
406 else
407 addItem( item );
408 }
409 ++it;
410 }
411}
412
413void KHistoryComboBox::slotClear()
414{
415 clearHistory();
416 emit cleared();
417}
418
419void KHistoryComboBox::slotSimulateActivated( const QString& text )
420{
421 /* With the insertion policy NoInsert, which we use by default,
422 Qt doesn't emit activated on typed text if the item is not already there,
423 which is perhaps reasonable. Generate the signal ourselves if that's the case.
424 */
425 if ((insertPolicy() == NoInsert && findText(text, Qt::MatchFixedString|Qt::MatchCaseSensitive) == -1)) {
426 emit activated(text);
427 }
428
429 /*
430 Qt also doesn't emit it if the box is full, and policy is not
431 InsertAtCurrent
432 */
433 else if (insertPolicy() != InsertAtCurrent && count() >= maxCount()) {
434 emit activated(text);
435 }
436}
437
438KPixmapProvider *KHistoryComboBox::pixmapProvider() const
439{
440 return d->myPixProvider;
441}
442
443void KHistoryComboBox::reset()
444{
445 slotReset();
446}
447
448#include "khistorycombobox.moc"
KComboBox
An enhanced combo box.
Definition: kcombobox.h:149
KComboBox::contains
bool contains(const QString &text) const
Convenience method which iterates over all items and checks if any of them is equal to text.
Definition: kcombobox.cpp:88
KCompletionBase::compObj
KCompletion * compObj() const
Returns a pointer to the completion object.
Definition: kcompletionbase.cpp:220
KCompletionBase::completionObject
KCompletion * completionObject(bool hsig=true)
Returns a pointer to the current completion object.
Definition: kcompletionbase.cpp:96
KCompletion
A generic class for completing QStrings.
Definition: kcompletion.h:131
KCompletion::setItems
virtual void setItems(const QStringList &list)
Sets the list of items available for completion.
Definition: kcompletion.cpp:99
KCompletion::removeItem
void removeItem(const QString &item)
Removes an item from the list of available completions.
Definition: kcompletion.cpp:208
KCompletion::setOrder
virtual void setOrder(CompOrder order)
KCompletion offers three different ways in which it offers its items:
Definition: kcompletion.cpp:78
KCompletion::Insertion
@ Insertion
Use order of insertion.
Definition: kcompletion.h:144
KCompletion::Weighted
@ Weighted
Use weighted order.
Definition: kcompletion.h:145
KCompletion::clear
virtual void clear()
Removes all inserted items.
Definition: kcompletion.cpp:218
KCompletion::addItem
void addItem(const QString &item)
Adds an item to the list of available completions.
Definition: kcompletion.cpp:146
KHistoryComboBox
A combobox for offering a history and completion.
Definition: khistorycombobox.h:49
KHistoryComboBox::setPixmapProvider
void setPixmapProvider(KPixmapProvider *prov)
Sets a pixmap provider, so that items in the combobox can have a pixmap.
Definition: khistorycombobox.cpp:377
KHistoryComboBox::addToHistory
void addToHistory(const QString &item)
Adds an item to the end of the history list and to the completion list.
Definition: khistorycombobox.cpp:183
KHistoryComboBox::historyItems
QStringList historyItems
Definition: khistorycombobox.h:51
KHistoryComboBox::keyPressEvent
virtual void keyPressEvent(QKeyEvent *)
Handling key-events, the shortcuts to rotate the items.
Definition: khistorycombobox.cpp:340
KHistoryComboBox::removeFromHistory
bool removeFromHistory(const QString &item)
Removes all items named item.
Definition: khistorycombobox.cpp:235
KHistoryComboBox::pixmapProvider
KPixmapProvider * pixmapProvider() const
Definition: khistorycombobox.cpp:438
KHistoryComboBox::clearHistory
void clearHistory()
Clears the history and the completion list.
Definition: khistorycombobox.cpp:163
KHistoryComboBox::~KHistoryComboBox
~KHistoryComboBox()
Destructs the combo, the completion-object and the pixmap-provider.
Definition: khistorycombobox.cpp:107
KHistoryComboBox::KHistoryComboBox
KHistoryComboBox(QWidget *parent=0)
Constructs a "read-write" combobox.
Definition: khistorycombobox.cpp:66
KHistoryComboBox::insertItems
void insertItems(const QStringList &items)
Inserts items into the combo, honoring pixmapProvider() Does not update the completionObject.
Definition: khistorycombobox.cpp:395
KHistoryComboBox::setHistoryItems
void setHistoryItems(const QStringList &items)
Inserts items into the combobox.
Definition: khistorycombobox.cpp:113
KHistoryComboBox::wheelEvent
virtual void wheelEvent(QWheelEvent *ev)
Handling wheel-events, to rotate the items.
Definition: khistorycombobox.cpp:352
KHistoryComboBox::reset
void reset()
Resets the current position of the up/down history.
Definition: khistorycombobox.cpp:443
KHistoryComboBox::useCompletion
bool useCompletion() const
Definition: khistorycombobox.cpp:158
KIcon
A wrapper around QIcon that provides KDE icon features.
Definition: kicon.h:41
KNotification::event
static KNotification * event(const QString &eventId, const QString &title, const QString &text, const QPixmap &pixmap=QPixmap(), QWidget *widget=0L, const NotificationFlags &flags=CloseOnTimeout, const KComponentData &componentData=KComponentData())
emit an event
Definition: knotification.cpp:291
KNotification::DefaultEvent
@ DefaultEvent
Definition: knotification.h:247
KPixmapProvider
A tiny abstract class with just one method: pixmapFor()
Definition: kpixmapprovider.h:39
QAction
QMenu
QWidget
kdebug.h
khistorycombobox.h
kicon.h
kicontheme.h
setEditText
static void setEditText(KLineEdit *edit, const QString &text)
Definition: klineedit.cpp:1454
klocale.h
i18n
QString i18n(const char *text)
knotification.h
kpixmapprovider.h
kstandardshortcut.h
KStandardShortcut::rotateUp
const KShortcut & rotateUp()
Help users iterate through a list of entries.
Definition: kstandardshortcut.cpp:366
KStandardShortcut::rotateDown
const KShortcut & rotateDown()
Help users iterate through a list of entries.
Definition: kstandardshortcut.cpp:367
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal