KCompletion

klineedit.cpp
1 /*
2  This file is part of the KDE libraries
3 
4  SPDX-FileCopyrightText: 1997 Sven Radej <[email protected]>
5  SPDX-FileCopyrightText: 1999 Patrick Ward <[email protected]>
6  SPDX-FileCopyrightText: 1999 Preston Brown <[email protected]>
7 
8  Re-designed for KDE 2.x by
9  SPDX-FileCopyrightText: 2000, 2001 Dawit Alemayehu <[email protected]>
10  SPDX-FileCopyrightText: 2000, 2001 Carsten Pfeiffer <[email protected]>
11 
12  SPDX-License-Identifier: LGPL-2.0-or-later
13 */
14 
15 #include "klineedit.h"
16 #include "klineedit_p.h"
17 
18 #include <KAuthorized>
19 #include <KConfigGroup>
20 #include <KCursor>
21 #include <KSharedConfig>
22 #include <KStandardShortcut>
23 #include <kcompletionbox.h>
24 #include <lineediturldropeventfilter.h>
25 
26 #include <QActionGroup>
27 #include <QApplication>
28 #include <QClipboard>
29 #include <QKeyEvent>
30 #include <QMenu>
31 #include <QTimer>
32 #include <QToolTip>
33 
34 KLineEditPrivate::~KLineEditPrivate()
35 {
36  // causes a weird crash in KWord at least, so let Qt delete it for us.
37  // delete completionBox;
38 }
39 
40 void KLineEditPrivate::_k_textChanged(const QString &text)
41 {
42  Q_Q(KLineEdit);
43  // COMPAT (as documented): emit userTextChanged whenever textChanged is emitted
44  if (!completionRunning && (text != userText)) {
45  userText = text;
46 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
47  Q_EMIT q->userTextChanged(text);
48 #endif
49  }
50 }
51 
52 // Call this when a completion operation changes the lineedit text
53 // "as if it had been edited by the user".
54 void KLineEditPrivate::updateUserText(const QString &text)
55 {
56  Q_Q(KLineEdit);
57  if (!completionRunning && (text != userText)) {
58  userText = text;
59  q->setModified(true);
60 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
61  Q_EMIT q->userTextChanged(text);
62 #endif
63  Q_EMIT q->textEdited(text);
64  Q_EMIT q->textChanged(text);
65  }
66 }
67 
68 bool KLineEditPrivate::s_backspacePerformsCompletion = false;
69 bool KLineEditPrivate::s_initialized = false;
70 
71 void KLineEditPrivate::init()
72 {
73  Q_Q(KLineEdit);
74  //---
75  completionBox = nullptr;
76  handleURLDrops = true;
77  trapReturnKeyEvents = false;
78 
79  userSelection = true;
80  autoSuggest = false;
81  disableRestoreSelection = false;
82  enableSqueezedText = false;
83 
84  completionRunning = false;
85  if (!s_initialized) {
87  s_backspacePerformsCompletion = config.readEntry("Backspace performs completion", false);
88  s_initialized = true;
89  }
90 
91  urlDropEventFilter = new LineEditUrlDropEventFilter(q);
92 
93  // i18n: Placeholder text in line edit widgets is the text appearing
94  // before any user input, briefly explaining to the user what to type
95  // (e.g. "Enter search pattern").
96  // By default the text is set in italic, which may not be appropriate
97  // for some languages and scripts (e.g. for CJK ideographs).
98  QString metaMsg = KLineEdit::tr("1", "Italic placeholder text in line edits: 0 no, 1 yes");
99  italicizePlaceholder = (metaMsg.trimmed() != QLatin1Char('0'));
100  //---
101  possibleTripleClick = false;
102  bgRole = q->backgroundRole();
103 
104  // Enable the context menu by default.
105  q->QLineEdit::setContextMenuPolicy(Qt::DefaultContextMenu);
106  KCursor::setAutoHideCursor(q, true, true);
107 
108  KCompletion::CompletionMode mode = q->completionMode();
109  autoSuggest = (mode == KCompletion::CompletionMan //
111  || mode == KCompletion::CompletionAuto);
112  q->connect(q, &KLineEdit::selectionChanged, q, [this]() {
113  _k_restoreSelectionColors();
114  });
115 
116  if (handleURLDrops) {
117  q->installEventFilter(urlDropEventFilter);
118  }
119 
120  const QPalette p = q->palette();
121  if (!previousHighlightedTextColor.isValid()) {
122  previousHighlightedTextColor = p.color(QPalette::Normal, QPalette::HighlightedText);
123  }
124  if (!previousHighlightColor.isValid()) {
125  previousHighlightColor = p.color(QPalette::Normal, QPalette::Highlight);
126  }
127 
128  q->connect(q, &KLineEdit::textChanged, q, [this](const QString &text) {
129  _k_textChanged(text);
130  });
131 }
132 
133 KLineEdit::KLineEdit(const QString &string, QWidget *parent)
134  : QLineEdit(string, parent)
135  , d_ptr(new KLineEditPrivate(this))
136 {
137  Q_D(KLineEdit);
138  d->init();
139 }
140 
142  : QLineEdit(parent)
143  , d_ptr(new KLineEditPrivate(this))
144 {
145  Q_D(KLineEdit);
146  d->init();
147 }
148 
150 {
151 }
152 
153 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 0)
154 QString KLineEdit::clickMessage() const
155 {
156  return placeholderText();
157 }
158 #endif
159 
160 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 46)
162 {
164 }
165 #endif
166 
167 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 46)
169 {
170  return isClearButtonEnabled();
171 }
172 #endif
173 
175 {
176  QSize s;
177 
178  if (isClearButtonEnabled()) {
179  // from qlineedit_p.cpp
180 
181  const int iconSize = height() < 34 ? 16 : 32;
182  const int buttonWidth = iconSize + 6;
183  const int buttonHeight = iconSize + 2;
184 
185  s = QSize(buttonWidth, buttonHeight);
186  }
187 
188  return s;
189 }
190 
192 {
193  Q_D(KLineEdit);
195 
196  if (oldMode != mode //
197  && (oldMode == KCompletion::CompletionPopup || oldMode == KCompletion::CompletionPopupAuto) //
198  && d->completionBox && d->completionBox->isVisible()) {
199  d->completionBox->hide();
200  }
201 
202  // If the widgets echo mode is not Normal, no completion
203  // feature will be enabled even if one is requested.
204  if (echoMode() != QLineEdit::Normal) {
205  mode = KCompletion::CompletionNone; // Override the request.
206  }
207 
208  if (!KAuthorized::authorize(QStringLiteral("lineedit_text_completion"))) {
210  }
211 
213  d->autoSuggest = true;
214  } else {
215  d->autoSuggest = false;
216  }
217 
219 }
220 
222 {
223  Q_D(KLineEdit);
224  d->disableCompletionMap[mode] = disable;
225 }
226 
227 void KLineEdit::setCompletedText(const QString &t, bool marked)
228 {
229  Q_D(KLineEdit);
230  if (!d->autoSuggest) {
231  return;
232  }
233 
234  const QString txt = text();
235 
236  if (t != txt) {
237  setText(t);
238  if (marked) {
239  setSelection(t.length(), txt.length() - t.length());
240  }
241  setUserSelection(false);
242  } else {
243  setUserSelection(true);
244  }
245 }
246 
248 {
250  const bool marked = (mode == KCompletion::CompletionAuto //
251  || mode == KCompletion::CompletionMan //
252  || mode == KCompletion::CompletionPopup //
254  setCompletedText(text, marked);
255 }
256 
258 {
259  KCompletion *comp = compObj();
260  if (comp && //
263  QString input;
264 
266  input = comp->previousMatch();
267  } else {
268  input = comp->nextMatch();
269  }
270 
271  // Skip rotation if previous/next match is null or the same text
272  if (input.isEmpty() || input == displayText()) {
273  return;
274  }
276  }
277 }
278 
280 {
281  Q_D(KLineEdit);
282  KCompletion *comp = compObj();
284 
285  if (!comp || mode == KCompletion::CompletionNone) {
286  return; // No completion object...
287  }
288 
289  const QString match = comp->makeCompletion(text);
290 
292  if (match.isEmpty()) {
293  if (d->completionBox) {
294  d->completionBox->hide();
295  d->completionBox->clear();
296  }
297  } else {
299  }
300  } else { // Auto, ShortAuto (Man) and Shell
301  // all other completion modes
302  // If no match or the same match, simply return without completing.
303  if (match.isEmpty() || match == text) {
304  return;
305  }
306 
307  if (mode != KCompletion::CompletionShell) {
308  setUserSelection(false);
309  }
310 
311  if (d->autoSuggest) {
312  setCompletedText(match);
313  }
314  }
315 }
316 
317 void KLineEdit::setReadOnly(bool readOnly)
318 {
319  Q_D(KLineEdit);
320  // Do not do anything if nothing changed...
321  if (readOnly == isReadOnly()) {
322  return;
323  }
324 
326 
327  if (readOnly) {
328  d->bgRole = backgroundRole();
330  if (d->enableSqueezedText && d->squeezedText.isEmpty()) {
331  d->squeezedText = text();
332  d->setSqueezedText();
333  }
334  } else {
335  if (!d->squeezedText.isEmpty()) {
336  setText(d->squeezedText);
337  d->squeezedText.clear();
338  }
339 
340  setBackgroundRole(d->bgRole);
341  }
342 }
343 
345 {
347  setText(text);
348 }
349 
351 {
352  Q_D(KLineEdit);
353  d->enableSqueezedText = enable;
354 }
355 
357 {
358  Q_D(const KLineEdit);
359  return d->enableSqueezedText;
360 }
361 
362 void KLineEdit::setText(const QString &text)
363 {
364  Q_D(KLineEdit);
365  if (d->enableSqueezedText && isReadOnly()) {
366  d->squeezedText = text;
367  d->setSqueezedText();
368  return;
369  }
370 
372 }
373 
374 void KLineEditPrivate::setSqueezedText()
375 {
376  Q_Q(KLineEdit);
377  squeezedStart = 0;
378  squeezedEnd = 0;
379  const QString fullText = squeezedText;
380  const int fullLength = fullText.length();
381  const QFontMetrics fm(q->fontMetrics());
382  const int labelWidth = q->size().width() - 2 * q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) - 2;
383  const int textWidth = fm.boundingRect(fullText).width();
384 
385  // TODO: investigate use of QFontMetrics::elidedText for this
386  if (textWidth > labelWidth) {
387  const QStringView sview{fullText};
388  // TODO: better would be "…" char (0x2026), but for that one would need to ensure it's from the main font,
389  // otherwise if resulting in use of a new fallback font this can affect the metrics of the complete text,
390  // resulting in shifted characters
391  const QString ellipsisText = QStringLiteral("...");
392  // start with the dots only
393  QString squeezedText = ellipsisText;
394  int squeezedWidth = fm.boundingRect(squeezedText).width();
395 
396  // estimate how many letters we can add to the dots on both sides
397  int letters = fullText.length() * (labelWidth - squeezedWidth) / textWidth / 2;
398  squeezedText = sview.left(letters) + ellipsisText + sview.right(letters);
399  squeezedWidth = fm.boundingRect(squeezedText).width();
400 
401  if (squeezedWidth < labelWidth) {
402  // we estimated too short
403  // add letters while text < label
404  do {
405  letters++;
406  squeezedText = sview.left(letters) + ellipsisText + sview.right(letters);
407  squeezedWidth = fm.boundingRect(squeezedText).width();
408  } while (squeezedWidth < labelWidth && letters <= fullLength / 2);
409  letters--;
410  squeezedText = sview.left(letters) + ellipsisText + sview.right(letters);
411  } else if (squeezedWidth > labelWidth) {
412  // we estimated too long
413  // remove letters while text > label
414  do {
415  letters--;
416  squeezedText = sview.left(letters) + ellipsisText + sview.right(letters);
417  squeezedWidth = fm.boundingRect(squeezedText).width();
418  } while (squeezedWidth > labelWidth && letters >= 5);
419  }
420 
421  if (letters < 5) {
422  // too few letters added -> we give up squeezing
423  q->QLineEdit::setText(fullText);
424  } else {
425  q->QLineEdit::setText(squeezedText);
426  squeezedStart = letters;
427  squeezedEnd = fullText.length() - letters;
428  }
429 
430  q->setToolTip(fullText);
431 
432  } else {
433  q->QLineEdit::setText(fullText);
434 
435  q->setToolTip(QString());
436  QToolTip::showText(q->pos(), QString()); // hide
437  }
438 
439  q->setCursorPosition(0);
440 }
441 
442 void KLineEdit::copy() const
443 {
444  Q_D(const KLineEdit);
445  if (!d->copySqueezedText(true)) {
446  QLineEdit::copy();
447  }
448 }
449 
450 bool KLineEditPrivate::copySqueezedText(bool copy) const
451 {
452  Q_Q(const KLineEdit);
453  if (!squeezedText.isEmpty() && squeezedStart) {
454  KLineEdit *that = const_cast<KLineEdit *>(q);
455  if (!that->hasSelectedText()) {
456  return false;
457  }
458  int start = q->selectionStart();
459  int end = start + q->selectedText().length();
460  if (start >= squeezedStart + 3) {
461  start = start - 3 - squeezedStart + squeezedEnd;
462  } else if (start > squeezedStart) {
463  start = squeezedStart;
464  }
465  if (end >= squeezedStart + 3) {
466  end = end - 3 - squeezedStart + squeezedEnd;
467  } else if (end > squeezedStart) {
468  end = squeezedEnd;
469  }
470  if (start == end) {
471  return false;
472  }
473  QString t = squeezedText;
474  t = t.mid(start, end - start);
476  return true;
477  }
478  return false;
479 }
480 
482 {
483  Q_D(KLineEdit);
484  if (!d->squeezedText.isEmpty()) {
485  d->setSqueezedText();
486  }
487 
489 }
490 
492 {
493  Q_D(KLineEdit);
494  const int key = e->key() | e->modifiers();
495 
496  if (KStandardShortcut::copy().contains(key)) {
497  copy();
498  return;
499  } else if (KStandardShortcut::paste().contains(key)) {
500  // TODO:
501  // we should restore the original text (not autocompleted), otherwise the paste
502  // will get into troubles Bug: 134691
503  if (!isReadOnly()) {
504  paste();
505  }
506  return;
507  } else if (KStandardShortcut::pasteSelection().contains(key)) {
509  insert(text);
510  deselect();
511  return;
512  } else if (KStandardShortcut::cut().contains(key)) {
513  if (!isReadOnly()) {
514  cut();
515  }
516  return;
517  } else if (KStandardShortcut::undo().contains(key)) {
518  if (!isReadOnly()) {
519  undo();
520  }
521  return;
522  } else if (KStandardShortcut::redo().contains(key)) {
523  if (!isReadOnly()) {
524  redo();
525  }
526  return;
527  } else if (KStandardShortcut::deleteWordBack().contains(key)) {
528  cursorWordBackward(true);
529  if (hasSelectedText() && !isReadOnly()) {
530  del();
531  }
532 
533  e->accept();
534  return;
535  } else if (KStandardShortcut::deleteWordForward().contains(key)) {
536  // Workaround for QT bug where
537  cursorWordForward(true);
538  if (hasSelectedText() && !isReadOnly()) {
539  del();
540  }
541 
542  e->accept();
543  return;
544  } else if (KStandardShortcut::backwardWord().contains(key)) {
545  cursorWordBackward(false);
546  e->accept();
547  return;
548  } else if (KStandardShortcut::forwardWord().contains(key)) {
549  cursorWordForward(false);
550  e->accept();
551  return;
552  } else if (KStandardShortcut::beginningOfLine().contains(key)) {
553  home(false);
554  e->accept();
555  return;
556  } else if (KStandardShortcut::endOfLine().contains(key)) {
557  end(false);
558  e->accept();
559  return;
560  }
561 
562  // Filter key-events if EchoMode is normal and
563  // completion mode is not set to CompletionNone
565  if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
566  const bool trap = (d->completionBox && d->completionBox->isVisible());
567  const bool stopEvent = (trap
568  || (d->trapReturnKeyEvents //
569  && (e->modifiers() == Qt::NoButton || //
570  e->modifiers() == Qt::KeypadModifier)));
571 
572  if (stopEvent) {
574  e->accept();
575  }
576 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 81)
578 #endif
580  if (trap) {
581  d->completionBox->hide();
582  deselect();
583  setCursorPosition(text().length());
584  }
585 
586  // Eat the event if the user asked for it, or if a completionbox was visible
587  if (stopEvent) {
588  return;
589  }
590  }
591 
592  const KeyBindingMap keys = keyBindingMap();
594  const bool noModifier = (e->modifiers() == Qt::NoButton //
595  || e->modifiers() == Qt::ShiftModifier //
596  || e->modifiers() == Qt::KeypadModifier);
597 
598  if ((mode == KCompletion::CompletionAuto //
600  || mode == KCompletion::CompletionMan) //
601  && noModifier) {
602  if (!d->userSelection && hasSelectedText() //
603  && (e->key() == Qt::Key_Right || e->key() == Qt::Key_Left) //
604  && e->modifiers() == Qt::NoButton) {
605  const QString old_txt = text();
606  d->disableRestoreSelection = true;
607  const int start = selectionStart();
608 
609  deselect();
611  const int cPosition = cursorPosition();
612  setText(old_txt);
613 
614  // keep cursor at cPosition
615  setSelection(old_txt.length(), cPosition - old_txt.length());
616  if (e->key() == Qt::Key_Right && cPosition > start) {
617  // the user explicitly accepted the autocompletion
618  d->updateUserText(text());
619  }
620 
621  d->disableRestoreSelection = false;
622  return;
623  }
624 
625  if (e->key() == Qt::Key_Escape) {
626  if (hasSelectedText() && !d->userSelection) {
627  del();
628  setUserSelection(true);
629  }
630 
631  // Don't swallow the Escape press event for the case
632  // of dialogs, which have Escape associated to Cancel
633  e->ignore();
634  return;
635  }
636  }
637 
638  if ((mode == KCompletion::CompletionAuto //
639  || mode == KCompletion::CompletionMan)
640  && noModifier) {
641  const QString keycode = e->text();
642  if (!keycode.isEmpty()
643  && (keycode.unicode()->isPrint() //
644  || e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete)) {
645  const bool hasUserSelection = d->userSelection;
646  const bool hadSelection = hasSelectedText();
647 
648  bool cursorNotAtEnd = false;
649 
650  const int start = selectionStart();
651  const int cPos = cursorPosition();
652 
653  // When moving the cursor, we want to keep the autocompletion as an
654  // autocompletion, so we want to process events at the cursor position
655  // as if there was no selection. After processing the key event, we
656  // can set the new autocompletion again.
657  if (hadSelection && !hasUserSelection && start > cPos) {
658  del();
659  setCursorPosition(cPos);
660  cursorNotAtEnd = true;
661  }
662 
663  d->disableRestoreSelection = true;
665  d->disableRestoreSelection = false;
666 
667  QString txt = text();
668  int len = txt.length();
669  if (!hasSelectedText() && len /*&& cursorPosition() == len */) {
670  if (e->key() == Qt::Key_Backspace) {
671  if (hadSelection && !hasUserSelection && !cursorNotAtEnd) {
672  backspace();
673  txt = text();
674  len = txt.length();
675  }
676 
677  if (!d->s_backspacePerformsCompletion || !len) {
678  d->autoSuggest = false;
679  }
680  }
681 
682  if (e->key() == Qt::Key_Delete) {
683  d->autoSuggest = false;
684  }
685 
686  doCompletion(txt);
687 
688  if ((e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete)) {
689  d->autoSuggest = true;
690  }
691 
692  e->accept();
693  }
694 
695  return;
696  }
697 
698  } else if ((mode == KCompletion::CompletionPopup || mode == KCompletion::CompletionPopupAuto) //
699  && noModifier && !e->text().isEmpty()) {
700  const QString old_txt = text();
701  const bool hasUserSelection = d->userSelection;
702  const bool hadSelection = hasSelectedText();
703  bool cursorNotAtEnd = false;
704 
705  const int start = selectionStart();
706  const int cPos = cursorPosition();
707  const QString keycode = e->text();
708 
709  // When moving the cursor, we want to keep the autocompletion as an
710  // autocompletion, so we want to process events at the cursor position
711  // as if there was no selection. After processing the key event, we
712  // can set the new autocompletion again.
713  if (hadSelection && !hasUserSelection && start > cPos
714  && ((!keycode.isEmpty() && keycode.unicode()->isPrint()) //
715  || e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete)) {
716  del();
717  setCursorPosition(cPos);
718  cursorNotAtEnd = true;
719  }
720 
721  const int selectedLength = selectedText().length();
722 
723  d->disableRestoreSelection = true;
725  d->disableRestoreSelection = false;
726 
727  if ((selectedLength != selectedText().length()) && !hasUserSelection) {
728  d->_k_restoreSelectionColors(); // and set userSelection to true
729  }
730 
731  QString txt = text();
732  int len = txt.length();
733  if ((txt != old_txt || txt != e->text()) && len /* && ( cursorPosition() == len || force )*/
734  && ((!keycode.isEmpty() && keycode.unicode()->isPrint()) //
735  || e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete)) {
736  if (e->key() == Qt::Key_Backspace) {
737  if (hadSelection && !hasUserSelection && !cursorNotAtEnd) {
738  backspace();
739  txt = text();
740  len = txt.length();
741  }
742 
743  if (!d->s_backspacePerformsCompletion) {
744  d->autoSuggest = false;
745  }
746  }
747 
748  if (e->key() == Qt::Key_Delete) {
749  d->autoSuggest = false;
750  }
751 
752  if (d->completionBox) {
753  d->completionBox->setCancelledText(txt);
754  }
755 
756  doCompletion(txt);
757 
758  if ((e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete) //
760  d->autoSuggest = true;
761  }
762 
763  e->accept();
764  } else if (!len && d->completionBox && d->completionBox->isVisible()) {
765  d->completionBox->hide();
766  }
767 
768  return;
769  } else if (mode == KCompletion::CompletionShell) {
770  // Handles completion.
772  if (keys[TextCompletion].isEmpty()) {
774  } else {
775  cut = keys[TextCompletion];
776  }
777 
778  if (cut.contains(key)) {
779  // Emit completion if the completion mode is CompletionShell
780  // and the cursor is at the end of the string.
781  const QString txt = text();
782  const int len = txt.length();
783  if (cursorPosition() == len && len != 0) {
784  doCompletion(txt);
785  return;
786  }
787  } else if (d->completionBox) {
788  d->completionBox->hide();
789  }
790  }
791 
792  // handle rotation
793  // Handles previous match
795  if (keys[PrevCompletionMatch].isEmpty()) {
797  } else {
798  cut = keys[PrevCompletionMatch];
799  }
800 
801  if (cut.contains(key)) {
802  if (emitSignals()) {
804  }
805  if (handleSignals()) {
807  }
808  return;
809  }
810 
811  // Handles next match
812  if (keys[NextCompletionMatch].isEmpty()) {
814  } else {
815  cut = keys[NextCompletionMatch];
816  }
817 
818  if (cut.contains(key)) {
819  if (emitSignals()) {
821  }
822  if (handleSignals()) {
824  }
825  return;
826  }
827 
828  // substring completion
829  if (compObj()) {
831  if (keys[SubstringCompletion].isEmpty()) {
833  } else {
834  cut = keys[SubstringCompletion];
835  }
836 
837  if (cut.contains(key)) {
838  if (emitSignals()) {
840  }
841  if (handleSignals()) {
843  e->accept();
844  }
845  return;
846  }
847  }
848  }
849  const int selectedLength = selectedText().length();
850 
851  // Let QLineEdit handle any other keys events.
853 
854  if (selectedLength != selectedText().length()) {
855  d->_k_restoreSelectionColors(); // and set userSelection to true
856  }
857 }
858 
860 {
861  Q_D(KLineEdit);
862  if (e->button() == Qt::LeftButton) {
863  d->possibleTripleClick = true;
865  d->_k_tripleClickTimeout();
866  });
867  }
869 }
870 
872 {
873  Q_D(KLineEdit);
874  if (e->button() == Qt::LeftButton && d->possibleTripleClick) {
875  selectAll();
876  e->accept();
877  return;
878  }
879 
880  // if middle clicking and if text is present in the clipboard then clear the selection
881  // to prepare paste operation
882  if (e->button() == Qt::MiddleButton) {
883  if (hasSelectedText() && !isReadOnly()) {
884  if (QApplication::clipboard()->text(QClipboard::Selection).length() > 0) {
885  backspace();
886  }
887  }
888  }
889 
891 }
892 
894 {
895  Q_D(KLineEdit);
897 
898  if (QApplication::clipboard()->supportsSelection()) {
899  if (e->button() == Qt::LeftButton) {
900  // Fix copying of squeezed text if needed
901  d->copySqueezedText(false);
902  }
903  }
904 }
905 
906 void KLineEditPrivate::_k_tripleClickTimeout()
907 {
908  possibleTripleClick = false;
909 }
910 
912 {
913  Q_D(KLineEdit);
915 
916  if (!isReadOnly()) {
917  // FIXME: This code depends on Qt's action ordering.
918  const QList<QAction *> actionList = popup->actions();
919  enum {
920  UndoAct,
921  RedoAct,
922  Separator1,
923  CutAct,
924  CopyAct,
925  PasteAct,
926  DeleteAct,
927  ClearAct,
928  Separator2,
929  SelectAllAct,
930  NCountActs,
931  };
932  QAction *separatorAction = nullptr;
933  // separator we want is right after Delete right now.
934  const int idx = actionList.indexOf(actionList[DeleteAct]) + 1;
935  if (idx < actionList.count()) {
936  separatorAction = actionList.at(idx);
937  }
938  if (separatorAction) {
939  QAction *clearAllAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-clear")), tr("C&lear", "@action:inmenu"), this);
941  connect(clearAllAction, &QAction::triggered, this, &QLineEdit::clear);
942  if (text().isEmpty()) {
943  clearAllAction->setEnabled(false);
944  }
945  popup->insertAction(separatorAction, clearAllAction);
946  }
947  }
948 
949  // If a completion object is present and the input
950  // widget is not read-only, show the Text Completion
951  // menu item.
952  if (compObj() && !isReadOnly() && KAuthorized::authorize(QStringLiteral("lineedit_text_completion"))) {
953  QMenu *subMenu = popup->addMenu(QIcon::fromTheme(QStringLiteral("text-completion")), tr("Text Completion", "@title:menu"));
954  connect(subMenu, &QMenu::triggered, this, [d](QAction *action) {
955  d->_k_completionMenuActivated(action);
956  });
957 
958  popup->addSeparator();
959 
960  QActionGroup *ag = new QActionGroup(this);
961  d->noCompletionAction = ag->addAction(tr("None", "@item:inmenu Text Completion"));
962  d->shellCompletionAction = ag->addAction(tr("Manual", "@item:inmenu Text Completion"));
963  d->autoCompletionAction = ag->addAction(tr("Automatic", "@item:inmenu Text Completion"));
964  d->popupCompletionAction = ag->addAction(tr("Dropdown List", "@item:inmenu Text Completion"));
965  d->shortAutoCompletionAction = ag->addAction(tr("Short Automatic", "@item:inmenu Text Completion"));
966  d->popupAutoCompletionAction = ag->addAction(tr("Dropdown List && Automatic", "@item:inmenu Text Completion"));
967  subMenu->addActions(ag->actions());
968 
969  // subMenu->setAccel( KStandardShortcut::completion(), ShellCompletion );
970 
971  d->shellCompletionAction->setCheckable(true);
972  d->noCompletionAction->setCheckable(true);
973  d->popupCompletionAction->setCheckable(true);
974  d->autoCompletionAction->setCheckable(true);
975  d->shortAutoCompletionAction->setCheckable(true);
976  d->popupAutoCompletionAction->setCheckable(true);
977 
978  d->shellCompletionAction->setEnabled(!d->disableCompletionMap[KCompletion::CompletionShell]);
979  d->noCompletionAction->setEnabled(!d->disableCompletionMap[KCompletion::CompletionNone]);
980  d->popupCompletionAction->setEnabled(!d->disableCompletionMap[KCompletion::CompletionPopup]);
981  d->autoCompletionAction->setEnabled(!d->disableCompletionMap[KCompletion::CompletionAuto]);
982  d->shortAutoCompletionAction->setEnabled(!d->disableCompletionMap[KCompletion::CompletionMan]);
983  d->popupAutoCompletionAction->setEnabled(!d->disableCompletionMap[KCompletion::CompletionPopupAuto]);
984 
986  d->noCompletionAction->setChecked(mode == KCompletion::CompletionNone);
987  d->shellCompletionAction->setChecked(mode == KCompletion::CompletionShell);
988  d->popupCompletionAction->setChecked(mode == KCompletion::CompletionPopup);
989  d->autoCompletionAction->setChecked(mode == KCompletion::CompletionAuto);
990  d->shortAutoCompletionAction->setChecked(mode == KCompletion::CompletionMan);
991  d->popupAutoCompletionAction->setChecked(mode == KCompletion::CompletionPopupAuto);
992 
994  if (mode != defaultMode && !d->disableCompletionMap[defaultMode]) {
995  subMenu->addSeparator();
996  d->defaultAction = subMenu->addAction(tr("Default", "@item:inmenu Text Completion"));
997  }
998  }
999 
1000  return popup;
1001 }
1002 
1004 {
1006  return;
1007  }
1008  QMenu *popup = createStandardContextMenu();
1009 
1010  // ### do we really need this? Yes, Please do not remove! This
1011  // allows applications to extend the popup menu without having to
1012  // inherit from this class! (DA)
1014 
1015  popup->exec(e->globalPos());
1016  delete popup;
1017 }
1018 
1019 void KLineEditPrivate::_k_completionMenuActivated(QAction *act)
1020 {
1021  Q_Q(KLineEdit);
1022  KCompletion::CompletionMode oldMode = q->completionMode();
1023 
1024  if (act == noCompletionAction) {
1025  q->setCompletionMode(KCompletion::CompletionNone);
1026  } else if (act == shellCompletionAction) {
1027  q->setCompletionMode(KCompletion::CompletionShell);
1028  } else if (act == autoCompletionAction) {
1029  q->setCompletionMode(KCompletion::CompletionAuto);
1030  } else if (act == popupCompletionAction) {
1031  q->setCompletionMode(KCompletion::CompletionPopup);
1032  } else if (act == shortAutoCompletionAction) {
1033  q->setCompletionMode(KCompletion::CompletionMan);
1034  } else if (act == popupAutoCompletionAction) {
1035  q->setCompletionMode(KCompletion::CompletionPopupAuto);
1036  } else if (act == defaultAction) {
1037  q->setCompletionMode(KCompletion::CompletionPopup);
1038  } else {
1039  return;
1040  }
1041 
1042  if (oldMode != q->completionMode()) {
1043  if ((oldMode == KCompletion::CompletionPopup || oldMode == KCompletion::CompletionPopupAuto) //
1044  && completionBox //
1045  && completionBox->isVisible()) {
1046  completionBox->hide();
1047  }
1048  Q_EMIT q->completionModeChanged(q->completionMode());
1049  }
1050 }
1051 
1053 {
1054  Q_D(KLineEdit);
1055  KCursor::autoHideEventFilter(this, ev);
1056  if (ev->type() == QEvent::ShortcutOverride) {
1057  QKeyEvent *e = static_cast<QKeyEvent *>(ev);
1058  if (d->overrideShortcut(e)) {
1059  ev->accept();
1060  }
1061  } else if (ev->type() == QEvent::ApplicationPaletteChange || ev->type() == QEvent::PaletteChange) {
1062  // Assume the widget uses the application's palette
1064  d->previousHighlightedTextColor = p.color(QPalette::Normal, QPalette::HighlightedText);
1065  d->previousHighlightColor = p.color(QPalette::Normal, QPalette::Highlight);
1066  setUserSelection(d->userSelection);
1067  } else if (ev->type() == QEvent::ChildAdded) {
1068  QObject *obj = static_cast<QChildEvent *>(ev)->child();
1069  if (obj) {
1070  connect(obj, &QObject::objectNameChanged, this, [this, obj] {
1071  if (obj->objectName() == QLatin1String("_q_qlineeditclearaction")) {
1072  QAction *action = qobject_cast<QAction *>(obj);
1074  }
1075  });
1076  }
1077  }
1078 
1079  return QLineEdit::event(ev);
1080 }
1081 
1082 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 0)
1084 {
1085  Q_D(KLineEdit);
1086  if (enable && !d->handleURLDrops) {
1087  installEventFilter(d->urlDropEventFilter);
1088  d->handleURLDrops = true;
1089  } else if (!enable && d->handleURLDrops) {
1090  removeEventFilter(d->urlDropEventFilter);
1091  d->handleURLDrops = false;
1092  }
1093 }
1094 #endif
1095 
1096 bool KLineEdit::urlDropsEnabled() const
1097 {
1098  Q_D(const KLineEdit);
1099  return d->handleURLDrops;
1100 }
1101 
1103 {
1104  Q_D(KLineEdit);
1105  d->trapReturnKeyEvents = trap;
1106 }
1107 
1109 {
1110  Q_D(const KLineEdit);
1111  return d->trapReturnKeyEvents;
1112 }
1113 
1114 void KLineEdit::setUrl(const QUrl &url)
1115 {
1116  setText(url.toDisplayString());
1117 }
1118 
1120 {
1121  Q_D(KLineEdit);
1122  if (d->completionBox) {
1123  return;
1124  }
1125 
1126  d->completionBox = box;
1127  if (handleSignals()) {
1128  connect(d->completionBox, &KCompletionBox::currentTextChanged, this, [d](const QString &text) {
1129  d->_k_completionBoxTextChanged(text);
1130  });
1131 
1133 
1134 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 81)
1135  connect(d->completionBox, qOverload<const QString &>(&KCompletionBox::activated), this, &KLineEdit::completionBoxActivated);
1136  connect(d->completionBox, qOverload<const QString &>(&KCompletionBox::activated), this, &KLineEdit::textEdited);
1137 #else
1139  connect(d->completionBox, &KCompletionBox::textActivated, this, &KLineEdit::textEdited);
1140 #endif
1141  }
1142 }
1143 
1144 /*
1145  * Set the line edit text without changing the modified flag. By default
1146  * calling setText resets the modified flag to false.
1147  */
1148 static void setEditText(KLineEdit *edit, const QString &text)
1149 {
1150  if (!edit) {
1151  return;
1152  }
1153 
1154  const bool wasModified = edit->isModified();
1155  edit->setText(text);
1156  edit->setModified(wasModified);
1157 }
1158 
1159 void KLineEdit::userCancelled(const QString &cancelText)
1160 {
1161  Q_D(KLineEdit);
1163  setEditText(this, cancelText);
1164  } else if (hasSelectedText()) {
1165  if (d->userSelection) {
1166  deselect();
1167  } else {
1168  d->autoSuggest = false;
1169  const int start = selectionStart();
1170  const QString s = text().remove(selectionStart(), selectedText().length());
1171  setEditText(this, s);
1173  d->autoSuggest = true;
1174  }
1175  }
1176 }
1177 
1178 bool KLineEditPrivate::overrideShortcut(const QKeyEvent *e)
1179 {
1180  Q_Q(KLineEdit);
1181  QList<QKeySequence> scKey;
1182 
1183  const int key = e->key() | e->modifiers();
1184  const KLineEdit::KeyBindingMap keys = q->keyBindingMap();
1185 
1186  if (keys[KLineEdit::TextCompletion].isEmpty()) {
1188  } else {
1189  scKey = keys[KLineEdit::TextCompletion];
1190  }
1191 
1192  if (scKey.contains(key)) {
1193  return true;
1194  }
1195 
1196  if (keys[KLineEdit::NextCompletionMatch].isEmpty()) {
1198  } else {
1199  scKey = keys[KLineEdit::NextCompletionMatch];
1200  }
1201 
1202  if (scKey.contains(key)) {
1203  return true;
1204  }
1205 
1206  if (keys[KLineEdit::PrevCompletionMatch].isEmpty()) {
1208  } else {
1209  scKey = keys[KLineEdit::PrevCompletionMatch];
1210  }
1211 
1212  if (scKey.contains(key)) {
1213  return true;
1214  }
1215 
1216 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1217  constexpr int ctrlE = QKeyCombination(Qt::CTRL | Qt::Key_E).toCombined();
1218  constexpr int ctrlU = QKeyCombination(Qt::CTRL | Qt::Key_U).toCombined();
1219 #else
1220  constexpr int ctrlE = Qt::CTRL | Qt::Key_E;
1221  constexpr int ctrlU = Qt::CTRL | Qt::Key_U;
1222 #endif
1223 
1224  // Override all the text manupilation accelerators...
1225  if (KStandardShortcut::copy().contains(key)) {
1226  return true;
1227  } else if (KStandardShortcut::paste().contains(key)) {
1228  return true;
1229  } else if (KStandardShortcut::cut().contains(key)) {
1230  return true;
1231  } else if (KStandardShortcut::undo().contains(key)) {
1232  return true;
1233  } else if (KStandardShortcut::redo().contains(key)) {
1234  return true;
1235  } else if (KStandardShortcut::deleteWordBack().contains(key)) {
1236  return true;
1237  } else if (KStandardShortcut::deleteWordForward().contains(key)) {
1238  return true;
1239  } else if (KStandardShortcut::forwardWord().contains(key)) {
1240  return true;
1241  } else if (KStandardShortcut::backwardWord().contains(key)) {
1242  return true;
1243  } else if (KStandardShortcut::beginningOfLine().contains(key)) {
1244  return true;
1245  } else if (KStandardShortcut::endOfLine().contains(key)) {
1246  return true;
1247  }
1248 
1249  // Shortcut overrides for shortcuts that QLineEdit handles
1250  // but doesn't dare force as "stronger than kaction shortcuts"...
1251  else if (e->matches(QKeySequence::SelectAll)) {
1252  return true;
1253  } else if (qApp->platformName() == QLatin1String("xcb") && (key == ctrlE || key == ctrlU)) {
1254  return true;
1255  }
1256 
1257  if (completionBox && completionBox->isVisible()) {
1258  const int key = e->key();
1259  const Qt::KeyboardModifiers modifiers = e->modifiers();
1260  if ((key == Qt::Key_Backtab || key == Qt::Key_Tab) //
1261  && (modifiers == Qt::NoModifier || (modifiers & Qt::ShiftModifier))) {
1262  return true;
1263  }
1264  }
1265 
1266  return false;
1267 }
1268 
1269 void KLineEdit::setCompletedItems(const QStringList &items, bool autoSuggest)
1270 {
1271  Q_D(KLineEdit);
1272  QString txt;
1273  if (d->completionBox && d->completionBox->isVisible()) {
1274  // The popup is visible already - do the matching on the initial string,
1275  // not on the currently selected one.
1276  txt = completionBox()->cancelledText();
1277  } else {
1278  txt = text();
1279  }
1280 
1281  if (!items.isEmpty() //
1282  && !(items.count() == 1 && txt == items.first())) {
1283  // create completion box if non-existent
1284  completionBox();
1285 
1286  if (d->completionBox->isVisible()) {
1287  QListWidgetItem *currentItem = d->completionBox->currentItem();
1288 
1289  QString currentSelection;
1290  if (currentItem != nullptr) {
1291  currentSelection = currentItem->text();
1292  }
1293 
1294  d->completionBox->setItems(items);
1295 
1296  const QList<QListWidgetItem *> matchedItems = d->completionBox->findItems(currentSelection, Qt::MatchExactly);
1297  QListWidgetItem *matchedItem = matchedItems.isEmpty() ? nullptr : matchedItems.first();
1298 
1299  if (matchedItem) {
1300  const bool blocked = d->completionBox->blockSignals(true);
1301  d->completionBox->setCurrentItem(matchedItem);
1302  d->completionBox->blockSignals(blocked);
1303  } else {
1304  d->completionBox->setCurrentRow(-1);
1305  }
1306  } else { // completion box not visible yet -> show it
1307  if (!txt.isEmpty()) {
1308  d->completionBox->setCancelledText(txt);
1309  }
1310  d->completionBox->setItems(items);
1311  d->completionBox->popup();
1312  }
1313 
1314  if (d->autoSuggest && autoSuggest) {
1315  const int index = items.first().indexOf(txt);
1316  const QString newText = items.first().mid(index);
1317  setUserSelection(false); // can be removed? setCompletedText sets it anyway
1318  setCompletedText(newText, true);
1319  }
1320  } else {
1321  if (d->completionBox && d->completionBox->isVisible()) {
1322  d->completionBox->hide();
1323  }
1324  }
1325 }
1326 
1328 {
1329  Q_D(KLineEdit);
1330  if (create && !d->completionBox) {
1331  setCompletionBox(new KCompletionBox(this));
1332  d->completionBox->setObjectName(QStringLiteral("completion box"));
1333  d->completionBox->setFont(font());
1334  }
1335 
1336  return d->completionBox;
1337 }
1338 
1340 {
1341  Q_D(class KLineEdit);
1342 
1343  KCompletion *oldComp = compObj();
1344  if (oldComp && handleSignals()) {
1345  disconnect(d->m_matchesConnection);
1346  }
1347 
1348  if (comp && handle) {
1349  d->m_matchesConnection = connect(comp, &KCompletion::matches, this, [this](const QStringList &list) {
1350  setCompletedItems(list);
1351  });
1352  }
1353 
1355 }
1356 
1357 void KLineEdit::setUserSelection(bool userSelection)
1358 {
1359  Q_D(KLineEdit);
1360  // if !d->userSelection && userSelection we are accepting a completion,
1361  // so trigger an update
1362 
1363  if (!d->userSelection && userSelection) {
1364  d->updateUserText(text());
1365  }
1366 
1367  QPalette p = palette();
1368 
1369  if (userSelection) {
1370  p.setColor(QPalette::Highlight, d->previousHighlightColor);
1371  p.setColor(QPalette::HighlightedText, d->previousHighlightedTextColor);
1372  } else {
1376  p.setColor(QPalette::Highlight, color);
1377  }
1378 
1379  d->userSelection = userSelection;
1380  setPalette(p);
1381 }
1382 
1383 void KLineEditPrivate::_k_restoreSelectionColors()
1384 {
1385  Q_Q(KLineEdit);
1386  if (disableRestoreSelection) {
1387  return;
1388  }
1389 
1390  q->setUserSelection(true);
1391 }
1392 
1393 void KLineEditPrivate::_k_completionBoxTextChanged(const QString &text)
1394 {
1395  Q_Q(KLineEdit);
1396  if (!text.isEmpty()) {
1397  q->setText(text);
1398  q->setModified(true);
1399  q->end(false); // force cursor at end
1400  }
1401 }
1402 
1404 {
1405  Q_D(const KLineEdit);
1406  if (d->enableSqueezedText && isReadOnly()) {
1407  return d->squeezedText;
1408  }
1409 
1410  return text();
1411 }
1412 
1414 {
1415  Q_D(const KLineEdit);
1416  return d->userText;
1417 }
1418 
1420 {
1421  Q_D(const KLineEdit);
1422  return d->autoSuggest;
1423 }
1424 
1425 void KLineEdit::paintEvent(QPaintEvent *ev)
1426 {
1427  Q_D(KLineEdit);
1428  if (echoMode() == Password && d->threeStars) {
1429  // ### hack alert!
1430  // QLineEdit has currently no hooks to modify the displayed string.
1431  // When we call setText(), an update() is triggered and we get
1432  // into an infinite recursion.
1433  // Qt offers the setUpdatesEnabled() method, but when we re-enable
1434  // them, update() is triggered, and we get into the same recursion.
1435  // To work around this problem, we set/clear the internal Qt flag which
1436  // marks the updatesDisabled state manually.
1438  blockSignals(true);
1439  const QString oldText = text();
1440  const bool isModifiedState = isModified(); // save modified state because setText resets it
1441  setText(oldText + oldText + oldText);
1443  setText(oldText);
1444  setModified(isModifiedState);
1445  blockSignals(false);
1447  } else {
1449  }
1450 }
1451 
1452 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 0)
1454 {
1455  setPlaceholderText(msg);
1456 }
1457 #endif
1458 
1459 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
1461 {
1463 }
1464 #endif
1465 
1466 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
1468 {
1470 }
1471 #endif
1472 
1473 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 83)
1474 void KLineEdit::setPasswordMode(bool passwordMode)
1475 {
1476  Q_D(KLineEdit);
1477  if (passwordMode) {
1478  KConfigGroup cg(KSharedConfig::openConfig(), "Passwords");
1479  const QString val = cg.readEntry("EchoMode", "OneStar");
1480  if (val == QLatin1String("NoEcho")) {
1482  } else {
1483  d->threeStars = (val == QLatin1String("ThreeStars"));
1485  }
1486  } else {
1488  }
1489 }
1490 #endif
1491 
1492 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 83)
1493 bool KLineEdit::passwordMode() const
1494 {
1495  return echoMode() == NoEcho || echoMode() == Password;
1496 }
1497 #endif
1498 
1500 {
1501  Q_D(KLineEdit);
1502  if (emitSignals()) {
1503  Q_EMIT completion(text); // emit when requested...
1504  }
1505  d->completionRunning = true;
1506  if (handleSignals()) {
1507  makeCompletion(text); // handle when requested...
1508  }
1509  d->completionRunning = false;
1510 }
1511 
1512 #include "moc_klineedit.cpp"
QString previousMatch()
Returns the next item from the list of matching items.
const QColor & color(QPalette::ColorGroup group, QPalette::ColorRole role) const const
void paste()
void triggered(QAction *action)
T & first()
void removeEventFilter(QObject *obj)
void showText(const QPoint &pos, const QString &text, QWidget *w)
QString readEntry(const char *key, const char *aDefault=nullptr) const
QString text() const const
const QList< QKeySequence > & pasteSelection()
void setCompletionMode(KCompletion::CompletionMode mode) override
Reimplemented from KCompletionBase for internal reasons.
Definition: klineedit.cpp:191
void activated(const QString &text)
Emitted when an item is selected, text is the text of the selected item.
@ CompletionAuto
Text is automatically filled in whenever possible.
Definition: kcompletion.h:139
@ CompletionPopup
Lists all possible matches in a popup list box to choose from.
Definition: kcompletion.h:151
void addActions(QList< QAction * > actions)
QList< QAction * > actions() const const
ShortcutOverride
bool event(QEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:1052
QMenu * createStandardContextMenu()
virtual void mouseDoubleClickEvent(QMouseEvent *e) override
const QPoint & globalPos() const const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
const QList< QKeySequence > & shortcut(StandardShortcut id)
Q_EMITQ_EMIT
Qt::MouseButton button() const const
void setSelection(int start, int length)
bool handleSignals() const
Returns true if the object handles the signals.
void setShortcuts(const QList< QKeySequence > &shortcuts)
void setUserSelection(bool userSelection)
Sets the widget in userSelection mode or in automatic completion selection mode.
Definition: klineedit.cpp:1357
void undo()
int count(const T &value) const const
@ PrevCompletionMatch
Switch to previous completion (by default Ctrl-Up).
void cursorWordBackward(bool mark)
virtual void resizeEvent(QResizeEvent *event)
QString trimmed() const const
void clear()
A generic class for completing QStrings.
Definition: kcompletion.h:117
Q_SCRIPTABLE Q_NOREPLY void start()
@ CompletionMan
Same as automatic, but shortest match is used for completion.
Definition: kcompletion.h:143
void setClearButtonShown(bool show)
This makes the line edit display an icon on one side of the line edit which, when clicked,...
Definition: klineedit.cpp:161
QIcon fromTheme(const QString &name)
QAction * addSeparator()
void aboutToShowContextMenu(QMenu *contextMenu)
Emitted before the context menu is displayed.
int selectionStart() const const
KLineEdit(const QString &string, QWidget *parent=nullptr)
Constructs a KLineEdit object with a default text, a parent, and a name.
Definition: klineedit.cpp:133
void resizeEvent(QResizeEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:481
void selectAll()
void setCompletionModeDisabled(KCompletion::CompletionMode mode, bool disable=true)
Disables completion modes by making them non-checkable.
Definition: klineedit.cpp:221
void setTrapReturnKey(bool trap)
By default, KLineEdit recognizes Key_Return and Key_Enter and emits the returnPressed() signals,...
Definition: klineedit.cpp:1102
DefaultContextMenu
virtual void keyPressEvent(QKeyEvent *event) override
virtual void setText(const QString &)
Reimplemented to enable text squeezing.
Definition: klineedit.cpp:362
void setClearButtonEnabled(bool enable)
const QList< QKeySequence > & undo()
const QChar * unicode() const const
void setAttribute(Qt::WidgetAttribute attribute, bool on)
bool isSqueezedTextEnabled() const
Returns true if text squeezing is enabled.
Definition: klineedit.cpp:356
void cursorWordForward(bool mark)
NoButton
bool contains(const T &value) const const
const QList< QKeySequence > & forwardWord()
void mousePressEvent(QMouseEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:871
virtual void copy() const
Reimplemented for internal reasons, the API is not affected.
Definition: klineedit.cpp:442
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
CompletionMode
This enum describes the completion mode used for by the KCompletion class.
Definition: kcompletion.h:131
@ CompletionNone
No completion is used.
Definition: kcompletion.h:135
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QString text() const const
virtual bool event(QEvent *e) override
void insertAction(QAction *before, QAction *action)
void setSqueezedText(const QString &text)
Squeezes text into the line edit.
Definition: klineedit.cpp:344
QString userText() const
Returns the text as given by the user (i.e.
Definition: klineedit.cpp:1413
void end(bool mark)
bool emitSignals() const
Returns true if the object emits the signals.
void del()
QAction * addAction(const QString &text)
void cut()
QClipboard * clipboard()
void clear()
Qt::KeyboardModifiers modifiers() const const
bool isPrint() const const
void insert(const QString &newText)
void redo()
void completionBoxActivated(const QString &)
Emitted whenever the completion box is activated.
void setUrl(const QUrl &url)
Sets url into the lineedit.
Definition: klineedit.cpp:1114
KCompletion * compObj() const
Returns a pointer to the completion object.
QSize clearButtonUsedSize() const
Definition: klineedit.cpp:174
QList< QAction * > actions() const const
@ NextCompletionMatch
Switch to next completion (by default Ctrl-Down).
void matches(const QStringList &matchlist)
This signal is emitted by makeCompletion() in shell-completion mode when the same string is passed to...
void keyPressEvent(QKeyEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:491
void currentTextChanged(const QString &currentText)
bool blockSignals(bool block)
virtual void setContextMenuEnabled(bool showMenu)
Enables/disables the popup (context) menu.
Definition: klineedit.cpp:1460
const QList< QKeySequence > & cut()
~KLineEdit() override
Destructor.
Definition: klineedit.cpp:149
virtual KCompletionBox * completionBox(bool create=true)
This method will create a completion-box if none is there, yet.
Definition: klineedit.cpp:1327
void mouseDoubleClickEvent(QMouseEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:859
int indexOf(const T &value, int from) const const
KCompletion::CompletionMode completionMode() const
Returns the current completion mode.
void rotateText(KCompletionBase::KeyBindingType type)
Iterates through all possible matches of the completed text or the history list.
Definition: klineedit.cpp:257
void installEventFilter(QObject *filterObj)
void textChanged(const QString &text)
QString nextMatch()
Returns the next item from the list of matching items.
void setClickMessage(const QString &msg)
This makes the line edit display a grayed-out hinting text as long as the user didn't enter any text.
Definition: klineedit.cpp:1453
bool isEmpty() const const
void setSqueezedTextEnabled(bool enable)
Enable text squeezing whenever the supplied text is too long.
Definition: klineedit.cpp:350
virtual void setCompletionMode(KCompletion::CompletionMode mode)
Sets the type of completion to be used.
virtual void setCompletionObject(KCompletion *completionObject, bool handleSignals=true)
Sets up the completion object to be used.
bool trapReturnKey() const
Definition: klineedit.cpp:1108
bool matches(QKeySequence::StandardKey key) const const
int length() const const
void contextMenuEvent(QContextMenuEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:1003
QString toDisplayString(QUrl::FormattingOptions options) const const
QAction * addMenu(QMenu *menu)
QString text(QClipboard::Mode mode) const const
const T & at(int i) const const
void returnPressed()
void setBackgroundRole(QPalette::ColorRole role)
@ SubstringCompletion
Substring completion (by default Ctrl-T).
void textRotation(KCompletionBase::KeyBindingType)
Emitted when the text rotation key-bindings are pressed.
void backspace()
bool isEmpty() const const
KeyBindingMap keyBindingMap() const
Returns a key binding map.
void clearButtonClicked()
Emitted when the user clicked on the clear button.
@ CompletionShell
Completes text much in the same way as a typical *nix shell would.
Definition: kcompletion.h:147
void deselect()
bool isContextMenuEnabled() const
Returns true when the context menu is enabled.
Definition: klineedit.cpp:1467
A helper widget for "completion-widgets" (KLineEdit, KComboBox))
Key_Return
KSharedConfigPtr config()
void setText(const QString &text, QClipboard::Mode mode)
QStringList allMatches()
Returns a list of all items matching the last completed string.
@ CompletionPopupAuto
Lists all possible matches in a popup list box to choose from, and automatically fills the result whe...
Definition: kcompletion.h:156
KeyBindingType
Constants that represent the items whose shortcut key binding is programmable.
const QList< QKeySequence > & deleteWordBack()
@ TextCompletion
Text completion (by default Ctrl-E).
void mouseReleaseEvent(QMouseEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:893
virtual void setReadOnly(bool)
Sets the lineedit to read-only.
Definition: klineedit.cpp:317
PM_DefaultFrameWidth
void setColor(QPalette::ColorGroup group, QPalette::ColorRole role, const QColor &color)
void completion(const QString &)
Emitted when the completion key is pressed.
void substringCompletion(const QString &)
Emitted when the shortcut for substring completion is pressed.
void show()
virtual QString makeCompletion(const QString &string)
Attempts to find an item in the list of available completions that begins with string.
KCONFIGCORE_EXPORT bool authorize(const QString &action)
virtual void mouseReleaseEvent(QMouseEvent *e) override
void textEdited(const QString &text)
void userCancelled(const QString &)
Emitted whenever the user chooses to ignore the available selections and closes this box.
void userCancelled(const QString &cancelText)
Resets the current displayed text.
Definition: klineedit.cpp:1159
void triggered(bool checked)
virtual void paintEvent(QPaintEvent *) override
virtual void makeCompletion(const QString &)
Completes the remaining text with a matching one from a given list.
Definition: klineedit.cpp:279
void setEnabled(bool)
int key() const const
void setPasswordMode(bool passwordMode=true)
set the line edit in password mode.
Definition: klineedit.cpp:1474
QString left(int n) const const
QString right(int n) const const
QEvent::Type type() const const
void returnKeyPressed(const QString &text)
Emitted when the user presses the Return or Enter key.
const QList< QKeySequence > & deleteWordForward()
void ignore()
void setCompletionObject(KCompletion *, bool handle=true) override
Reimplemented for internal reasons, the API is not affected.
Definition: klineedit.cpp:1339
bool shouldAutoSuggest() const
Informs the caller if they should display the auto-suggestion for the last completion operation perfo...
const QList< QKeySequence > & backwardWord()
void setUrlDropsEnabled(bool enable)
Enables/Disables handling of URL drops.
Definition: klineedit.cpp:1083
const QList< QKeySequence > & paste()
void setCompletedItems(const QStringList &items, bool autoSuggest=true) override
Same as the above function except it allows you to temporarily turn off text completion in Completion...
Definition: klineedit.cpp:1269
bool autoSuggest() const
Whether in current state text should be auto-suggested.
Definition: klineedit.cpp:1419
void setCompletedText(const QString &) override
See KCompletionBase::setCompletedText.
Definition: klineedit.cpp:247
void doCompletion(const QString &text)
Do completion now.
Definition: klineedit.cpp:1499
QPalette palette()
void setCursorPosition(int)
QPalette::ColorRole backgroundRole() const const
QAction * addAction(QAction *action)
MatchExactly
static void setAutoHideCursor(QWidget *w, bool enable, bool customEventFilter=false)
bool isModified() const const
void textActivated(const QString &text)
Emitted when an item is selected, text is the text of the selected item.
void selectionChanged()
KeypadModifier
QList< QKeySequence > keyBindings(QKeySequence::StandardKey key)
void objectNameChanged(const QString &objectName)
void home(bool mark)
QString mid(int position, int n) const const
QString tr(const char *sourceText, const char *disambiguation, int n)
void setCompletionBox(KCompletionBox *box)
Set the completion-box to be used in completion mode CompletionPopup.
Definition: klineedit.cpp:1119
bool isClearButtonShown() const
Definition: klineedit.cpp:168
void create(WId window, bool initializeWindow, bool destroyOldWindow)
QString originalText() const
Returns the original text if text squeezing is enabled.
Definition: klineedit.cpp:1403
QMenu * createStandardContextMenu()
Reimplemented for internal reasons.
Definition: klineedit.cpp:911
void copy() const const
WA_UpdatesDisabled
const QList< QKeySequence > & end()
const QList< QKeySequence > & copy()
const QList< QKeySequence > & redo()
QAction * exec()
const QList< QKeySequence > & beginningOfLine()
Q_D(Todo)
const QList< QKeySequence > & endOfLine()
static void autoHideEventFilter(QObject *, QEvent *)
void accept()
virtual void mousePressEvent(QMouseEvent *e) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Wed Jun 29 2022 04:14:59 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.