KCompletion

kcombobox.h
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 
7  SPDX-License-Identifier: LGPL-2.1-or-later
8 */
9 
10 #ifndef KCOMBOBOX_H
11 #define KCOMBOBOX_H
12 
13 #include <kcompletion.h>
14 
15 #include <kcompletion_export.h>
16 #include <kcompletionbase.h>
17 
18 #include <QComboBox>
19 #include <memory>
20 
21 class KCompletionBox;
22 class KComboBoxPrivate;
23 
24 class QLineEdit;
25 class QMenu;
26 
27 /**
28  * @class KComboBox kcombobox.h KComboBox
29  *
30  * @short A combo box with completion support.
31  *
32  * This widget inherits from QComboBox and implements the following
33  * additional features:
34  * @li a completion object that provides both automatic
35  * and manual text completion as well as text rotation
36  * @li configurable key bindings to activate these features
37  * @li a popup menu item that can be used to allow the user to change
38  * the text completion mode on the fly.
39  *
40  * To support these additional features, KComboBox emits a few additional signals
41  * such as completion(const QString&) and textRotation(KeyBindingType).
42  *
43  * The completion signal can be connected to a slot that will assist the user in
44  * filling out the remaining text while the rotation signal can be used to traverse
45  * through all possible matches whenever text completion results in multiple matches.
46  * Additionally, the returnPressed(const QString &) signal is emitted when the user
47  * presses the Return or Enter key.
48  *
49  * KCombobox by default creates a completion object when you invoke the
50  * completionObject(bool) member function for the first time or
51  * explicitly use setCompletionObject(KCompletion*, bool) to assign your
52  * own completion object. Additionally, to make this widget more functional,
53  * KComboBox will by default handle text rotation and completion events
54  * internally whenever a completion object is created through either one of the
55  * methods mentioned above. If you do not need this functionality, simply use
56  * KCompletionBase::setHandleSignals(bool) or alternatively set the boolean
57  * parameter in the @c setCompletionObject() call to @c false.
58  *
59  * Beware: The completion object can be deleted on you, especially if a call
60  * such as setEditable(false) is made. Store the pointer at your own risk,
61  * and consider using QPointer<KCompletion>.
62  *
63  * The default key bindings for completion and rotation are determined from the
64  * global settings in KStandardShortcut. These values, however, can be overridden
65  * locally by invoking KCompletionBase::setKeyBinding(). The values can
66  * easily be reverted back to the default settings by calling
67  * useGlobalSettings(). An alternate method would be to default individual
68  * key bindings by using setKeyBinding() with the default second argument.
69  *
70  * A non-editable combo box only has one completion mode, @c CompletionAuto.
71  * Unlike an editable combo box, the CompletionAuto mode works by matching
72  * any typed key with the first letter of entries in the combo box. Please note
73  * that if you call setEditable(false) to change an editable combo box to a
74  * non-editable one, the text completion object associated with the combo box will
75  * no longer exist unless you created the completion object yourself and assigned
76  * it to this widget or you called setAutoDeleteCompletionObject(false). In other
77  * words do not do the following:
78  *
79  * \code
80  * KComboBox* combo = new KComboBox(true, this);
81  * KCompletion* comp = combo->completionObject();
82  * combo->setEditable(false);
83  * comp->clear(); // CRASH: completion object does not exist anymore.
84  * \endcode
85  *
86  *
87  * A read-only KComboBox will have the same background color as a
88  * disabled KComboBox, but its foreground color will be the one used for
89  * the editable mode. This differs from QComboBox's implementation
90  * and is done to give visual distinction between the three different modes:
91  * disabled, read-only, and editable.
92  *
93  * \b Usage
94  *
95  * To enable the basic completion feature:
96  *
97  * \code
98  * KComboBox *combo = new KComboBox(true, this);
99  * KCompletion *comp = combo->completionObject();
100  * // Connect to the Return pressed signal - optional
101  * connect(combo, &KComboBox::returnPressed, comp, [this](const QString &text) { addItem(text); });
102  *
103  * // Provide the to be completed strings. Note that those are separate from the combo's
104  * // contents.
105  * comp->insertItems(someQStringList);
106  * \endcode
107  *
108  * To use your own completion object:
109  *
110  * \code
111  * KComboBox *combo = new KComboBox(this);
112  * KUrlCompletion *comp = new KUrlCompletion();
113  * // You can either delete the allocated completion object manually when you
114  * // don't need it anymore, or call setAutoDeleteCompletionObject(true) and it
115  * // will be deleted automatically
116  * comp->setAutoDeleteCompletionObject(true);
117  * combo->setCompletionObject(comp);
118  * // Connect to the return pressed signal - optional
119  * connect(combo, &KComboBox::returnPressed, comp, [this](const QString &text) { addItem(text); });
120  * \endcode
121  *
122  * Miscellaneous function calls:
123  *
124  * \code
125  * // Tell the widget not to handle completion and rotation
126  * combo->setHandleSignals(false);
127  * // Set your own completion key for manual completions.
128  * combo->setKeyBinding(KCompletionBase::TextCompletion, Qt::End);
129  * \endcode
130  *
131  * \image html kcombobox.png "KComboBox widgets, one non-editable, one editable with KUrlCompletion"
132  *
133  * @author Dawit Alemayehu <[email protected]>
134  */
135 class KCOMPLETION_EXPORT KComboBox : public QComboBox, public KCompletionBase // krazy:exclude=qclasses
136 {
137  Q_OBJECT
138  Q_PROPERTY(bool autoCompletion READ autoCompletion WRITE setAutoCompletion)
139 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 0)
140  Q_PROPERTY(bool urlDropsEnabled READ urlDropsEnabled WRITE setUrlDropsEnabled)
141 #endif
142  Q_PROPERTY(bool trapReturnKey READ trapReturnKey WRITE setTrapReturnKey)
143 
144 public:
145  /**
146  * Constructs a read-only (or rather select-only) combo box.
147  *
148  * @param parent The parent object of this widget
149  */
150  explicit KComboBox(QWidget *parent = nullptr);
151 
152  /**
153  * Constructs an editable or read-only combo box.
154  *
155  * @param rw When @c true, widget will be editable.
156  * @param parent The parent object of this widget.
157  */
158  explicit KComboBox(bool rw, QWidget *parent = nullptr);
159 
160  /**
161  * Destructor.
162  */
163  ~KComboBox() override;
164 
165 #if KCOMPLETION_ENABLE_DEPRECATED_SINCE(4, 5)
166  /**
167  * Deprecated to reflect Qt api changes
168  * @deprecated since 4.5
169  */
170  KCOMPLETION_DEPRECATED_VERSION(4, 5, "Use KComboBox::insertUrl(int, const QUrl&)")
171  void insertURL(const QUrl &url, int index = -1)
172  {
173  insertUrl(index < 0 ? count() : index, url);
174  }
175  KCOMPLETION_DEPRECATED_VERSION(4, 5, "Use KComboBox::insertUrl(int, const QIcon&, const QUrl&)")
176  void insertURL(const QPixmap &pixmap, const QUrl &url, int index = -1)
177  {
178  insertUrl(index < 0 ? count() : index, QIcon(pixmap), url);
179  }
180  KCOMPLETION_DEPRECATED_VERSION(4, 5, "Use KComboBox::changeUrl(int, const QUrl&)")
181  void changeURL(const QUrl &url, int index)
182  {
183  changeUrl(index, url);
184  }
185  KCOMPLETION_DEPRECATED_VERSION(4, 5, "Use KComboBox::changeUrl(int, const QIcon&, const QUrl&)")
186  void changeURL(const QPixmap &pixmap, const QUrl &url, int index)
187  {
188  changeUrl(index, QIcon(pixmap), url);
189  }
190 #endif
191 
192  /**
193  * Sets @p url into the edit field of the combo box.
194  *
195  * It uses QUrl::toDisplayString() so that the url is properly decoded for
196  * displaying.
197  */
198  void setEditUrl(const QUrl &url);
199 
200  /**
201  * Appends @p url to the combo box.
202  *
203  * QUrl::toDisplayString() is used so that the url is properly decoded
204  * for displaying.
205  */
206  void addUrl(const QUrl &url);
207 
208  /**
209  * Appends @p url with the @p icon to the combo box.
210  *
211  * QUrl::toDisplayString() is used so that the url is properly decoded
212  * for displaying.
213  */
214  void addUrl(const QIcon &icon, const QUrl &url);
215 
216  /**
217  * Inserts @p url at position @p index into the combo box.
218  *
219  * QUrl::toDisplayString() is used so that the url is properly decoded
220  * for displaying.
221  */
222  void insertUrl(int index, const QUrl &url);
223 
224  /**
225  * Inserts @p url with the @p icon at position @p index into
226  * the combo box.
227  *
228  * QUrl::toDisplayString() is used so that the url is
229  * properly decoded for displaying.
230  */
231  void insertUrl(int index, const QIcon &icon, const QUrl &url);
232 
233  /**
234  * Replaces the item at position @p index with @p url.
235  *
236  * QUrl::toDisplayString() is used so that the url is properly decoded
237  * for displaying.
238  */
239  void changeUrl(int index, const QUrl &url);
240 
241  /**
242  * Replaces the item at position @p index with @p url and @p icon.
243  *
244  * QUrl::toDisplayString() is used so that the url is properly decoded
245  * for displaying.
246  */
247  void changeUrl(int index, const QIcon &icon, const QUrl &url);
248 
249  /**
250  * Returns the current cursor position.
251  *
252  * This method always returns a -1 if the combo box is @em not
253  * editable (read-only).
254  *
255  * @return Current cursor position.
256  */
257  int cursorPosition() const;
258 
259  /**
260  * Reimplemented from QComboBox.
261  *
262  * If @c true, the completion mode will be set to automatic.
263  * Otherwise, it is defaulted to the global setting. This
264  * method has been replaced by the more comprehensive
265  * setCompletionMode().
266  *
267  * @param autocomplete Flag to enable/disable automatic completion mode.
268  */
269  virtual void setAutoCompletion(bool autocomplete);
270 
271  /**
272  * Reimplemented from QComboBox.
273  *
274  * Returns @c true if the current completion mode is set
275  * to automatic. See its more comprehensive replacement
276  * completionMode().
277  *
278  * @return @c true when completion mode is automatic.
279  */
280  bool autoCompletion() const;
281 
282 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(4, 5)
283  /**
284  * Enables or disables the popup (context) menu.
285  *
286  * This method only works if this widget is editable, and
287  * allows you to enable/disable the context menu. It does nothing if invoked
288  * for a non-editable combo box.
289  *
290  * By default, the context menu is created if this widget is editable.
291  * Call this function with the argument set to false to disable the popup
292  * menu.
293  *
294  * @param showMenu If @c true, show the context menu.
295  * @deprecated since 4.5, use setContextMenuPolicy instead
296  */
297  KCOMPLETION_DEPRECATED_VERSION(4, 5, "Use QWidget::setContextMenuPolicy(...)")
298  virtual void setContextMenuEnabled(bool showMenu);
299 #endif
300 
301 #if KCOMPLETION_ENABLE_DEPRECATED_SINCE(5, 0)
302  /**
303  * Enables/Disables handling of URL drops.
304  *
305  * If enabled and the user drops an URL, the decoded URL will
306  * be inserted. Otherwise the default behavior of QComboBox is used,
307  * which inserts the encoded URL.
308  *
309  * @param enable If @c true, insert decoded URLs
310  * @deprecated since 5.0. Use lineEdit()->installEventFilter with a LineEditUrlDropEventFilter
311  */
312  KCOMPLETION_DEPRECATED_VERSION(5, 0, "Use KComboBox::lineEdit()->installEventFilter(...) with a LineEditUrlDropEventFilter")
313  void setUrlDropsEnabled(bool enable);
314 #endif
315 
316  /**
317  * Returns @c true when decoded URL drops are enabled
318  */
319  bool urlDropsEnabled() const;
320 
321  /**
322  * Convenience method which iterates over all items and checks if
323  * any of them is equal to @p text.
324  *
325  * If @p text is an empty string, @c false
326  * is returned.
327  *
328  * @return @c true if an item with the string @p text is in the combo box.
329  */
330  bool contains(const QString &text) const;
331 
332  /**
333  * By default, KComboBox recognizes Key_Return and Key_Enter and emits the
334  * returnPressed(const QString &) signal, but it also lets the event pass,
335  * for example causing a dialog's default button to be called.
336  *
337  * Call this method with @p trap set to true to make KComboBox stop these
338  * events. The signals will still be emitted of course.
339  *
340  * @note This only affects editable combo boxes.
341  *
342  * @see setTrapReturnKey()
343  */
344  void setTrapReturnKey(bool trap);
345 
346  /**
347  * @return @c true if Key_Return or Key_Enter input events will be stopped or
348  * @c false if they will be propagated.
349  *
350  * @see setTrapReturnKey()
351  */
352  bool trapReturnKey() const;
353 
354  /**
355  * This method will create a completion box by calling
356  * KLineEdit::completionBox, if none is there yet.
357  *
358  * @param create Set this to false if you don't want the box to be created
359  * i.e. to test if it is available.
360  * @returns the completion box that is used in completion mode
361  * CompletionPopup and CompletionPopupAuto.
362  */
363  KCompletionBox *completionBox(bool create = true);
364 
365  /**
366  * Reimplemented for internal reasons. API remains unaffected.
367  * Note that QComboBox::setLineEdit is not virtual in Qt4, do not
368  * use a KComboBox in a QComboBox pointer.
369  *
370  * NOTE: Only editable combo boxes can have a line editor. As such
371  * any attempt to assign a line edit to a non-editable combo box will
372  * simply be ignored.
373  */
374  virtual void setLineEdit(QLineEdit *);
375 
376  /**
377  * Reimplemented so that setEditable(true) creates a KLineEdit
378  * instead of QLineEdit.
379  *
380  * Note that QComboBox::setEditable is not virtual, so do not
381  * use a KComboBox in a QComboBox pointer.
382  */
383  void setEditable(bool editable);
384 
385  /**
386  * Pointer to KLineEdit's context menu, or nullptr if it does not exist at
387  * the given moment.
388  *
389  * @since 5.78
390  */
391  QMenu *contextMenu() const;
392 
393 Q_SIGNALS:
394 #if KCOMPLETION_ENABLE_DEPRECATED_SINCE(5, 81)
395  /**
396  * Emitted when the user presses the Enter key.
397  *
398  * Note that this signal is only emitted when the widget is editable.
399  *
400  * @deprecated since 5.81, use the KComboBox::returnPressed(const QString &) signal
401  */
402  KCOMPLETION_DEPRECATED_VERSION(5, 81, "Use the KComboBox::returnPressed(const QString &) signal instead")
403  void returnPressed(); // clazy:exclude=overloaded-signal
404 #endif
405 
406  /**
407  * Emitted when the user presses the Return or Enter key.
408  *
409  * The argument is the current text being edited.
410  *
411  * @note This signal is only emitted when the widget is editable.
412  *
413  */
414  void returnPressed(const QString &text); // clazy:exclude=overloaded-signal
415 
416  /**
417  * Emitted when the completion key is pressed.
418  *
419  * The argument is the current text being edited.
420  *
421  * Note that this signal is @em not available when the widget is non-editable
422  * or the completion mode is set to @c CompletionNone.
423  */
424  void completion(const QString &);
425 
426  /**
427  * Emitted when the shortcut for substring completion is pressed.
428  */
429  void substringCompletion(const QString &);
430 
431  /**
432  * Emitted when the text rotation key bindings are pressed.
433  *
434  * The argument indicates which key binding was pressed. In this case this
435  * can be either one of four values: @c PrevCompletionMatch,
436  * @c NextCompletionMatch, @c RotateUp or @c RotateDown.
437  *
438  * Note that this signal is @em not emitted if the completion
439  * mode is set to CompletionNone.
440  *
441  * @see KCompletionBase::setKeyBinding() for details
442  */
443  void textRotation(KCompletionBase::KeyBindingType);
444 
445  /**
446  * Emitted whenever the completion mode is changed by the user
447  * through the context menu.
448  */
449  void completionModeChanged(KCompletion::CompletionMode);
450 
451  /**
452  * Emitted before the context menu is displayed.
453  *
454  * The signal allows you to add your own entries into the context menu.
455  * Note that you <em>must not</em> store the pointer to the QPopupMenu since it is
456  * created and deleted on demand. Otherwise, you can crash your app.
457  *
458  * @param contextMenu the context menu about to be displayed
459  */
460  void aboutToShowContextMenu(QMenu *contextMenu);
461 
462 public Q_SLOTS:
463 
464  /**
465  * Iterates through all possible matches of the completed text
466  * or the history list.
467  *
468  * Depending on the value of the argument, this function either
469  * iterates through the history list of this widget or all the
470  * possible matches in whenever multiple matches result from a
471  * text completion request. Note that the all-possible-match
472  * iteration will not work if there are no previous matches, i.e.
473  * no text has been completed and the *nix shell history list
474  * rotation is only available if the insertion policy for this
475  * widget is set either @c QComobBox::AtTop or @c QComboBox::AtBottom.
476  * For other insertion modes whatever has been typed by the user
477  * when the rotation event was initiated will be lost.
478  *
479  * @param type The key binding invoked.
480  */
481  void rotateText(KCompletionBase::KeyBindingType type);
482 
483  /**
484  * Sets the completed text in the line edit appropriately.
485  *
486  * This function is an implementation for
487  * KCompletionBase::setCompletedText.
488  */
489  void setCompletedText(const QString &) override;
490 
491  /**
492  * Sets @p items into the completion box if completionMode() is
493  * CompletionPopup. The popup will be shown immediately.
494  */
495  void setCompletedItems(const QStringList &items, bool autoSuggest = true) override;
496 
497  /**
498  * Selects the first item that matches @p item.
499  *
500  * If there is no such item, it is inserted at position @p index
501  * if @p insert is true. Otherwise, no item is selected.
502  */
503  void setCurrentItem(const QString &item, bool insert = false, int index = -1);
504 
505 protected Q_SLOTS:
506 
507  /**
508  * Completes text according to the completion mode.
509  *
510  * @note This method is not invoked if the completion mode is
511  * set to @c CompletionNone. Also if the mode is set to @c CompletionShell
512  * and multiple matches are found, this method will complete the
513  * text to the first match with a beep to indicate that there are
514  * more matches. Then any successive completion key event iterates
515  * through the remaining matches. This way the rotation functionality
516  * is left to iterate through the list as usual.
517  */
518  virtual void makeCompletion(const QString &);
519 
520 protected:
521  /**
522  * This function sets the line edit text and
523  * highlights the text appropriately if the boolean
524  * value is set to true.
525  *
526  * @param text The text to be set in the line edit
527  * @param marked Whether the text inserted should be highlighted
528  */
529  virtual void setCompletedText(const QString &text, bool marked);
530 
531  // TODO KF6: make public like in base classes, so consumers do not need to cast to base classes
532  // when they have a KComboBox (or subclasses) object and want to access this property
533  QSize minimumSizeHint() const override;
534 
535 protected:
536  KComboBox(KComboBoxPrivate &dd, QWidget *parent);
537 
538 private:
539  friend class KHistoryComboBox;
540  Q_DECLARE_PRIVATE(KComboBox)
541  std::unique_ptr<KComboBoxPrivate> const d_ptr;
542  // KF6 TODO: change private d_ptr to protected d_ptr, remove friend
543 };
544 
545 #endif
Q_PROPERTY(...)
Q_SLOTSQ_SLOTS
virtual void setCompletedItems(const QStringList &items, bool autoSuggest=true)=0
A pure virtual function that must be implemented by all inheriting classes.
void setAutoCompletion(bool enable)
CompletionMode
This enum describes the completion mode used for by the KCompletion class.
Definition: kcompletion.h:131
const QList< QKeySequence > & substringCompletion()
void setLineEdit(QLineEdit *edit)
virtual QSize minimumSizeHint() const const override
An abstract class for adding text completion support to widgets.
A helper widget for "completion-widgets" (KLineEdit, KComboBox))
KeyBindingType
Constants that represent the items whose shortcut key binding is programmable.
A combo box with completion support.
Definition: kcombobox.h:135
Q_SIGNALSQ_SIGNALS
void setEditable(bool editable)
virtual void setCompletedText(const QString &text)=0
A pure virtual function that must be implemented by all inheriting classes.
A combobox for offering a history and completion.
const QList< QKeySequence > & completion()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Jul 1 2022 05:34:24 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.