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 | |
27 | class QAction; |
28 | class ; |
29 | class KCompletionBox; |
30 | class QUrl; |
31 | class 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 | |
138 | class 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 | |
148 | public: |
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 | |
307 | Q_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 (QMenu *); |
369 | |
370 | /** |
371 | * Emitted when the user clicked on the clear button |
372 | */ |
373 | void clearButtonClicked(); |
374 | |
375 | public 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 | |
421 | protected 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 | |
436 | protected: |
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 (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 | |
514 | private: |
515 | std::unique_ptr<KLineEditPrivate> const d_ptr; |
516 | }; |
517 | |
518 | #endif |
519 | |