File indexing completed on 2025-01-05 04:00:03

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-04-18
0007  * Description : User interface for searches
0008  *
0009  * SPDX-FileCopyrightText: 2008-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #ifndef DIGIKAM_CHOICE_SEARCH_UTILITIES_H
0016 #define DIGIKAM_CHOICE_SEARCH_UTILITIES_H
0017 
0018 // Qt includes
0019 
0020 #include <QAbstractListModel>
0021 #include <QList>
0022 #include <QVariant>
0023 
0024 // Local includes
0025 
0026 #include "dexpanderbox.h"
0027 #include "coredbsearchxml.h"
0028 #include "comboboxutilities.h"
0029 
0030 namespace Digikam
0031 {
0032 
0033 class ChoiceSearchModel : public QAbstractListModel
0034 {
0035     Q_OBJECT
0036 
0037 public:
0038 
0039     enum CustomRoles
0040     {
0041         IdRole = Qt::UserRole
0042     };
0043 
0044 public:
0045 
0046     explicit ChoiceSearchModel(QObject* const parent = nullptr);
0047 
0048     /**
0049      * Sets the data from the given map, with integer keys and QString user displayable value.
0050      */
0051     void setChoice(const QMap<int, QString>& data);
0052 
0053     /**
0054      * Sets the data from the given list,
0055      * taking every first entry as the key, every second as the user displayable value.
0056      * Ensure that the QVariants' type is correct (identical for all even entries, QString for all odd entries).
0057      */
0058     void setChoice(const QVariantList& data);
0059 
0060     /**
0061      * Sets the data from the given list,
0062      * taking every first entry as the key, every second as the user displayable value.
0063      */
0064     void setChoice(const QStringList& data);
0065 
0066     /**
0067      * Returns the keys of all entries that are selected (checked).
0068      */
0069     QVariantList checkedKeys() const;
0070 
0071     /**
0072      * Returns the keys of all entries that are selected (checked), converted to
0073      * a list of the template type. Supported for Int and QString types.
0074      */
0075     template <typename T> QList<T> checkedKeys() const;
0076 
0077     /**
0078      * Returns the display text of all entries that are selected.
0079      */
0080     QStringList checkedDisplayTexts() const;
0081 
0082     /**
0083      * Sets the check state of the entry with given key.
0084      */
0085     template <typename T> void setChecked(const T& key, bool checked = true);
0086 
0087     /**
0088      * Sets the check state of all the entries whose key is found in the list to checked.
0089      */
0090     template <typename T> void setChecked(const QList<T>& keys, bool checked = true);
0091 
0092     /**
0093      * Sets the check state of all entries. The check state is determined by
0094      * the key of an entry, the relation, and a constant value.
0095      * Think of "Set to checked if key is less than 5".
0096      * Supported for Int and QString types.
0097      */
0098     template <typename T> void setChecked(const T& value, SearchXml::Relation relation);
0099 
0100     /**
0101      * Sets all entries to unchecked.
0102      */
0103     void resetChecked();
0104 
0105     int           rowCount(const QModelIndex& parent) const override;
0106     QVariant      data(const QModelIndex& index, int role) const override;
0107     QModelIndex   index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override;
0108     Qt::ItemFlags flags(const QModelIndex& index) const override;
0109     bool          setData(const QModelIndex& index, const QVariant& value, int role) override;
0110 
0111 Q_SIGNALS:
0112 
0113     void checkStateChanged(const QVariant& key, bool isChecked);
0114 
0115 protected:
0116 
0117     void setChecked(int index, bool checked);
0118 
0119 protected:
0120 
0121     class Entry
0122     {
0123     public:
0124 
0125         Entry();
0126         Entry(const QVariant& key, const QString& userDisplay);
0127 
0128         bool operator==(const Entry& other) const;
0129 
0130         /// @todo This function has no definition.
0131         bool operator==(const QVariant& other) const;
0132 
0133     public:
0134 
0135         QVariant m_key;
0136         QString  m_display;
0137         bool     m_checkState;
0138     };
0139 
0140 protected:
0141 
0142     QList<Entry> m_entries;
0143 };
0144 
0145 template <typename T> void ChoiceSearchModel::setChecked(const T& key, bool checked)
0146 {
0147     QVariant variantKey(key);
0148 
0149     for (int i = 0 ; i < m_entries.size() ; ++i)
0150     {
0151         if (m_entries[i].m_key == variantKey)
0152         {
0153             setChecked(i, checked);
0154         }
0155     }
0156 }
0157 
0158 template <typename T> void ChoiceSearchModel::setChecked(const T& value, SearchXml::Relation relation)
0159 {
0160     for (int i = 0 ; i < m_entries.size() ; ++i)
0161     {
0162         setChecked(i, SearchXml::testRelation(m_entries.at(i).m_key.value<T>(), value, relation));
0163     }
0164 }
0165 
0166 template <typename T> void ChoiceSearchModel::setChecked(const QList<T>& keys, bool checked)
0167 {
0168     Q_FOREACH (T key, keys)
0169     {
0170         setChecked(key, checked);
0171     }
0172 }
0173 
0174 template <typename T> QList<T> ChoiceSearchModel::checkedKeys() const
0175 {
0176     QList<T> list;
0177 
0178     for (QList<Entry>::const_iterator it = m_entries.begin() ; it != m_entries.end() ; ++it)
0179     {
0180         if ((*it).m_checkState)
0181         {
0182             list << (*it).m_key.value<T>();
0183         }
0184     }
0185 
0186     return list;
0187 }
0188 
0189 // -------------------------------------------------------------------------------------
0190 
0191 class ChoiceSearchComboBox : public ListViewComboBox
0192 {
0193     Q_OBJECT
0194 
0195 public:
0196 
0197     /**
0198      * A combo box for entering a choice of values.
0199      * Operates on a ChoiceSearchModel.
0200      * After constructing the object, call setModel
0201      * with your model.
0202      */
0203     explicit ChoiceSearchComboBox(QWidget* const parent = nullptr);
0204 
0205     /**
0206      * Sets the model and initializes the widget.
0207      * Can only be called once for a widget.
0208      */
0209     void setSearchModel(ChoiceSearchModel* model);
0210 
0211     /**
0212      * Updates the text on the line edit area.
0213      */
0214     void setLabelText(const QString& text);
0215 
0216     ChoiceSearchModel*   model() const;
0217     DSqueezedClickLabel* label() const;
0218 
0219 Q_SIGNALS:
0220 
0221     void checkStateChanged();
0222 
0223 protected Q_SLOTS:
0224 
0225     void labelClicked();
0226 
0227 protected:
0228 
0229     void installView(QAbstractItemView* view = nullptr) override;
0230 
0231 protected:
0232 
0233     DSqueezedClickLabel* m_label;
0234 };
0235 
0236 } // namespace Digikam
0237 
0238 #endif // DIGIKAM_CHOICE_SEARCH_UTILITIES_H