KCompletion

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

KDE's Doxygen guidelines are available online.