1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include <QtCore/qfileinfo.h>
5#include <QtCore/qstringlist.h>
6
7#include <QtNetwork/qhostaddress.h>
8#include <QtNetwork/qtcpserver.h>
9#include <QtNetwork/qtcpsocket.h>
10
11#include "qdesigner.h"
12#include "qdesigner_server.h"
13
14#include <qevent.h>
15
16QT_BEGIN_NAMESPACE
17
18using namespace Qt::StringLiterals;
19
20// ### review
21
22QDesignerServer::QDesignerServer(QObject *parent)
23 : QObject(parent)
24{
25 m_socket = nullptr;
26 m_server = new QTcpServer(this);
27 if (m_server->listen(address: QHostAddress::LocalHost, port: 0)) {
28 connect(sender: m_server, signal: &QTcpServer::newConnection,
29 context: this, slot: &QDesignerServer::handleNewConnection);
30 }
31}
32
33QDesignerServer::~QDesignerServer() = default;
34
35quint16 QDesignerServer::serverPort() const
36{
37 return m_server ? m_server->serverPort() : 0;
38}
39
40void QDesignerServer::sendOpenRequest(int port, const QStringList &files)
41{
42 QTcpSocket *sSocket = new QTcpSocket();
43 sSocket->connectToHost(address: QHostAddress::LocalHost, port);
44 if(sSocket->waitForConnected(msecs: 3000))
45 {
46 for (const QString &file : files) {
47 QFileInfo fi(file);
48 sSocket->write(data: fi.absoluteFilePath().toUtf8() + '\n');
49 }
50 sSocket->waitForBytesWritten(msecs: 3000);
51 sSocket->close();
52 }
53 delete sSocket;
54}
55
56void QDesignerServer::readFromClient()
57{
58 while (m_socket->canReadLine()) {
59 QString file = QString::fromUtf8(ba: m_socket->readLine());
60 if (!file.isNull()) {
61 file.remove(c: u'\n');
62 file.remove(c: u'\r');
63 qDesigner->postEvent(qDesigner, event: new QFileOpenEvent(file));
64 }
65 }
66}
67
68void QDesignerServer::socketClosed()
69{
70 m_socket = nullptr;
71}
72
73void QDesignerServer::handleNewConnection()
74{
75 // no need for more than one connection
76 if (m_socket == nullptr) {
77 m_socket = m_server->nextPendingConnection();
78 connect(sender: m_socket, signal: &QTcpSocket::readyRead,
79 context: this, slot: &QDesignerServer::readFromClient);
80 connect(sender: m_socket, signal: &QTcpSocket::disconnected,
81 context: this, slot: &QDesignerServer::socketClosed);
82 }
83}
84
85
86QDesignerClient::QDesignerClient(quint16 port, QObject *parent)
87: QObject(parent)
88{
89 m_socket = new QTcpSocket(this);
90 m_socket->connectToHost(address: QHostAddress::LocalHost, port);
91 connect(sender: m_socket, signal: &QTcpSocket::readyRead,
92 context: this, slot: &QDesignerClient::readFromSocket);
93
94}
95
96QDesignerClient::~QDesignerClient()
97{
98 m_socket->close();
99 m_socket->flush();
100}
101
102void QDesignerClient::readFromSocket()
103{
104 while (m_socket->canReadLine()) {
105 QString file = QString::fromUtf8(ba: m_socket->readLine());
106 if (!file.isNull()) {
107 file.remove(c: u'\n');
108 file.remove(c: u'\r');
109 if (QFile::exists(fileName: file))
110 qDesigner->postEvent(qDesigner, event: new QFileOpenEvent(file));
111 }
112 }
113}
114
115QT_END_NAMESPACE
116

source code of qttools/src/designer/src/designer/qdesigner_server.cpp