1 #include "connectionmanager.h"
7 #include "shareboard.h"
9 ConnectionManager::ConnectionManager(QObject* parent) : QObject(parent) {
10 sock = new QTcpSocket();
11 textStream = new QTextStream(sock);
12 QObject::connect(sock, SIGNAL(connected()), this, SLOT(onConnect()));
13 QObject::connect(sock, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
14 QObject::connect(sock, SIGNAL(readyRead()), this, SLOT(haveData()));
15 QObject::connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError()));
18 ConnectionManager::~ConnectionManager() {
19 if (sock) delete sock;
22 void ConnectionManager::setTarget(Shareboard* t) {
26 void ConnectionManager::joinServer(QString _username, QString host) {
29 sock->connectToHost(host, port);
30 qDebug() << "Connecting to " << host << "as " << _username;
33 void ConnectionManager::sendAction(Action* action) {
35 QTextStream t(&output);
38 qDebug() << "Sending" << output.size() << "bytes for action of type" << action->type;
41 void ConnectionManager::haveData() {
42 while(sock->canReadLine()) {
43 QByteArray data = sock->readLine(0); // Read a line, however many bytes it takes
44 QTextStream textstream(&data);
47 quint16 t = 0; // Type
49 textstream >> mesgID >> userID >> timestring >> t;
50 /*qDebug() << "Read line:";
51 qDebug() << "\tmesgID: "<< mesgID;
52 qDebug() << "\tuserID: "<< userID;
53 qDebug() << "\ttime : "<< timestring;
54 qDebug() << "\ttype : "<< t;*/
57 QDateTime timestamp = QDateTime::fromString(timestring, "yyyy-MM-ddTHH:mm:ss.zzz");
58 if(mesgID == -1 || userID == -1 || !timestamp.isValid() ) {
59 qWarning() << "Received invalid message from server; discarding.";
63 // Abstract factory go!
64 Action::Type type = static_cast<Action::Type>(t);
67 case Action::INVALID: // We should never get an invalid action from the server...
69 case Action::UserJoin:
71 act = new UserJoinAction();
72 UserJoinAction* action = static_cast<UserJoinAction*>(act);
74 textstream >> username;
75 if(textstream.status() != QTextStream::Ok) {
76 qWarning() << "Got invalid username from server :(";
80 action->username = username;
81 action->mesgID = mesgID;
82 action->userID = userID;
83 action->timestamp = timestamp;
84 qDebug() << "Update: got UserJoin:" << username << "joined";
87 case Action::UserPart:
89 act = new UserPartAction();
90 UserPartAction* action = static_cast<UserPartAction*>(act);
91 action->mesgID = mesgID;
92 action->userID = userID;
93 action->timestamp = timestamp;
96 case Action::MouseMove:
98 act = new MouseMoveAction();
101 textstream >> x >> y;
102 // Ignore invalid mouse positions; replace with 0,0
103 MouseMoveAction* action = static_cast<MouseMoveAction*>(act);
104 action->pos = QPointF(x,y);
105 action->mesgID = mesgID;
106 action->userID = userID;
107 action->timestamp = timestamp;
110 case Action::DrawLine:
112 act = new DrawLineAction();
113 DrawLineAction* action = static_cast<DrawLineAction*>(act);
118 textstream >> red >> green >> blue >> width;
119 if(textstream.status() != QTextStream::Ok){
120 qWarning() << "Received invalid line data from server :(";
127 textstream >> x >> y;
128 action->points.append(QPointF(x,y));
129 // some stuff with the points
130 } while(textstream.status() == QTextStream::Ok);
131 action->color = QColor::fromRgb(red, green, blue);
132 action->width = width;
133 action->mesgID = mesgID;
134 action->userID = userID;
135 action->timestamp = timestamp;
138 case Action::AddImage:
140 qDebug() << "Sending AddImage action!";
141 act = new AddImageAction();
142 AddImageAction* action = static_cast<AddImageAction*>(act);
145 textstream >> x >> y;
146 action->topLeft = QPointF(x,y);
147 // handle reading image data as base64-encoded binary, bleah
150 // im is a base64-encoded binary string.
151 QByteArray ba = fromBase64(im); // Convert back to binary data
152 action->image.loadFromData(ba, "PNG");
153 action->mesgID = mesgID;
154 action->userID = userID;
155 action->timestamp = timestamp;
158 case Action::UserChat:
160 act = new UserChatAction();
161 UserChatAction* action = static_cast<UserChatAction*>(act);
164 if(textstream.status() != QTextStream::Ok) {
165 qWarning() << "Got invalid text chat from server :(";
169 action->mesgID = mesgID;
170 action->userID = userID;
171 action->timestamp = timestamp;
175 case Action::UserSynced:
177 board->setUserID(userID);
178 qDebug() << "User is synced :)";
182 case Action::ClearBoard:
184 act = new ClearBoardAction();
185 ClearBoardAction* action = static_cast<ClearBoardAction*>(act);
186 action->mesgID = mesgID;
187 action->userID = userID;
188 action->timestamp = timestamp;
192 qWarning() << "Received invalid type from server :(";
195 Q_ASSERT(act != NULL);
197 board->postAction(act);
199 //qDebug() << "Dispatched action with type " << act->type << " that was " << data.size() << " bytes long";
203 void ConnectionManager::onConnect() {
204 qDebug() << "connection established";
206 (*textStream) << "0 0 0 1 " << username << endl;
207 qDebug() << "sent JoinAction";
210 void ConnectionManager::onDisconnect() {
211 qDebug() << "Disconnected";
215 void ConnectionManager::onError() {
216 QString e = sock->errorString();
217 qDebug() << "connection error: " << e;