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_SESSION_LOADER_H 20 #define DP_SESSION_LOADER_H 21 22 #include <QSize> 23 #include <QColor> 24 #include <QString> 25 #include <QImage> 26 27 #include "../libshared/net/message.h" 28 29 namespace paintcore { 30 class LayerStack; 31 } 32 33 namespace canvas { 34 35 class AclFilter; 36 37 /** 38 * \brief Base class for session initializers. 39 * 40 * Note. The initializers make two assumptions: they are running in 41 * loopback mode and that the session has not already been initialized. 42 * 43 * These assumptions allow the initializers to pick the initial layer/annotation 44 * IDs. 45 */ 46 class SessionLoader { 47 public: 48 virtual ~SessionLoader(); 49 50 /** 51 * @brief Get the commands needed to initialize the session. 52 * 53 * The commands should be sent to the server in response to a snapshot request, 54 * or when initializing the session in local mode. 55 * 56 * @param client 57 * @return empty list if an error occurred 58 */ 59 virtual protocol::MessageList loadInitCommands() = 0; 60 61 /** 62 * @brief Get the error message 63 * 64 * The error message is available if loadInitCommands() returns false. 65 * @return error message 66 */ 67 virtual QString errorMessage() const = 0; 68 69 /** 70 * @brief Get the warning message (if any) 71 */ warningMessage()72 virtual QString warningMessage() const { return QString(); } 73 74 /** 75 * @brief get the name of the file 76 * 77 * This if for image loaders. If there is no file (that can be saved again), 78 * this function should return an empty string. 79 * @return filename or empty string 80 */ 81 virtual QString filename() const = 0; 82 83 /** 84 * @brief Get the canvas resolution 85 * 86 * Note. This should be called after calling loadInitCommands, to ensure the 87 * value has been loaded. 88 * 89 * This is not currently used internally, except for passing through opening 90 * and saving files that record this information. If we do start using it at some 91 * point, this function should be removed and a SetDPI command added to the protocol. 92 * 93 * @return 94 */ dotsPerInch()95 virtual QPair<int,int> dotsPerInch() const { return QPair<int,int>(0, 0); } 96 }; 97 98 class BlankCanvasLoader : public SessionLoader { 99 public: BlankCanvasLoader(const QSize & size,const QColor & color)100 BlankCanvasLoader(const QSize &size, const QColor &color) : _size(size), _color(color) 101 {} 102 103 protocol::MessageList loadInitCommands(); filename()104 QString filename() const { return QString(); } errorMessage()105 QString errorMessage() const { return QString(); /* cannot fail */ } 106 107 private: 108 QSize _size; 109 QColor _color; 110 }; 111 112 class ImageCanvasLoader : public SessionLoader { 113 public: ImageCanvasLoader(const QString & filename)114 ImageCanvasLoader(const QString &filename) : m_filename(filename) {} 115 116 protocol::MessageList loadInitCommands() override; filename()117 QString filename() const override { return m_filename; } errorMessage()118 QString errorMessage() const override { return m_error; } warningMessage()119 QString warningMessage() const override { return m_warning; } dotsPerInch()120 QPair<int,int> dotsPerInch() const override { return m_dpi; } 121 122 QPixmap loadThumbnail(const QSize &maxSize) const; 123 124 private: 125 QString m_filename; 126 QString m_error; 127 QString m_warning; 128 QPair<int,int> m_dpi; 129 }; 130 131 class QImageCanvasLoader : public SessionLoader { 132 public: QImageCanvasLoader(const QImage & image)133 QImageCanvasLoader(const QImage &image) : m_image(image) {} 134 135 protocol::MessageList loadInitCommands() override; filename()136 QString filename() const override { return QString(); } errorMessage()137 QString errorMessage() const override { return QString(); } dotsPerInch()138 QPair<int,int> dotsPerInch() const override { 139 return QPair<int,int>( 140 int(m_image.dotsPerMeterX() * 0.0254), 141 int(m_image.dotsPerMeterY() * 0.0254) 142 ); 143 } 144 145 private: 146 QImage m_image; 147 }; 148 149 /** 150 * @brief A session loader that takes an existing layer stack and generates a new snapshot from it 151 * 152 * If the optional canvas is given, extra data will be included. 153 */ 154 class SnapshotLoader : public SessionLoader { 155 public: 156 //SnapshotLoader() : m_layers(nullptr), m_aclfilter(nullptr), m_defaultLayer(0), m_contextId(0) { } 157 158 /** 159 * Construct a snapshot from an existing session. 160 * 161 * @param context ID resetting user ID 162 * @param layers the layer stack (required) 163 * @param aclfilter Access controls (optional) 164 */ SnapshotLoader(uint8_t contextId,const paintcore::LayerStack * layers,const AclFilter * aclfilter)165 SnapshotLoader(uint8_t contextId, const paintcore::LayerStack *layers, const AclFilter *aclfilter) 166 : m_layers(layers), m_aclfilter(aclfilter), m_defaultLayer(0), m_contextId(contextId) {} 167 168 //! Include a default layer message setDefaultLayer(int defaultLayer)169 void setDefaultLayer(int defaultLayer) { m_defaultLayer = defaultLayer; } 170 171 //! Include a pinned chat message setPinnedMessage(const QString & message)172 void setPinnedMessage(const QString &message) { m_pinnedMessage = message; } 173 174 protocol::MessageList loadInitCommands() override; filename()175 QString filename() const override { return QString(); } errorMessage()176 QString errorMessage() const override { return QString(); } 177 QPair<int,int> dotsPerInch() const override; 178 179 private: 180 const paintcore::LayerStack *m_layers; 181 const AclFilter *m_aclfilter; 182 183 QString m_pinnedMessage; 184 int m_defaultLayer; 185 186 uint8_t m_contextId; 187 188 }; 189 190 } 191 192 #endif 193