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