1 /*******************************************************************************************************
2  DkConnection.h
3  Created on:	20.07.2011
4 
5  nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
6 
7  Copyright (C) 2011-2013 Markus Diem <markus@nomacs.org>
8  Copyright (C) 2011-2013 Stefan Fiel <stefan@nomacs.org>
9  Copyright (C) 2011-2013 Florian Kleber <florian@nomacs.org>
10 
11  This file is part of nomacs.
12 
13  nomacs is free software: you can redistribute it and/or modify
14  it under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  nomacs is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 
26  *******************************************************************************************************/
27 
28 #pragma once
29 
30 #pragma warning(push, 0)	// no warnings from includes - begin
31 #include <QTcpSocket>
32 #include <QRect>
33 #include <QTransform>
34 #include <QHostAddress>
35 #include <QImage>
36 #pragma warning(pop)		// no warnings from includes - end
37 
38 #pragma warning(disable: 4251)
39 
40 #ifdef QT_NO_DEBUG_OUTPUT
41 #pragma warning(disable: 4127)		// no 'conditional expression is constant' if qDebug() messages are removed
42 #endif
43 
44 #ifndef DllCoreExport
45 #ifdef DK_CORE_DLL_EXPORT
46 #define DllCoreExport Q_DECL_EXPORT
47 #elif DK_DLL_IMPORT
48 #define DllCoreExport Q_DECL_IMPORT
49 #else
50 #define DllCoreExport Q_DECL_IMPORT
51 #endif
52 #endif
53 
54 // Qt defines
55 class QTimer;
56 
57 namespace nmc {
58 
59 static const int MaxBufferSize = 102400000;
60 static const char SeparatorToken = '<';
61 
62 class DllCoreExport DkConnection : public QTcpSocket {
63 	Q_OBJECT
64 
65 	public:
66 		DkConnection(QObject* parent=0);
~DkConnection()67 		~DkConnection() {
68 			//qDebug() << "connection destructed...";
69 		};
70 
release()71 		void release() {
72 			sendNewGoodbyeMessage();
73 		};
74 
getPeerPort()75 		quint16 getPeerPort() { return mPortOfPeer;};
getPeerId()76 		quint16 getPeerId() {return mPeerId;};
setPeerId(quint16 peerId)77 		void setPeerId(quint16 peerId) { mPeerId = peerId;};
78 		void setTitle(const QString& newTitle);
79 
80 		bool connectionCreated;
81 
82 	signals:
83 		void connectionReadyForUse(quint16 peerServerPort, const QString& title, DkConnection* connection) const;
84 		void connectionStartSynchronize(QList<quint16> synchronizedPeersOfOtherClient, DkConnection* connection) const;
85 		void connectionStopSynchronize(DkConnection* connection) const;
86 		void connectionTitleHasChanged(DkConnection* connection, const QString& newTitle) const;
87 		void connectionNewPosition(DkConnection* connection, QRect position, bool opacity, bool overlaid) const;
88 		void connectionNewTransform(DkConnection* connection, QTransform transform, QTransform imgTransform, QPointF canvasSize) const;
89 		void connectionNewFile(DkConnection* connection, qint16 op, const QString& filename) const;
90 		void connectionGoodBye(DkConnection* connection) const;
91 		void connectionShowStatusMessage(DkConnection* connection, const QString& msg) const;
92 
93 	public slots:
94 		virtual void sendGreetingMessage(const QString& currenTitle) = 0;
95 		void sendStartSynchronizeMessage();
96 		void sendStopSynchronizeMessage();
97 		void sendNewTitleMessage(const QString& newtitle);
98 		virtual void sendNewPositionMessage(QRect position, bool opacity, bool overlaid);
99 		virtual void sendNewTransformMessage(QTransform transform, QTransform imgTransform, QPointF canvasSize);
100 		virtual void sendNewFileMessage(qint16 op, const QString& filename);
101 		void sendNewGoodbyeMessage();
102 		void synchronizedPeersListChanged(QList<quint16> newList);
103 
104 
105 	protected:
106 		enum ConnectionState {
107 			WaitingForGreeting,
108 			ReadyForUse,
109 			Synchronized
110 		};
111 		enum DataType {
112 			Greeting,
113 			startSynchronize,
114 			stopSynchronize,
115 			newTitle,
116 			newPosition,
117 			newTransform,
118 			newFile,
119 			GoodBye,
120 			Undefined
121 		};
122 
123 		virtual bool readProtocolHeader();
124 		virtual void checkState();
125 		int readDataIntoBuffer(int maxSize = MaxBufferSize);
126 		bool readDataTypeIntoBuffer();
127 		virtual void processData();
128 		virtual void readWhileBytesAvailable();
129 		virtual void readGreetingMessage() = 0;
130 		bool hasEnoughData();
131 		int dataLengthForCurrentDataType();
allowedToSynchronize()132 		virtual bool allowedToSynchronize() {return true;};
133 
134 		ConnectionState mState = WaitingForGreeting;
135 		DataType mCurrentDataType = Undefined;
136 		QByteArray mBuffer;
137 		QString mCurrentTitle;
138 		int mNumBytesForCurrentDataType = 0;
139 		quint16 mPortOfPeer = 0;
140 		quint16 mPeerServerPort = 0;
141 		bool mIsGreetingMessageSent = false;
142 		bool mIsSynchronizeMessageSent = false;
143 
144 	protected slots:
145 		virtual void processReadyRead();
146 
147 	private slots:
148 		void synchronizedTimerTimeout();
149 
150 	protected:
151 
152 		QTimer* mSynchronizedTimer;
153 		QList<quint16> mSynchronizedPeersServerPorts;
154 		quint16 mPeerId;
155 };
156 
157 class DllCoreExport DkLocalConnection : public DkConnection {
158 	Q_OBJECT
159 
160 	public:
161 		DkLocalConnection(QObject* parent=0);
162 
getLocalTcpServerPort()163 		quint16 getLocalTcpServerPort() { return mLocalTcpServerPort;};
setLocalTcpServerPort(quint16 localTcpServerPort)164 		void setLocalTcpServerPort(quint16 localTcpServerPort) { mLocalTcpServerPort = localTcpServerPort;};
165 		void sendGreetingMessage(const QString& currentTitle);
166 
167 
168 	signals:
169 		void connectionQuitReceived();
170 
171 	protected slots:
172 		void processReadyRead();
173 		void processData();
174 		void sendQuitMessage();
175 
176 	protected:
177 		enum LocalDataType {
178 			Quit,
179 			Undefined
180 		};
181 
182 	private:
183 		bool readProtocolHeader();
184 		void readGreetingMessage();
185 
186 		quint16 mLocalTcpServerPort;
187 		LocalDataType mCurrentLocalDataType = Undefined;
188 };
189 
190 }
191 
192