File indexing completed on 2025-01-19 03:59:43

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-11-15
0007  * Description : collections setup tab model/view
0008  *
0009  * SPDX-FileCopyrightText: 2008-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  * SPDX-FileCopyrightText: 2005-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #ifndef DIGIKAM_SETUP_COLLECTION_VIEW_H
0017 #define DIGIKAM_SETUP_COLLECTION_VIEW_H
0018 
0019 // Qt includes
0020 
0021 #include <QAbstractItemModel>
0022 #include <QAbstractItemDelegate>
0023 #include <QList>
0024 #include <QTreeView>
0025 #include <QStyledItemDelegate>
0026 #include <QPushButton>
0027 #include <QToolButton>
0028 
0029 // Local includes
0030 
0031 #include "collectionlocation.h"
0032 #include "dwitemdelegate.h"
0033 #include "digikam_export.h"
0034 
0035 namespace Digikam
0036 {
0037 
0038 class DIGIKAM_GUI_EXPORT SetupCollectionModel : public QAbstractItemModel
0039 {
0040     Q_OBJECT
0041 
0042 public:
0043 
0044     /**
0045      * SetupCollectionModel is a model specialized for use in
0046      * SetupCollectionTreeView. It provides a reads the current collections
0047      * from CollectionManager, displays them in three categories,
0048      * and supports adding and removing collections
0049      */
0050 
0051     enum SetupCollectionDataRole
0052     {
0053         /// Returns true if the model index is the index of a category
0054         IsCategoryRole             = Qt::UserRole,
0055 
0056         /// The text for the category button
0057         CategoryButtonDisplayRole  = Qt::UserRole + 1,
0058         CategoryButtonMapId        = Qt::UserRole + 2,
0059 
0060         /// Returns true if the model index is the index of a button
0061         IsAppendRole               = Qt::UserRole + 3,
0062 
0063         /// The pixmap of the button
0064         AppendDecorationRole       = Qt::UserRole + 4,
0065         AppendMapId                = Qt::UserRole + 5,
0066 
0067         /// Returns true if the model index is the index of a button
0068         IsUpdateRole               = Qt::UserRole + 6,
0069 
0070         /// The pixmap of the button
0071         UpdateDecorationRole       = Qt::UserRole + 7,
0072         UpdateMapId                = Qt::UserRole + 8,
0073 
0074         /// Returns true if the model index is the index of a button
0075         IsDeleteRole               = Qt::UserRole + 9,
0076 
0077         /// The pixmap of the button
0078         DeleteDecorationRole       = Qt::UserRole + 10,
0079         DeleteMapId                = Qt::UserRole + 11
0080     };
0081 
0082     enum Columns
0083     {
0084         ColumnStatus       = 0,
0085         ColumnName         = 1,
0086         ColumnPath         = 2,
0087         ColumnAppendButton = 3,
0088         ColumnUpdateButton = 4,
0089         ColumnDeleteButton = 5,
0090         NumberOfColumns
0091     };
0092 
0093     enum Category
0094     {
0095         CategoryLocal      = 0,
0096         CategoryRemovable  = 1,
0097         CategoryRemote     = 2,
0098         NumberOfCategories
0099     };
0100 
0101 public:
0102 
0103     explicit SetupCollectionModel(QObject* const parent = nullptr);
0104     ~SetupCollectionModel() override;
0105 
0106     /// Read collections from CollectionManager
0107     void loadCollections();
0108 
0109     /// Set a widget used as parent for dialogs and message boxes
0110     void setParentWidgetForDialogs(QWidget* const widget);
0111 
0112     /// Apply the changed settings to CollectionManager
0113     void apply();
0114 
0115     QModelIndex indexForCategory(Category category)                                           const;
0116     QList<QModelIndex> categoryIndexes()                                                      const;
0117 
0118     /// QAbstractItemModel implementation
0119     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole)                       const override;
0120     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
0121     int rowCount(const QModelIndex& parent = QModelIndex())                                   const override;
0122     int columnCount(const QModelIndex& parent = QModelIndex())                                const override;
0123     Qt::ItemFlags flags(const QModelIndex& index)                                             const override;
0124     bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole)          override;
0125     QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex())         const override;
0126     QModelIndex parent(const QModelIndex& index)                                              const override;
0127 
0128 /*
0129     virtual Qt::DropActions supportedDropActions() const;
0130     virtual QStringList mimeTypes() const;
0131     virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
0132     virtual QMimeData * mimeData(const QModelIndexList& indexes) const;
0133 */
0134 
0135 Q_SIGNALS:
0136 
0137     /// Emitted when all collections were loaded and the model reset in loadCollections
0138     void collectionsLoaded();
0139 
0140 public Q_SLOTS:
0141 
0142     /**
0143      * Forward category button clicked signals to this slot.
0144      * mappedId is retrieved with the CategoryButtonMapId role
0145      * for the model index of the button
0146      */
0147     void slotCategoryButtonPressed(int mappedId);
0148 
0149     /**
0150      * Forward button clicked signals to this slot.
0151      * mappedId is retrieved with the ButtonMapId role
0152      * for the model index of the button
0153      */
0154     void slotAppendPressed(int mappedId);
0155     void slotUpdatePressed(int mappedId);
0156     void slotDeletePressed(int mappedId);
0157 
0158 public:
0159 
0160     QString lastAddedCollectionPath;
0161 
0162 protected Q_SLOTS:
0163 
0164     void addCollection(int category);
0165     void updateCollection(int internalId);
0166     void deleteCollection(int internalId);
0167 
0168 protected:
0169 
0170     QModelIndex indexForId(int id, int column)          const;
0171 
0172     bool askForNewCollectionPath(bool adding,
0173                                  int category,
0174                                  QString* const newPath,
0175                                  QString* const newLabel);
0176     bool askForNewCollectionCategory(int* const category);
0177 
0178     int categoryButtonMapId(const QModelIndex& index)   const;
0179     int buttonMapId(const QModelIndex& index)           const;
0180 
0181     static Category typeToCategory(CollectionLocation::Type type);
0182 
0183 protected:
0184 
0185     class Item
0186     {
0187     public:
0188 
0189         Item();
0190         explicit Item(const CollectionLocation& location);
0191         Item(const QString& path, const QString& label, SetupCollectionModel::Category category);
0192 
0193     public:
0194 
0195         CollectionLocation location;
0196         QStringList        childs;
0197         QString            label;
0198         QString            path;
0199         int                parentId;
0200         int                orgIndex;
0201         bool               appended;
0202         bool               updated;
0203         bool               deleted;
0204     };
0205 
0206 protected:
0207 
0208     QList<Item> m_collections;
0209     QWidget*    m_dialogParentWidget;
0210 
0211 private Q_SLOTS:
0212 
0213     void slotHelp();
0214 };
0215 
0216 // -----------------------------------------------------------------------
0217 
0218 class SetupCollectionTreeView : public QTreeView
0219 {
0220     Q_OBJECT
0221 
0222 public:
0223 
0224     explicit SetupCollectionTreeView(QWidget* const parent = nullptr);
0225 
0226     void setModel(SetupCollectionModel* model);
0227 
0228 protected Q_SLOTS:
0229 
0230     void modelLoadedCollections();
0231 
0232 private:
0233 
0234     void setModel(QAbstractItemModel* model) override
0235     {
0236         setModel(static_cast<SetupCollectionModel*>(model));
0237     }
0238 };
0239 
0240 // -----------------------------------------------------------------------
0241 
0242 class SetupCollectionDelegate : public DWItemDelegate
0243 {
0244     Q_OBJECT
0245 
0246 public:
0247 
0248     explicit SetupCollectionDelegate(QAbstractItemView* const view,
0249                                      QObject* const parent = nullptr);
0250     ~SetupCollectionDelegate()                                                    override;
0251 
0252     QWidget* createEditor(QWidget* parent,
0253                           const QStyleOptionViewItem& option,
0254                           const QModelIndex& index)                         const override;
0255 
0256     bool     editorEvent(QEvent* event,
0257                          QAbstractItemModel* model,
0258                          const QStyleOptionViewItem& option,
0259                          const QModelIndex& index)                                override;
0260 
0261     void     paint(QPainter* painter,
0262                    const QStyleOptionViewItem& option,
0263                    const QModelIndex& index)                                const override;
0264 
0265     void     setEditorData(QWidget* editor,
0266                            const QModelIndex& index)                        const override;
0267 
0268     void     setModelData(QWidget* editor,
0269                           QAbstractItemModel* model,
0270                           const QModelIndex& index)                         const override;
0271 
0272     QSize    sizeHint(const QStyleOptionViewItem& option,
0273                       const QModelIndex& index)                             const override;
0274 
0275     void     updateEditorGeometry(QWidget* editor,
0276                                   const QStyleOptionViewItem& option,
0277                                   const QModelIndex& index)                 const override;
0278 
0279     QList<QWidget*> createItemWidgets(const QModelIndex& index)             const override;
0280     void            updateItemWidgets(const QList<QWidget*>& widgets,
0281                                       const QStyleOptionViewItem& option,
0282                                       const QPersistentModelIndex& index)   const override;
0283 
0284 Q_SIGNALS:
0285 
0286     void categoryButtonPressed(int mappedId)                                const;     // clazy:exclude=const-signal-or-slot
0287     void appendPressed(int mappedId)                                        const;     // clazy:exclude=const-signal-or-slot
0288     void updatePressed(int mappedId)                                        const;     // clazy:exclude=const-signal-or-slot
0289     void deletePressed(int mappedId)                                        const;     // clazy:exclude=const-signal-or-slot
0290 
0291 protected:
0292 
0293     QStyledItemDelegate* m_styledDelegate;
0294 
0295     QPushButton*         m_samplePushButton;
0296     QToolButton*         m_sampleAppendButton;
0297     QToolButton*         m_sampleUpdateButton;
0298     QToolButton*         m_sampleDeleteButton;
0299     int                  m_categoryMaxStyledWidth;
0300 };
0301 
0302 } // namespace Digikam
0303 
0304 #endif // DIGIKAM_SETUP_COLLECTION_VIEW_H