added plugin downloading from servere #4168

This commit is contained in:
XinyuHou 2015-02-09 15:37:47 +00:00
parent 05e6cb6254
commit b178d33d62
21 changed files with 545 additions and 92 deletions

View File

@ -53,7 +53,8 @@ SOURCES += src/main.cpp \
src/AddClientDialog.cpp \
src/CommandProcess.cpp \
src/WebClient.cpp \
src/PluginWizardPage.cpp
src/PluginWizardPage.cpp \
src/PluginManager.cpp
HEADERS += src/MainWindow.h \
src/AboutDialog.h \
src/ServerConfig.h \
@ -92,7 +93,9 @@ HEADERS += src/MainWindow.h \
src/CommandProcess.h \
src/WebClient.h \
src/EditionType.h \
src/PluginWizardPage.h
src/PluginWizardPage.h \
src/ProcessorArch.h \
src/PluginManager.h
RESOURCES += res/Synergy.qrc
RC_FILE = res/win/Synergy.rc
macx {

View File

@ -17,37 +17,39 @@
#include "DataDownloader.h"
DataDownloader::DataDownloader(QUrl url, QObject* parent) :
DataDownloader::DataDownloader(QObject* parent) :
QObject(parent)
{
connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)),
SLOT(fileDownloaded(QNetworkReply*)));
QNetworkRequest request(url);
m_pReply = m_WebCtrl.get(request);
connect(&m_NetworkManager, SIGNAL(finished(QNetworkReply*)),
SLOT(complete(QNetworkReply*)));
}
DataDownloader::~DataDownloader()
{
}
void DataDownloader::fileDownloaded(QNetworkReply* reply)
void DataDownloader::complete(QNetworkReply* reply)
{
m_DownloadedData = reply->readAll();
m_Data = reply->readAll();
reply->deleteLater();
if (!m_DownloadedData.isEmpty()) {
emit downloaded();
if (!m_Data.isEmpty()) {
emit isComplete();
}
}
QByteArray DataDownloader::downloadedData() const
QByteArray DataDownloader::data() const
{
return m_DownloadedData;
return m_Data;
}
void DataDownloader::cancelDownload()
void DataDownloader::cancel()
{
m_pReply->abort();
}
void DataDownloader::download(QUrl url)
{
QNetworkRequest request(url);
m_pReply = m_NetworkManager.get(request);
}

View File

@ -27,23 +27,24 @@
class DataDownloader : public QObject
{
Q_OBJECT
public:
explicit DataDownloader(QUrl url, QObject* parent = 0);
explicit DataDownloader(QObject* parent = 0);
virtual ~DataDownloader();
QByteArray downloadedData() const;
void cancelDownload();
QByteArray data() const;
void cancel();
void download(QUrl url);
signals:
void downloaded();
void isComplete();
private slots:
void fileDownloaded(QNetworkReply* reply);
void complete(QNetworkReply* reply);
private:
QNetworkAccessManager m_WebCtrl;
QByteArray m_DownloadedData;
QNetworkAccessManager m_NetworkManager;
QByteArray m_Data;
QNetworkReply* m_pReply;
};

View File

@ -30,6 +30,7 @@
#include "CommandProcess.h"
#include "EditionType.h"
#include "QUtility.h"
#include "ProcessorArch.h"
#include <QtCore>
#include <QtGui>
@ -54,10 +55,10 @@
#if defined(Q_OS_WIN)
static const char synergyConfigName[] = "synergy.sgc";
static const QString synergyConfigFilter(QObject::tr("Synergy Configurations (*.sgc);;All files (*.*)"));
static const char bonjourUrl[] = "http://synergy-project.org/bonjour/";
static const char bonjour32Url[] = "http://synergy-project.org/bonjour/Bonjour.msi";
static const char bonjour64Url[] = "http://synergy-project.org/bonjour/Bonjour64.msi";
static const char bonjourInstaller[] = "BonjourSetup.msi";
static QString bonjourBaseUrl = "http://synergy-project.org/bonjour/";
static const char bonjourFilename32[] = "Bonjour.msi";
static const char bonjourFilename64[] = "Bonjour64.msi";
static const char bonjourTargetFilename[] = "Bonjour.msi";
#else
static const char synergyConfigName[] = "synergy.conf";
static const QString synergyConfigFilter(QObject::tr("Synergy Configurations (*.conf);;All files (*.*)"));
@ -865,26 +866,6 @@ void MainWindow::serverDetected(const QString name)
}
}
int MainWindow::checkWinArch()
{
#if defined(Q_OS_WIN)
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
switch (systemInfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_INTEL:
return x86;
case PROCESSOR_ARCHITECTURE_IA64:
return x64;
case PROCESSOR_ARCHITECTURE_AMD64:
return x64;
default:
appendLogNote("failed to detect system architecture");
}
#endif
return unknown;
}
void MainWindow::setEdition(int type)
{
QString title;
@ -1063,33 +1044,30 @@ bool MainWindow::isBonjourRunning()
void MainWindow::downloadBonjour()
{
#if defined(Q_OS_WIN)
QUrl url;
int arch = checkWinArch();
if (arch == x86) {
url.setUrl(bonjour32Url);
int arch = checkProcessorArch();
if (arch == Win_x86) {
url.setUrl(bonjourBaseUrl + bonjourFilename32);
appendLogNote("downloading 32-bit Bonjour");
}
else if (arch == x64) {
url.setUrl(bonjour64Url);
else if (arch == Win_x64) {
url.setUrl(bonjourBaseUrl + bonjourFilename64);
appendLogNote("downloading 64-bit Bonjour");
}
else {
QString msg("Failed to detect system architecture.\n"
"Please download the installer manually from this link:\n");
QMessageBox::warning(
QMessageBox::critical(
this, tr("Synergy"),
msg + bonjourUrl);
tr("Failed to detect system architecture."));
return;
}
if (m_pDataDownloader != NULL) {
delete m_pDataDownloader;
m_pDataDownloader = NULL;
if (m_pDataDownloader == NULL) {
m_pDataDownloader = new DataDownloader(this);
connect(m_pDataDownloader, SIGNAL(isComplete()), SLOT(installBonjour()));
}
m_pDataDownloader = new DataDownloader(url, this);
connect(m_pDataDownloader, SIGNAL(downloaded()), SLOT(installBonjour()));
m_pDataDownloader->download(url);
if (m_DownloadMessageBox == NULL) {
m_DownloadMessageBox = new QMessageBox(this);
@ -1104,7 +1082,7 @@ void MainWindow::downloadBonjour()
m_DownloadMessageBox->exec();
if (m_DownloadMessageBox->clickedButton() == m_pCancelButton) {
m_pDataDownloader->cancelDownload();
m_pDataDownloader->cancel();
}
#endif
}
@ -1115,21 +1093,19 @@ void MainWindow::installBonjour()
QString tempLocation = QDesktopServices::storageLocation(
QDesktopServices::TempLocation);
QString filename = tempLocation;
filename.append("\\").append(bonjourInstaller);
filename.append("\\").append(bonjourTargetFilename);
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
m_DownloadMessageBox->hide();
QMessageBox::warning(
this, "Synergy",
"Failed to download Bonjour installer to location: " +
tempLocation + "\n"
"Please download the installer manually from this link: \n" +
bonjourUrl);
tr("Failed to download Bonjour installer to location: %1")
.arg(tempLocation));
return;
}
file.write(m_pDataDownloader->downloadedData());
file.write(m_pDataDownloader->data());
file.close();
QStringList arguments;

View File

@ -83,12 +83,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
Info
};
enum qProcessorArch {
x86,
x64,
unknown
};
public:
MainWindow(QSettings& settings, AppConfig& appConfig);
~MainWindow();
@ -111,7 +105,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
void autoAddScreen(const QString name);
void updateZeroconfService();
void serverDetected(const QString name);
int checkWinArch();
void setEdition(int type);
public slots:

View File

@ -0,0 +1,207 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2015 Synergy Si Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "PluginManager.h"
#include "DataDownloader.h"
#include "QUtility.h"
#include "ProcessorArch.h"
#include <QCoreApplication>
#include <QProcess>
#include <QFile>
#include <QDir>
#include <QMessageBox>
static const char kGetPluginDirArg[] = "--get-plugin-dir";
static QString kPluginsBaseUrl = "http://synergy-project.org/files/plugins/";
static const char kWinProcessorArch32[] = "Windows-x86";
static const char kWinProcessorArch64[] = "Windows-x64";
static const char kMacProcessorArch[] = "MacOSX-i386";
static const char kLinuxProcessorArch32[] = "Linux-i686";
static const char kLinuxProcessorArch64[] = "Linux-x86_64";
#if defined(Q_OS_WIN)
static const char kWinPluginExt[] = ".dll";
#elif defined(Q_OS_MAC)
static const char kMacPluginPrefix[] = "lib";
static const char kMacPluginExt[] = ".dylib";
#else
static const char kLinuxPluginPrefix[] = "lib";
static const char kLinuxPluginExt[] = ".so";
#endif
PluginManager::PluginManager(QStringList pluginList) :
m_PluginList(pluginList),
m_DownloadIndex(-1),
m_pPluginDownloader(NULL)
{
}
PluginManager::~PluginManager()
{
if (m_pPluginDownloader != NULL) {
delete m_pPluginDownloader;
}
}
void PluginManager::downloadPlugins()
{
if (m_pPluginDownloader != NULL) {
savePlugin();
if (m_DownloadIndex != m_PluginList.size() - 1) {
emit downloadNext();
}
else {
emit downloadFinished();
return;
}
}
m_DownloadIndex++;
if (m_DownloadIndex < m_PluginList.size()) {
QUrl url;
QString pluginUrl = getPluginUrl(m_PluginList.at(m_DownloadIndex));
url.setUrl(pluginUrl);
if (m_pPluginDownloader == NULL) {
m_pPluginDownloader = new DataDownloader();
connect(m_pPluginDownloader, SIGNAL(isComplete()), this, SLOT(downloadPlugins()));
}
m_pPluginDownloader->download(url);
}
}
void PluginManager::savePlugin()
{
QString pluginDir = getPluginDir();
if (pluginDir.isEmpty()) {
return;
}
QString filename = pluginDir;
QString pluginName = m_PluginList.at(m_DownloadIndex);
pluginName = getPluginOSSpecificName(pluginName);
filename.append(QDir::separator()).append(pluginName);
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
QMessageBox::warning(
(QWidget*)parent(), "Synergy",
tr("Failed to download plugin %1 to location: %2")
.arg(m_PluginList.at(m_DownloadIndex))
.arg(pluginDir));
return;
}
file.write(m_pPluginDownloader->data());
file.close();
}
QString PluginManager::getPluginDir()
{
QString program(QCoreApplication::applicationDirPath() + "/syntool");
QProcess process;
process.setReadChannel(QProcess::StandardOutput);
QStringList args(kGetPluginDirArg);
process.start(program, args);
bool success = process.waitForStarted();
QString out, error;
if (success)
{
if (process.waitForFinished()) {
out = process.readAllStandardOutput();
error = process.readAllStandardError();
}
}
out = out.trimmed();
error = error.trimmed();
if (out.isEmpty() ||
!error.isEmpty() ||
!success ||
process.exitCode() != 0)
{
QMessageBox::critical(
(QWidget*)parent(), tr("Synergy"),
tr("An error occured while trying to get "
"plugin directory from syntool. Code: %1\nError: %2")
.arg(process.exitCode())
.arg(error.isEmpty() ? "Unknown" : error));
return "";
}
// create the path if not exist
// TODO: synergy folder should be hidden
QDir dir(out);
if (!dir.exists()) {
dir.mkpath(".");
}
return out;
}
QString PluginManager::getPluginUrl(const QString& pluginName)
{
QString result;
result = kPluginsBaseUrl.append(pluginName).append("/1.0/");
int arch = checkProcessorArch();
if (arch == Win_x86) {
result.append(kWinProcessorArch32);
}
else if (arch == Win_x64) {
result.append(kWinProcessorArch64);
}
else if (arch == Mac_i386) {
result.append(kMacProcessorArch);
}
else if (arch == Linux_i686) {
result.append(kLinuxProcessorArch32);
}
else if (arch == Linux_x86_64) {
result.append(kLinuxProcessorArch64);
}
else {
QMessageBox::critical(
(QWidget*)parent(), tr("Synergy"),
tr("Failed to detect system architecture."));
return "";
}
result.append("/");
result.append(getPluginOSSpecificName(pluginName));
return result;
}
QString PluginManager::getPluginOSSpecificName(const QString& pluginName)
{
QString result = pluginName;
#if defined(Q_OS_WIN)
result.append(kWinPluginExt);
#elif defined(Q_OS_MAC)
result = kMacPluginPrefix + pluginName + kMacPluginExt;
#else
result = kLinuxPluginPrefix + pluginName + kLinuxPluginExt;
#endif
return result;
}

View File

@ -0,0 +1,56 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2015 Synergy Si Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLUGINMANAGER_H
#define PLUGINMANAGER_H
#include <QString>
#include <QStringList>
#include <QObject>
class DataDownloader;
class PluginManager: public QObject
{
Q_OBJECT
public:
PluginManager(QStringList pluginList);
~PluginManager();
int downloadIndex() { return m_DownloadIndex; }
public slots:
void downloadPlugins();
private:
void savePlugin();
QString getPluginDir();
QString getPluginUrl(const QString& pluginName);
QString getPluginOSSpecificName(const QString& pluginName);
signals:
void downloadNext();
void downloadFinished();
private:
QStringList m_PluginList;
int m_DownloadIndex;
DataDownloader* m_pPluginDownloader;
};
#endif // PLUGINMANAGER_H

View File

@ -2,6 +2,7 @@
#include "ui_PluginWizardPageBase.h"
#include "WebClient.h"
#include "PluginManager.h"
#include <QMovie>
#include <QThread>
@ -9,7 +10,8 @@
PluginWizardPage::PluginWizardPage(QWidget *parent) :
QWizardPage(parent),
m_Finished(false),
m_pWebClient(NULL)
m_pWebClient(NULL),
m_pPluginManager(NULL)
{
setupUi(this);
@ -23,6 +25,10 @@ PluginWizardPage::~PluginWizardPage()
if (m_pWebClient != NULL) {
delete m_pWebClient;
}
if (m_pPluginManager != NULL) {
delete m_pPluginManager;
}
}
void PluginWizardPage::changeEvent(QEvent *e)
@ -39,8 +45,8 @@ void PluginWizardPage::changeEvent(QEvent *e)
void PluginWizardPage::queryPluginDone()
{
QStringList plguinList = m_pWebClient->getPluginList();
if (plguinList.isEmpty()) {
QStringList pluginList = m_pWebClient->getPluginList();
if (pluginList.isEmpty()) {
if (!m_pWebClient->getLastError().isEmpty()) {
updateStatus(m_pWebClient->getLastError());
m_Finished = true;
@ -48,15 +54,73 @@ void PluginWizardPage::queryPluginDone()
}
}
else {
updateStatus(plguinList.at(0));
downloadPlugins();
}
}
void PluginWizardPage::updateDownloadStatus()
{
QStringList pluginList = m_pWebClient->getPluginList();
int index = m_pPluginManager->downloadIndex();
updateStatus(
tr("Downloading plugin: %1 (%2/%3)")
.arg(pluginList.at(index + 1))
.arg(index + 2)
.arg(pluginList.size()));
}
void PluginWizardPage::finished()
{
updateStatus(tr("Plugins are ready."));
stopSpinning();
m_Finished = true;
emit completeChanged();
}
void PluginWizardPage::updateStatus(QString info)
{
m_pLabelStatus->setText(info);
}
void PluginWizardPage::downloadPlugins()
{
QStringList pluginList = m_pWebClient->getPluginList();
m_pPluginManager = new PluginManager(pluginList);
QThread* thread = new QThread;
connect(m_pPluginManager,
SIGNAL(downloadNext()),
this,
SLOT(updateDownloadStatus()));
connect(m_pPluginManager,
SIGNAL(downloadFinished()),
this,
SLOT(finished()));
connect(m_pPluginManager,
SIGNAL(downloadFinished()),
thread,
SLOT(quit()));
connect(thread,
SIGNAL(finished()),
thread,
SLOT(deleteLater()));
updateStatus(
tr("Downloading plugin: %1 (1/%2)")
.arg(pluginList.at(0))
.arg(pluginList.size()));
QMetaObject::invokeMethod(m_pPluginManager, "downloadPlugins", Qt::QueuedConnection);
}
void PluginWizardPage::stopSpinning()
{
m_pLabelSpinning->hide();
}
bool PluginWizardPage::isComplete() const
{
return m_Finished;
@ -69,13 +133,15 @@ void PluginWizardPage::initializePage()
if (m_Email.isEmpty() ||
m_Password.isEmpty()) {
updateStatus("No plugin available.");
//TODO: stop spinning icon
stopSpinning();
m_Finished = true;
emit completeChanged();
return;
}
m_pLabelSpinning->show();
m_pWebClient = new WebClient();
m_pWebClient->setEmail(m_Email);
m_pWebClient->setPassword(m_Password);
@ -86,7 +152,11 @@ void PluginWizardPage::initializePage()
this,
SLOT(queryPluginDone()));
connect(m_pWebClient, SIGNAL(queryPluginDone()), thread, SLOT(quit()));
connect(m_pWebClient,
SIGNAL(queryPluginDone()),
thread,
SLOT(quit()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
m_pWebClient->moveToThread(thread);

View File

@ -5,6 +5,7 @@
#include <QWizardPage>
class WebClient;
class PluginManager;
class PluginWizardPage : public QWizardPage, public Ui::PluginWizardPage {
@ -26,14 +27,19 @@ protected:
protected slots:
void queryPluginDone();
void updateDownloadStatus();
void finished();
private:
void updateStatus(QString info);
void downloadPlugins();
void stopSpinning();
private:
bool m_Finished;
WebClient* m_pWebClient;
QString m_Email;
QString m_Password;
WebClient* m_pWebClient;
PluginManager* m_pPluginManager;
};
#endif // PLUGINWIZARDPAGE_H

View File

@ -0,0 +1,30 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2015 Synergy Si Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESSORARCH_H
#define PROCESSORARCH_H
enum qProcessorArch {
Win_x86,
Win_x64,
Mac_i386,
Linux_i686,
Linux_x86_64,
unknown
};
#endif // PROCESSORARCH_H

View File

@ -17,6 +17,23 @@
#include "QUtility.h"
#include "ProcessorArch.h"
#if defined(Q_OS_LINUX)
#include <QProcess>
#endif
#if defined(Q_OS_WIN)
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
#if defined(Q_OS_LINUX)
static const char kLinuxI686[] = "i686";
static const char kLinuxX8664[] = "x86_64";
#endif
void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData)
{
for (int i = 0; i < comboBox->count(); ++i)
@ -49,3 +66,59 @@ QString getFirstMacAddress()
}
return mac;
}
int checkProcessorArch()
{
#if defined(Q_OS_WIN)
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
switch (systemInfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_INTEL:
return Win_x86;
case PROCESSOR_ARCHITECTURE_IA64:
return Win_x64;
case PROCESSOR_ARCHITECTURE_AMD64:
return Win_x64;
default:
return unknown;
}
#elif defined(Q_OS_MAC)
return Mac_i386;
#else
QString program("uname");
QStringList args("-m");
QProcess process;
process.setReadChannel(QProcess::StandardOutput);
process.start(program, args);
bool success = process.waitForStarted();
QString out, error;
if (success)
{
if (process.waitForFinished()) {
out = process.readAllStandardOutput();
error = process.readAllStandardError();
}
}
out = out.trimmed();
error = error.trimmed();
if (out.isEmpty() ||
!error.isEmpty() ||
!success ||
process.exitCode() != 0)
{
return unknown;
}
if (out == kLinuxI686) {
return Linux_i686;
}
else if (out == kLinuxX8664) {
return Linux_x86_64;
}
#endif
return unknown;
}

View File

@ -25,3 +25,4 @@
void setIndexFromItemData(QComboBox* comboBox, const QVariant& itemData);
QString hash(const QString& string);
QString getFirstMacAddress();
int checkProcessorArch();

View File

@ -62,6 +62,12 @@ public:
*/
virtual std::string getLogDirectory() = 0;
//! Get plugins directory
/*!
Returns the plugin files directory.
*/
virtual std::string getPluginDirectory() = 0;
//! Concatenate path components
/*!
Concatenate pathname components with a directory separator

View File

@ -104,6 +104,16 @@ ArchFileUnix::getLogDirectory()
return "/var/log";
}
std::string
ArchFileUnix::getPluginDirectory()
{
#if WINAPI_XWINDOWS
return getUserDirectory().append("/.synergy/plugins");
#else
return getUserDirectory().append("/Libraries/Synergy/Plugins");
#endif
}
std::string
ArchFileUnix::concatPath(const std::string& prefix,
const std::string& suffix)

View File

@ -34,6 +34,7 @@ public:
virtual std::string getSystemDirectory();
virtual std::string getInstalledDirectory();
virtual std::string getLogDirectory();
virtual std::string getPluginDirectory();
virtual std::string concatPath(const std::string& prefix,
const std::string& suffix);
};

View File

@ -139,6 +139,14 @@ ArchFileWindows::getLogDirectory()
return getInstalledDirectory();
}
std::string
ArchFileWindows::getPluginDirectory()
{
std::string dir = getUserDirectory();
dir.append("\\Synergy\\Plugins");
return dir;
}
std::string
ArchFileWindows::concatPath(const std::string& prefix,
const std::string& suffix)

View File

@ -34,6 +34,7 @@ public:
virtual std::string getSystemDirectory();
virtual std::string getInstalledDirectory();
virtual std::string getLogDirectory();
virtual std::string getPluginDirectory();
virtual std::string concatPath(const std::string& prefix,
const std::string& suffix);
};

View File

@ -173,6 +173,10 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
args.m_getPluginList = true;
return true;
}
if (isArg(i, argc, argv, NULL, "--get-plugin-dir", 0)) {
args.m_getPluginDir = true;
return true;
}
else {
return false;
}

View File

@ -73,6 +73,9 @@ ToolApp::run(int argc, char** argv)
else if (m_args.m_getPluginList) {
getPluginList();
}
else if (m_args.m_getPluginDir) {
std::cout << ARCH->getPluginDirectory() << std::endl;
}
else {
throw XSynergy("Nothing to do");
}

View File

@ -20,6 +20,7 @@
ToolArgs::ToolArgs() :
m_printActiveDesktopName(false),
m_loginAuthenticate(false),
m_getPluginList(false)
m_getPluginList(false),
m_getPluginDir(false)
{
}

View File

@ -27,4 +27,5 @@ public:
bool m_printActiveDesktopName;
bool m_loginAuthenticate;
bool m_getPluginList;
bool m_getPluginDir;
};