Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #ifndef __PALETTEMODEL_H__
24 : #define __PALETTEMODEL_H__
25 :
26 : #include <QAbstractItemModel>
27 : #include <QSortFilterProxyModel>
28 :
29 : #include "internal/palettetree.h"
30 :
31 : #include "modularity/ioc.h"
32 : #include "ipaletteconfiguration.h"
33 : #include "async/asyncable.h"
34 :
35 : namespace mu::engraving {
36 : class Selection;
37 : }
38 :
39 : namespace mu::palette {
40 : //---------------------------------------------------------
41 : // PaletteCellFilter
42 : /// Interface for filtering elements in a palette
43 : //---------------------------------------------------------
44 :
45 : class PaletteCellFilter : public QObject
46 : {
47 : Q_OBJECT
48 :
49 : PaletteCellFilter * chainedFilter = nullptr;
50 :
51 : signals:
52 : void filterChanged();
53 :
54 : protected:
55 : virtual bool acceptCell(const PaletteCell&) const = 0;
56 :
57 : public:
58 0 : PaletteCellFilter(QObject* parent = nullptr)
59 0 : : QObject(parent) {}
60 :
61 : bool accept(const PaletteCell&) const;
62 :
63 : void addChainedFilter(PaletteCellFilter*);
64 : void connectToModel(const QAbstractItemModel*);
65 : };
66 :
67 : //---------------------------------------------------------
68 : // VisibilityCellFilter
69 : //---------------------------------------------------------
70 :
71 : class VisibilityCellFilter : public PaletteCellFilter
72 : {
73 : bool acceptedValue;
74 :
75 0 : bool acceptCell(const PaletteCell& cell) const override { return cell.visible == acceptedValue; }
76 :
77 : public:
78 0 : VisibilityCellFilter(bool acceptedVal, QObject* parent = nullptr)
79 0 : : PaletteCellFilter(parent), acceptedValue(acceptedVal) {}
80 : };
81 :
82 : //---------------------------------------------------------
83 : // CustomizedCellFilter
84 : //---------------------------------------------------------
85 :
86 : class CustomizedCellFilter : public PaletteCellFilter
87 : {
88 : bool acceptedValue;
89 :
90 0 : bool acceptCell(const PaletteCell& cell) const override { return cell.custom == acceptedValue; }
91 :
92 : public:
93 0 : CustomizedCellFilter(bool acceptedVal, QObject* parent = nullptr)
94 0 : : PaletteCellFilter(parent), acceptedValue(acceptedVal) {}
95 : };
96 :
97 : //---------------------------------------------------------
98 : // PaletteTreeModel
99 : //---------------------------------------------------------
100 :
101 : class PaletteTreeModel : public QAbstractItemModel, public muse::async::Asyncable, public muse::Contextable
102 : {
103 : Q_OBJECT
104 :
105 : muse::GlobalInject<IPaletteConfiguration> configuration;
106 :
107 : public:
108 : enum PaletteTreeModelRoles {
109 : PaletteCellRole = Qt::UserRole,
110 : VisibleRole,
111 : CustomRole,
112 : EditableRole,
113 : MimeDataRole,
114 : GridSizeRole,
115 : DrawGridRole,
116 : PaletteExpandedRole,
117 : PaletteTypeRole,
118 : PaletteContentTypeRole,
119 : CellActiveRole
120 : };
121 0 : Q_ENUM(PaletteTreeModelRoles)
122 :
123 : private:
124 : PaletteTreePtr _paletteTree;
125 : bool _treeChanged = false;
126 : bool _treeChangedSignalBlocked = false;
127 :
128 0 : std::vector<PalettePtr>& palettes() { return _paletteTree->palettes; }
129 0 : const std::vector<PalettePtr>& palettes() const { return _paletteTree->palettes; }
130 :
131 : Palette* iptrToPalette(void* iptr, int* idx = nullptr);
132 0 : const Palette* iptrToPalette(void* iptr, int* idx = nullptr) const
133 : {
134 0 : return const_cast<PaletteTreeModel*>(this)->iptrToPalette(iptr, idx);
135 : }
136 :
137 : void notifyAboutCellsChanged(int changedRole);
138 :
139 : private slots:
140 : void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles);
141 :
142 : public slots:
143 : void itemDataChanged(const QModelIndex& idx);
144 : void setTreeChanged();
145 0 : void setTreeUnchanged() { _treeChanged = false; }
146 :
147 : signals:
148 : void treeChanged();
149 :
150 : public:
151 : explicit PaletteTreeModel(PaletteTreePtr tree, const muse::modularity::ContextPtr& ctx, QObject* parent = nullptr);
152 :
153 : bool blockTreeChanged(bool block);
154 :
155 : void setPaletteTree(PaletteTreePtr tree);
156 0 : const PaletteTree* paletteTree() const { return _paletteTree.get(); }
157 0 : const PaletteTreePtr paletteTreePtr() const { return _paletteTree; }
158 :
159 : bool paletteTreeChanged() const { return _treeChanged; }
160 :
161 : QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
162 : QModelIndex parent(const QModelIndex& index) const override;
163 :
164 : int rowCount(const QModelIndex& parent = QModelIndex()) const override;
165 : int columnCount(const QModelIndex& parent = QModelIndex()) const override;
166 : QVariant data(const QModelIndex& index, int role) const override;
167 : bool setData(const QModelIndex& index, const QVariant& value, int role) override;
168 :
169 : QHash<int, QByteArray> roleNames() const override;
170 :
171 : Qt::ItemFlags flags(const QModelIndex& index) const override;
172 : Qt::DropActions supportedDropActions() const override;
173 :
174 : QMimeData* mimeData(const QModelIndexList& indexes) const override;
175 : QStringList mimeTypes() const override;
176 :
177 : bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const override;
178 : bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override;
179 :
180 : QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const override;
181 : QModelIndex findPaletteCell(const PaletteCell& cell, const QModelIndex& parent) const;
182 : PaletteCellFilter* getFilter(const QModelIndex&) const;
183 :
184 : bool moveRows(const QModelIndex& sourceParent, int sourceRow, int count, const QModelIndex& destinationParent,
185 : int destinationChild) override;
186 : bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
187 : bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
188 :
189 : const Palette* findPalette(const QModelIndex&) const;
190 : Palette* findPalette(const QModelIndex& index);
191 : PaletteCellConstPtr findCell(const QModelIndex&) const;
192 : PaletteCellPtr findCell(const QModelIndex& index);
193 : bool insertPalette(PalettePtr pp, int row, const QModelIndex& parent = QModelIndex());
194 :
195 : void updateCellsState(const engraving::Selection&);
196 : void retranslate();
197 : };
198 :
199 : //---------------------------------------------------------
200 : // FilterPaletteTreeModel
201 : //---------------------------------------------------------
202 :
203 : class FilterPaletteTreeModel : public QSortFilterProxyModel
204 : {
205 : Q_OBJECT
206 :
207 : PaletteCellFilter * cellFilter;
208 :
209 : bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
210 0 : bool filterAcceptsColumn(int /* sourceColumn */, const QModelIndex& /* sourceParent */) const override
211 : {
212 0 : return true;
213 : }
214 :
215 : private slots:
216 0 : void invalidateFilter()
217 : {
218 0 : QSortFilterProxyModel::endFilterChange(QSortFilterProxyModel::Direction::Rows);
219 0 : }
220 :
221 : public:
222 : FilterPaletteTreeModel(PaletteCellFilter* filter, PaletteTreeModel* model, QObject* parent = nullptr);
223 : };
224 :
225 : //---------------------------------------------------------
226 : // PaletteCellFilterProxyModel
227 : //---------------------------------------------------------
228 :
229 : class PaletteCellFilterProxyModel : public QSortFilterProxyModel
230 : {
231 : Q_OBJECT
232 : public:
233 : PaletteCellFilterProxyModel(QObject* parent = nullptr);
234 :
235 : bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
236 : };
237 : }
238 :
239 : #endif
|