1 /*
2  *  Copyright (c) 2013 Sven Langkamp <sven.langkamp@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 
20 #ifndef KIS_PALETTEMODEL_H
21 #define KIS_PALETTEMODEL_H
22 
23 #include <QPointer>
24 #include <QModelIndex>
25 #include <QMap>
26 
27 #include <KoColorDisplayRendererInterface.h>
28 
29 #include "kritawidgets_export.h"
30 #include <KoColorSet.h>
31 #include <QScopedPointer>
32 
33 class KoColorSet;
34 class KisPaletteView;
35 
36 /**
37  * @brief The KisPaletteModel class
38  * This, together with KisPaletteView and KisPaletteDelegate forms a mvc way to access kocolorsets.
39  * A display renderer is given to this model to convert KoColor to QColor when
40  * colors are requested
41  */
42 class KRITAWIDGETS_EXPORT KisPaletteModel : public QAbstractTableModel
43 {
44     Q_OBJECT
45 public:
46     explicit KisPaletteModel(QObject* parent = 0);
47     ~KisPaletteModel() override;
48 
49     enum AdditionalRoles {
50         IsGroupNameRole = Qt::UserRole + 1,
51         CheckSlotRole,
52         GroupNameRole,
53         RowInGroupRole
54     };
55 
56 public /* overridden methods */: // QAbstractTableModel
57     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
58     int rowCount(const QModelIndex& parent = QModelIndex()) const override;
59     int columnCount(const QModelIndex& parent = QModelIndex()) const override;
60     /**
61      * @brief index
62      * @param row
63      * @param column
64      * @param parent
65      * @return the index of for the data at row, column
66      * if the data is a color entry, the internal pointer points to the group
67      * the entry belongs to, and the row and column are row number and column
68      * number inside the group.
69      * if the data is a group, the row number and group number is Q_INFINIFY,
70      * and the internal pointer also points to the group
71      */
72     QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
73 
74     Qt::ItemFlags flags(const QModelIndex& index) const override;
75 
76     /**
77      * @brief dropMimeData
78      * This is an overridden function that handles dropped mimedata.
79      * right now only colorsetentries and colorsetgroups are handled.
80      * @return
81      */
82     bool dropMimeData(const QMimeData *data, Qt::DropAction action,
83                       int row, int column, const QModelIndex &parent) override;
84     /**
85      * @brief mimeData
86      * gives the mimedata for a kocolorsetentry or a kocolorsetgroup.
87      * @param indexes
88      * @return the mimedata for the given indices
89      */
90     QMimeData *mimeData(const QModelIndexList &indexes) const override;
91 
92     QStringList mimeTypes() const override;
93 
94     Qt::DropActions supportedDropActions() const override;
95     /**
96      * @brief setData
97      * setData is not used as KoColor is not a QVariant
98      * use setEntry, addEntry and removeEntry instead
99      */
100     // TODO Used QVariant::setValue and QVariant.value<KoColor> to implement this
101     // bool setData(const QModelIndex &index, const QVariant &value, int role) override;
102 
103 Q_SIGNALS:
104     /**
105      * @brief sigPaletteModified
106      * emitted when palette associated with the model is modified
107      */
108     void sigPaletteModified();
109     /**
110      * @brief sigPaletteChanged
111      * emitted when the palette associated with the model is made another one
112      */
113     void sigPaletteChanged();
114 
115 public /* methods */:
116     /**
117      * @brief addEntry
118      * proper function to handle adding entries.
119      * @return whether successful.
120      */
121     bool addEntry(const KisSwatch &entry,
122                   const QString &groupName = KoColorSet::GLOBAL_GROUP_NAME);
123 
124     void setEntry(const KisSwatch &entry, const QModelIndex &index);
125 
126     /**
127      * @brief removeEntry
128      * proper function to remove the colorsetentry at the given index.
129      * The consolidates both removeentry and removegroup.
130      * @param index the given index
131      * @param keepColors This bool determines whether, when deleting a group,
132      * the colors should be added to the default group. This is usually desirable,
133      * so hence the default is true.
134      * @return if successful
135      */
136     bool removeEntry(const QModelIndex &index, bool keepColors=true);
137     void removeGroup(const QString &groupName, bool keepColors);
138     bool renameGroup(const QString &groupName, const QString &newName);
139     void addGroup(const KisSwatchGroup &group);
140     void setRowNumber(const QString &groupName, int rowCount);
141     void clear();
142     void clear(int defaultColumnsCount);
143 
144     KisSwatch getEntry(const QModelIndex &index) const;
145 
146     void setPalette(KoColorSet* colorSet);
147     KoColorSet* colorSet() const;
148 
149     QModelIndex indexForClosest(const KoColor &compare);
150     int indexRowForInfo(const KisSwatchGroup::SwatchInfo &info);
151 
152 public Q_SLOTS:
153 
154 private Q_SLOTS:
155     void slotDisplayConfigurationChanged();
156     void slotPaletteModified();
157 
158 private /* methods */:
159     QVariant dataForGroupNameRow(const QModelIndex &idx, int role) const;
160     QVariant dataForSwatch(const QModelIndex &idx, int role) const;
161     int rowNumberInGroup(int rowInModel) const;
162     int groupNameRowForRow(int rowInModel) const;
163     int groupNameRowForName(const QString &groupName);
164     void resetGroupNameRows();
165     /**
166      * Installs a display renderer object for a palette that will
167      * convert the KoColor to the displayable QColor. Default is the
168      * dumb renderer.
169      */
170     void setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer);
171 
172 
173 private /* member variables */:
174     QPointer<KoColorSet> m_colorSet;
175     QPointer<const KoColorDisplayRendererInterface> m_displayRenderer;
176     QMap<int, QString> m_rowGroupNameMap;
177 
178 friend class KisPaletteView;
179 };
180 
181 #endif
182