93 lines
2.1 KiB
C++
Executable File
93 lines
2.1 KiB
C++
Executable File
// For license of this file, see <project-root-folder>/LICENSE.md.
|
|
|
|
#include "miscellaneous/singleapplication.h"
|
|
|
|
#include "definitions/definitions.h"
|
|
|
|
#include <QDataStream>
|
|
#include <QLocalServer>
|
|
#include <QLocalSocket>
|
|
|
|
SingleApplication::SingleApplication(const QString& id, int& argc, char** argv)
|
|
: QApplication(argc, argv), m_id(id), m_server(new QLocalServer(this)) {}
|
|
|
|
void SingleApplication::finish() {
|
|
if (m_server->isListening()) {
|
|
m_server->close();
|
|
}
|
|
}
|
|
|
|
bool SingleApplication::isOtherInstanceRunning(const QString& message) {
|
|
QLocalSocket sck;
|
|
|
|
sck.connectToServer(m_id);
|
|
|
|
if (sck.waitForConnected(200)) {
|
|
if (!message.isEmpty()) {
|
|
QDataStream out(&sck);
|
|
|
|
out.setVersion(QDataStream::Version::Qt_5_5);
|
|
|
|
out << quint32(message.size());
|
|
out << message;
|
|
|
|
sck.flush();
|
|
sck.waitForBytesWritten(200);
|
|
}
|
|
|
|
sck.disconnectFromServer();
|
|
sck.abort();
|
|
return true;
|
|
}
|
|
|
|
auto i_am_first = m_server->listen(m_id);
|
|
|
|
if (i_am_first) {
|
|
connect(m_server, &QLocalServer::newConnection, this, &SingleApplication::processMessageFromOtherInstance);
|
|
}
|
|
|
|
return !i_am_first;
|
|
}
|
|
|
|
bool SingleApplication::sendMessage(const QString& message) {
|
|
return isOtherInstanceRunning(message);
|
|
}
|
|
|
|
void SingleApplication::processMessageFromOtherInstance() {
|
|
auto* sck = m_server->nextPendingConnection();
|
|
|
|
if (sck == nullptr) {
|
|
return;
|
|
}
|
|
|
|
quint32 block_size = 0;
|
|
QEventLoop loop;
|
|
QDataStream in(sck);
|
|
|
|
in.setVersion(QDataStream::Version::Qt_5_5);
|
|
|
|
connect(sck, &QLocalSocket::disconnected, sck, &QLocalSocket::deleteLater);
|
|
connect(sck, &QLocalSocket::readyRead, this, [this, sck, &loop, &in, &block_size]() {
|
|
if (block_size == 0) {
|
|
if (sck->bytesAvailable() < int(sizeof(quint32))) {
|
|
return;
|
|
}
|
|
|
|
in >> block_size;
|
|
}
|
|
|
|
if (sck->bytesAvailable() < block_size || in.atEnd()) {
|
|
return;
|
|
}
|
|
|
|
QString dat;
|
|
in >> dat;
|
|
|
|
emit messageReceived(dat);
|
|
loop.exit();
|
|
});
|
|
|
|
sck->flush();
|
|
loop.exec();
|
|
}
|