mirror of
https://github.com/itay-grudev/SingleApplication.git
synced 2025-01-15 17:02:06 +08:00
Completly rewritten and simplified source
This commit is contained in:
parent
31eadace45
commit
5c89ab17cf
@ -2,6 +2,3 @@ SingleApplication
|
|||||||
=================
|
=================
|
||||||
|
|
||||||
This is a replacement of QSingleApplication for Qt5.
|
This is a replacement of QSingleApplication for Qt5.
|
||||||
|
|
||||||
P.S. I will document it dome day, when I have time.
|
|
||||||
Otherwise it is pretty straighforward. I added a signal to notify the root proccess that another instance had been started. You can use it to raise the Main window of the root app, for example.
|
|
||||||
|
129
localserver.cpp
129
localserver.cpp
@ -1,129 +0,0 @@
|
|||||||
#include "localserver.h"
|
|
||||||
|
|
||||||
#include <QFile>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LocalServer::LocalServer
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
LocalServer::LocalServer()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LocalServer::~LocalServer
|
|
||||||
* Destructor
|
|
||||||
*/
|
|
||||||
LocalServer::~LocalServer()
|
|
||||||
{
|
|
||||||
server->close();
|
|
||||||
for(int i = 0; i < clients.size(); ++i)
|
|
||||||
{
|
|
||||||
clients[i]->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* -----------------------
|
|
||||||
* QThread requred methods
|
|
||||||
* -----------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief run
|
|
||||||
* Initiate the thread.
|
|
||||||
*/
|
|
||||||
void LocalServer::run()
|
|
||||||
{
|
|
||||||
server = new QLocalServer();
|
|
||||||
|
|
||||||
QObject::connect(server, SIGNAL(newConnection()), this, SLOT(slotNewConnection()));
|
|
||||||
QObject::connect(this, SIGNAL(privateDataReceived(QString)), this, SLOT(slotOnData(QString)));
|
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
// Make sure the temp address file is deleted
|
|
||||||
QFile address(QString("/tmp/" LOCAL_SERVER_NAME));
|
|
||||||
if(address.exists()){
|
|
||||||
address.remove();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString serverName = QString(LOCAL_SERVER_NAME);
|
|
||||||
server->listen(serverName);
|
|
||||||
while(server->isListening() == false){
|
|
||||||
server->listen(serverName);
|
|
||||||
msleep(100);
|
|
||||||
}
|
|
||||||
exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LocalServer::exec
|
|
||||||
* Keeps the thread alive. Waits for incomming connections
|
|
||||||
*/
|
|
||||||
void LocalServer::exec()
|
|
||||||
{
|
|
||||||
while(server->isListening())
|
|
||||||
{
|
|
||||||
msleep(100);
|
|
||||||
server->waitForNewConnection(100);
|
|
||||||
for(int i = 0; i < clients.size(); ++i)
|
|
||||||
{
|
|
||||||
if(clients[i]->waitForReadyRead(100)){
|
|
||||||
QByteArray data = clients[i]->readAll();
|
|
||||||
emit privateDataReceived(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* -------
|
|
||||||
* SLOTS
|
|
||||||
* -------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LocalServer::slotNewConnection
|
|
||||||
* Executed when a new connection is available
|
|
||||||
*/
|
|
||||||
void LocalServer::slotNewConnection()
|
|
||||||
{
|
|
||||||
clients.push_front(server->nextPendingConnection());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LocalServer::slotOnData
|
|
||||||
* Executed when data is received
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
void LocalServer::slotOnData(QString data)
|
|
||||||
{
|
|
||||||
if(data.contains("CMD:", Qt::CaseInsensitive)){
|
|
||||||
onSGC(data);
|
|
||||||
} else {
|
|
||||||
emit dataReceived(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* -------
|
|
||||||
* Helper methods
|
|
||||||
* -------
|
|
||||||
*/
|
|
||||||
|
|
||||||
void LocalServer::onCMD(QString data)
|
|
||||||
{
|
|
||||||
// Trim the leading part from the command
|
|
||||||
data.replace(0, 4, "");
|
|
||||||
|
|
||||||
QStringList commands;
|
|
||||||
commands << "showUp";
|
|
||||||
|
|
||||||
switch(commands.indexOf(data)){
|
|
||||||
case 0:
|
|
||||||
emit showUp();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
#ifndef LOCALSERVER_H
|
|
||||||
#define LOCALSERVER_H
|
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
#include <QVector>
|
|
||||||
#include <QLocalServer>
|
|
||||||
#include <QLocalSocket>
|
|
||||||
|
|
||||||
class LocalServer : public QThread
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
LocalServer();
|
|
||||||
~LocalServer();
|
|
||||||
void shut();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void run();
|
|
||||||
void exec();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void dataReceived(QString data);
|
|
||||||
void privateDataReceived(QString data);
|
|
||||||
void showUp();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotNewConnection();
|
|
||||||
void slotOnData(QString data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QLocalServer* server;
|
|
||||||
QVector<QLocalSocket*> clients;
|
|
||||||
void onCMD(QString data);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LOCALSERVER_H
|
|
11
main.cpp
11
main.cpp
@ -1,11 +0,0 @@
|
|||||||
#include "singleapplication.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
SingleApplication app(argc, argv);
|
|
||||||
|
|
||||||
// Is another instance of the program is already running
|
|
||||||
if(!app.shouldContinue())return 0;
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
@ -1,61 +1,52 @@
|
|||||||
#include "singleapplication.h"
|
#include "singleapplication.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SingleApplication::SingleApplication
|
* @brief Constructor. Checks and fires up LocalServer or closes the
|
||||||
* Constructor. Checks and fires up LocalServer or closes the program
|
program
|
||||||
* if another instance already exists
|
* if another instance already exists
|
||||||
* @param argc
|
* @param argc
|
||||||
* @param argv
|
* @param argv
|
||||||
*/
|
*/
|
||||||
SingleApplication::SingleApplication(int argc, char *argv[]) :
|
SingleApplication::SingleApplication(int argc, char *argv[])
|
||||||
QGuiApplication(argc, argv)
|
: QApplication(argc, argv)
|
||||||
{
|
{
|
||||||
_shouldContinue = false; // By default this is not the main process
|
QString serverName = QApplication::organizationName() +
|
||||||
|
QApplication::applicationName();
|
||||||
socket = new QLocalSocket();
|
serverName.replace(QRegExp("\\s"), "");
|
||||||
|
|
||||||
// Attempt to connect to the LocalServer
|
// Attempt to connect to the LocalServer
|
||||||
socket->connectToServer(LOCAL_SERVER_NAME);
|
socket = new QLocalSocket();
|
||||||
if(socket->waitForConnected(100)){
|
socket->connectToServer(serverName);
|
||||||
socket->write("CMD:showUp");
|
if(socket->waitForConnected(1000)){
|
||||||
socket->flush();
|
|
||||||
QThread::msleep(100);
|
|
||||||
socket->close();
|
socket->close();
|
||||||
|
::exit(EXIT_SUCCESS); // Terminate the program using STDLib's
|
||||||
|
exit function
|
||||||
} else {
|
} else {
|
||||||
// The attempt was insuccessful, so we continue the program
|
// If the connection is insuccessful, this is the main process
|
||||||
_shouldContinue = true;
|
// So we create a Local Server
|
||||||
server = new LocalServer();
|
server = new QLocalServer();
|
||||||
server->start();
|
server->removeServer(serverName);
|
||||||
QObject::connect(server, SIGNAL(showUp()), this, SLOT(slotShowUp()));
|
server->listen(serverName);
|
||||||
|
QObject::connect(server, SIGNAL(newConnection()), this,
|
||||||
|
SLOT(slotConnectionEstablished()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SingleApplication::~SingleApplication
|
* @brief Destructor
|
||||||
* Destructor
|
|
||||||
*/
|
*/
|
||||||
Application::~SingleApplication()
|
SingleApplication::~SingleApplication()
|
||||||
{
|
{
|
||||||
if(_shouldContinue){
|
server->close();
|
||||||
server->terminate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SingleApplication::shouldContinue
|
* @brief Executed when the showUp command is sent to LocalServer
|
||||||
* Weather the program should be terminated
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
bool SingleApplication::shouldContinue()
|
void SingleApplication::slotConnectionEstablished()
|
||||||
{
|
|
||||||
return _shouldContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief SingleApplication::slotShowUp
|
|
||||||
* Executed when the showUp command is sent to LocalServer
|
|
||||||
*/
|
|
||||||
void SingleApplication::slotShowUp()
|
|
||||||
{
|
{
|
||||||
|
server->nextPendingConnection();
|
||||||
emit showUp();
|
emit showUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
#ifndef APPLICATION_H
|
#ifndef SINGLE_APPLICATION_H
|
||||||
#define APPLICATION_H
|
#define SINGLE_APPLICATION_H
|
||||||
|
|
||||||
#include "localserver.h"
|
#include <QApplication>
|
||||||
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
|
#include <QLocalServer>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The Application class handles trivial application initialization procedures
|
* @brief The SingleApplication class handles multipe instances of the
|
||||||
|
same Application
|
||||||
|
* @see QApplication
|
||||||
*/
|
*/
|
||||||
class SingleApplication : public QGuiApplication
|
class SingleApplication : public QApplication
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SingleApplication(int, char *[]);
|
explicit SingleApplication(int, char *[]);
|
||||||
~SingleApplication();
|
~SingleApplication();
|
||||||
bool shouldContinue();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void showUp();
|
void showUp();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotShowUp();
|
void slotConnectionEstablished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLocalSocket* socket;
|
QLocalSocket *socket;
|
||||||
LocalServer* server;
|
QLocalServer *server;
|
||||||
bool _shouldContinue;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPLICATION_H
|
#endif // SINGLE_APPLICATION_H
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user