1/*
2 This file is part of the KDE libraries
3
4 This class was originally inspired by Torben Weis'
5 fileentry.cpp for KFM II.
6
7 SPDX-FileCopyrightText: 1997 Sven Radej <sven.radej@iname.com>
8 SPDX-FileCopyrightText: 1999 Patrick Ward <PAT_WARD@HP-USA-om5.om.hp.com>
9 SPDX-FileCopyrightText: 1999 Preston Brown <pbrown@kde.org>
10
11 Completely re-designed:
12 SPDX-FileCopyrightText: 2000, 2001 Dawit Alemayehu <adawit@kde.org>
13
14 SPDX-License-Identifier: LGPL-2.0-or-later
15*/
16
17#ifndef KLINEEDIT_H
18#define KLINEEDIT_H
19
20#include <kcompletion.h>
21#include <kcompletion_export.h>
22#include <kcompletionbase.h>
23
24#include <QLineEdit>
25#include <memory>
26
27class QAction;
28class QMenu;
29class KCompletionBox;
30class QUrl;
31class KLineEditPrivate;
32
33/**
34 * @class KLineEdit klineedit.h KLineEdit
35 *
36 * An enhanced QLineEdit widget for inputting text.
37 *
38 * \b Detail \n
39 *
40 * This widget inherits from QLineEdit and implements the following
41 * additional functionalities:
42 * @li a completion object that provides both automatic and manual text
43 * completion as well as multiple match iteration features
44 * @li configurable key-bindings to activate these features
45 * @li a popup-menu item that can be used to allow the user to set text
46 * completion modes on the fly based on their preference
47 *
48 * To support these features KLineEdit also emits a few more additional
49 * signals:
50 * @li @c completion(const QString &): this signal can be connected to
51 * a slot that will assist the user in filling out the remaining text
52 * @li @c textRotation(KeyBindingType): this signal is intended to be
53 * used to iterate through the list of all possible matches whenever
54 * there is more than one match for the entered text
55 * @li @c returnKeyPressed(const QString &): this signal provides the
56 * current text in the widget as its argument whenever appropriate (this
57 * is in addition to the @c QLineEdit::returnPressed() signal which KLineEdit
58 * inherits from QLineEdit).
59 *
60 * This widget by default creates a completion object when you invoke
61 * the @c completionObject(bool) member function for the first time or
62 * use @c setCompletionObject(KCompletion *, bool) to assign your own
63 * completion object. Additionally, to make this widget more functional,
64 * KLineEdit will by default handle the text rotation and completion
65 * events internally when a completion object is created through either one
66 * of the methods mentioned above. If you do not need this functionality,
67 * simply use @c KCompletionBase::setHandleSignals(bool) or set the boolean
68 * parameter in the above functions to false.
69 *
70 * The default key-bindings for completion and rotation is determined
71 * from the global settings in KStandardShortcut. These values, however,
72 * can be overridden locally by invoking @c KCompletionBase::setKeyBinding().
73 * The values can easily be reverted back to the default setting, by simply
74 * calling @c useGlobalSettings(). An alternate method would be to default
75 * individual key-bindings by using setKeyBinding() with the default
76 * second argument.
77 *
78 * If @c EchoMode for this widget is set to something other than @c QLineEdit::Normal,
79 * the completion mode will always be defaulted to CompletionNone.
80 * This is done purposefully to guard against protected entries, such as
81 * passwords, being cached in KCompletion's list. Hence, if the @c EchoMode
82 * is not @c QLineEdit::Normal, the completion mode is automatically disabled.
83 *
84 * A read-only KLineEdit will have the same background color as a disabled
85 * KLineEdit, but its foreground color will be the one used for the read-write
86 * mode. This differs from QLineEdit's implementation and is done to give visual
87 * distinction between the three different modes: disabled, read-only, and read-write.
88 *
89 * @b Usage
90 *
91 * To enable the basic completion feature:
92 *
93 * @code
94 * KLineEdit *edit = new KLineEdit(this);
95 * KCompletion *comp = edit->completionObject();
96 * // Connect to the Return pressed signal - optional
97 * connect(edit, &KLineEdit::returnKeyPressed, comp, [this](const QString &text) { addItem(text); });
98 * @endcode
99 *
100 * To use a customized completion object or your own completion object:
101 *
102 * @code
103 * KLineEdit *edit = new KLineEdit(this);
104 * KUrlCompletion *comp = new KUrlCompletion();
105 * edit->setCompletionObject(comp);
106 * // Connect to the return pressed signal - optional
107 * connect(edit, &KLineEdit::returnKeyPressed, comp, [this](const QString &text) { addItem(text); });
108 * @endcode
109 *
110 * Note if you specify your own completion object you have to either delete
111 * it when you don't need it anymore, or you can tell KLineEdit to delete it
112 * for you:
113 * @code
114 * edit->setAutoDeleteCompletionObject(true);
115 * @endcode
116 *
117 * <b>Miscellaneous function calls :</b>\n
118 *
119 * @code
120 * // Tell the widget to not handle completion and iteration automatically
121 * edit->setHandleSignals(false);
122 *
123 * // Set your own key-bindings for a text completion mode
124 * edit->setKeyBinding(KCompletionBase::TextCompletion, Qt::End);
125 *
126 * // Hide the context (popup) menu
127 * edit->setContextMenuPolicy(Qt::NoContextMenu);
128 *
129 * // Default the key-bindings back to the default system settings
130 * edit->useGlobalKeyBindings();
131 * @endcode
132 *
133 * @image html klineedit.png "KLineEdit widgets with clear-button"
134 *
135 * @author Dawit Alemayehu <adawit@kde.org>
136 */
137
138class KCOMPLETION_EXPORT KLineEdit : public QLineEdit, public KCompletionBase // krazy:exclude=qclasses
139{
140 friend class KComboBox;
141 friend class KLineEditStyle;
142
143 Q_OBJECT
144 Q_DECLARE_PRIVATE(KLineEdit)
145 Q_PROPERTY(bool trapEnterKeyEvent READ trapReturnKey WRITE setTrapReturnKey)
146 Q_PROPERTY(bool squeezedTextEnabled READ isSqueezedTextEnabled WRITE setSqueezedTextEnabled)
147
148public:
149 /**
150 * Constructs a KLineEdit object with a default text, a parent,
151 * and a name.
152 *
153 * @param string Text to be shown in the edit widget.
154 * @param parent The parent widget of the line edit.
155 */
156 explicit KLineEdit(const QString &string, QWidget *parent = nullptr);
157
158 /**
159 * Constructs a line edit
160 * @param parent The parent widget of the line edit.
161 */
162 explicit KLineEdit(QWidget *parent = nullptr);
163
164 /**
165 * Destructor.
166 */
167 ~KLineEdit() override;
168
169 /**
170 * Sets @p url into the lineedit. It uses QUrl::toDisplayString() so
171 * that the url is properly decoded for displaying.
172 */
173 void setUrl(const QUrl &url);
174
175 /**
176 * Reimplemented from KCompletionBase for internal reasons.
177 *
178 * This function is re-implemented in order to make sure that
179 * the EchoMode is acceptable before we set the completion mode.
180 *
181 * See KCompletionBase::setCompletionMode
182 */
183 void setCompletionMode(KCompletion::CompletionMode mode) override;
184
185 /**
186 * Disables completion modes by making them non-checkable.
187 *
188 * The context menu allows to change the completion mode.
189 * This method allows to disable some modes.
190 */
191 void setCompletionModeDisabled(KCompletion::CompletionMode mode, bool disable = true);
192
193 /**
194 * Enables/Disables handling of URL drops. If enabled and the user
195 * drops an URL, the decoded URL will be inserted. Otherwise the default
196 * behavior of QLineEdit is used, which inserts the encoded URL.
197 * Call setUrlDropsEnabled(false) if you need dropEvent to be called in a KLineEdit subclass.
198 *
199 * @param enable If @c true, insert decoded URLs
200 */
201 void setUrlDropsEnabled(bool enable); // KF6: remove it and don't create LineEditUrlDropEventFilter by default.
202
203 /**
204 * Returns @c true when decoded URL drops are enabled
205 */
206 bool urlDropsEnabled() const;
207
208 /**
209 * By default, KLineEdit recognizes @c Key_Return and @c Key_Enter and emits
210 * the returnPressed() signals, but it also lets the event pass,
211 * for example causing a dialog's default-button to be called.
212 *
213 * Call this method with @p trap = @c true to make @c KLineEdit stop these
214 * events. The signals will still be emitted of course.
215 *
216 * @see trapReturnKey()
217 */
218 void setTrapReturnKey(bool trap);
219
220 /**
221 * @returns @c true if keyevents of @c Key_Return or
222 * @c Key_Enter will be stopped or if they will be propagated.
223 *
224 * @see setTrapReturnKey ()
225 */
226 bool trapReturnKey() const;
227
228 /**
229 * This method will create a completion-box if none is there, yet.
230 *
231 * @param create Set this to false if you don't want the box to be created
232 * i.e. to test if it is available.
233 * @returns the completion-box, that is used in completion mode
234 * CompletionPopup.
235 */
236 virtual KCompletionBox *completionBox(bool create = true);
237
238 /**
239 * Reimplemented for internal reasons, the API is not affected.
240 */
241 void setCompletionObject(KCompletion *, bool handle = true) override;
242
243 /**
244 * Reimplemented for internal reasons, the API is not affected.
245 */
246 virtual void copy() const;
247
248 /**
249 * Enable text squeezing whenever the supplied text is too long.
250 * Only works for "read-only" mode.
251 *
252 * Note that once text squeezing is enabled, QLineEdit::text()
253 * and QLineEdit::displayText() return the squeezed text. If
254 * you want the original text, use @ref originalText.
255 *
256 * @see QLineEdit
257 */
258 void setSqueezedTextEnabled(bool enable);
259
260 /**
261 * Returns true if text squeezing is enabled.
262 * This is only valid when the widget is in read-only mode.
263 */
264 bool isSqueezedTextEnabled() const;
265
266 /**
267 * Returns the original text if text squeezing is enabled.
268 * If the widget is not in "read-only" mode, this function
269 * returns the same thing as QLineEdit::text().
270 *
271 * @see QLineEdit
272 */
273 QString originalText() const;
274
275 /**
276 * Returns the text as given by the user (i.e. not autocompleted)
277 * if the widget has autocompletion disabled, this function
278 * returns the same as QLineEdit::text().
279 * @since 4.2.2
280 */
281 QString userText() const;
282
283 /**
284 * Set the completion-box to be used in completion mode
285 * CompletionPopup.
286 * This will do nothing if a completion-box already exists.
287 *
288 * @param box The KCompletionBox to set
289 */
290 void setCompletionBox(KCompletionBox *box);
291
292 /**
293 * @return the size used by the clear button
294 * @since 4.1
295 */
296 QSize clearButtonUsedSize() const;
297
298 /**
299 * Do completion now. This is called automatically when typing a key for instance.
300 * Emits completion() and/or calls makeCompletion(), depending on
301 * emitSignals and handleSignals.
302 *
303 * @since 4.2.1
304 */
305 void doCompletion(const QString &text);
306
307Q_SIGNALS:
308 /**
309 * Emitted whenever the completion box is activated.
310 */
311 void completionBoxActivated(const QString &);
312
313 /**
314 * Emitted when the user presses the Return or Enter key.
315 *
316 * The argument is the current text. Note that this signal is @em not emitted
317 * if the widget's @c EchoMode is set to QLineEdit::EchoMode.
318 *
319 * @since 5.81
320 */
321 void returnKeyPressed(const QString &text);
322
323 /**
324 * Emitted when the completion key is pressed.
325 *
326 * Please note that this signal is @em not emitted if the
327 * completion mode is set to @c CompletionNone or @c EchoMode is
328 * @em normal.
329 */
330 void completion(const QString &);
331
332 /**
333 * Emitted when the shortcut for substring completion is pressed.
334 */
335 void substringCompletion(const QString &);
336
337 /**
338 * Emitted when the text rotation key-bindings are pressed.
339 *
340 * The argument indicates which key-binding was pressed.
341 * In KLineEdit's case this can be either one of two values:
342 * PrevCompletionMatch or NextCompletionMatch. See
343 * KCompletionBase::setKeyBinding for details.
344 *
345 * Note that this signal is @em not emitted if the completion
346 * mode is set to @c CompletionNone or @c echoMode() is @em not normal.
347 */
348 void textRotation(KCompletionBase::KeyBindingType);
349
350 /**
351 * Emitted when the user changed the completion mode by using the
352 * popupmenu.
353 */
354 void completionModeChanged(KCompletion::CompletionMode);
355
356 /**
357 * Emitted before the context menu is displayed.
358 *
359 * The signal allows you to add your own entries into the
360 * the context menu that is created on demand.
361 *
362 * NOTE: Do not store the pointer to the QMenu
363 * provided through since it is created and deleted
364 * on demand.
365 *
366 * @param contextMenu the context menu about to be displayed
367 */
368 void aboutToShowContextMenu(QMenu *contextMenu);
369
370 /**
371 * Emitted when the user clicked on the clear button
372 */
373 void clearButtonClicked();
374
375public Q_SLOTS:
376
377 /**
378 * Sets the lineedit to read-only. Similar to QLineEdit::setReadOnly
379 * but also takes care of the background color, and the clear button.
380 */
381 virtual void setReadOnly(bool);
382
383 /**
384 * Iterates through all possible matches of the completed text or
385 * the history list.
386 *
387 * This function simply iterates over all possible matches in case
388 * multiple matches are found as a result of a text completion request.
389 * It will have no effect if only a single match is found.
390 *
391 * @param type The key-binding invoked.
392 */
393 void rotateText(KCompletionBase::KeyBindingType type);
394
395 /**
396 * See KCompletionBase::setCompletedText.
397 */
398 void setCompletedText(const QString &) override;
399
400 /**
401 * Same as the above function except it allows you to temporarily
402 * turn off text completion in CompletionPopupAuto mode.
403 *
404 *
405 * @param items list of completion matches to be shown in the completion box.
406 * @param autoSuggest true if you want automatic text completion (suggestion) enabled.
407 */
408 void setCompletedItems(const QStringList &items, bool autoSuggest = true) override;
409
410 /**
411 * Squeezes @p text into the line edit.
412 * This can only be used with read-only line-edits.
413 */
414 void setSqueezedText(const QString &text);
415
416 /**
417 * Reimplemented to enable text squeezing. API is not affected.
418 */
419 virtual void setText(const QString &);
420
421protected Q_SLOTS:
422
423 /**
424 * Completes the remaining text with a matching one from
425 * a given list.
426 */
427 virtual void makeCompletion(const QString &);
428
429 /**
430 * Resets the current displayed text.
431 * Call this function to revert a text completion if the user
432 * cancels the request. Mostly applies to popup completions.
433 */
434 void userCancelled(const QString &cancelText);
435
436protected:
437 /**
438 * Reimplemented for internal reasons. API not affected.
439 */
440 bool event(QEvent *) override;
441
442 /**
443 * Reimplemented for internal reasons. API not affected.
444 *
445 * See QLineEdit::resizeEvent().
446 */
447 void resizeEvent(QResizeEvent *) override;
448
449 /**
450 * Reimplemented for internal reasons. API not affected.
451 *
452 * See QLineEdit::keyPressEvent().
453 */
454 void keyPressEvent(QKeyEvent *) override;
455
456 /**
457 * Reimplemented for internal reasons. API not affected.
458 *
459 * See QLineEdit::mousePressEvent().
460 */
461 void mousePressEvent(QMouseEvent *) override;
462
463 /**
464 * Reimplemented for internal reasons. API not affected.
465 *
466 * See QLineEdit::mouseReleaseEvent().
467 */
468 void mouseReleaseEvent(QMouseEvent *) override;
469
470 /**
471 * Reimplemented for internal reasons. API not affected.
472 *
473 * See QWidget::mouseDoubleClickEvent().
474 */
475 void mouseDoubleClickEvent(QMouseEvent *) override;
476
477 /**
478 * Reimplemented for internal reasons. API not affected.
479 *
480 * See QLineEdit::contextMenuEvent().
481 */
482 void contextMenuEvent(QContextMenuEvent *) override;
483
484 /**
485 * Reimplemented for internal reasons. API not affected.
486 *
487 * See QLineEdit::createStandardContextMenu().
488 */
489 QMenu *createStandardContextMenu();
490
491 /**
492 * This function simply sets the lineedit text and
493 * highlights the text appropriately if the boolean
494 * value is set to true.
495 *
496 * @param text
497 * @param marked
498 */
499 virtual void setCompletedText(const QString & /*text*/, bool /*marked*/);
500
501 /**
502 * Sets the widget in userSelection mode or in automatic completion
503 * selection mode. This changes the colors of selections.
504 */
505 void setUserSelection(bool userSelection);
506
507 /**
508 * Whether in current state text should be auto-suggested
509 */
510 bool autoSuggest() const;
511
512 void paintEvent(QPaintEvent *ev) override;
513
514private:
515 std::unique_ptr<KLineEditPrivate> const d_ptr;
516};
517
518#endif
519

source code of kcompletion/src/klineedit.h