1 /*******************************************************************************************************
2 DkNetwork.cpp
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 #include "DkNetwork.h"
29 #include "DkSettings.h"
30 #include "DkTimer.h"
31 #include "DkControlWidget.h" // needed for a connection
32 #include "DkUtils.h"
33 #include "DkActionManager.h"
34
35 #pragma warning(push, 0) // no warnings from includes - begin
36 #include <QTcpSocket>
37 #include <QStringBuilder>
38 #include <QDir>
39 #include <QNetworkInterface>
40 #include <QList>
41 #include <QThread>
42 #include <QTimer>
43 #include <QHostInfo>
44 #include <QUrl>
45 #include <QNetworkAccessManager>
46 #include <QApplication>
47 #include <QDesktopWidget>
48 #include <QMutex>
49 #include <QMutexLocker>
50 #include <QNetworkCookieJar>
51 #include <QDesktopServices>
52 #include <QDebug>
53 #include <QNetworkProxyFactory>
54 #include <QXmlStreamReader>
55 #include <QMessageBox>
56 #include <QAbstractButton>
57 #include <QProcess>
58 #include <QMimeData>
59 #include <qmath.h>
60
61 #ifdef QT_NO_DEBUG_OUTPUT
62 #pragma warning(disable: 4127) // no 'conditional expression is constant' if qDebug() messages are removed
63 #endif
64
65 #pragma warning(pop) // no warnings from includes - end
66
67 #include <assert.h>
68
69 namespace nmc {
70
71 // DkClientManager --------------------------------------------------------------------
DkClientManager(const QString & title,QObject * parent)72 DkClientManager::DkClientManager(const QString& title, QObject* parent) : QObject(parent) {
73 mNewPeerId = 0;
74 this->mCurrentTitle = title;
75 qRegisterMetaType<QList<quint16> >("QList<quint16>");
76 qRegisterMetaType<QList<DkPeer*> >("QList<DkPeer*>");
77 }
78
~DkClientManager()79 DkClientManager::~DkClientManager() {
80
81 // save settings
82 sendGoodByeToAll(); // does nothing...
83 }
84
85
connectionReadyForUse(quint16 peerServerPort,const QString & title,DkConnection * connection)86 void DkClientManager::connectionReadyForUse(quint16 peerServerPort, const QString& title, DkConnection* connection) {
87 //qDebug() << "connection ready for use" << connection->peerPort() << " with title:" << title << " peerServerPort:" << peerServerPort;
88
89 mNewPeerId++;
90 DkPeer* peer = new DkPeer(connection->peerPort(), mNewPeerId, connection->peerAddress(), peerServerPort, title, connection, false, "", false, this);
91 connection->setPeerId(mNewPeerId);
92 mPeerList.addPeer(peer);
93
94 sendTitle(mCurrentTitle);
95
96 }
97
disconnected()98 void DkClientManager::disconnected() {
99
100 if (DkConnection *connection = qobject_cast<DkConnection *>(sender())) {
101 removeConnection(connection);
102 }
103 }
104
removeConnection(DkConnection * connection)105 void DkClientManager::removeConnection(DkConnection* connection) {
106 mPeerList.setSynchronized(connection->getPeerId(), false);
107 emit synchronizedPeersListChanged(mPeerList.getSynchronizedPeerServerPorts());
108
109 auto aps = mPeerList.getActivePeers();
110 emit clientConnectedSignal(!aps.isEmpty());
111
112 qDebug() << "connection Disconnected:" << connection->getPeerPort();
113 mPeerList.removePeer(connection->getPeerId());
114
115 auto p = mPeerList.getPeerById(connection->getPeerId());
116 if (p && p->isSynchronized()) {
117 QString msg = listConnections(aps, false);
118 emit updateConnectionSignal(msg);
119 }
120 }
121
connectionSentNewTitle(DkConnection * connection,const QString & newTitle)122 void DkClientManager::connectionSentNewTitle(DkConnection* connection, const QString& newTitle) {
123 mPeerList.setTitle(connection->getPeerId(), newTitle);
124 }
125
connectionReceivedTransformation(DkConnection *,const QTransform & transform,const QTransform & imgTransform,const QPointF & canvasSize)126 void DkClientManager::connectionReceivedTransformation(DkConnection*, const QTransform& transform, const QTransform& imgTransform, const QPointF& canvasSize) {
127 emit receivedTransformation(transform, imgTransform, canvasSize);
128 }
129
connectionReceivedPosition(DkConnection *,const QRect & rect,bool opacity,bool overlaid)130 void DkClientManager::connectionReceivedPosition(DkConnection*, const QRect& rect, bool opacity, bool overlaid) {
131 emit receivedPosition(rect, opacity, overlaid);
132 }
133
connectionReceivedNewFile(DkConnection *,qint16 op,const QString & filename)134 void DkClientManager::connectionReceivedNewFile(DkConnection*, qint16 op, const QString& filename) {
135 emit receivedNewFile(op, filename);
136 }
137
connectionReceivedGoodBye(DkConnection * connection)138 void DkClientManager::connectionReceivedGoodBye(DkConnection* connection) {
139 mPeerList.removePeer(connection->getPeerId());
140 qDebug() << "goodbye received from " << connection->getPeerId();
141
142 emit synchronizedPeersListChanged(mPeerList.getSynchronizedPeerServerPorts());
143
144 auto aps = mPeerList.getActivePeers();
145 QString msg = listConnections(aps, false);
146 emit updateConnectionSignal(msg);
147 emit clientConnectedSignal(!aps.isEmpty());
148 }
149
connectionShowStatusMessage(DkConnection *,const QString & msg)150 void DkClientManager::connectionShowStatusMessage(DkConnection*, const QString& msg) {
151 emit sendInfoSignal(msg, 2000);
152 }
153
sendTitle(const QString & newTitle)154 void DkClientManager::sendTitle(const QString& newTitle) {
155 this->mCurrentTitle = newTitle;
156
157 QList<DkPeer*> peers = mPeerList.getPeerList();
158 foreach (DkPeer* peer , peers) {
159
160 if (!peer)
161 continue;
162
163 connect(this,SIGNAL(sendNewTitleMessage(const QString&)), peer->connection, SLOT(sendNewTitleMessage(const QString&)));
164 emit sendNewTitleMessage(newTitle);
165 disconnect(this,SIGNAL(sendNewTitleMessage(const QString&)), peer->connection, SLOT(sendNewTitleMessage(const QString&)));
166 }
167
168 }
169
sendTransform(QTransform transform,QTransform imgTransform,QPointF canvasSize)170 void DkClientManager::sendTransform(QTransform transform, QTransform imgTransform, QPointF canvasSize) {
171 QList<DkPeer*> synchronizedPeers = mPeerList.getSynchronizedPeers();
172 foreach (DkPeer* peer , synchronizedPeers) {
173
174 if (!peer)
175 continue;
176
177 connect(this,SIGNAL(sendNewTransformMessage(QTransform, QTransform, QPointF)), peer->connection, SLOT(sendNewTransformMessage(QTransform, QTransform, QPointF)));
178 emit sendNewTransformMessage(transform, imgTransform, canvasSize);
179 disconnect(this,SIGNAL(sendNewTransformMessage(QTransform, QTransform, QPointF)), peer->connection, SLOT(sendNewTransformMessage(QTransform, QTransform, QPointF)));
180 }
181 }
182
sendPosition(QRect newRect,bool overlaid)183 void DkClientManager::sendPosition(QRect newRect, bool overlaid) {
184 QList<DkPeer*> synchronizedPeers = mPeerList.getSynchronizedPeers();
185 foreach (DkPeer* peer , synchronizedPeers) {
186
187 if (!peer)
188 continue;
189
190 connect(this,SIGNAL(sendNewPositionMessage(QRect, bool, bool)), peer->connection, SLOT(sendNewPositionMessage(QRect, bool, bool)));
191 emit sendNewPositionMessage(newRect, true, overlaid);
192 disconnect(this,SIGNAL(sendNewPositionMessage(QRect, bool, bool)), peer->connection, SLOT(sendNewPositionMessage(QRect, bool, bool)));
193 }
194 }
195
sendNewFile(qint16 op,const QString & filename)196 void DkClientManager::sendNewFile(qint16 op, const QString& filename) {
197 QList<DkPeer*> synchronizedPeers = mPeerList.getSynchronizedPeers();
198 foreach (DkPeer* peer , synchronizedPeers) {
199
200 if (!peer)
201 continue;
202
203 connect(this,SIGNAL(sendNewFileMessage(qint16, const QString&)), peer->connection, SLOT(sendNewFileMessage(qint16, const QString&)));
204 emit sendNewFileMessage(op, filename);
205 disconnect(this,SIGNAL(sendNewFileMessage(qint16, const QString&)), peer->connection, SLOT(sendNewFileMessage(qint16, const QString&)));
206 }
207 }
208
newConnection(int socketDescriptor)209 void DkClientManager::newConnection( int socketDescriptor ) {
210 DkConnection* connection = createConnection();
211 connection->setSocketDescriptor(socketDescriptor);
212 connection->setTitle(mCurrentTitle);
213 mStartUpConnections.append(connection);
214 //qDebug() << "new Connection " << connection->peerPort();
215 }
216
connectConnection(DkConnection * connection)217 void DkClientManager::connectConnection(DkConnection* connection) {
218 qRegisterMetaType<QList<quint16> >("QList<quint16>");
219 connect(connection, SIGNAL(connectionReadyForUse(quint16, const QString&, DkConnection*)), this, SLOT(connectionReadyForUse(quint16, const QString& , DkConnection*)));
220 connect(connection, SIGNAL(connectionStopSynchronize(DkConnection*)), this, SLOT(connectionStopSynchronized(DkConnection*)));
221 connect(connection, SIGNAL(connectionStartSynchronize(QList<quint16>,DkConnection*)), this, SLOT(connectionSynchronized(QList<quint16>,DkConnection*)));
222 connect(connection, SIGNAL(disconnected()), this, SLOT(disconnected()));
223 connect(connection, SIGNAL(connectionTitleHasChanged(DkConnection*, const QString&)), this, SLOT(connectionSentNewTitle(DkConnection*, const QString&)));
224 connect(connection, SIGNAL(connectionNewPosition(DkConnection*, QRect, bool, bool)), this, SLOT(connectionReceivedPosition(DkConnection*, QRect, bool, bool)));
225 connect(connection, SIGNAL(connectionNewTransform(DkConnection*, QTransform, QTransform, QPointF)), this, SLOT(connectionReceivedTransformation(DkConnection*, QTransform, QTransform, QPointF)));
226 connect(connection, SIGNAL(connectionNewFile(DkConnection*, qint16, const QString&)), this, SLOT(connectionReceivedNewFile(DkConnection*, qint16, const QString&)));
227 connect(connection, SIGNAL(connectionGoodBye(DkConnection*)), this, SLOT(connectionReceivedGoodBye(DkConnection*)));
228 connect(connection, SIGNAL(connectionShowStatusMessage(DkConnection*, const QString&)), this, SLOT(connectionShowStatusMessage(DkConnection*, const QString&)));
229
230 connection->synchronizedPeersListChanged(mPeerList.getSynchronizedPeerServerPorts());
231 }
232
listConnections(QList<DkPeer * > peers,bool connected)233 QString DkClientManager::listConnections(QList<DkPeer*> peers, bool connected) {
234
235 QString newPeers;
236
237 if (!peers.empty()) {
238 if (connected) {
239 newPeers = tr("connected with: ");
240 }
241 else {
242 newPeers = tr("disconnected with: ");
243 }
244
245 newPeers.append("\n\t");
246 }
247
248 for (const DkPeer* cp : peers) {
249
250 if (!cp->clientName.isEmpty())
251 newPeers.append(cp->clientName);
252 if (!cp->clientName.isEmpty() && !cp->title.isEmpty())
253 newPeers.append(": ");
254 if (!cp->title.isEmpty())
255 newPeers.append(cp->title);
256 }
257
258 return newPeers;
259 }
260
sendGoodByeToAll()261 void DkClientManager::sendGoodByeToAll() {
262
263 foreach (DkPeer* peer, mPeerList.getPeerList()) {
264
265 if (!peer)
266 continue;
267
268 connect(this,SIGNAL(sendGoodByeMessage()), peer->connection, SLOT(sendNewGoodbyeMessage()));
269 emit sendGoodByeMessage();
270 disconnect(this,SIGNAL(sendGoodByeMessage()), peer->connection, SLOT(sendNewGoodbyeMessage()));
271 }
272 }
273
274 // DkLocalClientManager --------------------------------------------------------------------
275
DkLocalClientManager(const QString & title,QObject * parent)276 DkLocalClientManager::DkLocalClientManager(const QString& title, QObject* parent ) : DkClientManager(title, parent) {
277 startServer();
278 }
279
getPeerList()280 QList<DkPeer*> DkLocalClientManager::getPeerList() {
281 return mPeerList.getPeerList();
282 }
283
getServerPort() const284 quint16 DkLocalClientManager::getServerPort() const {
285
286 if (!mServer)
287 return 0;
288
289 return mServer->serverPort();
290 }
291
mimeData() const292 QMimeData* DkLocalClientManager::mimeData() const {
293
294 QByteArray connectionData;
295 QDataStream dataStream(&connectionData, QIODevice::WriteOnly);
296 dataStream << getServerPort();
297
298 QMimeData* mimeData = new QMimeData;
299 mimeData->setData("network/sync-dir", connectionData);
300
301 return mimeData;
302 }
303
startServer()304 void DkLocalClientManager::startServer() {
305
306 mServer = new DkLocalTcpServer(this);
307 connect(mServer, SIGNAL(serverReiceivedNewConnection(int)), this, SLOT(newConnection(int)));
308
309 // TODO: hook on thread
310 searchForOtherClients();
311
312 DkActionManager & am = DkActionManager::instance();
313 connect(am.action(DkActionManager::menu_sync_connect_all), SIGNAL(triggered()), this, SLOT(connectAll()));
314 }
315
316 // slots
connectAll()317 void DkLocalClientManager::connectAll() {
318
319 QList<DkPeer*> peers = getPeerList();
320
321 for (auto p : peers)
322 synchronizeWithServerPort(p->peerServerPort);
323 }
324
synchronizeWithServerPort(quint16 port)325 void DkLocalClientManager::synchronizeWithServerPort(quint16 port) {
326 //qDebug() << "DkClientManager::synchronizeWithServerPort port:" << port;
327 DkPeer* peer = mPeerList.getPeerByServerport(port);
328 if (!peer)
329 return;
330 synchronizeWith(peer->peerId);
331 }
332
searchForOtherClients()333 void DkLocalClientManager::searchForOtherClients() {
334
335 assert(mServer);
336
337 for (int i = local_tcp_port_start; i <= local_tcp_port_end; i++) {
338
339 if (i == mServer->serverPort())
340 continue;
341
342 DkConnection* connection = createConnection();
343 connection->connectToHost(QHostAddress::LocalHost, (qint16)i);
344 }
345 }
346
connectionSynchronized(QList<quint16> synchronizedPeersOfOtherClient,DkConnection * connection)347 void DkLocalClientManager::connectionSynchronized(QList<quint16> synchronizedPeersOfOtherClient, DkConnection* connection) {
348
349 qDebug() << "Connection synchronized with:" << connection->getPeerPort();
350 mPeerList.setSynchronized(connection->getPeerId(), true);
351 emit synchronizedPeersListChanged(mPeerList.getSynchronizedPeerServerPorts());
352
353 auto aps = mPeerList.getActivePeers();
354
355 QString msg = listConnections(aps, true);
356 emit updateConnectionSignal(msg);
357
358 emit clientConnectedSignal(!aps.isEmpty());
359
360 for (int i = 0; i < synchronizedPeersOfOtherClient.size(); i++) {
361
362 if (synchronizedPeersOfOtherClient[i] != mServer->serverPort()) {
363
364 DkPeer* peer = mPeerList.getPeerByServerport(synchronizedPeersOfOtherClient[i]);
365 if (!peer)
366 continue;
367
368 connect(this,SIGNAL(sendSynchronizeMessage()), peer->connection, SLOT(sendStartSynchronizeMessage()));
369 emit sendSynchronizeMessage();
370 disconnect(this,SIGNAL(sendSynchronizeMessage()), peer->connection, SLOT(sendStartSynchronizeMessage()));
371
372 }
373 }
374 //qDebug() << "--------------------";
375 //qDebug() << "current peer list:";
376 //peerList.print();
377 //qDebug() << "--------------------";
378 }
379
connectionStopSynchronized(DkConnection * connection)380 void DkLocalClientManager::connectionStopSynchronized(DkConnection* connection) {
381 qDebug() << "Connection no longer synchronized with: " << connection->getPeerPort();
382 mPeerList.setSynchronized(connection->getPeerId(), false);
383
384 //qDebug() << "--------------------";
385 //qDebug() << "current peer list:";
386 //peerList.print();
387 //qDebug() << "--------------------";
388 emit synchronizedPeersListChanged(mPeerList.getSynchronizedPeerServerPorts());
389
390 auto aps = mPeerList.getActivePeers();
391
392 QString msg = listConnections(aps, false);
393 emit updateConnectionSignal(msg);
394 emit clientConnectedSignal(!aps.isEmpty());
395 }
396
397
synchronizeWith(quint16 peerId)398 void DkLocalClientManager::synchronizeWith(quint16 peerId) {
399 qDebug() << "DkLocalClientManager::synchronizeWith peerId:" << peerId;
400
401 mPeerList.setSynchronized(peerId, true); // will be reset if other client does not response within 1 sec
402 emit synchronizedPeersListChanged(mPeerList.getSynchronizedPeerServerPorts());
403
404 DkPeer* peer = mPeerList.getPeerById(peerId);
405 if (peer == 0 || peer->connection == 0) {
406 //qDebug() << "TcpClient: synchronizeWith: Peer is null or connection is null";
407 return;
408 }
409
410 //qDebug() << "synchronizing with: " << peerId;
411
412
413 connect(this,SIGNAL(sendSynchronizeMessage()), peer->connection, SLOT(sendStartSynchronizeMessage()));
414 emit sendSynchronizeMessage();
415 disconnect(this,SIGNAL(sendSynchronizeMessage()), peer->connection, SLOT(sendStartSynchronizeMessage()));
416
417 }
418
stopSynchronizeWith(quint16)419 void DkLocalClientManager::stopSynchronizeWith(quint16) {
420 QList<DkPeer*> synchronizedPeers = mPeerList.getSynchronizedPeers();
421
422 foreach (DkPeer* peer , synchronizedPeers) {
423
424 if (!peer)
425 continue;
426
427 connect(this,SIGNAL(sendDisableSynchronizeMessage()), peer->connection, SLOT(sendStopSynchronizeMessage()));
428 emit sendDisableSynchronizeMessage();
429 mPeerList.setSynchronized(peer->peerId, false);
430 disconnect(this,SIGNAL(sendDisableSynchronizeMessage()), peer->connection, SLOT(sendStopSynchronizeMessage()));
431 }
432
433 emit synchronizedPeersListChanged(mPeerList.getSynchronizedPeerServerPorts());
434
435 auto aps = mPeerList.getActivePeers();
436
437 QString msg = listConnections(aps, false);
438 emit updateConnectionSignal(msg);
439 emit clientConnectedSignal(!aps.isEmpty());
440 }
441
sendArrangeInstances(bool overlaid)442 void DkLocalClientManager::sendArrangeInstances(bool overlaid) {
443
444 int screen = QApplication::desktop()->screenNumber(DkUtils::getMainWindow());
445 const QRect screenGeometry = QApplication::desktop()->availableGeometry(screen);
446 int connectedInstances = mPeerList.getSynchronizedPeers().size() + 1 ; // +1 because of this instance itself
447 if (connectedInstances == 1)
448 return;
449 int instancesPerRow = (connectedInstances == 2 || connectedInstances == 4) ? 2 : 3;
450
451 int rows = (int)qCeil((float)connectedInstances / (float)instancesPerRow);
452 int width = screenGeometry.width() / instancesPerRow;
453 int height = screenGeometry.height() / rows;
454
455 int curX = screenGeometry.topLeft().x();
456 int curY = screenGeometry.topLeft().y();
457 emit receivedPosition(QRect(curX, curY, width, height), false, overlaid);
458 curX += width;
459 int count = 1;
460 for (DkPeer* peer : mPeerList.getSynchronizedPeers()) {
461
462 if (!peer)
463 continue;
464
465 QRect newPosition = QRect(curX, curY, width, height);
466 connect(this,SIGNAL(sendNewPositionMessage(QRect, bool, bool)), peer->connection, SLOT(sendNewPositionMessage(QRect, bool, bool)));
467 emit sendNewPositionMessage(newPosition, false, overlaid);
468 disconnect(this,SIGNAL(sendNewPositionMessage(QRect, bool, bool)), peer->connection, SLOT(sendNewPositionMessage(QRect, bool, bool)));
469
470 count++;
471 if (count < instancesPerRow)
472 curX += width;
473 else {
474 curX = screenGeometry.topLeft().x();
475 curY += height;
476 count = 0;
477 }
478 }
479 }
480
sendQuitMessageToPeers()481 void DkLocalClientManager::sendQuitMessageToPeers() {
482 emit sendQuitMessage();
483 }
484
connectToNomacs()485 void DkLocalClientManager::connectToNomacs() {
486
487 DkConnection* c = static_cast<DkConnection*>(QObject::sender());
488
489 if (c) {
490 c->sendGreetingMessage(mCurrentTitle);
491 mStartUpConnections.append(c);
492 }
493
494 }
495
connectionReceivedQuit()496 void DkLocalClientManager::connectionReceivedQuit() {
497 emit receivedQuit();
498 }
499
createConnection()500 DkLocalConnection* DkLocalClientManager::createConnection() {
501
502 // wow - there is no one owning connection (except for QOBJECT)
503 DkLocalConnection* connection = new DkLocalConnection(this);
504 connection->setLocalTcpServerPort(mServer->serverPort());
505 connection->setTitle(mCurrentTitle);
506 connectConnection(connection);
507 connect(this, SIGNAL(synchronizedPeersListChanged(QList<quint16>)), connection, SLOT(synchronizedPeersListChanged(QList<quint16>)));
508 connect(this, SIGNAL(sendQuitMessage()), connection, SLOT(sendQuitMessage()));
509 connect(connection, SIGNAL(connectionQuitReceived()), this, SLOT(connectionReceivedQuit()));
510 connect(connection, SIGNAL(connected()), this, SLOT(connectToNomacs()));
511
512 return connection;
513
514 }
515
516 // DkLocalTcpServer --------------------------------------------------------------------
DkLocalTcpServer(QObject * parent)517 DkLocalTcpServer::DkLocalTcpServer(QObject* parent) : QTcpServer(parent) {
518
519 for (int i = local_tcp_port_start; i < local_tcp_port_end; i++) {
520 if (listen(QHostAddress::LocalHost, (quint16)i)) {
521 break;
522 }
523 }
524 //qDebug() << "TCP Listening on port " << this->serverPort();
525 }
526
incomingConnection(qintptr socketDescriptor)527 void DkLocalTcpServer::incomingConnection(qintptr socketDescriptor) {
528 emit serverReiceivedNewConnection((int)socketDescriptor);
529 //qDebug() << "Server: NEW CONNECTION AVAIABLE";
530 }
531
DkPeer(quint16 port,quint16 peerId,const QHostAddress & hostAddress,quint16 peerServerPort,const QString & title,DkConnection * connection,bool sychronized,const QString & clientName,bool showInMenu,QObject * parent)532 DkPeer::DkPeer(
533 quint16 port,
534 quint16 peerId,
535 const QHostAddress& hostAddress,
536 quint16 peerServerPort,
537 const QString& title,
538 DkConnection* connection,
539 bool sychronized,
540 const QString& clientName,
541 bool showInMenu,
542 QObject* parent) : QObject(parent) {
543
544 this->peerId = peerId;
545 this->localServerPort = port;
546 this->peerServerPort = peerServerPort;
547 this->hostAddress = hostAddress;
548 this->title = title;
549 this->sychronized = sychronized;
550 this->connection = connection;
551 this->timer = new QTimer(this);
552 timer->setSingleShot(true);
553 this->clientName = clientName;
554 this->showInMenu = showInMenu;
555 mHasChangedRecently = false;
556 connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeout()), Qt::UniqueConnection);
557 }
558
~DkPeer()559 DkPeer::~DkPeer() {
560 }
561
setSynchronized(bool flag)562 void DkPeer::setSynchronized(bool flag) {
563 sychronized = flag;
564 mHasChangedRecently = true;
565 connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeout()), Qt::UniqueConnection);
566 timer->start(1000);
567 }
568
operator ==(const DkPeer & peer) const569 bool DkPeer::operator==(const DkPeer& peer) const {
570
571 return localServerPort == peer.localServerPort && sychronized == peer.sychronized && title == peer.title && hostAddress == peer.hostAddress;
572 }
573
timerTimeout()574 void DkPeer::timerTimeout() {
575 mHasChangedRecently = false;
576 }
577
578 // DkPeerList --------------------------------------------------------------------
DkPeerList()579 DkPeerList::DkPeerList() {
580 // do nothing
581 }
582
addPeer(DkPeer * peer)583 bool DkPeerList::addPeer(DkPeer* peer) {
584
585 if (!peer) {
586 qDebug() << "[WARNING] you try to append a NULL peer!";
587 return false;
588 }
589
590 if (peerList.contains(peer->peerId))
591 return false;
592 else {
593 peerList.insert(peer->peerId, peer);
594 return true;
595 }
596 }
597
removePeer(quint16 peerId)598 bool DkPeerList::removePeer(quint16 peerId) {
599 if (!peerList.contains(peerId))
600 return false;
601 else {
602 peerList.remove(peerId);
603 return true;
604 }
605 }
606
setSynchronized(quint16 peerId,bool synchronized)607 bool DkPeerList::setSynchronized(quint16 peerId, bool synchronized) {
608
609 if (!peerList.contains(peerId))
610 return false;
611 DkPeer* peer = peerList.value(peerId);
612 peer->setSynchronized(synchronized);
613 //peerList.replace(peerId, peer);
614
615 return true;
616 }
617
setTitle(quint16 peerId,const QString & title)618 bool DkPeerList::setTitle(quint16 peerId, const QString& title) {
619 if (!peerList.contains(peerId))
620 return false;
621 DkPeer* peer = peerList.value(peerId);
622 peer->title = title;
623 //peerList.replace(peerId, peer);
624
625 return true;
626 }
627
setShowInMenu(quint16 peerId,bool showInMenu)628 bool DkPeerList::setShowInMenu(quint16 peerId, bool showInMenu) {
629 if (!peerList.contains(peerId))
630 return false;
631 DkPeer* peer = peerList.value(peerId);
632 peer->showInMenu = showInMenu;
633 //peerList.replace(peerId, peer);
634
635 return true;
636 }
637
getSynchronizedPeers() const638 QList<DkPeer*> DkPeerList::getSynchronizedPeers() const {
639 QList<DkPeer*> sychronizedPeers;
640 foreach(DkPeer* peer, peerList) {
641 if (peer->isSynchronized())
642 sychronizedPeers.push_back(peer);
643 }
644 return sychronizedPeers;
645 }
646
getPeerList()647 QList<DkPeer*> DkPeerList::getPeerList() {
648 return peerList.values();
649 }
650
getSynchronizedPeerServerPorts() const651 QList<quint16> DkPeerList::getSynchronizedPeerServerPorts() const {
652 QList<quint16> sychronizedPeerServerPorts;
653 foreach(DkPeer* peer, peerList) {
654 if (peer->isSynchronized())
655 sychronizedPeerServerPorts.push_back(peer->peerServerPort);
656 }
657 return sychronizedPeerServerPorts;
658 }
659
getActivePeers() const660 QList<DkPeer*> DkPeerList::getActivePeers() const {
661 QList<DkPeer*> activePeers;
662 foreach(DkPeer* peer, peerList) {
663 if (peer->isActive())
664 activePeers.push_back(peer);
665 }
666 return activePeers;
667 }
668
getPeerByServerport(quint16 port) const669 DkPeer* DkPeerList::getPeerByServerport(quint16 port) const {
670 foreach (DkPeer* peer, peerList) {
671 if (peer->peerServerPort == port)
672 return peer;
673 }
674 return 0;
675 }
676
alreadyConnectedTo(const QHostAddress & address,quint16 port) const677 bool DkPeerList::alreadyConnectedTo(const QHostAddress& address, quint16 port) const {
678 foreach (DkPeer* peer, peerList) {
679 if (peer->hostAddress == address && peer->localServerPort == port ) // TODO: wieso localserver port ... aber es funkt
680 return true;
681 }
682 return false;
683 }
684
getPeerById(quint16 id)685 DkPeer* DkPeerList::getPeerById(quint16 id) {
686 return peerList.value(id, 0);
687 }
688
getPeerByAddress(const QHostAddress & address,quint16 port) const689 DkPeer* DkPeerList::getPeerByAddress(const QHostAddress& address, quint16 port) const {
690 foreach (DkPeer* peer, peerList) {
691 if (peer->hostAddress == address && peer->localServerPort == port)
692 return peer;
693 }
694 return 0; // should not happen
695 }
696
print() const697 void DkPeerList::print() const {
698 foreach (DkPeer* peer, peerList) {
699
700 if (!peer)
701 continue;
702
703 qDebug() << peer->peerId << " " << peer->clientName << " " << peer->hostAddress << " serverPort:" << peer->peerServerPort <<
704 " localPort:" << peer->localServerPort << " " << peer->title << " sync:" << peer->isSynchronized() << " menu:" << peer->showInMenu << " connection:" << peer->connection;
705 }
706 }
707
708 // DkStatusBarManager --------------------------------------------------------------------
DkSyncManager()709 DkSyncManager::DkSyncManager() {
710
711 DkTimer dt;
712 mClient = new DkLocalClientManager("nomacs | Image Lounge", 0);
713
714 //connect(this, SIGNAL(syncWithSignal(quint16)), mClient, SLOT(synchronizeWith(quint16)));
715 //connect(this, SIGNAL(stopSyncWithSignal(quint16)), mClient, SLOT(stopSynchronizeWith(quint16)));
716 qInfo() << "local client created in: " << dt; // takes 1 sec in the client thread
717 }
718
inst()719 DkSyncManager& DkSyncManager::inst() {
720
721 static DkSyncManager inst;
722 return inst;
723 }
724
client()725 DkClientManager* DkSyncManager::client() {
726
727 if (!mClient) {
728 qWarning() << "DkSyncManager::client() which is not created yet...";
729 return 0;
730 }
731
732 return mClient;
733 }
734
735 }
736