syncthingtray/tray/application/main.cpp

187 lines
6.9 KiB
C++
Raw Normal View History

#include "./singleinstance.h"
2016-09-01 16:34:30 +02:00
#include "../gui/trayicon.h"
#include "../gui/traywidget.h"
#include "../../widgets/settings/settings.h"
#include "../../connector/syncthingprocess.h"
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
2017-05-01 03:34:43 +02:00
#include "../../connector/syncthingservice.h"
#endif
2016-09-01 16:34:30 +02:00
#include "resources/config.h"
#include <c++utilities/application/argumentparser.h>
#include <c++utilities/application/commandlineutils.h>
#include <c++utilities/application/failure.h>
2017-05-01 03:34:43 +02:00
#include <qtutilities/resources/importplugin.h>
2016-09-01 16:34:30 +02:00
#include <qtutilities/resources/qtconfigarguments.h>
#include <qtutilities/resources/resources.h>
#include <qtutilities/settingsdialog/qtsettings.h>
#include <QApplication>
#include <QMessageBox>
2017-05-01 03:34:43 +02:00
#include <QNetworkAccessManager>
#include <QStringBuilder>
2016-09-01 16:34:30 +02:00
#include <iostream>
using namespace std;
using namespace ApplicationUtilities;
using namespace QtGui;
2016-09-03 19:39:43 +02:00
using namespace Data;
2016-09-01 16:34:30 +02:00
ENABLE_QT_RESOURCES_OF_STATIC_DEPENDENCIES
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
void handleSystemdServiceError(const QString &context, const QString &name, const QString &message)
{
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(QCoreApplication::translate("main", "Unable to ") + context);
msgBox.setInformativeText(name % QStringLiteral(":\n") % message);
msgBox.exec();
}
#endif
int initSyncthingTray(bool windowed, bool waitForTray)
2016-09-01 16:34:30 +02:00
{
2016-11-02 20:03:38 +01:00
auto &v = Settings::values();
#ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD
SyncthingService &service = syncthingService();
service.setUnitName(v.systemd.syncthingUnit);
QObject::connect(&service, &SyncthingService::errorOccurred, &handleSystemdServiceError);
#endif
2017-05-01 03:34:43 +02:00
if (windowed) {
v.launcher.autostart();
auto *trayWidget = new TrayWidget;
trayWidget->setAttribute(Qt::WA_DeleteOnClose);
trayWidget->show();
} else {
#ifndef QT_NO_SYSTEMTRAYICON
2017-05-01 03:34:43 +02:00
if (QSystemTrayIcon::isSystemTrayAvailable() || waitForTray) {
v.launcher.autostart();
auto *trayIcon = new TrayIcon;
trayIcon->show();
2017-05-01 03:34:43 +02:00
if (v.firstLaunch) {
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Information);
2017-05-01 03:34:43 +02:00
msgBox.setText(
QCoreApplication::translate("main", "You must configure how to connect to Syncthing when using Syncthing Tray the first time."));
msgBox.setInformativeText(QCoreApplication::translate(
"main", "Note that the settings dialog allows importing URL, credentials and API-key from the local Syncthing configuration."));
msgBox.exec();
trayIcon->trayMenu().widget()->showSettingsDialog();
}
} else {
2017-05-01 03:34:43 +02:00
QMessageBox::critical(nullptr, QApplication::applicationName(),
QApplication::translate("main",
"The system tray is (currently) not available. You could open the tray menu as a regular window using the -w flag, though."));
return -1;
}
#else
2017-05-01 03:34:43 +02:00
QMessageBox::critical(nullptr, QApplication::applicationName(),
QApplication::translate("main", "The Qt libraries have not been built with tray icon support. You could open the tray menu as a regular "
"window using the -w flag, though."));
return -2;
#endif
}
return 0;
}
2016-12-26 19:50:10 +01:00
void trigger(bool tray, bool webUi)
{
2017-05-01 03:34:43 +02:00
if (!TrayWidget::instances().empty() && (tray || webUi)) {
2016-12-26 19:50:10 +01:00
TrayWidget *trayWidget = TrayWidget::instances().front();
2017-05-01 03:34:43 +02:00
if (webUi) {
2016-12-26 19:50:10 +01:00
trayWidget->showWebUi();
}
2017-05-01 03:34:43 +02:00
if (tray) {
2016-12-26 19:50:10 +01:00
trayWidget->showAtCursor();
}
}
}
int runApplication(int argc, const char *const *argv)
{
static bool firstRun = true;
2016-09-01 16:34:30 +02:00
// setup argument parser
SET_APPLICATION_INFO;
2017-01-02 23:25:58 +01:00
CMD_UTILS_CONVERT_ARGS_TO_UTF8;
2016-09-01 16:34:30 +02:00
ArgumentParser parser;
HelpArgument helpArg(parser);
// Qt configuration arguments
QT_CONFIG_ARGUMENTS qtConfigArgs;
Argument windowedArg("windowed", 'w', "opens the tray menu as a regular window");
windowedArg.setCombinable(true);
2016-12-26 19:50:10 +01:00
Argument showWebUiArg("webui", '\0', "instantly shows the web UI - meant for creating shortcut to web UI");
showWebUiArg.setCombinable(true);
Argument triggerArg("trigger", '\0', "instantly shows the left-click tray menu - meant for creating a shortcut");
triggerArg.setCombinable(true);
2017-05-01 03:34:43 +02:00
Argument waitForTrayArg("wait", '\0',
"wait until the system tray becomes available instead of showing an error message if the system tray is not available on start-up");
waitForTrayArg.setCombinable(true);
2016-12-26 19:50:10 +01:00
Argument &widgetsGuiArg = qtConfigArgs.qtWidgetsGuiArg();
widgetsGuiArg.addSubArgument(&windowedArg);
widgetsGuiArg.addSubArgument(&showWebUiArg);
widgetsGuiArg.addSubArgument(&triggerArg);
widgetsGuiArg.addSubArgument(&waitForTrayArg);
2017-05-01 03:34:43 +02:00
parser.setMainArguments({ &qtConfigArgs.qtWidgetsGuiArg(), &helpArg });
2016-09-01 16:34:30 +02:00
try {
parser.parseArgs(argc, argv);
2017-05-01 03:34:43 +02:00
if (qtConfigArgs.qtWidgetsGuiArg().isPresent()) {
if (firstRun) {
firstRun = false;
SET_QT_APPLICATION_INFO;
QApplication application(argc, const_cast<char **>(argv));
QGuiApplication::setQuitOnLastWindowClosed(false);
SingleInstance singleInstance(argc, argv);
2016-10-02 21:59:28 +02:00
networkAccessManager().setParent(&singleInstance);
QObject::connect(&singleInstance, &SingleInstance::newInstance, &runApplication);
Settings::restore();
2016-11-02 20:03:38 +01:00
Settings::values().qt.apply();
qtConfigArgs.applySettings(true);
LOAD_QT_TRANSLATIONS;
int res = initSyncthingTray(windowedArg.isPresent(), waitForTrayArg.isPresent());
2017-05-01 03:34:43 +02:00
if (!res) {
2016-12-26 19:50:10 +01:00
trigger(triggerArg.isPresent(), showWebUiArg.isPresent());
2016-09-01 16:34:30 +02:00
res = application.exec();
}
Settings::Launcher::terminate();
Settings::save();
return res;
} else {
2017-05-01 03:34:43 +02:00
if (!TrayWidget::instances().empty() && (showWebUiArg.isPresent() || triggerArg.isPresent())) {
2016-12-26 19:50:10 +01:00
// if --webui or --trigger is present don't create a new tray icon, just trigger actions
trigger(triggerArg.isPresent(), showWebUiArg.isPresent());
2016-09-01 16:34:30 +02:00
} else {
2016-12-26 19:50:10 +01:00
const int res = initSyncthingTray(windowedArg.isPresent(), waitForTrayArg.isPresent());
2017-05-01 03:34:43 +02:00
if (!res) {
2016-12-26 19:50:10 +01:00
trigger(triggerArg.isPresent(), showWebUiArg.isPresent());
}
return res;
2016-09-01 16:34:30 +02:00
}
}
}
2017-05-01 03:34:43 +02:00
} catch (const Failure &ex) {
2016-09-01 16:34:30 +02:00
CMD_UTILS_START_CONSOLE;
2016-10-02 21:59:28 +02:00
cerr << "Unable to parse arguments. " << ex.what() << "\nSee --help for available commands." << endl;
return 1;
2016-09-01 16:34:30 +02:00
}
return 0;
}
int main(int argc, char *argv[])
{
return runApplication(argc, argv);
}