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

KDEUI

  • sources
  • kde-4.14
  • kdelibs
  • 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 
31 class KCompletionPrivate
32 {
33 public:
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 
67 KCompletion::KCompletion()
68  :d(new KCompletionPrivate)
69 {
70  setOrder( Insertion );
71 }
72 
73 KCompletion::~KCompletion()
74 {
75  delete d;
76 }
77 
78 void KCompletion::setOrder( CompOrder order )
79 {
80  d->myOrder = order;
81  d->matches.setSorting( order );
82 }
83 
84 KCompletion::CompOrder KCompletion::order() const
85 {
86  return d->myOrder;
87 }
88 
89 void KCompletion::setIgnoreCase( bool ignoreCase )
90 {
91  d->myIgnoreCase = ignoreCase;
92 }
93 
94 bool KCompletion::ignoreCase() const
95 {
96  return d->myIgnoreCase;
97 }
98 
99 void KCompletion::setItems( const QStringList& items )
100 {
101  clear();
102  insertItems( items );
103 }
104 
105 
106 void 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 
120 QStringList 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 
129 bool KCompletion::isEmpty() const
130 {
131  return (d->myTreeRoot->childrenCount() == 0);
132 }
133 
134 void KCompletion::postProcessMatch( QString * ) const
135 {
136 }
137 
138 void KCompletion::postProcessMatches( QStringList * ) const
139 {
140 }
141 
142 void KCompletion::postProcessMatches( KCompletionMatches * ) const
143 {
144 }
145 
146 void 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 
155 void 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 
182 void 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 
208 void 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 
218 void 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 
229 QString 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 
292 QStringList 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 
330 void KCompletion::setCompletionMode( KGlobalSettings::Completion mode )
331 {
332  d->myCompletionMode = mode;
333 }
334 
335 KGlobalSettings::Completion KCompletion::completionMode() const {
336  return d->myCompletionMode;
337 }
338 
339 QStringList 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 
352 KCompletionMatches 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 
365 QStringList 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 
375 KCompletionMatches 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 
385 void KCompletion::setSoundsEnabled( bool enable )
386 {
387  d->myBeep = enable;
388 }
389 
390 bool KCompletion::soundsEnabled() const
391 {
392  return d->myBeep;
393 }
394 
395 bool KCompletion::hasMultipleMatches() const
396 {
397  return d->myHasMultipleMatches;
398 }
399 
402 
403 
404 QString 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 
436 const QString& KCompletion::lastMatch() const
437 {
438  return d->myLastMatch;
439 }
440 
441 
442 QString 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
478 QString 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 
554 void 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 
609 void 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 
652 void 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 
686 void 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 
729 KCompTreeNode::~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.
743 KCompTreeNode * 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)
780 void 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 
812 bool lessThan( const QString &left, const QString &right )
813 {
814  return KStringHandler::naturalCompare( left, right ) < 0;
815 }
816 
817 QStringList 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 
836 class KCompletionMatchesPrivate
837 {
838 public:
839  KCompletionMatchesPrivate( bool sort )
840  : sorting( sort )
841  {}
842  bool sorting;
843 };
844 
845 KCompletionMatches::KCompletionMatches( const KCompletionMatches &o )
846  : KSortableList<QString, int>(),
847  d( new KCompletionMatchesPrivate( o.d->sorting ) )
848 {
849  *this = KCompletionMatches::operator=( o );
850 }
851 
852 KCompletionMatches &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 
862 KCompletionMatches::KCompletionMatches( bool sort_P )
863  : d( new KCompletionMatchesPrivate( sort_P ) )
864 {
865 }
866 
867 KCompletionMatches::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 
881 KCompletionMatches::~KCompletionMatches()
882 {
883  delete d;
884 }
885 
886 QStringList 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 
897 bool KCompletionMatches::sorting() const
898 {
899  return d->sorting;
900 }
901 
902 void 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 
918 void 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 
932 void 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 
945 void 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 
961 KCompTreeNode *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 
982 KCompTreeNode *KCompTreeNodeList::at(uint index) const
983 {
984  KCompTreeNode *cur = first;
985  while (index-- && cur) cur = cur->next;
986  return cur;
987 }
988 
989 QSharedPointer<KZoneAllocator> KCompTreeNode::alloc(new KZoneAllocator(8*1024));
990 
991 #include "kcompletion.moc"
QList< KSortableItem< T, Key > >::operator=
QList< T > & operator=(const QList< T > &other)
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
i18n
QString i18n(const char *text)
KNotification::DefaultEvent
Definition: knotification.h:247
KCompletion::clear
virtual void clear()
Removes all inserted items.
Definition: kcompletion.cpp:218
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KCompletionMatches::list
QStringList list(bool sort=true) const
Returns the matches as a QStringList.
Definition: kcompletion.cpp:886
QString::append
QString & append(QChar ch)
kdebug.h
KSortableItem
KStringHandler::naturalCompare
int naturalCompare(const QString &a, const QString &b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
KCompletion::setSoundsEnabled
virtual void setSoundsEnabled(bool enable)
Enables/disables playing a sound when.
Definition: kcompletion.cpp:385
KCompletion::Sorted
Use alphabetically sorted order.
Definition: kcompletion.h:143
KCompletion::Weighted
Use weighted order.
Definition: kcompletion.h:145
KCompletion::isEmpty
bool isEmpty() const
Returns true when the completion object contains no entries.
Definition: kcompletion.cpp:129
KCompletionMatches::operator=
KCompletionMatches & operator=(const KCompletionMatches &)
assignment operator.
Definition: kcompletion.cpp:852
QChar
KSortableList::sort
void sort()
QList< KSortableItem< T, Key > >::erase
iterator erase(iterator pos)
KStandardAction::find
KAction * find(const QObject *recvr, const char *slot, QObject *parent)
Initiate a 'find' request in the current document.
Definition: kstandardaction.cpp:329
klocale.h
KCompletion::items
QStringList items() const
Returns a list of all items inserted into KCompletion.
KCompletion::CompOrder
CompOrder
Constants that represent the order in which KCompletion performs completion-lookups.
Definition: kcompletion.h:143
KCompletion::lastMatch
virtual const QString & lastMatch() const
Returns the last match.
Definition: kcompletion.cpp:436
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString::isNull
bool isNull() const
QChar::isLetter
bool isLetter() const
QObject::event
virtual bool event(QEvent *e)
KCompletion::match
void match(const QString &item)
The matching item.
knotification.h
kglobal.h
KCompletion::Insertion
Use order of insertion.
Definition: kcompletion.h:144
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
KStandardGuiItem::remove
KGuiItem remove()
Returns the 'Remove' gui item.
Definition: kstandardguiitem.cpp:289
KCompletionMatches::removeDuplicates
void removeDuplicates()
Removes duplicate matches.
Definition: kcompletion.cpp:902
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
QSharedPointer< KZoneAllocator >
KStandardShortcut::insert
const KShortcut & insert()
Toggle insert/overwrite (with visual feedback, e.g.
Definition: kstandardguiitem.cpp:264
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
KCompletion::allMatches
QStringList allMatches()
Returns a list of all items matching the last completed string.
Definition: kcompletion.cpp:339
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
KGlobalSettings::CompletionAuto
Text is automatically filled in whenever possible.
Definition: kglobalsettings.h:187
QList< KSortableItem< T, Key > >::Iterator
typedef Iterator
KCompletion::setCompletionMode
virtual void setCompletionMode(KGlobalSettings::Completion mode)
Sets the completion mode to Auto/Manual, Shell or None.
Definition: kcompletion.cpp:330
KCompletion::insertItems
void insertItems(const QStringList &items)
Inserts items into the list of possible completions.
Definition: kcompletion.cpp:106
KCompletion::setIgnoreCase
virtual void setIgnoreCase(bool ignoreCase)
Setting this to true makes KCompletion behave case insensitively.
Definition: kcompletion.cpp:89
QString
QList
KCompletionMatches
This structure is returned by KCompletion::allWeightedMatches .
Definition: kcompletion.h:579
KCompletion::setItems
virtual void setItems(const QStringList &list)
Sets the list of items available for completion.
Definition: kcompletion.cpp:99
KCompletionMatches::~KCompletionMatches
~KCompletionMatches()
default destructor.
Definition: kcompletion.cpp:881
QStringList
KStandardAction::next
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
Scroll down one page.
Definition: kstandardaction.cpp:414
QPixmap
KCompletion::matches
void matches(const QStringList &matchlist)
All matching items.
kcompletion.h
QList::end
iterator end()
KCompletion::completionMode
KGlobalSettings::Completion completionMode() const
Return the current completion mode.
Definition: kcompletion.cpp:335
KGlobalSettings
Access the KDE global configuration.
Definition: kglobalsettings.h:58
lessThan
bool lessThan(const QString &left, const QString &right)
Definition: kcompletion.cpp:812
KCompletion::multipleMatches
void multipleMatches()
This signal is emitted, when calling makeCompletion() and more than one matching item is found...
KCompletion::nextMatch
QString nextMatch()
Returns the next item from the matching-items-list.
Definition: kcompletion.cpp:404
QChar::toLower
QChar toLower() const
kstringhandler.h
KCompletion::order
CompOrder order() const
Returns the completion order.
KStandardGuiItem::ok
KGuiItem ok()
Returns the 'Ok' gui item.
Definition: kstandardguiitem.cpp:107
KCompletion::~KCompletion
virtual ~KCompletion()
Destructor, nothing special here, either.
Definition: kcompletion.cpp:73
KZoneAllocator
KGlobalSettings::CompletionPopup
Lists all possible matches in a popup list-box to choose from.
Definition: kglobalsettings.h:199
KSortableList
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
KGlobalSettings::CompletionMan
Same as automatic except shortest match is used for completion.
Definition: kglobalsettings.h:191
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
QString::mid
QString mid(int position, int n) const
QVector
KGlobalSettings::CompletionNone
No completion is used.
Definition: kglobalsettings.h:183
QChar::toUpper
QChar toUpper() const
QLatin1String
QString::setNum
QString & setNum(short n, int base)
QString::at
const QChar at(int position) const
QList::ConstIterator
typedef ConstIterator
KCompletion::ignoreCase
bool ignoreCase() const
Return whether KCompletion acts case insensitively or not.
KCompletion::soundsEnabled
bool soundsEnabled() const
Tells you whether KCompletion will play sounds on certain occasions.
Definition: kcompletion.cpp:390
KGlobalSettings::Completion
Completion
This enum describes the completion mode used for by the KCompletion class.
Definition: kglobalsettings.h:179
QString::length
int length() const
KCompletion::substringCompletion
QStringList substringCompletion(const QString &string) const
Returns a list of all completion items that contain the given string.
Definition: kcompletion.cpp:292
QString::left
QString left(int n) const
KCompletion::removeItem
void removeItem(const QString &item)
Removes an item from the list of available completions.
Definition: kcompletion.cpp:208
KCompletion::addItem
void addItem(const QString &item)
Adds an item to the list of available completions.
Definition: kcompletion.cpp:146
QStringList::sort
void sort()
QList::prepend
void prepend(const T &value)
KCompletion::hasMultipleMatches
bool hasMultipleMatches() const
Returns true when more than one match is found.
Definition: kcompletion.cpp:395
KGlobalSettings::CompletionShell
Complete text much in the same way as a typical *nix shell would.
Definition: kglobalsettings.h:195
QString::find
int find(QChar c, int i, bool cs) const
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
KCompletion::allWeightedMatches
KCompletionMatches allWeightedMatches()
Returns a list of all items matching the last completed string.
Definition: kcompletion.cpp:352
KStandardShortcut::completion
const KShortcut & completion()
Complete text in input widgets.
Definition: kstandardshortcut.cpp:363
QList::begin
iterator begin()
KCompletionMatches::KCompletionMatches
KCompletionMatches(bool sort)
Default constructor.
Definition: kcompletion.cpp:862
KCompletion::setOrder
virtual void setOrder(CompOrder order)
KCompletion offers three different ways in which it offers its items:
Definition: kcompletion.cpp:78
KCompletion::previousMatch
QString previousMatch()
Returns the next item from the matching-items-list.
Definition: kcompletion.cpp:442
KGlobalSettings::CompletionPopupAuto
Lists all possible matches in a popup list-box to choose from, and automatically fill the result when...
Definition: kglobalsettings.h:204
KCompletion::KCompletion
KCompletion()
Constructor, nothing special here :)
Definition: kcompletion.cpp:67
QString::toUInt
uint toUInt(bool *ok, int base) const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:23:59 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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