From 230b4ebe94400ac7af47731e5c2b965b0c5fb2da Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Sun, 23 Dec 2012 00:12:38 +0200 Subject: Add base files --- .gitattributes | 22 +++++++ .gitignore | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 0 localserver.cpp | 129 +++++++++++++++++++++++++++++++++++++++ localserver.h | 37 ++++++++++++ main.cpp | 11 ++++ singleapplication.cpp | 61 +++++++++++++++++++ singleapplication.h | 33 ++++++++++ 8 files changed, 456 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 localserver.cpp create mode 100644 localserver.h create mode 100644 main.cpp create mode 100644 singleapplication.cpp create mode 100644 singleapplication.h diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ebd21a --- /dev/null +++ b/.gitignore @@ -0,0 +1,163 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/localserver.cpp b/localserver.cpp new file mode 100644 index 0000000..f3adcb9 --- /dev/null +++ b/localserver.cpp @@ -0,0 +1,129 @@ +#include "localserver.h" + +#include +#include + +/** + * @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(); + } +} diff --git a/localserver.h b/localserver.h new file mode 100644 index 0000000..92c9bb1 --- /dev/null +++ b/localserver.h @@ -0,0 +1,37 @@ +#ifndef LOCALSERVER_H +#define LOCALSERVER_H + +#include +#include +#include +#include + +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 clients; + void onCMD(QString data); + +}; + +#endif // LOCALSERVER_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..101534f --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#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(); +} diff --git a/singleapplication.cpp b/singleapplication.cpp new file mode 100644 index 0000000..7e63371 --- /dev/null +++ b/singleapplication.cpp @@ -0,0 +1,61 @@ +#include "singleapplication.h" + +/** + * @brief SingleApplication::SingleApplication + * 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) +{ + _shouldContinue = false; // By default this is not the main process + + socket = new QLocalSocket(); + + // 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->close(); + } 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())); + } +} + +/** + * @brief SingleApplication::~SingleApplication + * Destructor + */ +Application::~SingleApplication() +{ + if(_shouldContinue){ + server->terminate(); + } +} + +/** + * @brief SingleApplication::shouldContinue + * Weather the program should be terminated + * @return bool + */ +bool SingleApplication::shouldContinue() +{ + return _shouldContinue; +} + +/** + * @brief SingleApplication::slotShowUp + * Executed when the showUp command is sent to LocalServer + */ +void SingleApplication::slotShowUp() +{ + emit showUp(); +} diff --git a/singleapplication.h b/singleapplication.h new file mode 100644 index 0000000..03ac69c --- /dev/null +++ b/singleapplication.h @@ -0,0 +1,33 @@ +#ifndef APPLICATION_H +#define APPLICATION_H + +#include "localserver.h" + +#include +#include + +/** + * @brief The Application class handles trivial application initialization procedures + */ +class SingleApplication : public QGuiApplication +{ + Q_OBJECT +public: + explicit SingleApplication(int, char *[]); + ~SingleApplication(); + bool shouldContinue(); + +signals: + void showUp(); + +private slots: + void slotShowUp(); + +private: + QLocalSocket* socket; + LocalServer* server; + bool _shouldContinue; + +}; + +#endif // APPLICATION_H -- cgit v1.2.1