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)
155 {
156  return placeholderText();
157 }
158 #endif
159 
160 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 46)
162 {
163  setClearButtonEnabled(show);
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 
318 {
319  Q_D(KLineEdit);
320  // Do not do anything if nothing changed...
321  if (readOnly == isReadOnly()) {
322  return;
323  }
324 
325  QLineEdit::setReadOnly(readOnly);
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 
371  QLineEdit::setText(text);
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()) {
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);
1172  setCursorPosition(start);
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  // Override all the text manupilation accelerators...
1217  if (KStandardShortcut::copy().contains(key)) {
1218  return true;
1219  } else if (KStandardShortcut::paste().contains(key)) {
1220  return true;
1221  } else if (KStandardShortcut::cut().contains(key)) {
1222  return true;
1223  } else if (KStandardShortcut::undo().contains(key)) {
1224  return true;
1225  } else if (KStandardShortcut::redo().contains(key)) {
1226  return true;
1227  } else if (KStandardShortcut::deleteWordBack().contains(key)) {
1228  return true;
1229  } else if (KStandardShortcut::deleteWordForward().contains(key)) {
1230  return true;
1231  } else if (KStandardShortcut::forwardWord().contains(key)) {
1232  return true;
1233  } else if (KStandardShortcut::backwardWord().contains(key)) {
1234  return true;
1235  } else if (KStandardShortcut::beginningOfLine().contains(key)) {
1236  return true;
1237  } else if (KStandardShortcut::endOfLine().contains(key)) {
1238  return true;
1239  }
1240 
1241  // Shortcut overrides for shortcuts that QLineEdit handles
1242  // but doesn't dare force as "stronger than kaction shortcuts"...
1243  else if (e->matches(QKeySequence::SelectAll)) {
1244  return true;
1245  } else if (qApp->platformName() == QLatin1String("xcb") && (key == (Qt::CTRL | Qt::Key_E) || key == (Qt::CTRL | Qt::Key_U))) {
1246  return true;
1247  }
1248 
1250  const int key = e->key();
1251  const Qt::KeyboardModifiers modifiers = e->modifiers();
1252  if ((key == Qt::Key_Backtab || key == Qt::Key_Tab) //
1253  && (modifiers == Qt::NoModifier || (modifiers & Qt::ShiftModifier))) {
1254  return true;
1255  }
1256  }
1257 
1258  return false;
1259 }
1260 
1262 {
1263  Q_D(KLineEdit);
1264  QString txt;
1265  if (d->completionBox && d->completionBox->isVisible()) {
1266  // The popup is visible already - do the matching on the initial string,
1267  // not on the currently selected one.
1268  txt = completionBox()->cancelledText();
1269  } else {
1270  txt = text();
1271  }
1272 
1273  if (!items.isEmpty() //
1274  && !(items.count() == 1 && txt == items.first())) {
1275  // create completion box if non-existent
1276  completionBox();
1277 
1278  if (d->completionBox->isVisible()) {
1279  QListWidgetItem *currentItem = d->completionBox->currentItem();
1280 
1281  QString currentSelection;
1282  if (currentItem != nullptr) {
1283  currentSelection = currentItem->text();
1284  }
1285 
1286  d->completionBox->setItems(items);
1287 
1288  const QList<QListWidgetItem *> matchedItems = d->completionBox->findItems(currentSelection, Qt::MatchExactly);
1289  QListWidgetItem *matchedItem = matchedItems.isEmpty() ? nullptr : matchedItems.first();
1290 
1291  if (matchedItem) {
1292  const bool blocked = d->completionBox->blockSignals(true);
1293  d->completionBox->setCurrentItem(matchedItem);
1294  d->completionBox->blockSignals(blocked);
1295  } else {
1296  d->completionBox->setCurrentRow(-1);
1297  }
1298  } else { // completion box not visible yet -> show it
1299  if (!txt.isEmpty()) {
1300  d->completionBox->setCancelledText(txt);
1301  }
1302  d->completionBox->setItems(items);
1303  d->completionBox->popup();
1304  }
1305 
1306  if (d->autoSuggest && autoSuggest) {
1307  const int index = items.first().indexOf(txt);
1308  const QString newText = items.first().mid(index);
1309  setUserSelection(false); // can be removed? setCompletedText sets it anyway
1310  setCompletedText(newText, true);
1311  }
1312  } else {
1313  if (d->completionBox && d->completionBox->isVisible()) {
1314  d->completionBox->hide();
1315  }
1316  }
1317 }
1318 
1320 {
1321  Q_D(KLineEdit);
1322  if (create && !d->completionBox) {
1323  setCompletionBox(new KCompletionBox(this));
1324  d->completionBox->setObjectName(QStringLiteral("completion box"));
1325  d->completionBox->setFont(font());
1326  }
1327 
1328  return d->completionBox;
1329 }
1330 
1332 {
1333  KCompletion *oldComp = compObj();
1334  if (oldComp && handleSignals()) {
1335  disconnect(oldComp, SIGNAL(matches(QStringList)), this, SLOT(setCompletedItems(QStringList)));
1336  }
1337 
1338  if (comp && handle) {
1339  connect(comp, SIGNAL(matches(QStringList)), this, SLOT(setCompletedItems(QStringList)));
1340  }
1341 
1343 }
1344 
1345 void KLineEdit::setUserSelection(bool userSelection)
1346 {
1347  Q_D(KLineEdit);
1348  // if !d->userSelection && userSelection we are accepting a completion,
1349  // so trigger an update
1350 
1351  if (!d->userSelection && userSelection) {
1352  d->updateUserText(text());
1353  }
1354 
1355  QPalette p = palette();
1356 
1357  if (userSelection) {
1358  p.setColor(QPalette::Highlight, d->previousHighlightColor);
1359  p.setColor(QPalette::HighlightedText, d->previousHighlightedTextColor);
1360  } else {
1364  p.setColor(QPalette::Highlight, color);
1365  }
1366 
1367  d->userSelection = userSelection;
1368  setPalette(p);
1369 }
1370 
1371 void KLineEditPrivate::_k_restoreSelectionColors()
1372 {
1373  Q_Q(KLineEdit);
1374  if (disableRestoreSelection) {
1375  return;
1376  }
1377 
1378  q->setUserSelection(true);
1379 }
1380 
1381 void KLineEditPrivate::_k_completionBoxTextChanged(const QString &text)
1382 {
1383  Q_Q(KLineEdit);
1384  if (!text.isEmpty()) {
1385  q->setText(text);
1386  q->setModified(true);
1387  q->end(false); // force cursor at end
1388  }
1389 }
1390 
1392 {
1393  Q_D(const KLineEdit);
1394  if (d->enableSqueezedText && isReadOnly()) {
1395  return d->squeezedText;
1396  }
1397 
1398  return text();
1399 }
1400 
1402 {
1403  Q_D(const KLineEdit);
1404  return d->userText;
1405 }
1406 
1408 {
1409  Q_D(const KLineEdit);
1410  return d->autoSuggest;
1411 }
1412 
1413 void KLineEdit::paintEvent(QPaintEvent *ev)
1414 {
1415  Q_D(KLineEdit);
1416  if (echoMode() == Password && d->threeStars) {
1417  // ### hack alert!
1418  // QLineEdit has currently no hooks to modify the displayed string.
1419  // When we call setText(), an update() is triggered and we get
1420  // into an infinite recursion.
1421  // Qt offers the setUpdatesEnabled() method, but when we re-enable
1422  // them, update() is triggered, and we get into the same recursion.
1423  // To work around this problem, we set/clear the internal Qt flag which
1424  // marks the updatesDisabled state manually.
1426  blockSignals(true);
1427  const QString oldText = text();
1428  const bool isModifiedState = isModified(); // save modified state because setText resets it
1429  setText(oldText + oldText + oldText);
1431  setText(oldText);
1432  setModified(isModifiedState);
1433  blockSignals(false);
1435  } else {
1437  }
1438 }
1439 
1440 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 0)
1442 {
1443  setPlaceholderText(msg);
1444 }
1445 #endif
1446 
1447 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
1449 {
1451 }
1452 #endif
1453 
1454 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
1456 {
1458 }
1459 #endif
1460 
1461 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 83)
1463 {
1464  Q_D(KLineEdit);
1465  if (passwordMode) {
1466  KConfigGroup cg(KSharedConfig::openConfig(), "Passwords");
1467  const QString val = cg.readEntry("EchoMode", "OneStar");
1468  if (val == QLatin1String("NoEcho")) {
1470  } else {
1471  d->threeStars = (val == QLatin1String("ThreeStars"));
1473  }
1474  } else {
1476  }
1477 }
1478 #endif
1479 
1480 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 83)
1481 bool KLineEdit::passwordMode() const
1482 {
1483  return echoMode() == NoEcho || echoMode() == Password;
1484 }
1485 #endif
1486 
1488 {
1489  Q_D(KLineEdit);
1490  if (emitSignals()) {
1491  Q_EMIT completion(text); // emit when requested...
1492  }
1493  d->completionRunning = true;
1494  if (handleSignals()) {
1495  makeCompletion(text); // handle when requested...
1496  }
1497  d->completionRunning = false;
1498 }
1499 
1500 #include "moc_klineedit.cpp"
void setCompletionModeDisabled(KCompletion::CompletionMode mode, bool disable=true)
Disables completion modes by making them non-checkable.
Definition: klineedit.cpp:221
void undo()
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:1261
KeypadModifier
void triggered(bool checked)
Qt::KeyboardModifiers modifiers() const const
const QList< QKeySequence > & redo()
ShortcutOverride
const QList< QKeySequence > & deleteWordBack()
QEvent::Type type() const const
int doubleClickInterval()
const QPalette & palette() const const
QString toDisplayString(QUrl::FormattingOptions options) const const
Lists all possible matches in a popup list box to choose from.
Definition: kcompletion.h:151
void create(WId window, bool initializeWindow, bool destroyOldWindow)
int width() const const
void keyPressEvent(QKeyEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:491
MatchExactly
void setColor(QPalette::ColorGroup group, QPalette::ColorRole role, const QColor &color)
void setPasswordMode(bool passwordMode=true)
set the line edit in password mode.
Definition: klineedit.cpp:1462
void clear()
QString text() const const
A helper widget for "completion-widgets" (KLineEdit, KComboBox))
void addActions(QList< QAction * > actions)
QMenu * createStandardContextMenu()
Reimplemented for internal reasons.
Definition: klineedit.cpp:911
virtual bool event(QEvent *e) override
void paste()
Text is automatically filled in whenever possible.
Definition: kcompletion.h:139
const QColor & color(QPalette::ColorGroup group, QPalette::ColorRole role) const const
const T & at(int i) const const
QString userText() const
Returns the text as given by the user (i.e.
Definition: klineedit.cpp:1401
Switch to next completion (by default Ctrl-Down).
KLineEdit(const QString &string, QWidget *parent=nullptr)
Constructs a KLineEdit object with a default text, a parent, and a name.
Definition: klineedit.cpp:133
bool hasSelectedText() const const
bool isVisible() const const
void setCompletionBox(KCompletionBox *box)
Set the completion-box to be used in completion mode CompletionPopup.
Definition: klineedit.cpp:1119
QMenu * createStandardContextMenu()
NoButton
bool isSqueezedTextEnabled() const
Returns true if text squeezing is enabled.
Definition: klineedit.cpp:356
void triggered(QAction *action)
bool trapReturnKey() const
Definition: klineedit.cpp:1108
void setAttribute(Qt::WidgetAttribute attribute, bool on)
QLineEdit::EchoMode echoMode() const const
void textChanged(const QString &text)
bool autoSuggest() const
Whether in current state text should be auto-suggested.
Definition: klineedit.cpp:1407
QAction * addAction(QAction *action)
KCompletion * compObj() const
Returns a pointer to the completion object.
QString clickMessage() const
bool event(QEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:1052
void textActivated(const QString &text)
Emitted when an item is selected, text is the text of the selected item.
void textRotation(KCompletionBase::KeyBindingType)
Emitted when the text rotation key-bindings are pressed.
QString & remove(int position, int n)
Text completion (by default Ctrl-E).
const QList< QKeySequence > & cut()
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
const QPoint & globalPos() const const
void showText(const QPoint &pos, const QString &text, QWidget *w)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString selectedText() const const
virtual void keyPressEvent(QKeyEvent *event) override
QAction * addAction(const QString &text)
virtual KCompletionBox * completionBox(bool create=true)
This method will create a completion-box if none is there, yet.
Definition: klineedit.cpp:1319
DefaultContextMenu
void cursorWordBackward(bool mark)
static void autoHideEventFilter(QObject *, QEvent *)
bool isModified() const const
void setUrl(const QUrl &url)
Sets url into the lineedit.
Definition: klineedit.cpp:1114
KSharedConfigPtr config()
KCompletion::CompletionMode completionMode() const
Returns the current completion mode.
void userCancelled(const QString &cancelText)
Resets the current displayed text.
Definition: klineedit.cpp:1159
int indexOf(const T &value, int from) const const
void clear()
void contextMenuEvent(QContextMenuEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:1003
void clearButtonClicked()
Emitted when the user clicked on the clear button.
const QList< QKeySequence > & deleteWordForward()
virtual void setContextMenuEnabled(bool showMenu)
Enables/disables the popup (context) menu.
Definition: klineedit.cpp:1448
void setUrlDropsEnabled(bool enable)
Enables/Disables handling of URL drops.
Definition: klineedit.cpp:1083
bool isPrint() const const
KeyBindingMap keyBindingMap() const
Returns a key binding map.
const QList< QKeySequence > & beginningOfLine()
void mouseDoubleClickEvent(QMouseEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:859
void setCompletionMode(KCompletion::CompletionMode mode) override
Reimplemented from KCompletionBase for internal reasons.
Definition: klineedit.cpp:191
void insertAction(QAction *before, QAction *action)
const QList< QKeySequence > & undo()
int count(const T &value) const const
void mouseReleaseEvent(QMouseEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:893
const QList< QKeySequence > & forwardWord()
void setShortcuts(const QList< QKeySequence > &shortcuts)
void returnKeyPressed(const QString &text)
Emitted when the user presses the Return or Enter key.
void ignore()
Substring completion (by default Ctrl-T).
void substringCompletion(const QString &)
Emitted when the shortcut for substring completion is pressed.
void installEventFilter(QObject *filterObj)
Switch to previous completion (by default Ctrl-Up).
void completion(const QString &)
Emitted when the completion key is pressed.
const QList< QKeySequence > & copy()
No completion is used.
Definition: kcompletion.h:135
bool passwordMode() const
bool urlDropsEnabled() const
Returns true when decoded URL drops are enabled.
QPalette palette()
QStringList allMatches()
Returns a list of all items matching the last completed string.
Qt::MouseButton button() const const
QPalette::ColorRole backgroundRole() const const
CompletionMode
This enum describes the completion mode used for by the KCompletion class.
Definition: kcompletion.h:131
bool isEmpty() const const
bool isEmpty() const const
QString trimmed() const const
A generic class for completing QStrings.
Definition: kcompletion.h:117
void setUserSelection(bool userSelection)
Sets the widget in userSelection mode or in automatic completion selection mode.
Definition: klineedit.cpp:1345
QString text() const const
void setSqueezedTextEnabled(bool enable)
Enable text squeezing whenever the supplied text is too long.
Definition: klineedit.cpp:350
void setClearButtonEnabled(bool enable)
bool handleSignals() const
Returns true if the object handles the signals.
T & first()
QAction * addSeparator()
void hide()
void aboutToShowContextMenu(QMenu *contextMenu)
Emitted before the context menu is displayed.
void selectAll()
const QList< QKeySequence > & pasteSelection()
QString placeholderText() const const
void setSqueezedText(const QString &text)
Squeezes text into the line edit.
Definition: klineedit.cpp:344
QAction * exec()
virtual void paintEvent(QPaintEvent *) override
void backspace()
bool matches(QKeySequence::StandardKey key) const const
void redo()
void completionBoxActivated(const QString &)
Emitted whenever the completion box is activated.
void setCompletedText(const QString &) override
See KCompletionBase::setCompletedText.
Definition: klineedit.cpp:247
QString right(int n) const const
virtual void mouseReleaseEvent(QMouseEvent *e) override
int selectionStart() const const
QString originalText() const
Returns the original text if text squeezing is enabled.
Definition: klineedit.cpp:1391
static void setAutoHideCursor(QWidget *w, bool enable, bool customEventFilter=false)
int key() const const
void textEdited(const QString &text)
void setCompletionObject(KCompletion *, bool handle=true) override
Reimplemented for internal reasons, the API is not affected.
Definition: klineedit.cpp:1331
void accept()
void insert(const QString &newText)
bool blockSignals(bool block)
void setTrapReturnKey(bool trap)
By default, KLineEdit recognizes Key_Return and Key_Enter and emits the returnPressed() signals...
Definition: klineedit.cpp:1102
const QFont & font() const const
Qt::ContextMenuPolicy contextMenuPolicy() const const
bool contains(const T &value) const const
QString nextMatch()
Returns the next item from the list of matching items.
void resizeEvent(QResizeEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:481
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
QSize clearButtonUsedSize() const
Definition: klineedit.cpp:174
const QList< QKeySequence > & endOfLine()
void mousePressEvent(QMouseEvent *) override
Reimplemented for internal reasons.
Definition: klineedit.cpp:871
virtual void setCompletionMode(KCompletion::CompletionMode mode)
Sets the type of completion to be used.
bool isContextMenuEnabled() const
Returns true when the context menu is enabled.
Definition: klineedit.cpp:1455
WA_UpdatesDisabled
void returnPressed()
QString text(QClipboard::Mode mode) const const
const QChar * unicode() const const
QList< QAction * > actions() const const
Completes text much in the same way as a typical *nix shell would.
Definition: kcompletion.h:147
void end(bool mark)
virtual QString makeCompletion(const QString &string)
Attempts to find an item in the list of available completions that begins with string.
An enhanced QLineEdit widget for inputting text.
Definition: klineedit.h:138
void cut()
PM_DefaultFrameWidth
QString mid(int position, int n) const const
void del()
const QList< QKeySequence > & backwardWord()
void currentTextChanged(const QString &currentText)
void objectNameChanged(const QString &objectName)
void home(bool mark)
void cursorWordForward(bool mark)
virtual void copy() const
Reimplemented for internal reasons, the API is not affected.
Definition: klineedit.cpp:442
void selectionChanged()
QAction * addMenu(QMenu *menu)
KCONFIGCORE_EXPORT bool authorize(const QString &action)
bool isClearButtonShown() const
Definition: klineedit.cpp:168
int length() const const
bool emitSignals() const
Returns true if the object emits the signals.
KeyBindingType
Constants that represent the items whose shortcut key binding is programmable.
QString left(int n) const const
void userCancelled(const QString &)
Emitted whenever the user chooses to ignore the available selections and closes this box...
~KLineEdit() override
Destructor.
Definition: klineedit.cpp:149
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)
QList< QKeySequence > keyBindings(QKeySequence::StandardKey key)
void setText(const QString &text, QClipboard::Mode mode)
QSize size(int flags, const QString &text, int tabStops, int *tabArray) const const
const QList< QKeySequence > & shortcut(StandardShortcut id)
void show()
void setClickMessage(const QString &msg)
This makes the line edit display a grayed-out hinting text as long as the user didn&#39;t enter any text...
Definition: klineedit.cpp:1441
Lists all possible matches in a popup list box to choose from, and automatically fills the result whe...
Definition: kcompletion.h:156
virtual void setCompletionObject(KCompletion *completionObject, bool handleSignals=true)
Sets up the completion object to be used.
const QList< QKeySequence > & paste()
virtual void resizeEvent(QResizeEvent *event)
void copy() const const
void setBackgroundRole(QPalette::ColorRole role)
bool shouldAutoSuggest() const
Informs the caller if they should display the auto-suggestion for the last completion operation perfo...
void setCursorPosition(int)
virtual void makeCompletion(const QString &)
Completes the remaining text with a matching one from a given list.
Definition: klineedit.cpp:279
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QList< QAction * > actions() const const
void activated(const QString &text)
Emitted when an item is selected, text is the text of the selected item.
T qobject_cast(QObject *object)
virtual void setReadOnly(bool)
Sets the lineedit to read-only.
Definition: klineedit.cpp:317
QObject * parent() const const
virtual void setText(const QString &)
Reimplemented to enable text squeezing.
Definition: klineedit.cpp:362
virtual void mouseDoubleClickEvent(QMouseEvent *e) override
void deselect()
T readEntry(const QString &key, const T &aDefault) const
QClipboard * clipboard()
Same as automatic, but shortest match is used for completion.
Definition: kcompletion.h:143
Key_Return
void setEnabled(bool)
QString text() const const
QString previousMatch()
Returns the next item from the list of matching items.
void rotateText(KCompletionBase::KeyBindingType type)
Iterates through all possible matches of the completed text or the history list.
Definition: klineedit.cpp:257
void removeEventFilter(QObject *obj)
virtual void mousePressEvent(QMouseEvent *e) override
int height() const const
Q_EMITQ_EMIT
void doCompletion(const QString &text)
Do completion now.
Definition: klineedit.cpp:1487
void setSelection(int start, int length)
QString displayText() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Dec 6 2021 22:47:04 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.