1 /*
2    Drawpile - a collaborative drawing program.
3 
4    Copyright (C) 2013-2019 Calle Laakkonen
5 
6    Drawpile is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10 
11    Drawpile is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Drawpile.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef DP_NET_LAYERLIST_H
20 #define DP_NET_LAYERLIST_H
21 
22 #include "../core/blendmodes.h"
23 #include "features.h"
24 
25 #include <QAbstractListModel>
26 #include <QMimeData>
27 #include <QVector>
28 
29 #include <functional>
30 
31 namespace protocol {
32 	class MessagePtr;
33 
34 }
35 namespace paintcore {
36 	class Layer;
37 }
38 
39 namespace canvas {
40 
41 class AclFilter;
42 
43 struct LayerListItem {
44 	//! Layer ID
45 	// Note: normally, layer ID range is from 0 to 0xffff, but internal
46 	// layers use values outside that range. However, internal layers are not
47 	// shown in the layer list.
48 	uint16_t id;
49 
50 	//! Layer title
51 	QString title;
52 
53 	//! Layer opacity
54 	float opacity;
55 
56 	//! Blending mode
57 	paintcore::BlendMode::Mode blend;
58 
59 	//! Layer hidden flag (local only)
60 	bool hidden;
61 
62 	//! Layer is flagged for censoring
63 	bool censored;
64 
65 	//! This is a fixed background/foreground layer
66 	bool fixed;
67 
68 	//! Get the LayerAttributes flags as a bitfield
69 	uint8_t attributeFlags() const;
70 };
71 
72 }
73 
74 Q_DECLARE_TYPEINFO(canvas::LayerListItem, Q_MOVABLE_TYPE);
75 
76 namespace canvas {
77 
78 typedef std::function<const paintcore::Layer*(int id)> GetLayerFunction;
79 
80 class LayerListModel : public QAbstractListModel {
81 	Q_OBJECT
82 public:
83 	enum LayerListRoles {
84 		IdRole = Qt::UserRole + 1,
85 		TitleRole,
86 		IsDefaultRole,
87 		IsLockedRole,
88 		IsFixedRole
89 	};
90 
91 	LayerListModel(QObject *parent=nullptr);
92 
93 	int rowCount(const QModelIndex &parent=QModelIndex()) const;
94 	QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
95 	Qt::ItemFlags flags(const QModelIndex& index) const;
96 	Qt::DropActions supportedDropActions() const;
97 	QStringList mimeTypes() const;
98 	QMimeData *mimeData(const QModelIndexList& indexes) const;
99 	bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
100 
101 	QModelIndex layerIndex(uint16_t id);
102 
103 	void clear();
104 	void createLayer(uint16_t id, int index, const QString &title);
105 	void deleteLayer(uint16_t id);
106 	void changeLayer(uint16_t id, bool censored, bool fixed, float opacity, paintcore::BlendMode::Mode blend);
107 	void retitleLayer(uint16_t id, const QString &title);
108 	void setLayerHidden(uint16_t id, bool hidden);
109 	void reorderLayers(QList<uint16_t> neworder);
110 
getLayers()111 	QVector<LayerListItem> getLayers() const { return m_items; }
112 	void setLayers(const QVector<LayerListItem> &items);
113 
114 	void previewOpacityChange(uint16_t id, float opacity);
115 
setLayerGetter(GetLayerFunction fn)116 	void setLayerGetter(GetLayerFunction fn) { m_getlayerfn = fn; }
setAclFilter(AclFilter * filter)117 	void setAclFilter(AclFilter *filter) { m_aclfilter = filter; }
118 	const paintcore::Layer *getLayerData(uint16_t id) const;
119 
myId()120 	uint8_t myId() const { return m_myId; }
setMyId(uint8_t id)121 	void setMyId(uint8_t id) { m_myId = id; }
122 
123 	/**
124 	 * @brief Get the default layer to select when logging in
125 	 * Zero means no default.
126 	 */
defaultLayer()127 	uint16_t defaultLayer() const { return m_defaultLayer; }
128 	void setDefaultLayer(uint16_t id);
129 
130 	/**
131 	 * @brief Find a free layer ID
132 	 * @return layer ID or 0 if all are taken
133 	 */
134 	int getAvailableLayerId() const;
135 
136 	/**
137 	 * @brief Find a unique name for a layer
138 	 * @param basename
139 	 * @return unique name
140 	 */
141 	QString getAvailableLayerName(QString basename) const;
142 
143 signals:
144 	void layersReordered();
145 
146 	//! Emitted when layers are manually reordered
147 	void layerCommand(protocol::MessagePtr msg);
148 
149 	//! Request local change of layer opacity for preview purpose
150 	void layerOpacityPreview(int id, float opacity);
151 
152 private:
153 	void handleMoveLayer(int idx, int afterIdx);
154 
155 	int indexOf(uint16_t id) const;
156 
157 	QVector<LayerListItem> m_items;
158 	GetLayerFunction m_getlayerfn;
159 	AclFilter *m_aclfilter;
160 	uint16_t m_defaultLayer;
161 	uint8_t m_myId;
162 };
163 
164 /**
165  * A specialization of QMimeData for passing layers around inside
166  * the application.
167  */
168 class LayerMimeData : public QMimeData
169 {
170 Q_OBJECT
171 public:
LayerMimeData(const LayerListModel * source,uint16_t id)172 	LayerMimeData(const LayerListModel *source, uint16_t id)
173 		: QMimeData(), m_source(source), m_id(id) {}
174 
source()175 	const LayerListModel *source() const { return m_source; }
176 
layerId()177 	uint16_t layerId() const { return m_id; }
178 
179 	QStringList formats() const;
180 
181 protected:
182 	QVariant retrieveData(const QString& mimeType, QVariant::Type type) const;
183 
184 private:
185 	const LayerListModel *m_source;
186 	uint16_t m_id;
187 };
188 
189 }
190 
191 Q_DECLARE_METATYPE(canvas::LayerListItem)
192 
193 #endif
194 
195