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.
|
||||
|
||||
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 <cstdlib>
|
||||
|
||||
/**
|
||||
* @brief SingleApplication::SingleApplication
|
||||
* Constructor. Checks and fires up LocalServer or closes the program
|
||||
* @brief Constructor. Checks and fires up LocalServer or closes the
|
||||
program
|
||||
* if another instance already exists
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
SingleApplication::SingleApplication(int argc, char *argv[]) :
|
||||
QGuiApplication(argc, argv)
|
||||
SingleApplication::SingleApplication(int argc, char *argv[])
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
_shouldContinue = false; // By default this is not the main process
|
||||
|
||||
socket = new QLocalSocket();
|
||||
QString serverName = QApplication::organizationName() +
|
||||
QApplication::applicationName();
|
||||
serverName.replace(QRegExp("\\s"), "");
|
||||
|
||||
// Attempt to connect to the LocalServer
|
||||
socket->connectToServer(LOCAL_SERVER_NAME);
|
||||
if(socket->waitForConnected(100)){
|
||||
socket->write("CMD:showUp");
|
||||
socket->flush();
|
||||
QThread::msleep(100);
|
||||
socket = new QLocalSocket();
|
||||
socket->connectToServer(serverName);
|
||||
if(socket->waitForConnected(1000)){
|
||||
socket->close();
|
||||
::exit(EXIT_SUCCESS); // Terminate the program using STDLib's
|
||||
exit function
|
||||
} else {
|
||||
// The attempt was insuccessful, so we continue the program
|
||||
_shouldContinue = true;
|
||||
server = new LocalServer();
|
||||
server->start();
|
||||
QObject::connect(server, SIGNAL(showUp()), this, SLOT(slotShowUp()));
|
||||
// If the connection is insuccessful, this is the main process
|
||||
// So we create a Local Server
|
||||
server = new QLocalServer();
|
||||
server->removeServer(serverName);
|
||||
server->listen(serverName);
|
||||
QObject::connect(server, SIGNAL(newConnection()), this,
|
||||
SLOT(slotConnectionEstablished()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SingleApplication::~SingleApplication
|
||||
* Destructor
|
||||
* @brief Destructor
|
||||
*/
|
||||
Application::~SingleApplication()
|
||||
SingleApplication::~SingleApplication()
|
||||
{
|
||||
if(_shouldContinue){
|
||||
server->terminate();
|
||||
}
|
||||
server->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SingleApplication::shouldContinue
|
||||
* Weather the program should be terminated
|
||||
* @return bool
|
||||
* @brief Executed when the showUp command is sent to LocalServer
|
||||
*/
|
||||
bool SingleApplication::shouldContinue()
|
||||
{
|
||||
return _shouldContinue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SingleApplication::slotShowUp
|
||||
* Executed when the showUp command is sent to LocalServer
|
||||
*/
|
||||
void SingleApplication::slotShowUp()
|
||||
void SingleApplication::slotConnectionEstablished()
|
||||
{
|
||||
server->nextPendingConnection();
|
||||
emit showUp();
|
||||
}
|
||||
|
||||
|
@ -1,33 +1,33 @@
|
||||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
#ifndef SINGLE_APPLICATION_H
|
||||
#define SINGLE_APPLICATION_H
|
||||
|
||||
#include "localserver.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QApplication>
|
||||
#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
|
||||
public:
|
||||
explicit SingleApplication(int, char *[]);
|
||||
~SingleApplication();
|
||||
bool shouldContinue();
|
||||
|
||||
signals:
|
||||
void showUp();
|
||||
|
||||
private slots:
|
||||
void slotShowUp();
|
||||
void slotConnectionEstablished();
|
||||
|
||||
private:
|
||||
QLocalSocket *socket;
|
||||
LocalServer* server;
|
||||
bool _shouldContinue;
|
||||
QLocalServer *server;
|
||||
|
||||
};
|
||||
|
||||
#endif // APPLICATION_H
|
||||
#endif // SINGLE_APPLICATION_H
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user