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

KDEUI

  • kdeui
  • util
kcompletion.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (C) 1999,2000,2001 Carsten Pfeiffer <pfeiffer@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20
21#include "kcompletion.h"
22#include "kcompletion_p.h"
23
24#include <kdebug.h>
25#include <klocale.h>
26#include <knotification.h>
27#include <kglobal.h>
28#include <kstringhandler.h>
29#include <QtCore/QMutableVectorIterator>
30
31class KCompletionPrivate
32{
33public:
34 KCompletionPrivate()
35 : myCompletionMode( KGlobalSettings::completionMode() )
36 , myTreeNodeAllocator( KCompTreeNode::allocator() ) // keep strong-ref to allocator instance
37 , myTreeRoot( new KCompTreeNode )
38 , myBeep( true )
39 , myIgnoreCase( false )
40 , myHasMultipleMatches( false )
41 , myRotationIndex( 0 )
42 {
43 }
44 ~KCompletionPrivate()
45 {
46 delete myTreeRoot;
47 }
48 // list used for nextMatch() and previousMatch()
49 KCompletionMatchesWrapper matches;
50
51 KGlobalSettings::Completion myCompletionMode;
52
53 QSharedPointer<KZoneAllocator> myTreeNodeAllocator;
54
55 KCompletion::CompOrder myOrder;
56 QString myLastString;
57 QString myLastMatch;
58 QString myCurrentMatch;
59 KCompTreeNode * myTreeRoot;
60 //QStringList myRotations;
61 bool myBeep : 1;
62 bool myIgnoreCase : 1;
63 bool myHasMultipleMatches;
64 int myRotationIndex;
65};
66
67KCompletion::KCompletion()
68 :d(new KCompletionPrivate)
69{
70 setOrder( Insertion );
71}
72
73KCompletion::~KCompletion()
74{
75 delete d;
76}
77
78void KCompletion::setOrder( CompOrder order )
79{
80 d->myOrder = order;
81 d->matches.setSorting( order );
82}
83
84KCompletion::CompOrder KCompletion::order() const
85{
86 return d->myOrder;
87}
88
89void KCompletion::setIgnoreCase( bool ignoreCase )
90{
91 d->myIgnoreCase = ignoreCase;
92}
93
94bool KCompletion::ignoreCase() const
95{
96 return d->myIgnoreCase;
97}
98
99void KCompletion::setItems( const QStringList& items )
100{
101 clear();
102 insertItems( items );
103}
104
105
106void KCompletion::insertItems( const QStringList& items )
107{
108 bool weighted = (d->myOrder == Weighted);
109 QStringList::ConstIterator it;
110 if ( weighted ) { // determine weight
111 for ( it = items.begin(); it != items.end(); ++it )
112 addWeightedItem( *it );
113 }
114 else {
115 for ( it = items.begin(); it != items.end(); ++it )
116 addItem( *it, 0 );
117 }
118}
119
120QStringList KCompletion::items() const
121{
122 KCompletionMatchesWrapper list; // unsorted
123 bool addWeight = (d->myOrder == Weighted);
124 extractStringsFromNode( d->myTreeRoot, QString(), &list, addWeight );
125
126 return list.list();
127}
128
129bool KCompletion::isEmpty() const
130{
131 return (d->myTreeRoot->childrenCount() == 0);
132}
133
134void KCompletion::postProcessMatch( QString * ) const
135{
136}
137
138void KCompletion::postProcessMatches( QStringList * ) const
139{
140}
141
142void KCompletion::postProcessMatches( KCompletionMatches * ) const
143{
144}
145
146void KCompletion::addItem( const QString& item )
147{
148 d->matches.clear();
149 d->myRotationIndex = 0;
150 d->myLastString.clear();
151
152 addItem( item, 0 );
153}
154
155void KCompletion::addItem( const QString& item, uint weight )
156{
157 if ( item.isEmpty() )
158 return;
159
160 KCompTreeNode *node = d->myTreeRoot;
161 uint len = item.length();
162
163 bool sorted = (d->myOrder == Sorted);
164 bool weighted = ((d->myOrder == Weighted) && weight > 1);
165
166 // knowing the weight of an item, we simply add this weight to all of its
167 // nodes.
168
169 for ( uint i = 0; i < len; i++ ) {
170 node = node->insert( item.at(i), sorted );
171 if ( weighted )
172 node->confirm( weight -1 ); // node->insert() sets weighting to 1
173 }
174
175 // add 0x0-item as delimiter with evtl. weight
176 node = node->insert( 0x0, true );
177 if ( weighted )
178 node->confirm( weight -1 );
179// qDebug("*** added: %s (%i)", item.toLatin1().constData(), node->weight());
180}
181
182void KCompletion::addWeightedItem( const QString& item )
183{
184 if ( d->myOrder != Weighted ) {
185 addItem( item, 0 );
186 return;
187 }
188
189 uint len = item.length();
190 uint weight = 0;
191
192 // find out the weighting of this item (appended to the string as ":num")
193 int index = item.lastIndexOf(':');
194 if ( index > 0 ) {
195 bool ok;
196 weight = item.mid( index + 1 ).toUInt( &ok );
197 if ( !ok )
198 weight = 0;
199
200 len = index; // only insert until the ':'
201 }
202
203 addItem( item.left( len ), weight );
204 return;
205}
206
207
208void KCompletion::removeItem( const QString& item )
209{
210 d->matches.clear();
211 d->myRotationIndex = 0;
212 d->myLastString.clear();
213
214 d->myTreeRoot->remove( item );
215}
216
217
218void KCompletion::clear()
219{
220 d->matches.clear();
221 d->myRotationIndex = 0;
222 d->myLastString.clear();
223
224 delete d->myTreeRoot;
225 d->myTreeRoot = new KCompTreeNode;
226}
227
228
229QString KCompletion::makeCompletion( const QString& string )
230{
231 if ( d->myCompletionMode == KGlobalSettings::CompletionNone )
232 return QString();
233
234 //kDebug(0) << "KCompletion: completing: " << string;
235
236 d->matches.clear();
237 d->myRotationIndex = 0;
238 d->myHasMultipleMatches = false;
239 d->myLastMatch = d->myCurrentMatch;
240
241 // in Shell-completion-mode, emit all matches when we get the same
242 // complete-string twice
243 if ( d->myCompletionMode == KGlobalSettings::CompletionShell &&
244 string == d->myLastString ) {
245 // Don't use d->matches since calling postProcessMatches()
246 // on d->matches here would interfere with call to
247 // postProcessMatch() during rotation
248
249 findAllCompletions( string, &d->matches, d->myHasMultipleMatches );
250 QStringList l = d->matches.list();
251 postProcessMatches( &l );
252 emit matches( l );
253
254 if ( l.isEmpty() )
255 doBeep( NoMatch );
256
257 return QString();
258 }
259
260 QString completion;
261 // in case-insensitive popup mode, we search all completions at once
262 if ( d->myCompletionMode == KGlobalSettings::CompletionPopup ||
263 d->myCompletionMode == KGlobalSettings::CompletionPopupAuto ) {
264 findAllCompletions( string, &d->matches, d->myHasMultipleMatches );
265 if ( !d->matches.isEmpty() )
266 completion = d->matches.first();
267 }
268 else
269 completion = findCompletion( string );
270
271 if ( d->myHasMultipleMatches )
272 emit multipleMatches();
273
274 d->myLastString = string;
275 d->myCurrentMatch = completion;
276
277 postProcessMatch( &completion );
278
279 if ( !string.isEmpty() ) { // only emit match when string is not empty
280 //kDebug(0) << "KCompletion: Match: " << completion;
281 emit match( completion );
282 }
283
284 if ( completion.isNull() )
285 doBeep( NoMatch );
286
287 return completion;
288}
289
290
291
292QStringList KCompletion::substringCompletion( const QString& string ) const
293{
294 // get all items in the tree, eventually in sorted order
295 KCompletionMatchesWrapper allItems( d->myOrder );
296 extractStringsFromNode( d->myTreeRoot, QString(), &allItems, false );
297
298 QStringList list = allItems.list();
299
300 // subStringMatches is invoked manually, via a shortcut, so we should
301 // beep here, if necessary.
302 if ( list.isEmpty() ) {
303 doBeep( NoMatch );
304 return list;
305 }
306
307 if ( string.isEmpty() ) { // shortcut
308 postProcessMatches( &list );
309 return list;
310 }
311
312 QStringList matches;
313 QStringList::ConstIterator it = list.constBegin();
314
315 for( ; it != list.constEnd(); ++it ) {
316 QString item = *it;
317 if ( item.indexOf( string, 0, Qt::CaseInsensitive ) != -1 ) { // always case insensitive
318 postProcessMatch( &item );
319 matches.append( item );
320 }
321 }
322
323 if ( matches.isEmpty() )
324 doBeep( NoMatch );
325
326 return matches;
327}
328
329
330void KCompletion::setCompletionMode( KGlobalSettings::Completion mode )
331{
332 d->myCompletionMode = mode;
333}
334
335KGlobalSettings::Completion KCompletion::completionMode() const {
336 return d->myCompletionMode;
337}
338
339QStringList KCompletion::allMatches()
340{
341 // Don't use d->matches since calling postProcessMatches()
342 // on d->matches here would interfere with call to
343 // postProcessMatch() during rotation
344 KCompletionMatchesWrapper matches( d->myOrder );
345 bool dummy;
346 findAllCompletions( d->myLastString, &matches, dummy );
347 QStringList l = matches.list();
348 postProcessMatches( &l );
349 return l;
350}
351
352KCompletionMatches KCompletion::allWeightedMatches()
353{
354 // Don't use d->matches since calling postProcessMatches()
355 // on d->matches here would interfere with call to
356 // postProcessMatch() during rotation
357 KCompletionMatchesWrapper matches( d->myOrder );
358 bool dummy;
359 findAllCompletions( d->myLastString, &matches, dummy );
360 KCompletionMatches ret( matches );
361 postProcessMatches( &ret );
362 return ret;
363}
364
365QStringList KCompletion::allMatches( const QString &string )
366{
367 KCompletionMatchesWrapper matches( d->myOrder );
368 bool dummy;
369 findAllCompletions( string, &matches, dummy );
370 QStringList l = matches.list();
371 postProcessMatches( &l );
372 return l;
373}
374
375KCompletionMatches KCompletion::allWeightedMatches( const QString &string )
376{
377 KCompletionMatchesWrapper matches( d->myOrder );
378 bool dummy;
379 findAllCompletions( string, &matches, dummy );
380 KCompletionMatches ret( matches );
381 postProcessMatches( &ret );
382 return ret;
383}
384
385void KCompletion::setSoundsEnabled( bool enable )
386{
387 d->myBeep = enable;
388}
389
390bool KCompletion::soundsEnabled() const
391{
392 return d->myBeep;
393}
394
395bool KCompletion::hasMultipleMatches() const
396{
397 return d->myHasMultipleMatches;
398}
399
402
403
404QString KCompletion::nextMatch()
405{
406 QString completion;
407 d->myLastMatch = d->myCurrentMatch;
408
409 if ( d->matches.isEmpty() ) {
410 findAllCompletions( d->myLastString, &d->matches, d->myHasMultipleMatches );
411 if ( !d->matches.isEmpty() )
412 completion = d->matches.first();
413 d->myCurrentMatch = completion;
414 d->myRotationIndex = 0;
415 postProcessMatch( &completion );
416 emit match( completion );
417 return completion;
418 }
419
420 QStringList matches = d->matches.list();
421 d->myLastMatch = matches[ d->myRotationIndex++ ];
422
423 if ( d->myRotationIndex == matches.count() -1 )
424 doBeep( Rotation ); // indicate last matching item -> rotating
425
426 else if ( d->myRotationIndex == matches.count() )
427 d->myRotationIndex = 0;
428
429 completion = matches[ d->myRotationIndex ];
430 d->myCurrentMatch = completion;
431 postProcessMatch( &completion );
432 emit match( completion );
433 return completion;
434}
435
436const QString& KCompletion::lastMatch() const
437{
438 return d->myLastMatch;
439}
440
441
442QString KCompletion::previousMatch()
443{
444 QString completion;
445 d->myLastMatch = d->myCurrentMatch;
446
447 if ( d->matches.isEmpty() ) {
448 findAllCompletions( d->myLastString, &d->matches, d->myHasMultipleMatches );
449 if ( !d->matches.isEmpty() )
450 completion = d->matches.last();
451 d->myCurrentMatch = completion;
452 d->myRotationIndex = 0;
453 postProcessMatch( &completion );
454 emit match( completion );
455 return completion;
456 }
457
458 QStringList matches = d->matches.list();
459 d->myLastMatch = matches[ d->myRotationIndex ];
460 if ( d->myRotationIndex == 1 )
461 doBeep( Rotation ); // indicate first item -> rotating
462
463 else if ( d->myRotationIndex == 0 )
464 d->myRotationIndex = matches.count();
465
466 d->myRotationIndex--;
467
468 completion = matches[ d->myRotationIndex ];
469 d->myCurrentMatch = completion;
470 postProcessMatch( &completion );
471 emit match( completion );
472 return completion;
473}
474
475
476
477// tries to complete "string" from the tree-root
478QString KCompletion::findCompletion( const QString& string )
479{
480 QChar ch;
481 QString completion;
482 const KCompTreeNode *node = d->myTreeRoot;
483
484 // start at the tree-root and try to find the search-string
485 for( int i = 0; i < string.length(); i++ ) {
486 ch = string.at( i );
487 node = node->find( ch );
488
489 if ( node )
490 completion += ch;
491 else
492 return QString(); // no completion
493 }
494
495 // Now we have the last node of the to be completed string.
496 // Follow it as long as it has exactly one child (= longest possible
497 // completion)
498
499 while ( node->childrenCount() == 1 ) {
500 node = node->firstChild();
501 if ( !node->isNull() )
502 completion += *node;
503 }
504 // if multiple matches and auto-completion mode
505 // -> find the first complete match
506 if ( node && node->childrenCount() > 1 ) {
507 d->myHasMultipleMatches = true;
508
509 if ( d->myCompletionMode == KGlobalSettings::CompletionAuto ) {
510 d->myRotationIndex = 1;
511 if (d->myOrder != Weighted) {
512 while ( (node = node->firstChild()) ) {
513 if ( !node->isNull() )
514 completion += *node;
515 else
516 break;
517 }
518 }
519 else {
520 // don't just find the "first" match, but the one with the
521 // highest priority
522
523 const KCompTreeNode* temp_node = 0L;
524 while(1) {
525 int count = node->childrenCount();
526 temp_node = node->firstChild();
527 uint weight = temp_node->weight();
528 const KCompTreeNode* hit = temp_node;
529 for( int i = 1; i < count; i++ ) {
530 temp_node = node->childAt(i);
531 if( temp_node->weight() > weight ) {
532 hit = temp_node;
533 weight = hit->weight();
534 }
535 }
536 // 0x0 has the highest priority -> we have the best match
537 if ( hit->isNull() )
538 break;
539
540 node = hit;
541 completion += *node;
542 }
543 }
544 }
545
546 else
547 doBeep( PartialMatch ); // partial match -> beep
548 }
549
550 return completion;
551}
552
553
554void KCompletion::findAllCompletions(const QString& string,
555 KCompletionMatchesWrapper *matches,
556 bool& hasMultipleMatches) const
557{
558 //kDebug(0) << "*** finding all completions for " << string;
559
560 if ( string.isEmpty() )
561 return;
562
563 if ( d->myIgnoreCase ) { // case insensitive completion
564 extractStringsFromNodeCI( d->myTreeRoot, QString(), string, matches );
565 hasMultipleMatches = (matches->count() > 1);
566 return;
567 }
568
569 QChar ch;
570 QString completion;
571 const KCompTreeNode *node = d->myTreeRoot;
572
573 // start at the tree-root and try to find the search-string
574 for( int i = 0; i < string.length(); i++ ) {
575 ch = string.at( i );
576 node = node->find( ch );
577
578 if ( node )
579 completion += ch;
580 else
581 return; // no completion -> return empty list
582 }
583
584 // Now we have the last node of the to be completed string.
585 // Follow it as long as it has exactly one child (= longest possible
586 // completion)
587
588 while ( node->childrenCount() == 1 ) {
589 node = node->firstChild();
590 if ( !node->isNull() )
591 completion += *node;
592 // kDebug() << completion << node->latin1();
593 }
594
595
596 // there is just one single match)
597 if ( node->childrenCount() == 0 )
598 matches->append( node->weight(), completion );
599
600 else {
601 // node has more than one child
602 // -> recursively find all remaining completions
603 hasMultipleMatches = true;
604 extractStringsFromNode( node, completion, matches );
605 }
606}
607
608
609void KCompletion::extractStringsFromNode( const KCompTreeNode *node,
610 const QString& beginning,
611 KCompletionMatchesWrapper *matches,
612 bool addWeight ) const
613{
614 if ( !node || !matches )
615 return;
616
617 // kDebug() << "Beginning: " << beginning;
618 const KCompTreeChildren *list = node->children();
619 QString string;
620 QString w;
621
622 // loop thru all children
623 for ( KCompTreeNode *cur = list->begin(); cur ; cur = cur->next) {
624 string = beginning;
625 node = cur;
626 if ( !node->isNull() )
627 string += *node;
628
629 while ( node && node->childrenCount() == 1 ) {
630 node = node->firstChild();
631 if ( node->isNull() )
632 break;
633 string += *node;
634 }
635
636 if ( node && node->isNull() ) { // we found a leaf
637 if ( addWeight ) {
638 // add ":num" to the string to store the weighting
639 string += ':';
640 w.setNum( node->weight() );
641 string.append( w );
642 }
643 matches->append( node->weight(), string );
644 }
645
646 // recursively find all other strings.
647 if ( node && node->childrenCount() > 1 )
648 extractStringsFromNode( node, string, matches, addWeight );
649 }
650}
651
652void KCompletion::extractStringsFromNodeCI( const KCompTreeNode *node,
653 const QString& beginning,
654 const QString& restString,
655 KCompletionMatchesWrapper *matches ) const
656{
657 if ( restString.isEmpty() ) {
658 extractStringsFromNode( node, beginning, matches, false /*noweight*/ );
659 return;
660 }
661
662 QChar ch1 = restString.at(0);
663 QString newRest = restString.mid(1);
664 KCompTreeNode *child1, *child2;
665
666 child1 = node->find( ch1 ); // the correct match
667 if ( child1 )
668 extractStringsFromNodeCI( child1, beginning + QChar(*child1), newRest,
669 matches );
670
671 // append the case insensitive matches, if available
672 if ( ch1.isLetter() ) {
673 // find out if we have to lower or upper it. Is there a better way?
674 QChar ch2 = ch1.toLower();
675 if ( ch1 == ch2 )
676 ch2 = ch1.toUpper();
677 if ( ch1 != ch2 ) {
678 child2 = node->find( ch2 );
679 if ( child2 )
680 extractStringsFromNodeCI( child2, beginning + QChar(*child2), newRest,
681 matches );
682 }
683 }
684}
685
686void KCompletion::doBeep( BeepMode mode ) const
687{
688 if ( !d->myBeep )
689 return;
690
691 QString text, event;
692
693 switch ( mode ) {
694 case Rotation:
695 event = QLatin1String("Textcompletion: rotation");
696 text = i18n("You reached the end of the list\nof matching items.\n");
697 break;
698 case PartialMatch:
699 if ( d->myCompletionMode == KGlobalSettings::CompletionShell ||
700 d->myCompletionMode == KGlobalSettings::CompletionMan ) {
701 event = QLatin1String("Textcompletion: partial match");
702 text = i18n("The completion is ambiguous, more than one\nmatch is available.\n");
703 }
704 break;
705 case NoMatch:
706 if ( d->myCompletionMode == KGlobalSettings::CompletionShell ) {
707 event = QLatin1String("Textcompletion: no match");
708 text = i18n("There is no matching item available.\n");
709 }
710 break;
711 }
712
713 if ( !text.isEmpty() )
714 {
715 KNotification::event( event, text , QPixmap() , 0L , KNotification::DefaultEvent );
716 }
717}
718
719
722
723
724// Implements the tree. Every node is a QChar and has a list of children, which
725// are Nodes as well.
726// QChar( 0x0 ) is used as the delimiter of a string; the last child of each
727// inserted string is 0x0.
728
729KCompTreeNode::~KCompTreeNode()
730{
731 // delete all children
732 KCompTreeNode *cur = myChildren.begin();
733 while (cur) {
734 KCompTreeNode * next = cur->next;
735 delete myChildren.remove(cur);
736 cur = next;
737 }
738}
739
740
741// Adds a child-node "ch" to this node. If such a node is already existent,
742// it will not be created. Returns the new/existing node.
743KCompTreeNode * KCompTreeNode::insert( const QChar& ch, bool sorted )
744{
745 KCompTreeNode *child = find( ch );
746 if ( !child ) {
747 child = new KCompTreeNode( ch );
748
749 // FIXME, first (slow) sorted insertion implementation
750 if ( sorted ) {
751 KCompTreeNode * prev = 0;
752 KCompTreeNode * cur = myChildren.begin();
753 while ( cur ) {
754 if ( ch > *cur ) {
755 prev = cur;
756 cur = cur->next;
757 } else
758 break;
759 }
760 if (prev)
761 myChildren.insert( prev, child );
762 else
763 myChildren.prepend(child);
764 }
765
766 else
767 myChildren.append( child );
768 }
769
770 // implicit weighting: the more often an item is inserted, the higher
771 // priority it gets.
772 child->confirm();
773
774 return child;
775}
776
777
778// Iteratively removes a string from the tree. The nicer recursive
779// version apparently was a little memory hungry (see #56757)
780void KCompTreeNode::remove( const QString& str )
781{
782 QString string = str;
783 string += QChar(0x0);
784
785 QVector<KCompTreeNode *> deletables( string.length() + 1 );
786
787 KCompTreeNode *child = 0L;
788 KCompTreeNode *parent = this;
789 deletables.replace( 0, parent );
790
791 int i = 0;
792 for ( ; i < string.length(); i++ )
793 {
794 child = parent->find( string.at( i ) );
795 if ( child )
796 deletables.replace( i + 1, child );
797 else
798 break;
799
800 parent = child;
801 }
802
803 for ( ; i >= 1; i-- )
804 {
805 parent = deletables.at( i - 1 );
806 child = deletables.at( i );
807 if ( child->myChildren.count() == 0 )
808 delete parent->myChildren.remove( child );
809 }
810}
811
812bool lessThan( const QString &left, const QString &right )
813{
814 return KStringHandler::naturalCompare( left, right ) < 0;
815}
816
817QStringList KCompletionMatchesWrapper::list() const
818{
819 if ( sortedList && dirty ) {
820 sortedList->sort();
821 dirty = false;
822
823 stringList.clear();
824
825 // high weight == sorted last -> reverse the sorting here
826 QList<KSortableItem<QString> >::const_iterator it;
827 for ( it = sortedList->constBegin(); it != sortedList->constEnd(); ++it )
828 stringList.prepend( (*it).value() );
829 } else if ( compOrder == KCompletion::Sorted ) {
830 qStableSort(stringList.begin(), stringList.end(), lessThan);
831 }
832
833 return stringList;
834}
835
836class KCompletionMatchesPrivate
837{
838public:
839 KCompletionMatchesPrivate( bool sort )
840 : sorting( sort )
841 {}
842 bool sorting;
843};
844
845KCompletionMatches::KCompletionMatches( const KCompletionMatches &o )
846 : KSortableList<QString, int>(),
847 d( new KCompletionMatchesPrivate( o.d->sorting ) )
848{
849 *this = KCompletionMatches::operator=( o );
850}
851
852KCompletionMatches &KCompletionMatches::operator=( const KCompletionMatches &o )
853{
854 if( *this == o )
855 return *this;
856 KCompletionMatchesList::operator=( o );
857 d->sorting = o.d->sorting;
858
859 return *this;
860}
861
862KCompletionMatches::KCompletionMatches( bool sort_P )
863 : d( new KCompletionMatchesPrivate( sort_P ) )
864{
865}
866
867KCompletionMatches::KCompletionMatches( const KCompletionMatchesWrapper& matches )
868 : d( new KCompletionMatchesPrivate( matches.sorting() ) )
869{
870 if( matches.sortedList != 0L )
871 KCompletionMatchesList::operator=( *matches.sortedList );
872 else {
873 const QStringList l = matches.list();
874 for( QStringList::ConstIterator it = l.begin();
875 it != l.end();
876 ++it )
877 prepend( KSortableItem<QString, int>( 1, *it ) );
878 }
879}
880
881KCompletionMatches::~KCompletionMatches()
882{
883 delete d;
884}
885
886QStringList KCompletionMatches::list( bool sort_P ) const
887{
888 if( d->sorting && sort_P )
889 const_cast< KCompletionMatches* >( this )->sort();
890 QStringList stringList;
891 // high weight == sorted last -> reverse the sorting here
892 for ( ConstIterator it = begin(); it != end(); ++it )
893 stringList.prepend( (*it).value() );
894 return stringList;
895}
896
897bool KCompletionMatches::sorting() const
898{
899 return d->sorting;
900}
901
902void KCompletionMatches::removeDuplicates()
903{
904 Iterator it1, it2;
905 for ( it1 = begin(); it1 != end(); ++it1 ) {
906 for ( (it2 = it1), ++it2; it2 != end();) {
907 if( (*it1).value() == (*it2).value()) {
908 // use the max height
909 (*it1).first = qMax( (*it1).key(), (*it2).key());
910 it2 = erase( it2 );
911 continue;
912 }
913 ++it2;
914 }
915 }
916}
917
918void KCompTreeNodeList::append(KCompTreeNode *item)
919{
920 m_count++;
921 if (!last) {
922 last = item;
923 last->next = 0;
924 first = item;
925 return;
926 }
927 last->next = item;
928 item->next = 0;
929 last = item;
930}
931
932void KCompTreeNodeList::prepend(KCompTreeNode *item)
933{
934 m_count++;
935 if (!last) {
936 last = item;
937 last->next = 0;
938 first = item;
939 return;
940 }
941 item->next = first;
942 first = item;
943}
944
945void KCompTreeNodeList::insert(KCompTreeNode *after, KCompTreeNode *item)
946{
947 if (!after) {
948 append(item);
949 return;
950 }
951
952 m_count++;
953
954 item->next = after->next;
955 after->next = item;
956
957 if (after == last)
958 last = item;
959}
960
961KCompTreeNode *KCompTreeNodeList::remove(KCompTreeNode *item)
962{
963 if (!first || !item)
964 return 0;
965 KCompTreeNode *cur = 0;
966
967 if (item == first)
968 first = first->next;
969 else {
970 cur = first;
971 while (cur && cur->next != item) cur = cur->next;
972 if (!cur)
973 return 0;
974 cur->next = item->next;
975 }
976 if (item == last)
977 last = cur;
978 m_count--;
979 return item;
980}
981
982KCompTreeNode *KCompTreeNodeList::at(uint index) const
983{
984 KCompTreeNode *cur = first;
985 while (index-- && cur) cur = cur->next;
986 return cur;
987}
988
989QSharedPointer<KZoneAllocator> KCompTreeNode::alloc(new KZoneAllocator(8*1024));
990
991#include "kcompletion.moc"
KCompletionMatches
This structure is returned by KCompletion::allWeightedMatches .
Definition: kcompletion.h:580
KCompletionMatches::KCompletionMatches
KCompletionMatches(bool sort)
Default constructor.
Definition: kcompletion.cpp:862
KCompletionMatches::list
QStringList list(bool sort=true) const
Returns the matches as a QStringList.
Definition: kcompletion.cpp:886
KCompletionMatches::removeDuplicates
void removeDuplicates()
Removes duplicate matches.
Definition: kcompletion.cpp:902
KCompletionMatches::sorting
bool sorting() const
If sorting() returns false, the matches aren't sorted by their weight, even if true is passed to list...
Definition: kcompletion.cpp:897
KCompletionMatches::~KCompletionMatches
~KCompletionMatches()
default destructor.
Definition: kcompletion.cpp:881
KCompletionMatches::operator=
KCompletionMatches & operator=(const KCompletionMatches &)
assignment operator.
Definition: kcompletion.cpp:852
KCompletion::setItems
virtual void setItems(const QStringList &list)
Sets the list of items available for completion.
Definition: kcompletion.cpp:99
KCompletion::nextMatch
QString nextMatch()
Returns the next item from the matching-items-list.
Definition: kcompletion.cpp:404
KCompletion::order
CompOrder order
Definition: kcompletion.h:133
KCompletion::insertItems
void insertItems(const QStringList &items)
Inserts items into the list of possible completions.
Definition: kcompletion.cpp:106
KCompletion::completionMode
KGlobalSettings::Completion completionMode() const
Return the current completion mode.
Definition: kcompletion.cpp:335
KCompletion::removeItem
void removeItem(const QString &item)
Removes an item from the list of available completions.
Definition: kcompletion.cpp:208
KCompletion::multipleMatches
void multipleMatches()
This signal is emitted, when calling makeCompletion() and more than one matching item is found.
KCompletion::makeCompletion
virtual QString makeCompletion(const QString &string)
Attempts to find an item in the list of available completions, that begins with string.
Definition: kcompletion.cpp:229
KCompletion::soundsEnabled
bool soundsEnabled() const
Tells you whether KCompletion will play sounds on certain occasions.
Definition: kcompletion.cpp:390
KCompletion::isEmpty
bool isEmpty() const
Returns true when the completion object contains no entries.
Definition: kcompletion.cpp:129
KCompletion::matches
void matches(const QStringList &matchlist)
All matching items.
KCompletion::allMatches
QStringList allMatches()
Returns a list of all items matching the last completed string.
Definition: kcompletion.cpp:339
KCompletion::KCompletion
KCompletion()
Constructor, nothing special here :)
Definition: kcompletion.cpp:67
KCompletion::setOrder
virtual void setOrder(CompOrder order)
KCompletion offers three different ways in which it offers its items:
Definition: kcompletion.cpp:78
KCompletion::setSoundsEnabled
virtual void setSoundsEnabled(bool enable)
Enables/disables playing a sound when.
Definition: kcompletion.cpp:385
KCompletion::CompOrder
CompOrder
Constants that represent the order in which KCompletion performs completion-lookups.
Definition: kcompletion.h:143
KCompletion::Insertion
@ Insertion
Use order of insertion.
Definition: kcompletion.h:144
KCompletion::Weighted
@ Weighted
Use weighted order.
Definition: kcompletion.h:145
KCompletion::Sorted
@ Sorted
Use alphabetically sorted order.
Definition: kcompletion.h:143
KCompletion::substringCompletion
QStringList substringCompletion(const QString &string) const
Returns a list of all completion items that contain the given string.
Definition: kcompletion.cpp:292
KCompletion::ignoreCase
bool ignoreCase
Definition: kcompletion.h:134
KCompletion::items
QStringList items
Definition: kcompletion.h:135
KCompletion::setIgnoreCase
virtual void setIgnoreCase(bool ignoreCase)
Setting this to true makes KCompletion behave case insensitively.
Definition: kcompletion.cpp:89
KCompletion::previousMatch
QString previousMatch()
Returns the next item from the matching-items-list.
Definition: kcompletion.cpp:442
KCompletion::clear
virtual void clear()
Removes all inserted items.
Definition: kcompletion.cpp:218
KCompletion::match
void match(const QString &item)
The matching item.
KCompletion::setCompletionMode
virtual void setCompletionMode(KGlobalSettings::Completion mode)
Sets the completion mode to Auto/Manual, Shell or None.
Definition: kcompletion.cpp:330
KCompletion::addItem
void addItem(const QString &item)
Adds an item to the list of available completions.
Definition: kcompletion.cpp:146
KCompletion::hasMultipleMatches
bool hasMultipleMatches() const
Returns true when more than one match is found.
Definition: kcompletion.cpp:395
KCompletion::postProcessMatch
virtual void postProcessMatch(QString *pMatch) const
This method is called after a completion is found and before the matching string is emitted.
Definition: kcompletion.cpp:134
KCompletion::lastMatch
virtual const QString & lastMatch() const
Returns the last match.
Definition: kcompletion.cpp:436
KCompletion::allWeightedMatches
KCompletionMatches allWeightedMatches()
Returns a list of all items matching the last completed string.
Definition: kcompletion.cpp:352
KCompletion::postProcessMatches
virtual void postProcessMatches(QStringList *pMatches) const
This method is called before a list of all available completions is emitted via #matches.
Definition: kcompletion.cpp:138
KCompletion::~KCompletion
virtual ~KCompletion()
Destructor, nothing special here, either.
Definition: kcompletion.cpp:73
KGlobalSettings
Access the KDE global configuration.
Definition: kglobalsettings.h:59
KGlobalSettings::Completion
Completion
This enum describes the completion mode used for by the KCompletion class.
Definition: kglobalsettings.h:179
KGlobalSettings::CompletionPopup
@ CompletionPopup
Lists all possible matches in a popup list-box to choose from.
Definition: kglobalsettings.h:199
KGlobalSettings::CompletionShell
@ CompletionShell
Complete text much in the same way as a typical *nix shell would.
Definition: kglobalsettings.h:195
KGlobalSettings::CompletionMan
@ CompletionMan
Same as automatic except shortest match is used for completion.
Definition: kglobalsettings.h:191
KGlobalSettings::CompletionAuto
@ CompletionAuto
Text is automatically filled in whenever possible.
Definition: kglobalsettings.h:187
KGlobalSettings::CompletionNone
@ CompletionNone
No completion is used.
Definition: kglobalsettings.h:183
KGlobalSettings::CompletionPopupAuto
@ CompletionPopupAuto
Lists all possible matches in a popup list-box to choose from, and automatically fill the result when...
Definition: kglobalsettings.h:204
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
KSortableItem
KSortableList
KSortableList::sort
void sort()
KZoneAllocator
QList
lessThan
bool lessThan(const QString &left, const QString &right)
Definition: kcompletion.cpp:812
kcompletion.h
kdebug.h
kglobal.h
klocale.h
i18n
QString i18n(const char *text)
knotification.h
kstringhandler.h
KStandardAction::next
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
Scroll down one page.
Definition: kstandardaction.cpp:414
KStandardAction::find
KAction * find(const QObject *recvr, const char *slot, QObject *parent)
Initiate a 'find' request in the current document.
Definition: kstandardaction.cpp:329
KStandardGuiItem::ok
KGuiItem ok()
Returns the 'Ok' gui item.
Definition: kstandardguiitem.cpp:107
KStandardShortcut::completion
const KShortcut & completion()
Complete text in input widgets.
Definition: kstandardshortcut.cpp:363
KStringHandler::naturalCompare
int naturalCompare(const QString &a, const QString &b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
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