1 /*
2    Drawpile - a collaborative drawing program.
3 
4    Copyright (C) 2015-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 
20 #ifndef CANVASMODEL_H
21 #define CANVASMODEL_H
22 
23 #include "../libshared/net/message.h"
24 
25 // note: we must include these so the datatypes get registered properly for use in QML
26 #include "usercursormodel.h"
27 #include "lasertrailmodel.h"
28 #include "selection.h"
29 #include "core/layerstack.h"
30 #include "../libshared/record/writer.h"
31 
32 #include <QObject>
33 #include <QPointer>
34 
35 namespace protocol {
36 	class UserJoin;
37 	class UserLeave;
38 	class LaserTrail;
39 	class MovePointer;
40 	class Chat;
41 	class Marker;
42 	class DefaultLayer;
43 }
44 
45 namespace canvas {
46 
47 class StateTracker;
48 class AclFilter;
49 class UserListModel;
50 class LayerListModel;
51 
52 class CanvasModel : public QObject
53 {
54 	Q_PROPERTY(paintcore::LayerStack* layerStack READ layerStack CONSTANT)
55 	Q_PROPERTY(UserCursorModel* userCursors READ userCursors CONSTANT)
56 	Q_PROPERTY(LaserTrailModel* laserTrails READ laserTrails CONSTANT)
57 	Q_PROPERTY(StateTracker* stateTracker READ stateTracker CONSTANT)
58 	Q_PROPERTY(Selection* selection READ selection WRITE setSelection NOTIFY selectionChanged)
59 
60 	Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
61 	Q_PROPERTY(QString pinnedMessage READ pinnedMessage NOTIFY pinnedMessageChanged)
62 
63 	Q_OBJECT
64 
65 public:
66 	explicit CanvasModel(uint8_t localUserId, QObject *parent=nullptr);
67 
layerStack()68 	paintcore::LayerStack *layerStack() const { return m_layerstack; }
stateTracker()69 	StateTracker *stateTracker() const { return m_statetracker; }
userCursors()70 	UserCursorModel *userCursors() const { return m_usercursors; }
laserTrails()71 	LaserTrailModel *laserTrails() const { return m_lasers; }
72 
title()73 	QString title() const { return m_title; }
setTitle(const QString & title)74 	void setTitle(const QString &title) { if(m_title!=title) { m_title = title; emit titleChanged(title); } }
75 
pinnedMessage()76 	QString pinnedMessage() const { return m_pinnedMessage; }
77 
selection()78 	Selection *selection() const { return m_selection; }
79 	void setSelection(Selection *selection);
80 
81 	bool needsOpenRaster() const;
82 	QImage toImage(bool withBackground=true, bool withSublayers=false) const;
83 
84 	protocol::MessageList generateSnapshot() const;
85 
86 	uint8_t localUserId() const;
87 
88 	uint16_t getAvailableAnnotationId() const;
89 
90 	QImage selectionToImage(int layerId) const;
91 	void pasteFromImage(const QImage &image, const QPoint &defaultPoint, bool forceDefault);
92 
93 	void connectedToServer(uint8_t myUserId, bool join);
94 	void disconnectedFromServer();
95 	void startPlayback();
96 	void endPlayback();
97 
aclFilter()98 	AclFilter *aclFilter() const { return m_aclfilter; }
userlist()99 	UserListModel *userlist() const { return m_userlist; }
layerlist()100 	LayerListModel *layerlist() const { return m_layerlist; }
101 
102 	/**
103 	 * @brief Is the canvas in "online mode"?
104 	 *
105 	 * This mainly affects how certain access controls are checked.
106 	 */
isOnline()107 	bool isOnline() const { return m_mode == Mode::Online; }
108 
109 	/**
110 	 * @brief Set the Writer to use for recording
111 	 */
setRecorder(recording::Writer * writer)112 	void setRecorder(recording::Writer *writer) { m_recorder = writer; }
113 
114 public slots:
115 	//! Handle a meta/command message received from the server
116 	void handleCommand(protocol::MessagePtr cmd);
117 
118 	//! Handle a local drawing command (will be put in the local fork)
119 	void handleLocalCommand(protocol::MessagePtr cmd);
120 
121 	void resetCanvas();
122 
123 	void pickLayer(int x, int y);
124 	void pickColor(int x, int y, int layer, int diameter=0);
125 	void inspectCanvas(int x, int y);
126 	void inspectCanvas(int contextId);
127 	void stopInspectingCanvas();
128 
129 	void setLayerViewMode(int mode);
130 	void updateLayerViewOptions();
131 
132 signals:
133 	void layerAutoselectRequest(int id);
134 	void canvasModified();
135 	void selectionChanged(Selection *selection);
136 	void selectionRemoved();
137 
138 	void titleChanged(QString title);
139 	void pinnedMessageChanged(QString message);
140 	void imageSizeChanged();
141 
142 	void colorPicked(const QColor &color);
143 	void canvasInspected(int tx, int ty, int lastEditedBy);
144 	void canvasInspectionEnded();
145 
146 	void chatMessageReceived(const protocol::MessagePtr &msg);
147 	void markerMessageReceived(int id, const QString &message);
148 
149 	void userJoined(int id, const QString &name);
150 	void userLeft(int id, const QString &name);
151 
152 	void canvasLocked(bool locked);
153 
154 private slots:
155 	void onCanvasResize(int xoffset, int yoffset, const QSize &oldsize);
156 
157 private:
158 	void metaUserJoin(const protocol::UserJoin &msg);
159 	void metaUserLeave(const protocol::UserLeave &msg);
160 	void metaChatMessage(protocol::MessagePtr msg);
161 	void metaLaserTrail(const protocol::LaserTrail &msg);
162 	void metaMovePointer(const protocol::MovePointer &msg);
163 	void metaMarkerMessage(const protocol::Marker &msg);
164 	void metaDefaultLayer(const protocol::DefaultLayer &msg);
165 	void metaSoftReset(uint8_t resetterId);
166 
167 	AclFilter *m_aclfilter;
168 	UserListModel *m_userlist;
169 	LayerListModel *m_layerlist;
170 
171 	paintcore::LayerStack *m_layerstack;
172 	StateTracker *m_statetracker;
173 	UserCursorModel *m_usercursors;
174 	LaserTrailModel *m_lasers;
175 	Selection *m_selection;
176 
177 	QPointer<recording::Writer> m_recorder;
178 
179 	QString m_title;
180 	QString m_pinnedMessage;
181 
182 	enum class Mode { Offline, Online, Playback } m_mode;
183 };
184 
185 }
186 
187 #endif // CANVASSTATE_H
188