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

KDE's Doxygen guidelines are available online.