File indexing completed on 2024-05-12 11:47:09

0001 /*
0002     This file is part of the KDE libraries
0003 
0004     SPDX-FileCopyrightText: 2000, 2001 Dawit Alemayehu <adawit@kde.org>
0005     SPDX-FileCopyrightText: 2000, 2001 Carsten Pfeiffer <pfeiffer@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.1-or-later
0008 */
0009 
0010 #ifndef KHistoryComboBoxBOX_H
0011 #define KHistoryComboBoxBOX_H
0012 
0013 #include <kcombobox.h>
0014 #include <kcompletion_export.h>
0015 
0016 #include <functional>
0017 
0018 class KPixmapProvider;
0019 class KHistoryComboBoxPrivate;
0020 
0021 /**
0022  * @class KHistoryComboBox khistorycombobox.h KHistoryComboBox
0023  *
0024  * @short A combobox for offering a history and completion
0025  *
0026  * A combobox which implements a history like a unix shell. You can navigate
0027  * through all the items by using the Up or Down arrows (configurable of
0028  * course). Additionally, weighted completion is available. So you should
0029  * load and save the completion list to preserve the weighting between
0030  * sessions.
0031  *
0032  * KHistoryComboBox obeys the HISTCONTROL environment variable to determine
0033  * whether duplicates in the history should be tolerated in
0034  * addToHistory() or not. During construction of KHistoryComboBox,
0035  * duplicates will be disabled when HISTCONTROL is set to "ignoredups" or
0036  * "ignoreboth". Otherwise, duplicates are enabled by default.
0037  *
0038  * \image html khistorycombobox.png "KHistoryComboBox widget"
0039  *
0040  * @author Carsten Pfeiffer <pfeiffer@kde.org>
0041  */
0042 class KCOMPLETION_EXPORT KHistoryComboBox : public KComboBox
0043 {
0044     Q_OBJECT
0045 
0046     Q_PROPERTY(QStringList historyItems READ historyItems WRITE setHistoryItems)
0047 
0048 public:
0049     /**
0050      * Constructs a "read-write" combobox. A read-only history combobox
0051      * doesn't make much sense, so it is only available as read-write.
0052      * Completion will be used automatically for the items in the combo.
0053      *
0054      * The insertion-policy is set to NoInsert, you have to add the items
0055      * yourself via the slot addToHistory. If you want every item added,
0056      * use
0057      *
0058      * \code
0059      * connect( combo, SIGNAL( activated( const QString& )),
0060      *          combo, SLOT( addToHistory( const QString& )));
0061      * \endcode
0062      *
0063      * Use QComboBox::setMaxCount() to limit the history.
0064      *
0065      * @p parent the parent object of this widget.
0066      */
0067     explicit KHistoryComboBox(QWidget *parent = nullptr);
0068 
0069     /**
0070      * Same as the previous constructor, but additionally has the option
0071      * to specify whether you want to let KHistoryComboBox handle completion
0072      * or not. If set to @c true, KHistoryComboBox will sync the completion to the
0073      * contents of the combobox.
0074      */
0075     explicit KHistoryComboBox(bool useCompletion, QWidget *parent = nullptr);
0076 
0077     /**
0078      * Destructs the combo, the completion-object and the pixmap-provider
0079      */
0080     ~KHistoryComboBox() override;
0081 
0082     /**
0083      * Inserts @p items into the combobox. @p items might get
0084      * truncated if it is longer than maxCount()
0085      *
0086      * @see historyItems
0087      */
0088     void setHistoryItems(const QStringList &items);
0089 
0090     /**
0091      * Inserts @p items into the combobox. @p items might get
0092      * truncated if it is longer than maxCount()
0093      *
0094      * Set @c setCompletionList to true, if you don't have a list of
0095      * completions. This tells KHistoryComboBox to use all the items for the
0096      * completion object as well.
0097      * You won't have the benefit of weighted completion though, so normally
0098      * you should do something like
0099      * \code
0100      * KConfigGroup config(KSharedConfig::openConfig(), "somegroup");
0101      *
0102      * // load the history and completion list after creating the history combo
0103      * QStringList list;
0104      * list = config.readEntry("Completion list", QStringList());
0105      * combo->completionObject()->setItems(list);
0106      * list = config.readEntry("History list", QStringList());
0107      * combo->setHistoryItems(list);
0108      *
0109      * [...]
0110      *
0111      * // save the history and completion list when the history combo is
0112      * // destroyed
0113      * QStringList list;
0114      * KConfigGroup config(KSharedConfig::openConfig(), "somegroup");
0115      * list = combo->completionObject()->items();
0116      * config.writeEntry("Completion list", list);
0117      * list = combo->historyItems();
0118      * config.writeEntry("History list", list);
0119      * \endcode
0120      *
0121      * Be sure to use different names for saving with KConfig if you have more
0122      * than one KHistoryComboBox.
0123      *
0124      * @note When @c setCompletionList is true, the items are inserted into the
0125      * KCompletion object with mode KCompletion::Insertion and the mode is set
0126      * to KCompletion::Weighted afterwards.
0127      *
0128      * @see historyItems
0129      * @see KComboBox::completionObject
0130      * @see KCompletion::setItems
0131      * @see KCompletion::items
0132      */
0133     void setHistoryItems(const QStringList &items, bool setCompletionList);
0134 
0135     /**
0136      * Returns the list of history items. Empty, when this is not a read-write
0137      * combobox.
0138      *
0139      * @see setHistoryItems
0140      */
0141     QStringList historyItems() const;
0142 
0143     /**
0144      * Removes all items named @p item.
0145      *
0146      * @return @c true if at least one item was removed.
0147      *
0148      * @see addToHistory
0149      */
0150     bool removeFromHistory(const QString &item);
0151 
0152 #if KCOMPLETION_ENABLE_DEPRECATED_SINCE(5, 66)
0153     /**
0154      * Sets a pixmap provider, so that items in the combobox can have a pixmap.
0155      * KPixmapProvider is just an abstract class with the one pure virtual
0156      * method KPixmapProvider::pixmapFor(). This method is called whenever
0157      * an item is added to the KHistoryComboBoxBox. Implement it to return your
0158      * own custom pixmaps, or use the KUrlPixmapProvider from KIO,
0159      * which uses KMimeType::pixmapForUrl to resolve icons.
0160      *
0161      * Set @p provider to nullptr if you want to disable pixmaps. Default no pixmaps.
0162      *
0163      * @see pixmapProvider
0164      * @deprecated since 5.66, use setIconProvider
0165      */
0166     KCOMPLETION_DEPRECATED_VERSION(5, 66, "Use setIconProvider")
0167     void setPixmapProvider(KPixmapProvider *provider);
0168 #endif
0169 
0170 #if KCOMPLETION_ENABLE_DEPRECATED_SINCE(5, 66)
0171     /**
0172      * @returns the current pixmap provider.
0173      * @see setPixmapProvider
0174      * @see KPixmapProvider
0175      * @deprecated since 5.66, unused
0176      */
0177     KCOMPLETION_DEPRECATED_VERSION(5, 66, "unused")
0178     KPixmapProvider *pixmapProvider() const;
0179 #endif
0180 
0181     /**
0182      * Sets an icon provider, so that items in the combobox can have an icon.
0183      * The provider is a function that takes a QString and returns a QIcon
0184      * @since 5.66
0185      */
0186     void setIconProvider(std::function<QIcon(const QString &)> providerFunction);
0187 
0188     using QComboBox::insertItems;
0189 
0190 public Q_SLOTS:
0191     /**
0192      * Adds an item to the end of the history list and to the completion list.
0193      * If maxCount() is reached, the first item of the list will be
0194      * removed.
0195      *
0196      * If the last inserted item is the same as @p item, it will not be
0197      * inserted again.
0198      *
0199      * If duplicatesEnabled() is false, any equal existing item will be
0200      * removed before @p item is added.
0201      *
0202      * @note By using this method and not the Q and KComboBox insertItem()
0203      * methods, you make sure that the combobox stays in sync with the
0204      * completion. It would be annoying if completion would give an item
0205      * not in the combobox, and vice versa.
0206      *
0207      * @see removeFromHistory
0208      * @see QComboBox::setDuplicatesEnabled
0209      */
0210     void addToHistory(const QString &item);
0211 
0212     /**
0213      * Clears the history and the completion list.
0214      */
0215     void clearHistory();
0216 
0217     /**
0218      * Resets the current position of the up/down history. Call this
0219      * when you manually call setCurrentItem() or clearEdit().
0220      */
0221     void reset();
0222 
0223 Q_SIGNALS:
0224     /**
0225      * Emitted when the history was cleared by the entry in the popup menu.
0226      */
0227     void cleared();
0228 
0229 protected:
0230     /**
0231      * Handling key-events, the shortcuts to rotate the items.
0232      */
0233     void keyPressEvent(QKeyEvent *) override;
0234 
0235     /**
0236      * Handling wheel-events, to rotate the items.
0237      */
0238     void wheelEvent(QWheelEvent *ev) override;
0239 
0240     /**
0241      * Inserts @p items into the combo, honoring pixmapProvider()
0242      * Does not update the completionObject.
0243      *
0244      * @note duplicatesEnabled() is not honored here.
0245      *
0246      * Called from setHistoryItems() and setPixmapProvider()
0247      */
0248     void insertItems(const QStringList &items);
0249 
0250     /**
0251      * @returns if we can modify the completion object or not.
0252      */
0253     bool useCompletion() const;
0254 
0255 private:
0256     Q_DECLARE_PRIVATE_D(KComboBox::d_ptr, KHistoryComboBox)
0257 #if KCOMPLETION_BUILD_DEPRECATED_SINCE(5, 79)
0258     QT_WARNING_PUSH
0259     QT_WARNING_DISABLE_CLANG("-Wunused-private-field")
0260     // Unused, kept for ABI compatibility
0261     const void *__kcompletion_d_do_not_use;
0262     QT_WARNING_POP
0263 #endif
0264 
0265     Q_DISABLE_COPY(KHistoryComboBox)
0266 };
0267 
0268 #endif