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