diff --git a/README.md b/README.md index 7e5ec69..10569ff 100644 --- a/README.md +++ b/README.md @@ -70,12 +70,14 @@ The application depends on [c++utilities](https://github.com/Martchus/cpp-utilit The following Qt 5 modules are requried: core network gui widgets svg webenginewidgets/webkitwidgets -#### Select Qt modules for WebView +#### Select Qt module for WebView * If Qt WebKitWidgets is installed on the system, the tray will link against it. Otherwise it will link against Qt WebEngineWidgets. * To force usage of Qt WebKit/Qt WebEngine or to disable both add `-DWEBVIEW_PROVIDER=webkit/webengine/none` to the CMake arguments. -BTW: I still prefer the deprecated Qt WebKit because -* I currently don't know how to allow a particular self-signed certificate in Qt WebEngine. Currently any self-signed certificate is accepted! +#### BTW: I still prefer the deprecated Qt WebKit because +* Currently there is no way to allow a particular self-signed certificate in Qt + WebEngine. Currently any self-signed certificate is accepted! See: + https://bugreports.qt.io/browse/QTBUG-51176) * Qt WebEngine can not be built with mingw-w64. * Qt WebEngine is more buggy in my experience. * Security issues are not a concern because no other website than the Syncthing web UI is shown. diff --git a/application/settings.cpp b/application/settings.cpp index 2f49d8a..b8a4ec8 100644 --- a/application/settings.cpp +++ b/application/settings.cpp @@ -154,6 +154,8 @@ void restore() connectionSettings->userName = settings.value(QStringLiteral("userName")).toString(); connectionSettings->password = settings.value(QStringLiteral("password")).toString(); connectionSettings->apiKey = settings.value(QStringLiteral("apiKey")).toByteArray(); + connectionSettings->trafficPollInterval = settings.value(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval).toInt(); + connectionSettings->devStatsPollInterval = settings.value(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval).toInt(); connectionSettings->httpsCertPath = settings.value(QStringLiteral("httpsCertPath")).toString(); if(!connectionSettings->loadHttpsCert()) { QMessageBox::critical(nullptr, QCoreApplication::applicationName(), QCoreApplication::translate("Settings::restore", "Unable to load certificate \"%1\" when restoring settings.").arg(connectionSettings->httpsCertPath)); @@ -208,6 +210,8 @@ void save() settings.setValue(QStringLiteral("userName"), connectionSettings->userName); settings.setValue(QStringLiteral("password"), connectionSettings->password); settings.setValue(QStringLiteral("apiKey"), connectionSettings->apiKey); + settings.setValue(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval); + settings.setValue(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval); settings.setValue(QStringLiteral("httpsCertPath"), connectionSettings->httpsCertPath); } settings.endArray(); diff --git a/application/settings.h b/application/settings.h index 6cfc417..dbd0b1d 100644 --- a/application/settings.h +++ b/application/settings.h @@ -32,6 +32,8 @@ struct ConnectionSettings { QString userName; QString password; QByteArray apiKey; + int trafficPollInterval = 2000; + int devStatsPollInterval = 60000; QString httpsCertPath; QList expectedSslErrors; bool loadHttpsCert(); diff --git a/application/singleinstance.cpp b/application/singleinstance.cpp index 4375853..e06b4a4 100644 --- a/application/singleinstance.cpp +++ b/application/singleinstance.cpp @@ -77,7 +77,7 @@ void SingleInstance::readArgs() socket->close(); socket->deleteLater(); - // reconstruct argc argv array + // reconstruct argc and argv array uint16 argc = BE::toUInt16(argData.get()); vector args; args.reserve(argc + 1); @@ -91,7 +91,7 @@ void SingleInstance::readArgs() } args.push_back(nullptr); - emit newInstance(static_cast(argc), args.data()); + emit newInstance(static_cast(args.size() - 1), args.data()); } } diff --git a/data/syncthingconnection.cpp b/data/syncthingconnection.cpp index 0b00573..a48f6c8 100644 --- a/data/syncthingconnection.cpp +++ b/data/syncthingconnection.cpp @@ -137,6 +137,8 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt m_keepPolling(false), m_reconnecting(false), m_lastEventId(0), + m_trafficPollInterval(2000), + m_devStatsPollInterval(60000), m_totalIncomingTraffic(0), m_totalOutgoingTraffic(0), m_totalIncomingRate(0), @@ -237,6 +239,8 @@ void SyncthingConnection::reconnect(Settings::ConnectionSettings &connectionSett } else { setCredentials(QString(), QString()); } + setTrafficPollInterval(connectionSettings.trafficPollInterval); + setDevStatsPollInterval(connectionSettings.devStatsPollInterval); loadSelfSignedCertificate(); if(connectionSettings.expectedSslErrors.isEmpty()) { connectionSettings.expectedSslErrors = expectedSslErrors(); @@ -794,9 +798,9 @@ void SyncthingConnection::readConnections() m_lastConnectionsUpdate = DateTime::gmtNow(); - // since there seems no event for this data, just request every 2 seconds, FIXME: make interval configurable + // since there seems no event for this data, just request every 2 seconds if(m_keepPolling) { - QTimer::singleShot(2000, Qt::VeryCoarseTimer, this, SLOT(requestConnections())); + QTimer::singleShot(m_trafficPollInterval, Qt::VeryCoarseTimer, this, &SyncthingConnection::requestConnections); } } else { emit error(tr("Unable to parse connections: ") + jsonError.errorString()); @@ -900,7 +904,7 @@ void SyncthingConnection::readDeviceStatistics() } // since there seems no event for this data, just request every minute, FIXME: make interval configurable if(m_keepPolling) { - QTimer::singleShot(60000, Qt::VeryCoarseTimer, this, SLOT(requestConnections())); + QTimer::singleShot(m_devStatsPollInterval, Qt::VeryCoarseTimer, this, SLOT(requestConnections())); } } else { emit error(tr("Unable to parse device statistics: ") + jsonError.errorString()); @@ -1153,7 +1157,7 @@ void SyncthingConnection::readDirEvent(DateTime eventTime, const QString &eventT dirInfo->progressPercentage = percentage; } } else if(eventType == QLatin1String("FolderScanProgress")) { - // FIXME: for some reason current is always 0 + // FIXME: for some reason this is always 0 int current = eventData.value(QStringLiteral("current")).toInt(0), total = eventData.value(QStringLiteral("total")).toInt(0), rate = eventData.value(QStringLiteral("rate")).toInt(0); @@ -1193,7 +1197,8 @@ void SyncthingConnection::readDeviceEvent(DateTime eventTime, const QString &eve status = DevStatus::Rejected; } else if(eventType == QLatin1String("DeviceResumed")) { paused = false; - status = DevStatus::Disconnected; // FIXME: correct to assume device which has just been resumed is still disconnected? + // FIXME: correct to assume device which has just been resumed is still disconnected? + status = DevStatus::Disconnected; } else if(eventType == QLatin1String("DeviceDiscovered")) { // we know about this device already, set status anyways because it might still be unknown status = DevStatus::Disconnected; @@ -1243,7 +1248,8 @@ void SyncthingConnection::readItemFinished(DateTime eventTime, const QJsonObject } emit dirStatusChanged(*dirInfo, index); } - } else if(dirInfo->status == DirStatus::OutOfSync) { // FIXME: find better way to check whether the event is still relevant + } else if(dirInfo->status == DirStatus::OutOfSync) { + // FIXME: find better way to check whether the event is still relevant dirInfo->errors.emplace_back(error, item); emitNotification(eventTime, error); } diff --git a/data/syncthingconnection.h b/data/syncthingconnection.h index ff09e18..742402f 100644 --- a/data/syncthingconnection.h +++ b/data/syncthingconnection.h @@ -156,10 +156,14 @@ class SyncthingConnection : public QObject Q_PROPERTY(QString syncthingUrl READ syncthingUrl WRITE setSyncthingUrl) Q_PROPERTY(QByteArray apiKey READ apiKey WRITE setApiKey) Q_PROPERTY(SyncthingStatus status READ status NOTIFY statusChanged) + Q_PROPERTY(int trafficPollInterval READ trafficPollInterval WRITE setTrafficPollInterval) + Q_PROPERTY(int devStatsPollInterval READ devStatsPollInterval WRITE setDevStatsPollInterval) Q_PROPERTY(QString configDir READ configDir NOTIFY configDirChanged) Q_PROPERTY(QString myId READ myId NOTIFY myIdChanged) Q_PROPERTY(int totalIncomingTraffic READ totalIncomingTraffic NOTIFY trafficChanged) Q_PROPERTY(int totalOutgoingTraffic READ totalOutgoingTraffic NOTIFY trafficChanged) + Q_PROPERTY(double totalIncomingRate READ totalIncomingRate NOTIFY trafficChanged) + Q_PROPERTY(double totalOutgoingRate READ totalOutgoingRate NOTIFY trafficChanged) public: explicit SyncthingConnection(const QString &syncthingUrl = QStringLiteral("http://localhost:8080"), const QByteArray &apiKey = QByteArray(), QObject *parent = nullptr); @@ -175,6 +179,10 @@ public: SyncthingStatus status() const; QString statusText() const; bool isConnected() const; + int trafficPollInterval() const; + void setTrafficPollInterval(int trafficPollInterval); + int devStatsPollInterval() const; + void setDevStatsPollInterval(int devStatsPollInterval); const QString &configDir() const; const QString &myId() const; int totalIncomingTraffic() const; @@ -325,6 +333,8 @@ private: bool m_keepPolling; bool m_reconnecting; int m_lastEventId; + int m_trafficPollInterval; + int m_devStatsPollInterval; QString m_configDir; QString m_myId; int m_totalIncomingTraffic; @@ -421,6 +431,42 @@ inline bool SyncthingConnection::isConnected() const return m_status != SyncthingStatus::Disconnected && m_status != SyncthingStatus::Reconnecting; } +/*! + * \brief Returns the interval for polling traffic status (which currently can not be received via event API) in milliseconds. + * \remarks Default value is 2000 milliseconds. + */ +inline int SyncthingConnection::trafficPollInterval() const +{ + return m_trafficPollInterval; +} + +/*! + * \brief Sets the interval for polling traffic status (which currently can not be received via event API) in milliseconds. + * \remarks Default value is 2000 milliseconds. + */ +inline void SyncthingConnection::setTrafficPollInterval(int trafficPollInterval) +{ + m_trafficPollInterval = trafficPollInterval; +} + +/*! + * \brief Returns the interval for polling device statistics (which currently can not be received via event API) in milliseconds. + * \remarks Default value is 60000 milliseconds. + */ +inline int SyncthingConnection::devStatsPollInterval() const +{ + return m_devStatsPollInterval; +} + +/*! + * \brief Sets the interval for polling device statistics (which currently can not be received via event API) in milliseconds. + * \remarks Default value is 60000 milliseconds. + */ +inline void SyncthingConnection::setDevStatsPollInterval(int devStatsPollInterval) +{ + m_devStatsPollInterval = devStatsPollInterval; +} + /*! * \brief Returns the Syncthing home/configuration directory. */ diff --git a/gui/connectionoptionpage.ui b/gui/connectionoptionpage.ui index 5a35864..c865545 100644 --- a/gui/connectionoptionpage.ui +++ b/gui/connectionoptionpage.ui @@ -10,6 +10,9 @@ .. + + 4 + @@ -97,6 +100,41 @@ + + + + + 0 + 0 + + + + + 16777215 + 42 + + + + It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. + + + true + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + @@ -164,6 +202,23 @@ + + + + HTTPS certificate + + + + + + + + 0 + 0 + + + + @@ -191,21 +246,21 @@ - + Status - + disconnected - + Apply connection settings and try to reconnect with the currently selected config @@ -216,57 +271,69 @@ - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - - 16777215 - 42 - - + + - It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. + Poll interval - - true + + 1 - - - - HTTPS certificate + + + + 10 - - - - - - - 0 - 0 - - - + + + + Traffic + + + + + + + ms + + + 100 + + + 999999999 + + + + + + + Qt::Vertical + + + + + + + Device statistics + + + + + + + ms + + + 100 + + + 999999999 + + + + diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index 3b60a8d..ebc953d 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -117,6 +117,8 @@ bool ConnectionOptionPage::showConnectionSettings(int index) ui()->passwordLineEdit->setText(connectionSettings.password); ui()->apiKeyLineEdit->setText(connectionSettings.apiKey); ui()->certPathSelection->lineEdit()->setText(connectionSettings.httpsCertPath); + ui()->pollTrafficSpinBox->setValue(connectionSettings.trafficPollInterval); + ui()->pollDevStatsSpinBox->setValue(connectionSettings.devStatsPollInterval); m_currentIndex = index; } else { ui()->selectionComboBox->setCurrentIndex(m_currentIndex); @@ -139,6 +141,8 @@ bool ConnectionOptionPage::cacheCurrentSettings(bool applying) connectionSettings.apiKey = ui()->apiKeyLineEdit->text().toUtf8(); connectionSettings.expectedSslErrors.clear(); connectionSettings.httpsCertPath = ui()->certPathSelection->lineEdit()->text(); + connectionSettings.trafficPollInterval = ui()->pollTrafficSpinBox->value(); + connectionSettings.devStatsPollInterval = ui()->pollDevStatsSpinBox->value(); if(!connectionSettings.loadHttpsCert()) { const QString errorMessage = QCoreApplication::translate("QtGui::ConnectionOptionPage", "Unable to load specified certificate \"%1\".").arg(connectionSettings.httpsCertPath); if(!applying) { diff --git a/gui/traymenu.cpp b/gui/traymenu.cpp index bbb4019..53ff2f6 100644 --- a/gui/traymenu.cpp +++ b/gui/traymenu.cpp @@ -25,11 +25,6 @@ TrayMenu::TrayMenu(QWidget *parent) : setPlatformMenu(nullptr); } -TrayMenu::~TrayMenu() -{ - -} - QSize TrayMenu::sizeHint() const { return Settings::trayMenuSize(); diff --git a/gui/traymenu.h b/gui/traymenu.h index 8f126d3..c041782 100644 --- a/gui/traymenu.h +++ b/gui/traymenu.h @@ -15,7 +15,6 @@ class TrayMenu : public QMenu public: TrayMenu(TrayIcon *trayIcon, QWidget *parent = nullptr); TrayMenu(QWidget *parent = nullptr); - ~TrayMenu(); QSize sizeHint() const; TrayWidget *widget(); diff --git a/gui/traywidget.cpp b/gui/traywidget.cpp index 60a701e..eb46888 100644 --- a/gui/traywidget.cpp +++ b/gui/traywidget.cpp @@ -40,6 +40,8 @@ using namespace std; namespace QtGui { +SettingsDialog *TrayWidget::m_settingsDlg = nullptr; +Dialogs::AboutDialog *TrayWidget::m_aboutDlg = nullptr; vector TrayWidget::m_instances; /*! @@ -49,8 +51,6 @@ TrayWidget::TrayWidget(TrayMenu *parent) : QWidget(parent), m_menu(parent), m_ui(new Ui::TrayWidget), - m_settingsDlg(nullptr), - m_aboutDlg(nullptr), #ifndef SYNCTHINGTRAY_NO_WEBVIEW m_webViewDlg(nullptr), #endif @@ -146,7 +146,7 @@ void TrayWidget::showSettingsDialog() { if(!m_settingsDlg) { m_settingsDlg = new SettingsDialog(&m_connection, this); - connect(m_settingsDlg, &SettingsDialog::applied, this, &TrayWidget::applySettings); + connect(m_settingsDlg, &SettingsDialog::applied, &TrayWidget::applySettings); } centerWidget(m_settingsDlg); showDialog(m_settingsDlg); @@ -290,53 +290,56 @@ void TrayWidget::handleStatusChanged(SyncthingStatus status) void TrayWidget::applySettings() { - // update connections menu - int connectionIndex = 0; - const int connectionCount = static_cast(1 + Settings::secondaryConnectionSettings().size()); - const QList connectionActions = m_connectionsActionGroup->actions(); - m_selectedConnection = nullptr; - for(; connectionIndex < connectionCount; ++connectionIndex) { - Settings::ConnectionSettings &connectionSettings = (connectionIndex == 0 ? Settings::primaryConnectionSettings() : Settings::secondaryConnectionSettings()[static_cast(connectionIndex - 1)]); - if(connectionIndex < connectionActions.size()) { - QAction *action = connectionActions.at(connectionIndex); - action->setText(connectionSettings.label); - if(action->isChecked()) { - m_selectedConnection = &connectionSettings; + for(TrayWidget *instance : m_instances) { + // update connections menu + int connectionIndex = 0; + const int connectionCount = static_cast(1 + Settings::secondaryConnectionSettings().size()); + const QList connectionActions = instance->m_connectionsActionGroup->actions(); + instance->m_selectedConnection = nullptr; + for(; connectionIndex < connectionCount; ++connectionIndex) { + Settings::ConnectionSettings &connectionSettings = (connectionIndex == 0 ? Settings::primaryConnectionSettings() : Settings::secondaryConnectionSettings()[static_cast(connectionIndex - 1)]); + if(connectionIndex < connectionActions.size()) { + QAction *action = connectionActions.at(connectionIndex); + action->setText(connectionSettings.label); + if(action->isChecked()) { + instance->m_selectedConnection = &connectionSettings; + } + } else { + QAction *action = instance->m_connectionsMenu->addAction(connectionSettings.label); + action->setCheckable(true); + instance->m_connectionsActionGroup->addAction(action); } - } else { - QAction *action = m_connectionsMenu->addAction(connectionSettings.label); - action->setCheckable(true); - m_connectionsActionGroup->addAction(action); } - } - for(; connectionIndex < connectionActions.size(); ++connectionIndex) { - m_connectionsActionGroup->removeAction(connectionActions.at(connectionIndex)); - } - if(!m_selectedConnection) { - m_selectedConnection = &Settings::primaryConnectionSettings(); - m_connectionsMenu->actions().at(0)->setChecked(true); - } + for(; connectionIndex < connectionActions.size(); ++connectionIndex) { + delete connectionActions.at(connectionIndex); + } + if(!instance->m_selectedConnection) { + instance->m_selectedConnection = &Settings::primaryConnectionSettings(); + instance->m_connectionsMenu->actions().at(0)->setChecked(true); + instance->m_ui->connectionsPushButton->setText(instance->m_selectedConnection->label); + } - m_connection.reconnect(*m_selectedConnection); + instance->m_connection.reconnect(*instance->m_selectedConnection); - // web view + // web view #ifndef SYNCTHINGTRAY_NO_WEBVIEW - if(m_webViewDlg) { - m_webViewDlg->applySettings(*m_selectedConnection); - } + if(instance->m_webViewDlg) { + instance->m_webViewDlg->applySettings(*instance->m_selectedConnection); + } #endif - // update visual appearance - m_ui->trafficFormWidget->setVisible(Settings::showTraffic()); - if(Settings::showTraffic()) { - updateTraffic(); - } - m_ui->infoFrame->setFrameStyle(Settings::frameStyle()); - m_ui->buttonsFrame->setFrameStyle(Settings::frameStyle()); - if(QApplication::style() && !QApplication::style()->objectName().compare(QLatin1String("adwaita"), Qt::CaseInsensitive)) { - m_cornerFrame->setFrameStyle(QFrame::NoFrame); - } else { - m_cornerFrame->setFrameStyle(Settings::frameStyle()); + // update visual appearance + instance->m_ui->trafficFormWidget->setVisible(Settings::showTraffic()); + if(Settings::showTraffic()) { + instance->updateTraffic(); + } + instance->m_ui->infoFrame->setFrameStyle(Settings::frameStyle()); + instance->m_ui->buttonsFrame->setFrameStyle(Settings::frameStyle()); + if(QApplication::style() && !QApplication::style()->objectName().compare(QLatin1String("adwaita"), Qt::CaseInsensitive)) { + instance->m_cornerFrame->setFrameStyle(QFrame::NoFrame); + } else { + instance->m_cornerFrame->setFrameStyle(Settings::frameStyle()); + } } } diff --git a/gui/traywidget.h b/gui/traywidget.h index 3175091..a17200d 100644 --- a/gui/traywidget.h +++ b/gui/traywidget.h @@ -59,7 +59,7 @@ public slots: private slots: void handleStatusChanged(Data::SyncthingStatus status); - void applySettings(); + static void applySettings(); void openDir(const Data::SyncthingDir &dir); void openItemDir(const Data::SyncthingItemDownloadProgress &item); void scanDir(const Data::SyncthingDir &dir); @@ -76,8 +76,8 @@ private slots: private: TrayMenu *m_menu; std::unique_ptr m_ui; - SettingsDialog *m_settingsDlg; - Dialogs::AboutDialog *m_aboutDlg; + static SettingsDialog *m_settingsDlg; + static Dialogs::AboutDialog *m_aboutDlg; #ifndef SYNCTHINGTRAY_NO_WEBVIEW WebViewDialog *m_webViewDlg; #endif diff --git a/translations/syncthingtray_de_DE.ts b/translations/syncthingtray_de_DE.ts index 72cd214..9eb8456 100644 --- a/translations/syncthingtray_de_DE.ts +++ b/translations/syncthingtray_de_DE.ts @@ -4,145 +4,145 @@ Data::SyncthingConnection - + disconnected - + reconnecting - + connected - + connected, notifications available - + connected, paused - + connected, synchronizing - + unknown - - + + Connection configuration is insufficient. - + Unable to parse Syncthing log: - + Unable to request system log: - + Unable to locate certificate used by Syncthing GUI. - + Unable to load certificate used by Syncthing GUI. - - + + Unable to parse Syncthing config: - - + + Unable to request Syncthing config: - + Unable to parse connections: - + Unable to request connections: - + Unable to parse directory statistics: - + Unable to request directory statistics: - + Unable to parse device statistics: - + Unable to request device statistics: - + Unable to parse errors: - + Unable to request errors: - + Unable to parse Syncthing events: - + Unable to request Syncthing events: - + Unable to request rescan: - + Unable to request pause/resume: - + Unable to request restart: - + Unable to request QR-Code: @@ -478,22 +478,22 @@ - + This is achieved by adding a *.desktop file under <i>~/.config/autostart</i> so the setting only affects the current user. - + This is achieved by adding a registry key under <i>HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run</i> so the setting only affects the current user. Note that the startup entry is invalidated when moving <i>syncthingtray.exe</i>. - + This feature has not been implemented for your platform (yet). - + unable to modify startup entry @@ -506,72 +506,93 @@ - + Config label - + Add secondary instance - + Remove currently selected secondary instance - + Syncthing URL - + Authentication - + User - + disconnected - + + Poll interval + + + + + + ms + + + + Apply connection settings and try to reconnect with the currently selected config - + + Traffic + + + + + Device statistics + + + + It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. - + HTTPS certificate - + Status - + API key - + Insert values from local Syncthing configuration - + Password @@ -591,12 +612,12 @@ - + Unable to load specified certificate "%1". - + Instance %1 @@ -698,13 +719,13 @@ - + Syncthing existed with exit code %1 - + Syncthing crashed with exit code %1 @@ -746,22 +767,22 @@ QtGui::SettingsDialog - + Tray - + Startup - + Settings - + Web view @@ -896,7 +917,7 @@ For <i>all</i> notifications, checkout the log - + unknown @@ -998,12 +1019,12 @@ For <i>all</i> notifications, checkout the log - + The directory <i>%1</i> does not exist on the local machine. - + The file <i>%1</i> does not exist on the local machine. @@ -1035,7 +1056,7 @@ For <i>all</i> notifications, checkout the log QtGui::WebViewOptionPage - + General @@ -1065,7 +1086,7 @@ For <i>all</i> notifications, checkout the log - + Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine. The Web UI will be opened in the default web browser instead. @@ -1074,7 +1095,7 @@ The Web UI will be opened in the default web browser instead. Settings::restore - + Unable to load certificate "%1" when restoring settings. diff --git a/translations/syncthingtray_en_US.ts b/translations/syncthingtray_en_US.ts index ee5ef36..55be337 100644 --- a/translations/syncthingtray_en_US.ts +++ b/translations/syncthingtray_en_US.ts @@ -4,145 +4,145 @@ Data::SyncthingConnection - + disconnected - + reconnecting - + connected - + connected, notifications available - + connected, paused - + connected, synchronizing - + unknown - - + + Connection configuration is insufficient. - + Unable to parse Syncthing log: - + Unable to request system log: - + Unable to locate certificate used by Syncthing GUI. - + Unable to load certificate used by Syncthing GUI. - - + + Unable to parse Syncthing config: - - + + Unable to request Syncthing config: - + Unable to parse connections: - + Unable to request connections: - + Unable to parse directory statistics: - + Unable to request directory statistics: - + Unable to parse device statistics: - + Unable to request device statistics: - + Unable to parse errors: - + Unable to request errors: - + Unable to parse Syncthing events: - + Unable to request Syncthing events: - + Unable to request rescan: - + Unable to request pause/resume: - + Unable to request restart: - + Unable to request QR-Code: @@ -478,22 +478,22 @@ - + This is achieved by adding a *.desktop file under <i>~/.config/autostart</i> so the setting only affects the current user. - + This is achieved by adding a registry key under <i>HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run</i> so the setting only affects the current user. Note that the startup entry is invalidated when moving <i>syncthingtray.exe</i>. - + This feature has not been implemented for your platform (yet). - + unable to modify startup entry @@ -506,72 +506,93 @@ - + Config label - + Add secondary instance - + Remove currently selected secondary instance - + Syncthing URL - + Authentication - + User - + disconnected - + + Poll interval + + + + + + ms + + + + Apply connection settings and try to reconnect with the currently selected config - + + Traffic + + + + + Device statistics + + + + It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. - + HTTPS certificate - + Status - + API key - + Insert values from local Syncthing configuration - + Password @@ -591,12 +612,12 @@ - + Unable to load specified certificate "%1". - + Instance %1 @@ -698,13 +719,13 @@ - + Syncthing existed with exit code %1 - + Syncthing crashed with exit code %1 @@ -746,22 +767,22 @@ QtGui::SettingsDialog - + Tray - + Startup - + Settings - + Web view @@ -896,7 +917,7 @@ For <i>all</i> notifications, checkout the log - + unknown @@ -998,12 +1019,12 @@ For <i>all</i> notifications, checkout the log - + The directory <i>%1</i> does not exist on the local machine. - + The file <i>%1</i> does not exist on the local machine. @@ -1035,7 +1056,7 @@ For <i>all</i> notifications, checkout the log QtGui::WebViewOptionPage - + General @@ -1065,7 +1086,7 @@ For <i>all</i> notifications, checkout the log - + Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine. The Web UI will be opened in the default web browser instead. @@ -1074,7 +1095,7 @@ The Web UI will be opened in the default web browser instead. Settings::restore - + Unable to load certificate "%1" when restoring settings.