| 1 | /* |
| 2 | This file is part of the KDE libraries |
| 3 | |
| 4 | SPDX-FileCopyrightText: 2000, 2001 Dawit Alemayehu <adawit@kde.org> |
| 5 | SPDX-FileCopyrightText: 2000, 2001 Carsten Pfeiffer <pfeiffer@kde.org> |
| 6 | |
| 7 | SPDX-License-Identifier: LGPL-2.1-or-later |
| 8 | */ |
| 9 | |
| 10 | #ifndef KHistoryComboBoxBOX_H |
| 11 | #define KHistoryComboBoxBOX_H |
| 12 | |
| 13 | #include <kcombobox.h> |
| 14 | #include <kcompletion_export.h> |
| 15 | |
| 16 | #include <functional> |
| 17 | |
| 18 | class KHistoryComboBoxPrivate; |
| 19 | |
| 20 | /*! |
| 21 | * \class KHistoryComboBox |
| 22 | * \inmodule KCompletion |
| 23 | * |
| 24 | * \brief A combobox for offering a history and completion. |
| 25 | * |
| 26 | * A combobox which implements a history like a unix shell. You can navigate |
| 27 | * through all the items by using the Up or Down arrows (configurable of |
| 28 | * course). Additionally, weighted completion is available. So you should |
| 29 | * load and save the completion list to preserve the weighting between |
| 30 | * sessions. |
| 31 | * |
| 32 | * KHistoryComboBox obeys the HISTCONTROL environment variable to determine |
| 33 | * whether duplicates in the history should be tolerated in |
| 34 | * addToHistory() or not. During construction of KHistoryComboBox, |
| 35 | * duplicates will be disabled when HISTCONTROL is set to "ignoredups" or |
| 36 | * "ignoreboth". Otherwise, duplicates are enabled by default. |
| 37 | * |
| 38 | * \image khistorycombobox.png "KHistoryComboBox widget" |
| 39 | */ |
| 40 | class KCOMPLETION_EXPORT KHistoryComboBox : public KComboBox |
| 41 | { |
| 42 | Q_OBJECT |
| 43 | |
| 44 | /*! |
| 45 | * \property KHistoryComboBox::historyItems |
| 46 | */ |
| 47 | Q_PROPERTY(QStringList historyItems READ historyItems WRITE setHistoryItems) |
| 48 | |
| 49 | public: |
| 50 | /*! |
| 51 | * Constructs a "read-write" combobox. A read-only history combobox |
| 52 | * doesn't make much sense, so it is only available as read-write. |
| 53 | * Completion will be used automatically for the items in the combo. |
| 54 | * |
| 55 | * The insertion-policy is set to NoInsert, you have to add the items |
| 56 | * yourself via the slot addToHistory. If you want every item added, |
| 57 | * use |
| 58 | * |
| 59 | * \code |
| 60 | * connect( combo, SIGNAL( activated( const QString& )), |
| 61 | * combo, SLOT( addToHistory( const QString& ))); |
| 62 | * \endcode |
| 63 | * |
| 64 | * Use QComboBox::setMaxCount() to limit the history. |
| 65 | * |
| 66 | * \a parent the parent object of this widget. |
| 67 | */ |
| 68 | explicit KHistoryComboBox(QWidget *parent = nullptr); |
| 69 | |
| 70 | /*! |
| 71 | * Same as the previous constructor, but additionally has the option |
| 72 | * to specify whether you want to let KHistoryComboBox handle completion |
| 73 | * or not. If set to \c true, KHistoryComboBox will sync the completion to the |
| 74 | * contents of the combobox. |
| 75 | */ |
| 76 | explicit KHistoryComboBox(bool useCompletion, QWidget *parent = nullptr); |
| 77 | |
| 78 | ~KHistoryComboBox() override; |
| 79 | |
| 80 | /*! |
| 81 | * Inserts \a items into the combobox. \a items might get |
| 82 | * truncated if it is longer than maxCount() |
| 83 | * |
| 84 | * \sa historyItems |
| 85 | */ |
| 86 | void setHistoryItems(const QStringList &items); |
| 87 | |
| 88 | /*! |
| 89 | * Inserts \a items into the combobox. \a items might get |
| 90 | * truncated if it is longer than maxCount() |
| 91 | * |
| 92 | * Set \c setCompletionList to true, if you don't have a list of |
| 93 | * completions. This tells KHistoryComboBox to use all the items for the |
| 94 | * completion object as well. |
| 95 | * You won't have the benefit of weighted completion though, so normally |
| 96 | * you should do something like |
| 97 | * \code |
| 98 | * KConfigGroup config(KSharedConfig::openConfig(), "somegroup"); |
| 99 | * |
| 100 | * // load the history and completion list after creating the history combo |
| 101 | * QStringList list; |
| 102 | * list = config.readEntry("Completion list", QStringList()); |
| 103 | * combo->completionObject()->setItems(list); |
| 104 | * list = config.readEntry("History list", QStringList()); |
| 105 | * combo->setHistoryItems(list); |
| 106 | * |
| 107 | * [...] |
| 108 | * |
| 109 | * // save the history and completion list when the history combo is |
| 110 | * // destroyed |
| 111 | * QStringList list; |
| 112 | * KConfigGroup config(KSharedConfig::openConfig(), "somegroup"); |
| 113 | * list = combo->completionObject()->items(); |
| 114 | * config.writeEntry("Completion list", list); |
| 115 | * list = combo->historyItems(); |
| 116 | * config.writeEntry("History list", list); |
| 117 | * \endcode |
| 118 | * |
| 119 | * Be sure to use different names for saving with KConfig if you have more |
| 120 | * than one KHistoryComboBox. |
| 121 | * |
| 122 | * \note When setCompletionList is true, the items are inserted into the |
| 123 | * KCompletion object with mode KCompletion::Insertion and the mode is set |
| 124 | * to KCompletion::Weighted afterwards. |
| 125 | * |
| 126 | * \sa historyItems |
| 127 | * \sa KComboBox::completionObject |
| 128 | * \sa KCompletion::setItems |
| 129 | * \sa KCompletion::items |
| 130 | */ |
| 131 | void setHistoryItems(const QStringList &items, bool setCompletionList); |
| 132 | |
| 133 | /*! |
| 134 | * Returns the list of history items. Empty, when this is not a read-write |
| 135 | * combobox. |
| 136 | * |
| 137 | * \sa setHistoryItems |
| 138 | */ |
| 139 | QStringList historyItems() const; |
| 140 | |
| 141 | /*! |
| 142 | * Removes all items named \a item. |
| 143 | * |
| 144 | * Returns \c true if at least one item was removed. |
| 145 | * |
| 146 | * \sa addToHistory |
| 147 | */ |
| 148 | bool removeFromHistory(const QString &item); |
| 149 | |
| 150 | /*! |
| 151 | * Sets an icon provider, so that items in the combobox can have an icon. |
| 152 | * |
| 153 | * The provider is a function that takes a QString and returns a QIcon |
| 154 | * |
| 155 | * \since 5.66 |
| 156 | */ |
| 157 | void setIconProvider(std::function<QIcon(const QString &)> providerFunction); |
| 158 | |
| 159 | using QComboBox::insertItems; |
| 160 | |
| 161 | public Q_SLOTS: |
| 162 | /*! |
| 163 | * Adds an item to the end of the history list and to the completion list. |
| 164 | * If maxCount() is reached, the first item of the list will be |
| 165 | * removed. |
| 166 | * |
| 167 | * If the last inserted item is the same as \a item, it will not be |
| 168 | * inserted again. |
| 169 | * |
| 170 | * If duplicatesEnabled() is false, any equal existing item will be |
| 171 | * removed before \a item is added. |
| 172 | * |
| 173 | * \note By using this method and not the Q and KComboBox insertItem() |
| 174 | * methods, you make sure that the combobox stays in sync with the |
| 175 | * completion. It would be annoying if completion would give an item |
| 176 | * not in the combobox, and vice versa. |
| 177 | * |
| 178 | * \sa removeFromHistory |
| 179 | * \sa QComboBox::setDuplicatesEnabled |
| 180 | */ |
| 181 | void addToHistory(const QString &item); |
| 182 | |
| 183 | /*! |
| 184 | * Clears the history and the completion list. |
| 185 | */ |
| 186 | void clearHistory(); |
| 187 | |
| 188 | /*! |
| 189 | * Resets the current position of the up/down history. Call this |
| 190 | * when you manually call setCurrentItem() or clearEdit(). |
| 191 | */ |
| 192 | void reset(); |
| 193 | |
| 194 | Q_SIGNALS: |
| 195 | /*! |
| 196 | * Emitted when the history was cleared by the entry in the popup menu. |
| 197 | */ |
| 198 | void cleared(); |
| 199 | |
| 200 | protected: |
| 201 | /* |
| 202 | * Handling key-events, the shortcuts to rotate the items. |
| 203 | */ |
| 204 | void keyPressEvent(QKeyEvent *) override; |
| 205 | |
| 206 | /* |
| 207 | * Handling wheel-events, to rotate the items. |
| 208 | */ |
| 209 | void wheelEvent(QWheelEvent *ev) override; |
| 210 | |
| 211 | /*! |
| 212 | * Inserts \a items into the combo, honoring setIconProvider() |
| 213 | * Does not update the completionObject. |
| 214 | * |
| 215 | * \note duplicatesEnabled() is not honored here. |
| 216 | * |
| 217 | * Called from setHistoryItems() |
| 218 | */ |
| 219 | void insertItems(const QStringList &items); |
| 220 | |
| 221 | /*! |
| 222 | * Returns if we can modify the completion object or not. |
| 223 | */ |
| 224 | bool useCompletion() const; |
| 225 | |
| 226 | private: |
| 227 | Q_DECLARE_PRIVATE(KHistoryComboBox) |
| 228 | |
| 229 | Q_DISABLE_COPY(KHistoryComboBox) |
| 230 | }; |
| 231 | |
| 232 | #endif |
| 233 | |