KCompletion

kcombobox.cpp
1 /*
2  This file is part of the KDE libraries
3 
4  SPDX-FileCopyrightText: 2000, 2001 Dawit Alemayehu <[email protected]>
5  SPDX-FileCopyrightText: 2000, 2001 Carsten Pfeiffer <[email protected]>
6  SPDX-FileCopyrightText: 2000 Stefan Schimanski <[email protected]>
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 
19 void KComboBoxPrivate::init()
20 {
21  Q_Q(KComboBox);
22 }
23 
24 void 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 
43 KComboBox::KComboBox(KComboBoxPrivate &dd, QWidget *parent)
44  : QComboBox(parent)
45  , d_ptr(&dd)
46 {
47  Q_D(KComboBox);
48 
49  d->init();
50 }
51 
52 KComboBox::KComboBox(bool rw, QWidget *parent)
53  : KComboBox(*new KComboBoxPrivate(this), parent)
54 {
55  setEditable(rw);
56 }
57 
59 {
60  Q_D(KComboBox);
61  disconnect(d->m_klineEditConnection);
62 }
63 
64 bool 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 
84 void KComboBox::setAutoCompletion(bool autocomplete)
85 {
86  Q_D(KComboBox);
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 
98 bool KComboBox::autoCompletion() const
99 {
101 }
102 
103 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
105 {
106  Q_D(KComboBox);
107  if (d->klineEdit) {
108  d->klineEdit->setContextMenuPolicy(showMenu ? Qt::DefaultContextMenu : Qt::NoContextMenu);
109  }
110 }
111 #endif
112 
113 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 0)
115 {
116  Q_D(KComboBox);
117  if (d->klineEdit) {
118  d->klineEdit->setUrlDropsEnabled(enable);
119  }
120 }
121 #endif
122 
123 bool KComboBox::urlDropsEnabled() const
124 {
125  Q_D(const KComboBox);
126  return d->klineEdit && d->klineEdit->urlDropsEnabled();
127 }
128 
129 void KComboBox::setCompletedText(const QString &text, bool marked)
130 {
131  Q_D(KComboBox);
132  if (d->klineEdit) {
133  d->klineEdit->setCompletedText(text, marked);
134  }
135 }
136 
138 {
139  Q_D(KComboBox);
140  if (d->klineEdit) {
141  d->klineEdit->setCompletedText(text);
142  }
143 }
144 
146 {
147  Q_D(KComboBox);
148  if (d->klineEdit) {
149  d->klineEdit->makeCompletion(text);
150  }
151 
152  else { // read-only combo completion
153  if (text.isNull() || !view()) {
154  return;
155  }
156 
157  view()->keyboardSearch(text);
158  }
159 }
160 
162 {
163  Q_D(KComboBox);
164  if (d->klineEdit) {
165  d->klineEdit->rotateText(type);
166  }
167 }
168 
170 {
171  Q_D(KComboBox);
172  d->trapReturnKey = trap;
173 
174  if (d->klineEdit) {
175  d->klineEdit->setTrapReturnKey(trap);
176  } else {
177  qCWarning(KCOMPLETION_LOG) << "KComboBox::setTrapReturnKey not supported with a non-KLineEdit.";
178  }
179 }
180 
181 bool KComboBox::trapReturnKey() const
182 {
183  Q_D(const KComboBox);
184  return d->trapReturnKey;
185 }
186 
187 void KComboBox::setEditUrl(const QUrl &url)
188 {
190 }
191 
192 void KComboBox::addUrl(const QUrl &url)
193 {
195 }
196 
197 void KComboBox::addUrl(const QIcon &icon, const QUrl &url)
198 {
199  QComboBox::addItem(icon, url.toDisplayString());
200 }
201 
202 void KComboBox::insertUrl(int index, const QUrl &url)
203 {
205 }
206 
207 void KComboBox::insertUrl(int index, const QIcon &icon, const QUrl &url)
208 {
209  QComboBox::insertItem(index, icon, url.toDisplayString());
210 }
211 
212 void KComboBox::changeUrl(int index, const QUrl &url)
213 {
215 }
216 
217 void KComboBox::changeUrl(int index, const QIcon &icon, const QUrl &url)
218 {
219  QComboBox::setItemIcon(index, icon);
221 }
222 
223 void KComboBox::setCompletedItems(const QStringList &items, bool autoSuggest)
224 {
225  Q_D(KComboBox);
226  if (d->klineEdit) {
227  d->klineEdit->setCompletedItems(items, autoSuggest);
228  }
229 }
230 
232 {
233  Q_D(KComboBox);
234  if (d->klineEdit) {
235  return d->klineEdit->completionBox(create);
236  }
237  return nullptr;
238 }
239 
240 QSize KComboBox::minimumSizeHint() const
241 {
242  Q_D(const KComboBox);
244  if (isEditable() && d->klineEdit) {
245  // if it's a KLineEdit and it's editable add the clear button size
246  // to the minimum size hint, otherwise looks ugly because the
247  // clear button will cover the last 2/3 letters of the biggest entry
248  QSize bs = d->klineEdit->clearButtonUsedSize();
249  if (bs.isValid()) {
250  size.rwidth() += bs.width();
251  size.rheight() = qMax(size.height(), bs.height());
252  }
253  }
254  return size;
255 }
256 
258 {
259  Q_D(KComboBox);
260  if (!isEditable() && edit && !qstrcmp(edit->metaObject()->className(), "QLineEdit")) {
261  // uic generates code that creates a read-only KComboBox and then
262  // calls combo->setEditable(true), which causes QComboBox to set up
263  // a dumb QLineEdit instead of our nice KLineEdit.
264  // As some KComboBox features rely on the KLineEdit, we reject
265  // this order here.
266  delete edit;
267  KLineEdit *kedit = new KLineEdit(this);
268 
269  if (isEditable()) {
270  kedit->setClearButtonEnabled(true);
271  }
272 
273  edit = kedit;
274  }
275 
276  // reuse an existing completion object, if it does not belong to the previous
277  // line edit and gets destroyed with it
279 
281  edit->setCompleter(nullptr); // remove Qt's builtin completer (set by setLineEdit), we have our own
282  d->klineEdit = qobject_cast<KLineEdit *>(edit);
283  setDelegate(d->klineEdit);
284 
285  if (completion && d->klineEdit) {
286  d->klineEdit->setCompletionObject(completion);
287  }
288 
289 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 81)
290  // Connect the returnPressed signal for both Q[K]LineEdits'
291  if (edit) {
292  connect(edit, qOverload<>(&QLineEdit::returnPressed), this, qOverload<>(&KComboBox::returnPressed));
293  }
294 #endif
295 
296  if (d->klineEdit) {
297  // someone calling KComboBox::setEditable(false) destroys our
298  // line edit without us noticing. And KCompletionBase::delegate would
299  // be a dangling pointer then, so prevent that. Note: only do this
300  // when it is a KLineEdit!
301  d->m_klineEditConnection = connect(edit, &QObject::destroyed, this, [d, edit]() {
302  d->slotLineEditDeleted(edit);
303  });
304 
305  connect(d->klineEdit, &KLineEdit::returnKeyPressed, this, qOverload<const QString &>(&KComboBox::returnPressed));
306 
307  connect(d->klineEdit, &KLineEdit::completion, this, &KComboBox::completion);
308 
310 
312 
314 
315  connect(d->klineEdit, &KLineEdit::aboutToShowContextMenu, [this](QMenu *menu) {
316  Q_D(KComboBox);
317  d->contextMenu = menu;
318  Q_EMIT aboutToShowContextMenu(menu);
319  });
320 
321  // match the declaration of the deprecated signal
322 #if QT_DEPRECATED_SINCE(5, 15)
323  QT_WARNING_PUSH
324  QT_WARNING_DISABLE_CLANG("-Wdeprecated-declarations")
325  QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations")
326  connect(d->klineEdit, &KLineEdit::completionBoxActivated, this, qOverload<const QString &>(&QComboBox::activated));
327  QT_WARNING_POP
328 #endif
330 
331  d->klineEdit->setTrapReturnKey(d->trapReturnKey);
332  }
333 }
334 
336 {
337  return d_ptr->contextMenu;
338 }
339 
340 void KComboBox::setCurrentItem(const QString &item, bool insert, int index)
341 {
342  int sel = -1;
343 
344  const int itemCount = count();
345  for (int i = 0; i < itemCount; ++i) {
346  if (itemText(i) == item) {
347  sel = i;
348  break;
349  }
350  }
351 
352  if (sel == -1 && insert) {
353  if (index >= 0) {
354  insertItem(index, item);
355  sel = index;
356  } else {
357  addItem(item);
358  sel = count() - 1;
359  }
360  }
361  setCurrentIndex(sel);
362 }
363 
364 void KComboBox::setEditable(bool editable)
365 {
366  if (editable == isEditable()) {
367  return;
368  }
369 
370  if (editable) {
371  // Create a KLineEdit instead of a QLineEdit
372  // Compared to QComboBox::setEditable, we might be missing the SH_ComboBox_Popup code though...
373  // If a style needs this, then we'll need to call QComboBox::setEditable and then setLineEdit again
374  KLineEdit *edit = new KLineEdit(this);
375  edit->setClearButtonEnabled(true);
376  setLineEdit(edit);
377  } else {
378  if (d_ptr->contextMenu) {
379  d_ptr->contextMenu->close();
380  }
382  }
383 }
384 
385 #include "moc_kcombobox.cpp"
QLineEdit * lineEdit() const const
bool isNull() const const
@ CompletionAuto
Text is automatically filled in whenever possible.
Definition: kcompletion.h:139
@ CompletionPopup
Lists all possible matches in a popup list box to choose from.
Definition: kcompletion.h:151
void addUrl(const QUrl &url)
Appends url to the combo box.
Definition: kcombobox.cpp:192
bool isValid() const const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
~KComboBox() override
Destructor.
Definition: kcombobox.cpp:58
virtual void makeCompletion(const QString &)
Completes text according to the completion mode.
Definition: kcombobox.cpp:145
void completionModeChanged(KCompletion::CompletionMode)
Emitted when the user changed the completion mode by using the popupmenu.
QAbstractItemView * view() const const
virtual void setAutoCompletion(bool autocomplete)
Reimplemented from QComboBox.
Definition: kcombobox.cpp:84
KCompletionBox * completionBox(bool create=true)
This method will create a completion box by calling KLineEdit::completionBox, if none is there yet.
Definition: kcombobox.cpp:231
int cursorPosition() const
Returns the current cursor position.
Definition: kcombobox.cpp:79
void aboutToShowContextMenu(QMenu *contextMenu)
Emitted before the context menu is displayed.
void setCurrentIndex(int index)
DefaultContextMenu
void completionModeChanged(KCompletion::CompletionMode)
Emitted whenever the completion mode is changed by the user through the context menu.
void setClearButtonEnabled(bool enable)
int width() const const
void textActivated(const QString &text)
virtual void setLineEdit(QLineEdit *)
Reimplemented for internal reasons.
Definition: kcombobox.cpp:257
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void substringCompletion(const QString &)
Emitted when the shortcut for substring completion is pressed.
void setCompletedItems(const QStringList &items, bool autoSuggest=true) override
Sets items into the completion box if completionMode() is CompletionPopup.
Definition: kcombobox.cpp:223
QString itemText(int index) const const
void setEditText(const QString &text)
void destroyed(QObject *obj)
void setLineEdit(QLineEdit *edit)
void setCurrentItem(const QString &item, bool insert=false, int index=-1)
Selects the first item that matches item.
Definition: kcombobox.cpp:340
virtual QSize minimumSizeHint() const const override
void completionBoxActivated(const QString &)
Emitted whenever the completion box is activated.
KCompletion * compObj() const
Returns a pointer to the completion object.
void setItemText(int index, const QString &text)
int height() const const
void setDelegate(KCompletionBase *delegate)
Sets or removes the delegation object.
virtual void setContextMenuEnabled(bool showMenu)
Enables or disables the popup (context) menu.
Definition: kcombobox.cpp:104
void setEditUrl(const QUrl &url)
Sets url into the edit field of the combo box.
Definition: kcombobox.cpp:187
void insertItem(int index, const QString &text, const QVariant &userData)
KCompletion::CompletionMode completionMode() const
Returns the current completion mode.
bool isEmpty() const const
virtual void setCompletionMode(KCompletion::CompletionMode mode)
Sets the type of completion to be used.
An abstract class for adding text completion support to widgets.
QString toDisplayString(QUrl::FormattingOptions options) const const
void returnPressed()
void textRotation(KCompletionBase::KeyBindingType)
Emitted when the text rotation key-bindings are pressed.
void setCompleter(QCompleter *c)
void setTrapReturnKey(bool trap)
By default, KComboBox recognizes Key_Return and Key_Enter and emits the returnPressed(const QString &...
Definition: kcombobox.cpp:169
QMenu * contextMenu() const
Pointer to KLineEdit's context menu, or nullptr if it does not exist at the given moment.
Definition: kcombobox.cpp:335
A helper widget for "completion-widgets" (KLineEdit, KComboBox))
void returnPressed()
Emitted when the user presses the Enter key.
KeyBindingType
Constants that represent the items whose shortcut key binding is programmable.
void insertUrl(int index, const QUrl &url)
Inserts url at position index into the combo box.
Definition: kcombobox.cpp:202
void completion(const QString &)
Emitted when the completion key is pressed.
virtual const QMetaObject * metaObject() const const
A combo box with completion support.
Definition: kcombobox.h:135
void substringCompletion(const QString &)
Emitted when the shortcut for substring completion is pressed.
const char * className() const const
void setCompletedText(const QString &) override
Sets the completed text in the line edit appropriately.
Definition: kcombobox.cpp:137
void setUrlDropsEnabled(bool enable)
Enables/Disables handling of URL drops.
Definition: kcombobox.cpp:114
bool isEditable() const const
void returnKeyPressed(const QString &text)
Emitted when the user presses the Return or Enter key.
virtual void keyboardSearch(const QString &search)
void addItem(const QString &text, const QVariant &userData)
KComboBox(QWidget *parent=nullptr)
Constructs a read-only (or rather select-only) combo box.
Definition: kcombobox.cpp:38
void setItemIcon(int index, const QIcon &icon)
void rotateText(KCompletionBase::KeyBindingType type)
Iterates through all possible matches of the completed text or the history list.
Definition: kcombobox.cpp:161
void activated(int index)
void create(WId window, bool initializeWindow, bool destroyOldWindow)
void setEditable(bool editable)
Reimplemented so that setEditable(true) creates a KLineEdit instead of QLineEdit.
Definition: kcombobox.cpp:364
void changeUrl(int index, const QUrl &url)
Replaces the item at position index with url.
Definition: kcombobox.cpp:212
void textRotation(KCompletionBase::KeyBindingType)
Emitted when the text rotation key bindings are pressed.
Q_D(Todo)
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 completion(const QString &)
Emitted when the completion key is pressed.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sun Jun 26 2022 04:11:17 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.