1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 1999, 2000 Carsten Pfeiffer <pfeiffer@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #ifndef KCOMPLETION_H |
9 | #define KCOMPLETION_H |
10 | |
11 | #include <kcompletion_export.h> |
12 | |
13 | #include <QKeySequence> |
14 | #include <QObject> |
15 | #include <QPointer> |
16 | #include <QStringList> |
17 | #include <functional> |
18 | #include <memory> |
19 | |
20 | class KCompTreeNode; |
21 | class KCompletionPrivate; |
22 | class KCompletionMatchesWrapper; |
23 | class KCompletionMatches; |
24 | |
25 | /*! |
26 | * \class KCompletion |
27 | * \inmodule KCompletion |
28 | * |
29 | * \brief A generic class for completing QStrings. |
30 | * |
31 | * This class offers easy use of "auto completion", "manual completion" or |
32 | * "shell completion" on QString objects. A common use is completing filenames |
33 | * or URLs (see KUrlCompletion()). |
34 | * But it is not limited to URL-completion -- everything should be completable! |
35 | * The user should be able to complete email addresses, telephone numbers, |
36 | * commands, SQL queries... |
37 | * Every time your program knows what the user can type into an edit field, you |
38 | * should offer completion. With KCompletion, this is very easy, and if you are |
39 | * using a line edit widget (KLineEdit), it is even easier. |
40 | * Basically, you tell a KCompletion object what strings should be completable |
41 | * and, whenever completion should be invoked, you call makeCompletion(). |
42 | * KLineEdit and (an editable) KComboBox even do this automatically for you. |
43 | * |
44 | * KCompletion offers the completed string via the signal match() and |
45 | * all matching strings (when the result is ambiguous) via the method |
46 | * allMatches(). |
47 | * |
48 | * Notice: auto completion, shell completion and manual completion work |
49 | * slightly differently: |
50 | * \list |
51 | * \li auto completion always returns a complete item as match. |
52 | * When more than one matching item is available, it will deliver just |
53 | * the first one (depending on sorting order). Iterating over all matches |
54 | * is possible via nextMatch() and previousMatch(). |
55 | * |
56 | * \li popup completion works in the same way, the only difference being that |
57 | * the completed items are not put into the edit widget, but into a |
58 | * separate popup box. |
59 | * |
60 | * \li manual completion works the same way as auto completion, except that |
61 | * it is not invoked automatically while the user is typing, |
62 | * but only when the user presses a special key. The difference |
63 | * of manual and auto completion is therefore only visible in UI classes. |
64 | * KCompletion needs to know whether to deliver partial matches |
65 | * (shell completion) or whole matches (auto/manual completion), therefore |
66 | * KCompletion::CompletionMan and KCompletion::CompletionAuto have the exact |
67 | * same effect in KCompletion. |
68 | * |
69 | * \li shell completion works like "tab completion" in a shell: |
70 | * when multiple matches are available, the longest possible string of all |
71 | * matches is returned (i.e. only a partial item). |
72 | * Iterating over all matching items (complete, not partial) is possible |
73 | * via nextMatch() and previousMatch(). |
74 | * \endlist |
75 | * |
76 | * As an application programmer, you do not normally have to worry about |
77 | * the different completion modes; KCompletion handles |
78 | * that for you, according to the setting setCompletionMode(). |
79 | * The default setting is globally configured by the user and read |
80 | * from completionMode(). |
81 | * |
82 | * A short example: |
83 | * \code |
84 | * KCompletion completion; |
85 | * completion.setOrder(KCompletion::Sorted); |
86 | * completion.addItem("pfeiffer@kde.org"); |
87 | * completion.addItem("coolo@kde.org"); |
88 | * completion.addItem("carpdjih@sp.zrz.tu-berlin.de"); |
89 | * completion.addItem("carp\cs.tu-berlin.de"); |
90 | * |
91 | * cout << completion.makeCompletion("ca").latin1() << endl; |
92 | * \endcode |
93 | * |
94 | * In shell-completion mode, this will be "carp"; in auto-completion |
95 | * mode it will be "carp\\cs.tu-berlin.de", as that is alphabetically |
96 | * smaller. |
97 | * If setOrder was set to Insertion, "carpdjih\@sp.zrz.tu-berlin.de" |
98 | * would be completed in auto-completion mode, as that was inserted before |
99 | * "carp\\cs.tu-berlin.de". |
100 | * |
101 | * You can dynamically update the completable items by removing and adding them |
102 | * whenever you want. |
103 | * For advanced usage, you could even use multiple KCompletion objects. E.g. |
104 | * imagine an editor like kwrite with multiple open files. You could store |
105 | * items of each file in a different KCompletion object, so that you know (and |
106 | * tell the user) where a completion comes from. |
107 | * |
108 | * \note KCompletion does not work with strings that contain 0x0 characters |
109 | * (unicode null), as this is used internally as a delimiter. |
110 | * |
111 | * You may inherit from KCompletion and override makeCompletion() in |
112 | * special cases (like reading directories or urls and then supplying the |
113 | * contents to KCompletion, as KUrlCompletion does), but this is usually |
114 | * not necessary. |
115 | */ |
116 | class KCOMPLETION_EXPORT KCompletion : public QObject |
117 | { |
118 | /*! |
119 | * \property KCompletion::order |
120 | */ |
121 | Q_PROPERTY(CompOrder order READ order WRITE setOrder) |
122 | |
123 | /*! |
124 | * \property KCompletion::ignoreCase |
125 | */ |
126 | Q_PROPERTY(bool ignoreCase READ ignoreCase WRITE setIgnoreCase) |
127 | |
128 | /*! |
129 | * \property KCompletion::items |
130 | */ |
131 | Q_PROPERTY(QStringList items READ items WRITE setItems) |
132 | |
133 | Q_OBJECT |
134 | Q_DECLARE_PRIVATE(KCompletion) |
135 | |
136 | public: |
137 | /*! |
138 | * This enum describes the completion mode used for by the KCompletion class. |
139 | * |
140 | * \value CompletionNone No completion is used. |
141 | * \value CompletionAuto Text is automatically filled in whenever possible. |
142 | * \value CompletionMan Same as automatic, but shortest match is used for completion. |
143 | * \value CompletionShell Completes text much in the same way as a typical *nix shell would. |
144 | * \value CompletionPopup Lists all possible matches in a popup list box to choose from. |
145 | * \value CompletionPopupAuto Lists all possible matches in a popup list box to choose from, and automatically fills the result whenever possible. |
146 | * |
147 | * \since 5.0 |
148 | */ |
149 | enum CompletionMode { |
150 | CompletionNone = 1, |
151 | CompletionAuto, |
152 | CompletionMan, |
153 | CompletionShell, |
154 | , |
155 | , |
156 | }; |
157 | |
158 | /*! |
159 | * Constants that represent the order in which KCompletion performs |
160 | * completion lookups. |
161 | * |
162 | * \value Sorted Use alphabetically sorted order or custom sorter logic. |
163 | * \value Insertion Use order of insertion. |
164 | * \value Weighted Use weighted order |
165 | * |
166 | */ |
167 | enum CompOrder { |
168 | Sorted, |
169 | Insertion, |
170 | Weighted, |
171 | }; |
172 | Q_ENUM(CompOrder) |
173 | |
174 | /*! |
175 | * The sorter function signature. Deriving classes may provide |
176 | * custom sorting logic via the setSorterFunction method. |
177 | * |
178 | * \since 5.88 |
179 | */ |
180 | using SorterFunction = std::function<void(QStringList &)>; |
181 | |
182 | /*! |
183 | * Constructor, nothing special here :) |
184 | */ |
185 | KCompletion(); |
186 | |
187 | ~KCompletion() override; |
188 | |
189 | /*! |
190 | * Returns a list of all completion items that contain the given \a string. |
191 | * \a string the string to complete |
192 | * |
193 | * Returns a list of items which contain \a text as a substring, |
194 | * i.e. not necessarily at the beginning. |
195 | * |
196 | * \sa makeCompletion |
197 | */ |
198 | QStringList substringCompletion(const QString &string) const; |
199 | |
200 | /*! |
201 | * Returns the last match. Might be useful if you need to check whether |
202 | * a completion is different from the last one. |
203 | * |
204 | * QString() is returned when there is no |
205 | * last match. |
206 | */ |
207 | virtual const QString &lastMatch() const; |
208 | |
209 | /*! |
210 | * Returns a list of all items inserted into KCompletion. This is useful |
211 | * if you need to save the state of a KCompletion object and restore it |
212 | * later. |
213 | * |
214 | * \note When order() == Weighted, then every item in the |
215 | * stringlist has its weight appended, delimited by a colon. E.g. an item |
216 | * "www.kde.org" might look like "www.kde.org:4", where 4 is the weight. |
217 | * This is necessary so that you can save the items along with its |
218 | * weighting on disk and load them back with setItems(), restoring its |
219 | * weight as well. If you really don't want the appended weightings, call |
220 | * setOrder( KCompletion::Insertion ) before calling items(). |
221 | * |
222 | * \sa setItems |
223 | */ |
224 | QStringList items() const; |
225 | |
226 | /*! |
227 | * Returns \c true if the completion object contains no entries. |
228 | */ |
229 | bool isEmpty() const; |
230 | |
231 | /*! |
232 | * Sets the completion mode. |
233 | * |
234 | * \a mode the completion mode |
235 | * |
236 | * \sa CompletionMode |
237 | */ |
238 | virtual void setCompletionMode(CompletionMode mode); |
239 | |
240 | /*! |
241 | * Returns the current completion mode, default is CompletionPopup |
242 | * \sa setCompletionMode |
243 | * \sa CompletionMode |
244 | */ |
245 | CompletionMode completionMode() const; |
246 | |
247 | /*! |
248 | * KCompletion offers three different ways in which it offers its items: |
249 | * \list |
250 | * \li in the order of insertion |
251 | * \li sorted alphabetically |
252 | * \li weighted |
253 | * \endlist |
254 | * |
255 | * Choosing weighted makes KCompletion perform an implicit weighting based |
256 | * on how often an item is inserted. Imagine a web browser with a location |
257 | * bar, where the user enters URLs. The more often a URL is entered, the |
258 | * higher priority it gets. |
259 | * |
260 | * \note Setting the order to sorted only affects new inserted items, |
261 | * already existing items will stay in the current order. So you probably |
262 | * want to call setOrder(Sorted) before inserting items if you want |
263 | * everything sorted. |
264 | * |
265 | * Default is insertion order. |
266 | * |
267 | * \a order the new order |
268 | * \sa order |
269 | */ |
270 | virtual void setOrder(CompOrder order); |
271 | |
272 | /*! |
273 | * Returns the completion order. |
274 | * \sa setOrder |
275 | */ |
276 | CompOrder order() const; |
277 | |
278 | /*! |
279 | * Setting this to true makes KCompletion behave case insensitively. |
280 | * |
281 | * E.g. makeCompletion("CA"); might return "carp\\cs.tu-berlin.de". |
282 | * |
283 | * Default is false (case sensitive). |
284 | * |
285 | * \a ignoreCase true to ignore the case |
286 | * |
287 | * \sa ignoreCase |
288 | */ |
289 | virtual void setIgnoreCase(bool ignoreCase); |
290 | |
291 | /*! |
292 | * Returns whether KCompletion acts case insensitively or not. |
293 | * |
294 | * Default is \c false (case sensitive). |
295 | * |
296 | * \sa setIgnoreCase |
297 | */ |
298 | bool ignoreCase() const; |
299 | |
300 | /*! |
301 | * Informs the caller if they should display the auto-suggestion for the last completion operation performed. |
302 | * |
303 | * Applies for CompletionPopupAuto and CompletionAuto modes. |
304 | * |
305 | * Defaults to \c true, but deriving classes may set it to false in special cases via "setShouldAutoSuggest". |
306 | * |
307 | * Returns \c true if auto-suggestion should be displayed for the last completion operation performed. |
308 | * \since 5.87 |
309 | */ |
310 | bool shouldAutoSuggest() const; |
311 | |
312 | /*! |
313 | * Returns a list of all items matching the last completed string. |
314 | * It might take some time if you have a lot of items. |
315 | * \sa substringCompletion |
316 | */ |
317 | QStringList allMatches(); |
318 | |
319 | /*! |
320 | * Returns a list of all items matching \a string. |
321 | */ |
322 | QStringList allMatches(const QString &string); |
323 | |
324 | /*! |
325 | * Returns a list of all items matching the last completed string. |
326 | * It might take some time if you have a lot of items. |
327 | * The matches are returned as KCompletionMatches, which also |
328 | * keeps the weight of the matches, allowing |
329 | * you to modify some matches or merge them with matches |
330 | * from another call to allWeightedMatches(), and sort the matches |
331 | * after that in order to have the matches ordered correctly. |
332 | * |
333 | * \sa substringCompletion |
334 | */ |
335 | KCompletionMatches allWeightedMatches(); |
336 | |
337 | /*! |
338 | * Returns a list of all items matching \a string. |
339 | */ |
340 | KCompletionMatches allWeightedMatches(const QString &string); |
341 | |
342 | #if KCOMPLETION_BUILD_DEPRECATED_SINCE(6, 11) // not KCOMPLETION_ENABLE_DEPRECATED_SINCE because this is a virtual function |
343 | /*! |
344 | * Enables/disables emitting a sound when |
345 | * \list |
346 | * \li makeCompletion() can't find a match |
347 | * \li there is a partial completion (= multiple matches in |
348 | * Shell-completion mode) |
349 | * \li nextMatch() or previousMatch() hit the last possible |
350 | * match and the list is rotated |
351 | * \endlist |
352 | * |
353 | * KNotifyClient() is used to emit the sounds. |
354 | * |
355 | * \a enable true to enable sounds |
356 | * |
357 | * \deprecated[6.11] |
358 | * not implemented |
359 | * \sa soundsEnabled |
360 | */ |
361 | KCOMPLETION_DEPRECATED_VERSION(6, 11, "Not implemented" ) |
362 | virtual void setSoundsEnabled(bool enable); |
363 | #endif |
364 | |
365 | #if KCOMPLETION_ENABLE_DEPRECATED_SINCE(6, 11) |
366 | /*! |
367 | * Tells you whether KCompletion will emit sounds on certain occasions. |
368 | * |
369 | * Default is enabled. |
370 | * |
371 | * \deprecated[6.11] |
372 | * Not implemented |
373 | * |
374 | * Returns \c true if sounds are enabled |
375 | * \sa setSoundsEnabled |
376 | */ |
377 | KCOMPLETION_DEPRECATED_VERSION(6, 11, "Not implemented" ) |
378 | bool soundsEnabled() const; |
379 | #endif |
380 | |
381 | /*! |
382 | * Returns \c true when more than one match is found. |
383 | * \sa multipleMatches |
384 | */ |
385 | bool hasMultipleMatches() const; |
386 | |
387 | public Q_SLOTS: |
388 | /*! |
389 | * Attempts to find an item in the list of available completions |
390 | * that begins with \a string. Will either return the first matching item |
391 | * (if there is more than one match) or QString(), if no match is |
392 | * found. |
393 | * |
394 | * In the latter case, a sound will be emitted, depending on |
395 | * soundsEnabled(). |
396 | * If a match is found, it will be emitted via the signal |
397 | * match(). |
398 | * |
399 | * If this is called twice or more with the same string while no |
400 | * items were added or removed in the meantime, all available completions |
401 | * will be emitted via the signal matches(). |
402 | * This happens only in shell-completion mode. |
403 | * |
404 | * \a string the string to complete |
405 | * |
406 | * Returns the matching item, or QString() if there is no matching |
407 | * item. |
408 | * \sa substringCompletion |
409 | */ |
410 | virtual QString makeCompletion(const QString &string); |
411 | |
412 | /*! |
413 | * Returns the next item from the list of matching items. |
414 | * |
415 | * When reaching the beginning, the list is rotated so it will return the |
416 | * last match and a sound is emitted (depending on soundsEnabled()). |
417 | * |
418 | * Returns the next item from the list of matching items. |
419 | * When there is no match, QString() is returned and |
420 | * a sound is emitted. |
421 | */ |
422 | QString previousMatch(); |
423 | |
424 | /*! |
425 | * Returns the next item from the list of matching items. |
426 | * |
427 | * When reaching the last item, the list is rotated, so it will return |
428 | * the first match and a sound is emitted (depending on |
429 | * soundsEnabled()). |
430 | * |
431 | * Returns the next item from the list of matching items. When there is no |
432 | * match, QString() is returned and a sound is emitted. |
433 | */ |
434 | QString nextMatch(); |
435 | |
436 | /*! |
437 | * Inserts \a items into the list of possible completions. |
438 | * |
439 | * It does the same as setItems(), but without calling clear() before. |
440 | * |
441 | * \a items the items to insert |
442 | */ |
443 | void insertItems(const QStringList &items); |
444 | |
445 | /*! |
446 | * Sets the list of items available for completion. Removes all previous |
447 | * items. |
448 | * |
449 | * \note When order() == Weighted, then the weighting is looked up for |
450 | * every item in the stringlist. Every item should have ":number" appended, |
451 | * where number is an unsigned integer, specifying the weighting. |
452 | * If you don't like this, call |
453 | * setOrder(KCompletion::Insertion) |
454 | * before calling setItems(). |
455 | * |
456 | * \a itemList the list of items that are available for completion |
457 | * |
458 | * \sa items |
459 | */ |
460 | virtual void setItems(const QStringList &itemList); |
461 | |
462 | /*! |
463 | * Adds an item to the list of available completions. |
464 | * Resets the current item state (previousMatch() and nextMatch() |
465 | * won't work the next time they are called). |
466 | * |
467 | * \a item the item to add |
468 | */ |
469 | void addItem(const QString &item); |
470 | |
471 | /*! |
472 | * Adds an item to the list of available completions. |
473 | * Resets the current item state (previousMatch() and nextMatch() |
474 | * won't work the next time they are called). |
475 | * |
476 | * Sets the weight of the item to \a weight or adds it to the current |
477 | * weight if the item is already available. The weight has to be greater |
478 | * than 1 to take effect (default weight is 1). |
479 | * |
480 | * \a item the item to add |
481 | * |
482 | * \a weight the weight of the item, default is 1 |
483 | */ |
484 | void addItem(const QString &item, uint weight); |
485 | |
486 | /*! |
487 | * Removes an item from the list of available completions. |
488 | * Resets the current item state (previousMatch() and nextMatch() |
489 | * won't work the next time they are called). |
490 | * |
491 | * \a item the item to remove |
492 | */ |
493 | void removeItem(const QString &item); |
494 | |
495 | /*! |
496 | * Removes all inserted items. |
497 | */ |
498 | virtual void clear(); |
499 | |
500 | Q_SIGNALS: |
501 | /*! |
502 | * This signal is emitted when a match is found. |
503 | * |
504 | * In particular, makeCompletion(), previousMatch() and nextMatch() |
505 | * all emit this signal; makeCompletion() will only emit it when a |
506 | * match is found, but the other methods will always emit it (and so |
507 | * may emit it with an empty string). |
508 | * |
509 | * \a item the matching item, or QString() if there were no more |
510 | * matching items. |
511 | */ |
512 | void match(const QString &item); |
513 | |
514 | /*! |
515 | * This signal is emitted by makeCompletion() in shell-completion mode |
516 | * when the same string is passed to makeCompletion() multiple times in |
517 | * a row. |
518 | * |
519 | * \a matchlist the list of all matching items |
520 | */ |
521 | void matches(const QStringList &matchlist); |
522 | |
523 | /*! |
524 | * This signal is emitted when calling makeCompletion() and more than |
525 | * one matching item is found. |
526 | * \sa hasMultipleMatches |
527 | */ |
528 | void multipleMatches(); |
529 | |
530 | protected: |
531 | /*! |
532 | * This method is called after a completion is found and before the |
533 | * matching string is emitted. You can override this method to modify the |
534 | * string that will be emitted. |
535 | * This is necessary e.g. in KUrlCompletion(), where files with spaces |
536 | * in their names are shown escaped ("filename\ with\ spaces"), but stored |
537 | * unescaped inside KCompletion. |
538 | * Never delete that pointer! |
539 | * |
540 | * Default implementation does nothing. |
541 | * |
542 | * \a match the match to process |
543 | * |
544 | * \sa postProcessMatches |
545 | */ |
546 | virtual void postProcessMatch(QString *match) const; |
547 | |
548 | /*! |
549 | * This method is called before a list of all available completions is |
550 | * emitted via matches(). You can override this method to modify the |
551 | * found items before match() or matches() are emitted. |
552 | * Never delete that pointer! |
553 | * |
554 | * Default implementation does nothing. |
555 | * |
556 | * \a matchList the matches to process |
557 | * |
558 | * \sa postProcessMatch |
559 | */ |
560 | virtual void postProcessMatches(QStringList *matchList) const; |
561 | |
562 | /*! |
563 | * This method is called before a list of all available completions is |
564 | * emitted via #matches(). You can override this method to modify the |
565 | * found items before #match() or #matches() are emitted. |
566 | * Never delete that pointer! |
567 | * |
568 | * Default implementation does nothing. |
569 | * |
570 | * \a matches the matches to process |
571 | * |
572 | * \sa postProcessMatch |
573 | */ |
574 | virtual void postProcessMatches(KCompletionMatches *matches) const; |
575 | |
576 | /*! |
577 | * Deriving classes may set this property and control whether the auto-suggestion should be displayed |
578 | * for the last completion operation performed. |
579 | * |
580 | * Applies for CompletionPopupAuto and CompletionAuto modes. |
581 | * \since 5.87 |
582 | */ |
583 | void setShouldAutoSuggest(bool shouldAutosuggest); |
584 | |
585 | /*! |
586 | * Sets a custom function to be used to sort the matches. |
587 | * Can be set to nullptr to use the default sorting logic. |
588 | * |
589 | * Applies for CompOrder::Sorted mode. |
590 | * \since 5.88 |
591 | */ |
592 | void setSorterFunction(SorterFunction sortFunc); |
593 | |
594 | private: |
595 | Q_DISABLE_COPY(KCompletion) |
596 | std::unique_ptr<KCompletionPrivate> const d_ptr; |
597 | }; |
598 | |
599 | #endif // KCOMPLETION_H |
600 | |