KCompletion

kcombobox.cpp
1/*
2 This file is part of the KDE libraries
3
4 SPDX-FileCopyrightText: 2000, 2001 Dawit Alemayehu <adawit@kde.org>
5 SPDX-FileCopyrightText: 2000, 2001 Carsten Pfeiffer <pfeiffer@kde.org>
6 SPDX-FileCopyrightText: 2000 Stefan Schimanski <1Stein@gmx.de>
7
8 SPDX-License-Identifier: LGPL-2.1-or-later
9*/
10
11#include "kcombobox.h"
12#include "kcombobox_p.h"
13
14#include <kcompletion_debug.h>
15#include <kcompletionbox.h>
16
17#include <QUrl>
18
19void KComboBoxPrivate::init()
20{
21 Q_Q(KComboBox);
22}
23
24void KComboBoxPrivate::slotLineEditDeleted(QLineEdit *sender)
25{
26 Q_Q(KComboBox);
27 // yes, we need those ugly casts due to the multiple inheritance
28 // "sender" is guaranteed to be a KLineEdit (see the connect() to the
29 // destroyed() signal
30 const KCompletionBase *base = static_cast<const KCompletionBase *>(static_cast<const KLineEdit *>(sender));
31
32 // is it our delegate, that is destroyed?
33 if (base == q->delegate()) {
34 q->setDelegate(nullptr);
35 }
36}
37
39 : KComboBox(*new KComboBoxPrivate(this), parent)
40{
41}
42
43KComboBox::KComboBox(KComboBoxPrivate &dd, QWidget *parent)
44 : QComboBox(parent)
45 , d_ptr(&dd)
46{
48
49 d->init();
50}
51
53 : KComboBox(*new KComboBoxPrivate(this), parent)
54{
55 setEditable(rw);
56}
57
59{
61 disconnect(d->m_klineEditConnection);
62}
63
64bool KComboBox::contains(const QString &text) const
65{
66 if (text.isEmpty()) {
67 return false;
68 }
69
70 const int itemCount = count();
71 for (int i = 0; i < itemCount; ++i) {
72 if (itemText(i) == text) {
73 return true;
74 }
75 }
76 return false;
77}
78
80{
81 return (isEditable()) ? lineEdit()->cursorPosition() : -1;
82}
83
84void KComboBox::setAutoCompletion(bool autocomplete)
85{
87 if (d->klineEdit) {
88 if (autocomplete) {
89 d->klineEdit->setCompletionMode(KCompletion::CompletionAuto);
91 } else {
92 d->klineEdit->setCompletionMode(KCompletion::CompletionPopup);
94 }
95 }
96}
97
98bool KComboBox::autoCompletion() const
99{
101}
102
104{
105 Q_D(const KComboBox);
106 return d->klineEdit && d->klineEdit->urlDropsEnabled();
107}
108
109void KComboBox::setCompletedText(const QString &text, bool marked)
110{
111 Q_D(KComboBox);
112 if (d->klineEdit) {
113 d->klineEdit->setCompletedText(text, marked);
114 }
115}
116
118{
119 Q_D(KComboBox);
120 if (d->klineEdit) {
121 d->klineEdit->setCompletedText(text);
122 }
123}
124
126{
127 Q_D(KComboBox);
128 if (d->klineEdit) {
129 d->klineEdit->makeCompletion(text);
130 }
131
132 else { // read-only combo completion
133 if (text.isNull() || !view()) {
134 return;
135 }
136
137 view()->keyboardSearch(text);
138 }
139}
140
142{
143 Q_D(KComboBox);
144 if (d->klineEdit) {
145 d->klineEdit->rotateText(type);
146 }
147}
148
150{
151 Q_D(KComboBox);
152 d->trapReturnKey = trap;
153
154 if (d->klineEdit) {
155 d->klineEdit->setTrapReturnKey(trap);
156 } else {
157 qCWarning(KCOMPLETION_LOG) << "KComboBox::setTrapReturnKey not supported with a non-KLineEdit.";
158 }
159}
160
161bool KComboBox::trapReturnKey() const
162{
163 Q_D(const KComboBox);
164 return d->trapReturnKey;
165}
166
171
172void KComboBox::addUrl(const QUrl &url)
173{
175}
176
177void KComboBox::addUrl(const QIcon &icon, const QUrl &url)
178{
180}
181
182void KComboBox::insertUrl(int index, const QUrl &url)
183{
185}
186
187void KComboBox::insertUrl(int index, const QIcon &icon, const QUrl &url)
188{
189 QComboBox::insertItem(index, icon, url.toDisplayString());
190}
191
192void KComboBox::changeUrl(int index, const QUrl &url)
193{
195}
196
197void KComboBox::changeUrl(int index, const QIcon &icon, const QUrl &url)
198{
199 QComboBox::setItemIcon(index, icon);
201}
202
203void KComboBox::setCompletedItems(const QStringList &items, bool autoSuggest)
204{
205 Q_D(KComboBox);
206 if (d->klineEdit) {
207 d->klineEdit->setCompletedItems(items, autoSuggest);
208 }
209}
210
212{
213 Q_D(KComboBox);
214 if (d->klineEdit) {
215 return d->klineEdit->completionBox(create);
216 }
217 return nullptr;
218}
219
220QSize KComboBox::minimumSizeHint() const
221{
222 Q_D(const KComboBox);
224 if (isEditable() && d->klineEdit) {
225 // if it's a KLineEdit and it's editable add the clear button size
226 // to the minimum size hint, otherwise looks ugly because the
227 // clear button will cover the last 2/3 letters of the biggest entry
228 QSize bs = d->klineEdit->clearButtonUsedSize();
229 if (bs.isValid()) {
230 size.rwidth() += bs.width();
231 size.rheight() = qMax(size.height(), bs.height());
232 }
233 }
234 return size;
235}
236
238{
239 Q_D(KComboBox);
240 if (!isEditable() && edit && !qstrcmp(edit->metaObject()->className(), "QLineEdit")) {
241 // uic generates code that creates a read-only KComboBox and then
242 // calls combo->setEditable(true), which causes QComboBox to set up
243 // a dumb QLineEdit instead of our nice KLineEdit.
244 // As some KComboBox features rely on the KLineEdit, we reject
245 // this order here.
246 delete edit;
247 KLineEdit *kedit = new KLineEdit(this);
248
249 if (isEditable()) {
250 kedit->setClearButtonEnabled(true);
251 }
252
253 edit = kedit;
254 }
255
256 // reuse an existing completion object, if it does not belong to the previous
257 // line edit and gets destroyed with it
259
261 edit->setCompleter(nullptr); // remove Qt's builtin completer (set by setLineEdit), we have our own
262 d->klineEdit = qobject_cast<KLineEdit *>(edit);
263 setDelegate(d->klineEdit);
264
265 if (completion && d->klineEdit) {
266 d->klineEdit->setCompletionObject(completion);
267 }
268
269 if (d->klineEdit) {
270 // someone calling KComboBox::setEditable(false) destroys our
271 // line edit without us noticing. And KCompletionBase::delegate would
272 // be a dangling pointer then, so prevent that. Note: only do this
273 // when it is a KLineEdit!
274 d->m_klineEditConnection = connect(edit, &QObject::destroyed, this, [d, edit]() {
275 d->slotLineEditDeleted(edit);
276 });
277
279
281
283
285
287
288 connect(d->klineEdit, &KLineEdit::aboutToShowContextMenu, [this](QMenu *menu) {
289 Q_D(KComboBox);
290 d->contextMenu = menu;
291 Q_EMIT aboutToShowContextMenu(menu);
292 });
293
295
296 d->klineEdit->setTrapReturnKey(d->trapReturnKey);
297 }
298}
299
301{
302 return d_ptr->contextMenu;
303}
304
305void KComboBox::setCurrentItem(const QString &item, bool insert, int index)
306{
307 int sel = -1;
308
309 const int itemCount = count();
310 for (int i = 0; i < itemCount; ++i) {
311 if (itemText(i) == item) {
312 sel = i;
313 break;
314 }
315 }
316
317 if (sel == -1 && insert) {
318 if (index >= 0) {
319 insertItem(index, item);
320 sel = index;
321 } else {
322 addItem(item);
323 sel = count() - 1;
324 }
325 }
327}
328
329void KComboBox::setEditable(bool editable)
330{
331 if (editable == isEditable()) {
332 return;
333 }
334
335 if (editable) {
336 // Create a KLineEdit instead of a QLineEdit
337 // Compared to QComboBox::setEditable, we might be missing the SH_ComboBox_Popup code though...
338 // If a style needs this, then we'll need to call QComboBox::setEditable and then setLineEdit again
339 KLineEdit *edit = new KLineEdit(this);
340 edit->setClearButtonEnabled(true);
341 setLineEdit(edit);
342 } else {
343 if (d_ptr->contextMenu) {
344 d_ptr->contextMenu->close();
345 }
347 }
348}
349
350#include "moc_kcombobox.cpp"
A combo box with completion support.
Definition kcombobox.h:136
void substringCompletion(const QString &)
Emitted when the shortcut for substring completion is pressed.
QMenu * contextMenu() const
Pointer to KLineEdit's context menu, or nullptr if it does not exist at the given moment.
bool contains(const QString &text) const
Convenience method which iterates over all items and checks if any of them is equal to text.
Definition kcombobox.cpp:64
void completionModeChanged(KCompletion::CompletionMode)
Emitted whenever the completion mode is changed by the user through the context menu.
virtual void makeCompletion(const QString &)
Completes text according to the completion mode.
void setEditUrl(const QUrl &url)
Sets url into the edit field of the combo box.
void setCurrentItem(const QString &item, bool insert=false, int index=-1)
Selects the first item that matches item.
bool urlDropsEnabled() const
Returns true when decoded URL drops are enabled.
void changeUrl(int index, const QUrl &url)
Replaces the item at position index with url.
void textRotation(KCompletionBase::KeyBindingType)
Emitted when the text rotation key bindings are pressed.
void returnPressed(const QString &text)
Emitted when the user presses the Return or Enter key.
void setCompletedItems(const QStringList &items, bool autoSuggest=true) override
Sets items into the completion box if completionMode() is CompletionPopup.
void setTrapReturnKey(bool trap)
By default, KComboBox recognizes Key_Return and Key_Enter and emits the returnPressed(const QString &...
void insertUrl(int index, const QUrl &url)
Inserts url at position index into the combo box.
void setEditable(bool editable)
Reimplemented so that setEditable(true) creates a KLineEdit instead of QLineEdit.
~KComboBox() override
Destructor.
Definition kcombobox.cpp:58
int cursorPosition() const
Returns the current cursor position.
Definition kcombobox.cpp:79
void completion(const QString &)
Emitted when the completion key is pressed.
void setCompletedText(const QString &) override
Sets the completed text in the line edit appropriately.
KCompletionBox * completionBox(bool create=true)
This method will create a completion box by calling KLineEdit::completionBox, if none is there yet.
virtual void setAutoCompletion(bool autocomplete)
Reimplemented from QComboBox.
Definition kcombobox.cpp:84
void addUrl(const QUrl &url)
Appends url to the combo box.
void rotateText(KCompletionBase::KeyBindingType type)
Iterates through all possible matches of the completed text or the history list.
KComboBox(QWidget *parent=nullptr)
Constructs a read-only (or rather select-only) combo box.
Definition kcombobox.cpp:38
virtual void setLineEdit(QLineEdit *)
Reimplemented for internal reasons.
An abstract base class for adding a completion feature into widgets.
virtual void setCompletionMode(KCompletion::CompletionMode mode)
Sets the type of completion to be used.
void setDelegate(KCompletionBase *delegate)
Sets or removes the delegation object.
KCompletion * compObj() const
Returns a pointer to the completion object.
KCompletion::CompletionMode completionMode() const
Returns the current completion mode.
KeyBindingType
Constants that represent the items whose shortcut key binding is programmable.
A helper widget for "completion-widgets" (KLineEdit, KComboBox))
@ CompletionAuto
Text is automatically filled in whenever possible.
@ CompletionPopup
Lists all possible matches in a popup list box to choose from.
An enhanced QLineEdit widget for inputting text.
Definition klineedit.h:139
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 textRotation(KCompletionBase::KeyBindingType)
Emitted when the text rotation key-bindings are pressed.
void completionBoxActivated(const QString &)
Emitted whenever the completion box is activated.
void completionModeChanged(KCompletion::CompletionMode)
Emitted when the user changed the completion mode by using the popupmenu.
void completion(const QString &)
Emitted when the completion key is pressed.
void substringCompletion(const QString &)
Emitted when the shortcut for substring completion is pressed.
virtual void keyboardSearch(const QString &search)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void setCurrentIndex(int index)
bool isEditable() const const
void insertItem(int index, const QIcon &icon, const QString &text, const QVariant &userData)
QString itemText(int index) const const
QLineEdit * lineEdit() const const
virtual QSize minimumSizeHint() const const override
void setEditText(const QString &text)
void setItemIcon(int index, const QIcon &icon)
void setItemText(int index, const QString &text)
void setLineEdit(QLineEdit *edit)
void textActivated(const QString &text)
QAbstractItemView * view() const const
void setClearButtonEnabled(bool enable)
void setCompleter(QCompleter *c)
const char * className() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
bool disconnect(const QMetaObject::Connection &connection)
virtual const QMetaObject * metaObject() const const
T qobject_cast(QObject *object)
int height() const const
bool isValid() const const
int & rwidth()
int width() const const
bool isEmpty() const const
bool isNull() const const
QString toDisplayString(FormattingOptions options) const const
void create(WId window, bool initializeWindow, bool destroyOldWindow)
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.