Improve Syncthing notification/error handling

This commit is contained in:
Martchus 2016-09-08 23:35:15 +02:00
parent 3d44174992
commit 7e2f3cc86e
12 changed files with 422 additions and 182 deletions

View File

@ -45,6 +45,7 @@ set(WIDGETS_HEADER_FILES
gui/devbuttonsitemdelegate.h
gui/dirview.h
gui/devview.h
gui/textviewdialog.h
)
set(WIDGETS_SRC_FILES
application/main.cpp
@ -59,6 +60,7 @@ set(WIDGETS_SRC_FILES
gui/devbuttonsitemdelegate.cpp
gui/dirview.cpp
gui/devview.cpp
gui/textviewdialog.cpp
resources/icons.qrc
)
set(WIDGETS_UI_FILES

View File

@ -122,6 +122,7 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt
m_configReply(nullptr),
m_statusReply(nullptr),
m_connectionsReply(nullptr),
m_errorsReply(nullptr),
m_eventsReply(nullptr),
m_unreadNotifications(false),
m_hasConfig(false),
@ -197,7 +198,7 @@ void SyncthingConnection::reconnect()
m_hasConfig = m_hasStatus = false;
abortAllRequests();
} else {
continueReconnect();
continueReconnecting();
}
}
@ -224,7 +225,7 @@ void SyncthingConnection::reconnect(Settings::ConnectionSettings &connectionSett
/*!
* \brief Internally called to reconnect; ensures currently cached config is cleared.
*/
void SyncthingConnection::continueReconnect()
void SyncthingConnection::continueReconnecting()
{
emit newConfig(QJsonObject()); // configuration will be invalidated
setStatus(SyncthingStatus::Reconnecting);
@ -244,6 +245,7 @@ void SyncthingConnection::continueReconnect()
m_devs.clear();
m_lastConnectionsUpdate = DateTime();
m_lastFileTime = DateTime();
m_lastErrorTime = DateTime();
m_lastFileName.clear();
m_lastFileDeleted = false;
if(m_apiKey.isEmpty() || m_syncthingUrl.isEmpty()) {
@ -380,6 +382,7 @@ void SyncthingConnection::continueConnecting()
requestConnections();
requestDirStatistics();
requestDeviceStatistics();
requestErrors();
// since config and status could be read successfully, let's poll for events
m_lastEventId = 0;
requestEvents();
@ -400,6 +403,9 @@ void SyncthingConnection::abortAllRequests()
if(m_connectionsReply) {
m_connectionsReply->abort();
}
if(m_errorsReply) {
m_errorsReply->abort();
}
if(m_eventsReply) {
m_eventsReply->abort();
}
@ -435,6 +441,16 @@ void SyncthingConnection::requestConnections()
QObject::connect(m_connectionsReply = requestData(QStringLiteral("system/connections"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readConnections);
}
/*!
* \brief Requests errors asynchronously.
*
* The signal newNotification() is emitted on success; error() is emitted in the error case.
*/
void SyncthingConnection::requestErrors()
{
QObject::connect(m_errorsReply = requestData(QStringLiteral("system/error"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readErrors);
}
/*!
* \brief Requests directory statistics asynchronously.
*/
@ -509,10 +525,7 @@ QMetaObject::Connection SyncthingConnection::requestLog(std::function<void (cons
logEntries.reserve(log.size());
for(const QJsonValue &logVal : log) {
const QJsonObject logObj(logVal.toObject());
SyncthingLogEntry entry;
entry.when = logObj.value(QStringLiteral("when")).toString();
entry.message = logObj.value(QStringLiteral("message")).toString();
logEntries.emplace_back(move(entry));
logEntries.emplace_back(logObj.value(QStringLiteral("when")).toString(), logObj.value(QStringLiteral("message")).toString());
}
callback(logEntries);
} else {
@ -878,6 +891,52 @@ void SyncthingConnection::readDeviceStatistics()
}
}
void SyncthingConnection::readErrors()
{
auto *reply = static_cast<QNetworkReply *>(sender());
reply->deleteLater();
if(reply == m_errorsReply) {
m_errorsReply = nullptr;
}
// ignore any errors occured before connecting
if(m_lastErrorTime.isNull()) {
m_lastErrorTime = DateTime::now();
}
switch(reply->error()) {
case QNetworkReply::NoError: {
QJsonParseError jsonError;
const QJsonDocument replyDoc = QJsonDocument::fromJson(reply->readAll(), &jsonError);
if(jsonError.error == QJsonParseError::NoError) {
for(const QJsonValue &errorVal : replyDoc.object().value(QStringLiteral("errors")).toArray()) {
const QJsonObject errorObj(errorVal.toObject());
if(!errorObj.isEmpty()) {
try {
const DateTime when = DateTime::fromIsoStringLocal(errorObj.value(QStringLiteral("when")).toString().toLocal8Bit().data());
if(m_lastErrorTime < when) {
emitNotification(m_lastErrorTime = when, errorObj.value(QStringLiteral("message")).toString());
}
} catch(const ConversionException &) {
}
}
}
} else {
emit error(tr("Unable to parse errors: ") + jsonError.errorString());
}
// since there seems no event for this data, just request every thirty seconds, FIXME: make interval configurable
if(m_keepPolling) {
QTimer::singleShot(300/*00*/, Qt::VeryCoarseTimer, this, SLOT(requestErrors()));
}
break;
} case QNetworkReply::OperationCanceledError:
return; // intended, not an error
default:
emit error(tr("Unable to request errors: ") + reply->errorString());
}
}
/*!
* \brief Reads results of requestEvents().
*/
@ -937,7 +996,7 @@ void SyncthingConnection::readEvents()
// intended disconnect, not an error
if(m_reconnecting) {
// if reconnection flag is set, instantly etstablish a new connection ...
continueReconnect();
continueReconnecting();
} else {
// ... otherwise keep disconnected
setStatus(SyncthingStatus::Disconnected);
@ -1017,7 +1076,7 @@ void SyncthingConnection::readDirEvent(DateTime eventTime, const QString &eventT
if(!error.isEmpty()) {
dirInfo->errors.emplace_back(error.value(QStringLiteral("error")).toString(), error.value(QStringLiteral("path")).toString());
dirInfo->assignStatus(DirStatus::OutOfSync, eventTime);
emit newNotification(dirInfo->errors.back().message);
emitNotification(eventTime, dirInfo->errors.back().message);
}
}
emit dirStatusChanged(*dirInfo, index);
@ -1139,7 +1198,7 @@ void SyncthingConnection::readItemFinished(DateTime eventTime, const QJsonObject
}
} else if(dirInfo->status == DirStatus::OutOfSync) { // FIXME: find better way to check whether the event is still relevant
dirInfo->errors.emplace_back(error, item);
emit newNotification(error);
emitNotification(eventTime, error);
}
}
}
@ -1208,12 +1267,13 @@ void SyncthingConnection::setStatus(SyncthingStatus status)
// check whether at least one directory is scanning or synchronizing
bool scanning = false;
bool synchronizing = false;
for(const SyncthingDir &dir : m_dirs)
for(const SyncthingDir &dir : m_dirs) {
if(dir.status == DirStatus::Synchronizing) {
synchronizing = true;
break;
} else if(dir.status == DirStatus::Scanning) {
scanning = true;
}
}
if(synchronizing) {
status = SyncthingStatus::Synchronizing;
@ -1241,4 +1301,15 @@ void SyncthingConnection::setStatus(SyncthingStatus status)
}
}
/*!
* \brief Interanlly called to emit the notification with the specified \a message.
* \remarks Ensures the status is updated and the unread notifications flag is set.
*/
void SyncthingConnection::emitNotification(DateTime when, const QString &message)
{
m_unreadNotifications = true;
setStatus(status());
emit newNotification(when, message);
}
}

View File

@ -117,6 +117,10 @@ struct SyncthingDev
struct SyncthingLogEntry
{
SyncthingLogEntry(const QString &when, const QString &message) :
when(when),
message(message)
{}
QString when;
QString message;
};
@ -214,7 +218,7 @@ Q_SIGNALS:
/*!
* \brief Indicates a new Syncthing notification is available.
*/
void newNotification(const QString &message);
void newNotification(ChronoUtilities::DateTime when, const QString &message);
/*!
* \brief Indicates a request (for configuration, events, ...) failed.
@ -245,6 +249,7 @@ private Q_SLOTS:
void requestConfig();
void requestStatus();
void requestConnections();
void requestErrors();
void requestDirStatistics();
void requestDeviceStatistics();
void requestEvents();
@ -257,6 +262,7 @@ private Q_SLOTS:
void readConnections();
void readDirStatistics();
void readDeviceStatistics();
void readErrors();
void readEvents();
void readStartingEvent(const QJsonObject &eventData);
void readStatusChangedEvent(ChronoUtilities::DateTime eventTime, const QJsonObject &eventData);
@ -269,8 +275,10 @@ private Q_SLOTS:
void readPauseResume();
void readRestart();
void continueReconnect();
void continueConnecting();
void continueReconnecting();
void setStatus(SyncthingStatus status);
void emitNotification(ChronoUtilities::DateTime when, const QString &message);
private:
QNetworkRequest prepareRequest(const QString &path, const QUrlQuery &query, bool rest = true);
@ -278,7 +286,6 @@ private:
QNetworkReply *postData(const QString &path, const QUrlQuery &query, const QByteArray &data = QByteArray());
SyncthingDir *findDirInfo(const QString &dir, int &row);
SyncthingDev *findDevInfo(const QString &dev, int &row);
void continueConnecting();
QString m_syncthingUrl;
QByteArray m_apiKey;
@ -297,6 +304,7 @@ private:
QNetworkReply *m_configReply;
QNetworkReply *m_statusReply;
QNetworkReply *m_connectionsReply;
QNetworkReply *m_errorsReply;
QNetworkReply *m_eventsReply;
bool m_unreadNotifications;
bool m_hasConfig;
@ -305,6 +313,7 @@ private:
std::vector<SyncthingDev> m_devs;
ChronoUtilities::DateTime m_lastConnectionsUpdate;
ChronoUtilities::DateTime m_lastFileTime;
ChronoUtilities::DateTime m_lastErrorTime;
QString m_lastFileName;
bool m_lastFileDeleted;
QList<QSslError> m_expectedSslErrors;

46
gui/textviewdialog.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "./textviewdialog.h"
#include "resources/config.h"
#include <qtutilities/misc/dialogutils.h>
#include <QIcon>
#include <QTextBrowser>
#include <QFontDatabase>
#include <QVBoxLayout>
using namespace Dialogs;
namespace QtGui {
TextViewDialog::TextViewDialog(const QString &title, QWidget *parent) :
QWidget(parent, Qt::Window)
{
// set window title and icon
if(title.isEmpty()) {
setWindowTitle(QStringLiteral(APP_NAME));
} else {
setWindowTitle(title + QStringLiteral(" - " APP_NAME));
}
setWindowIcon(QIcon(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
// by default, delete on close
setAttribute(Qt::WA_DeleteOnClose);
// setup browser
m_browser = new QTextBrowser(this);
m_browser->setReadOnly(true);
m_browser->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
// setup layout
auto *layout = new QVBoxLayout(this);
layout->setAlignment(Qt::AlignCenter);
layout->addWidget(m_browser);
setLayout(layout);
// default position and size
resize(600, 500);
centerWidget(this);
}
}

29
gui/textviewdialog.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef TEXTVIEWDIALOG_H
#define TEXTVIEWDIALOG_H
#include <QWidget>
QT_FORWARD_DECLARE_CLASS(QTextBrowser)
namespace QtGui {
class TextViewDialog : public QWidget
{
Q_OBJECT
public:
TextViewDialog(const QString &title = QString(), QWidget *parent = nullptr);
QTextBrowser *browser();
private:
QTextBrowser *m_browser;
};
inline QTextBrowser *TextViewDialog::browser()
{
return m_browser;
}
}
#endif // TEXTVIEWDIALOG_H

View File

@ -45,6 +45,7 @@ TrayIcon::TrayIcon(QObject *parent) :
// connect signals and slots
SyncthingConnection *connection = &(m_trayMenu.widget()->connection());
connect(this, &TrayIcon::activated, this, &TrayIcon::handleActivated);
connect(this, &TrayIcon::messageClicked, this, &TrayIcon::handleMessageClicked);
connect(connection, &SyncthingConnection::error, this, &TrayIcon::showInternalError);
connect(connection, &SyncthingConnection::newNotification, this, &TrayIcon::showSyncthingNotification);
connect(connection, &SyncthingConnection::statusChanged, this, &TrayIcon::updateStatusIconAndText);
@ -72,6 +73,11 @@ void TrayIcon::handleActivated(QSystemTrayIcon::ActivationReason reason)
}
}
void TrayIcon::handleMessageClicked()
{
m_trayMenu.widget()->connection().notificationsRead();
}
void TrayIcon::showInternalError(const QString &errorMsg)
{
if(Settings::notifyOnInternalErrors()) {
@ -79,10 +85,10 @@ void TrayIcon::showInternalError(const QString &errorMsg)
}
}
void TrayIcon::showSyncthingNotification(const QString &message)
void TrayIcon::showSyncthingNotification(ChronoUtilities::DateTime when, const QString &message)
{
if(Settings::showSyncthingNotifications()) {
showMessage(tr("Syncthing notification"), message, QSystemTrayIcon::Warning);
showMessage(tr("Syncthing notification - click to dismiss"), message, QSystemTrayIcon::Warning);
}
}

View File

@ -10,6 +10,10 @@
QT_FORWARD_DECLARE_CLASS(QPixmap)
namespace ChronoUtilities {
class DateTime;
}
namespace Data {
enum class SyncthingStatus;
}
@ -26,8 +30,9 @@ public:
private slots:
void handleActivated(QSystemTrayIcon::ActivationReason reason);
void handleMessageClicked();
void showInternalError(const QString &errorMsg);
void showSyncthingNotification(const QString &message);
void showSyncthingNotification(ChronoUtilities::DateTime when, const QString &message);
void updateStatusIconAndText(Data::SyncthingStatus status);
private:

View File

@ -2,6 +2,7 @@
#include "./traymenu.h"
#include "./settingsdialog.h"
#include "./webviewdialog.h"
#include "./textviewdialog.h"
#include "../application/settings.h"
@ -30,6 +31,7 @@
using namespace ApplicationUtilities;
using namespace ConversionUtilities;
using namespace ChronoUtilities;
using namespace Dialogs;
using namespace Data;
using namespace std;
@ -73,13 +75,11 @@ TrayWidget::TrayWidget(TrayMenu *parent) :
restartButton->setToolTip(tr("Restart Syncthing"));
restartButton->setIcon(QIcon::fromTheme(QStringLiteral("system-reboot"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/view-refresh.svg"))));
restartButton->setFlat(true);
connect(restartButton, &QPushButton::clicked, &m_connection, &SyncthingConnection::restart);
cornerFrameLayout->addWidget(restartButton);
auto *showLogButton = new QPushButton(m_cornerFrame);
showLogButton->setToolTip(tr("Show Syncthing log"));
showLogButton->setIcon(QIcon::fromTheme(QStringLiteral("text-x-generic"), QIcon(QStringLiteral(":/icons/hicolor/scalable/mimetypes/text-x-generic.svg"))));
showLogButton->setFlat(true);
connect(showLogButton, &QPushButton::clicked, this, &TrayWidget::showLog);
cornerFrameLayout->addWidget(showLogButton);
auto *scanAllButton = new QPushButton(m_cornerFrame);
scanAllButton->setToolTip(tr("Rescan all directories"));
@ -96,6 +96,8 @@ TrayWidget::TrayWidget(TrayMenu *parent) :
// apply settings, this also establishes the connection to Syncthing
applySettings();
// setup other widgets
m_ui->notificationsPushButton->setHidden(true);
m_ui->trafficIconLabel->setPixmap(QIcon::fromTheme(QStringLiteral("network-card"), QIcon(QStringLiteral(":/icons/hicolor/scalable/devices/network-card.svg"))).pixmap(32));
// connect signals and slots
@ -112,6 +114,9 @@ TrayWidget::TrayWidget(TrayMenu *parent) :
connect(m_ui->devsTreeView, &DevView::pauseResumeDev, this, &TrayWidget::pauseResumeDev);
connect(scanAllButton, &QPushButton::clicked, &m_connection, &SyncthingConnection::rescanAllDirs);
connect(viewIdButton, &QPushButton::clicked, this, &TrayWidget::showOwnDeviceId);
connect(showLogButton, &QPushButton::clicked, this, &TrayWidget::showLog);
connect(m_ui->notificationsPushButton, &QPushButton::clicked, this, &TrayWidget::showNotifications);
connect(restartButton, &QPushButton::clicked, &m_connection, &SyncthingConnection::restart);
connect(m_connectionsActionGroup, &QActionGroup::triggered, this, &TrayWidget::handleConnectionSelected);
}
@ -124,12 +129,8 @@ void TrayWidget::showSettingsDialog()
m_settingsDlg = new SettingsDialog(&m_connection, this);
connect(m_settingsDlg, &SettingsDialog::applied, this, &TrayWidget::applySettings);
}
m_settingsDlg->show();
centerWidget(m_settingsDlg);
if(m_menu) {
m_menu->close();
}
m_settingsDlg->activateWindow();
showDialog(m_settingsDlg);
}
void TrayWidget::showAboutDialog()
@ -139,12 +140,8 @@ void TrayWidget::showAboutDialog()
m_aboutDlg->setWindowTitle(tr("About") + QStringLiteral(" - " APP_NAME));
m_aboutDlg->setWindowIcon(QIcon(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
}
m_aboutDlg->show();
centerWidget(m_aboutDlg);
if(m_menu) {
m_menu->close();
}
m_aboutDlg->activateWindow();
showDialog(m_aboutDlg);
}
void TrayWidget::showWebUi()
@ -162,11 +159,7 @@ void TrayWidget::showWebUi()
}
connect(m_webViewDlg, &WebViewDialog::destroyed, this, &TrayWidget::handleWebViewDeleted);
}
m_webViewDlg->show();
if(m_menu) {
m_menu->close();
}
m_webViewDlg->activateWindow();
showDialog(m_webViewDlg);
}
#endif
}
@ -200,42 +193,34 @@ void TrayWidget::showOwnDeviceId()
m_connection.requestQrCode(m_connection.myId(), bind(&QLabel::setPixmap, pixmapLabel, placeholders::_1))
));
dlg->setLayout(layout);
dlg->show();
centerWidget(dlg);
if(m_menu) {
m_menu->close();
}
dlg->activateWindow();
showDialog(dlg);
}
void TrayWidget::showLog()
{
auto *dlg = new QWidget(this, Qt::Window);
dlg->setWindowTitle(tr("Log") + QStringLiteral(" - " APP_NAME));
dlg->setWindowIcon(QIcon(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
dlg->setAttribute(Qt::WA_DeleteOnClose);
auto *layout = new QVBoxLayout(dlg);
layout->setAlignment(Qt::AlignCenter);
auto *browser = new QTextBrowser(dlg);
auto *dlg = new TextViewDialog(tr("Log"), this);
connect(dlg, &QWidget::destroyed,
bind(static_cast<bool(*)(const QMetaObject::Connection &)>(&QObject::disconnect),
m_connection.requestLog([browser] (const std::vector<SyncthingLogEntry> &entries) {
m_connection.requestLog([dlg] (const std::vector<SyncthingLogEntry> &entries) {
for(const SyncthingLogEntry &entry : entries) {
browser->append(entry.when % QChar(':') % QChar(' ') % QChar('\n') % entry.message % QChar('\n'));
dlg->browser()->append(entry.when % QChar(':') % QChar(' ') % QChar('\n') % entry.message % QChar('\n'));
}
})
));
browser->setReadOnly(true);
browser->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
layout->addWidget(browser);
dlg->setLayout(layout);
dlg->show();
dlg->resize(600, 500);
centerWidget(dlg);
if(m_menu) {
m_menu->close();
showDialog(dlg);
}
void TrayWidget::showNotifications()
{
auto *dlg = new TextViewDialog(tr("New notifications"), this);
for(const SyncthingLogEntry &entry : m_notifications) {
dlg->browser()->append(entry.when % QChar(':') % QChar(' ') % QChar('\n') % entry.message % QChar('\n'));
}
dlg->activateWindow();
m_notifications.clear();
showDialog(dlg);
m_connection.notificationsRead();
m_ui->notificationsPushButton->setHidden(true);
}
void TrayWidget::handleStatusChanged(SyncthingStatus status)
@ -312,7 +297,7 @@ void TrayWidget::applySettings()
if(Settings::showTraffic()) {
updateTraffic();
}
m_ui->trafficFrame->setFrameStyle(Settings::frameStyle());
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);
@ -372,7 +357,7 @@ void TrayWidget::changeStatus()
void TrayWidget::updateTraffic()
{
if(m_ui->trafficFrame->isHidden()) {
if(m_ui->trafficFormWidget->isHidden()) {
return;
}
static const QString unknownStr(tr("unknown"));
@ -405,9 +390,10 @@ void TrayWidget::handleWebViewDeleted()
}
#endif
void TrayWidget::handleNewNotification(const QString &msg)
void TrayWidget::handleNewNotification(DateTime when, const QString &msg)
{
// FIXME
m_notifications.emplace_back(QString::fromLocal8Bit(when.toString(DateTimeOutputFormat::DateAndTime, true).data()), msg);
m_ui->notificationsPushButton->setHidden(false);
}
void TrayWidget::handleConnectionSelected(QAction *connectionAction)
@ -431,4 +417,13 @@ void TrayWidget::showConnectionsMenu()
m_connectionsMenu->exec(QCursor::pos());
}
void TrayWidget::showDialog(QWidget *dlg)
{
if(m_menu) {
m_menu->close();
}
dlg->show();
dlg->activateWindow();
}
}

View File

@ -52,6 +52,7 @@ public slots:
void showWebUi();
void showOwnDeviceId();
void showLog();
void showNotifications();
private slots:
void handleStatusChanged(Data::SyncthingStatus status);
@ -64,9 +65,10 @@ private slots:
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
void handleWebViewDeleted();
#endif
void handleNewNotification(const QString &msg);
void handleNewNotification(ChronoUtilities::DateTime when, const QString &msg);
void handleConnectionSelected(QAction *connectionAction);
void showConnectionsMenu();
void showDialog(QWidget *dlg);
private:
TrayMenu *m_menu;
@ -83,6 +85,7 @@ private:
QMenu *m_connectionsMenu;
QActionGroup *m_connectionsActionGroup;
Settings::ConnectionSettings *m_selectedConnection;
std::vector<Data::SyncthingLogEntry> m_notifications;
};
inline Data::SyncthingConnection &TrayWidget::connection()

View File

@ -160,7 +160,7 @@
</widget>
</item>
<item>
<widget class="QFrame" name="trafficFrame">
<widget class="QFrame" name="infoFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@ -254,6 +254,35 @@
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="notificationsPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string>Click to show &lt;i&gt;new&lt;/i&gt; notifications&lt;br&gt;
For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</string>
</property>
<property name="text">
<string>New notifications</string>
</property>
<property name="icon">
<iconset theme="dialog-warning"/>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="connectionsPushButton">
<property name="sizePolicy">
@ -263,7 +292,8 @@
</sizepolicy>
</property>
<property name="icon">
<iconset theme="network-connect"/>
<iconset theme="network-connect">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="flat">
<bool>true</bool>

View File

@ -4,135 +4,145 @@
<context>
<name>Data::SyncthingConnection</name>
<message>
<location filename="../data/syncthingconnection.cpp" line="147"/>
<location filename="../data/syncthingconnection.cpp" line="148"/>
<source>disconnected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="149"/>
<location filename="../data/syncthingconnection.cpp" line="150"/>
<source>reconnecting</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="151"/>
<location filename="../data/syncthingconnection.cpp" line="152"/>
<source>connected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="153"/>
<location filename="../data/syncthingconnection.cpp" line="154"/>
<source>connected, notifications available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="155"/>
<location filename="../data/syncthingconnection.cpp" line="156"/>
<source>connected, paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="157"/>
<location filename="../data/syncthingconnection.cpp" line="158"/>
<source>connected, synchronizing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="159"/>
<location filename="../data/syncthingconnection.cpp" line="160"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="171"/>
<location filename="../data/syncthingconnection.cpp" line="250"/>
<location filename="../data/syncthingconnection.cpp" line="172"/>
<location filename="../data/syncthingconnection.cpp" line="252"/>
<source>Connection configuration is insufficient.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="519"/>
<location filename="../data/syncthingconnection.cpp" line="532"/>
<source>Unable to parse Syncthing log: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="523"/>
<location filename="../data/syncthingconnection.cpp" line="536"/>
<source>Unable to request system log: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="545"/>
<location filename="../data/syncthingconnection.cpp" line="558"/>
<source>Unable to locate certificate used by Syncthing GUI.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="551"/>
<location filename="../data/syncthingconnection.cpp" line="564"/>
<source>Unable to load certificate used by Syncthing GUI.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="584"/>
<location filename="../data/syncthingconnection.cpp" line="686"/>
<location filename="../data/syncthingconnection.cpp" line="597"/>
<location filename="../data/syncthingconnection.cpp" line="699"/>
<source>Unable to parse Syncthing config: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="590"/>
<location filename="../data/syncthingconnection.cpp" line="692"/>
<location filename="../data/syncthingconnection.cpp" line="603"/>
<location filename="../data/syncthingconnection.cpp" line="705"/>
<source>Unable to request Syncthing config: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="767"/>
<location filename="../data/syncthingconnection.cpp" line="780"/>
<source>Unable to parse connections: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="773"/>
<location filename="../data/syncthingconnection.cpp" line="786"/>
<source>Unable to request connections: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="828"/>
<location filename="../data/syncthingconnection.cpp" line="841"/>
<source>Unable to parse directory statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="834"/>
<location filename="../data/syncthingconnection.cpp" line="847"/>
<source>Unable to request directory statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="871"/>
<location filename="../data/syncthingconnection.cpp" line="884"/>
<source>Unable to parse device statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="877"/>
<location filename="../data/syncthingconnection.cpp" line="890"/>
<source>Unable to request device statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="928"/>
<location filename="../data/syncthingconnection.cpp" line="925"/>
<source>Unable to parse errors: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="936"/>
<source>Unable to request errors: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="987"/>
<source>Unable to parse Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="947"/>
<location filename="../data/syncthingconnection.cpp" line="1006"/>
<source>Unable to request Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="1159"/>
<location filename="../data/syncthingconnection.cpp" line="1218"/>
<source>Unable to request rescan: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="1174"/>
<location filename="../data/syncthingconnection.cpp" line="1233"/>
<source>Unable to request pause/resume: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="1189"/>
<location filename="../data/syncthingconnection.cpp" line="1248"/>
<source>Unable to request restart: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="487"/>
<location filename="../data/syncthingconnection.cpp" line="503"/>
<source>Unable to request QR-Code: </source>
<translation type="unfinished"></translation>
</message>
@ -753,57 +763,57 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="78"/>
<location filename="../gui/trayicon.cpp" line="84"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="85"/>
<source>Syncthing notification</source>
<location filename="../gui/trayicon.cpp" line="91"/>
<source>Syncthing notification - click to dismiss</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="94"/>
<location filename="../gui/trayicon.cpp" line="100"/>
<source>Not connected to Syncthing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="96"/>
<location filename="../gui/trayicon.cpp" line="102"/>
<source>Disconnected from Syncthing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="101"/>
<location filename="../gui/trayicon.cpp" line="107"/>
<source>Reconnecting ...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="105"/>
<location filename="../gui/trayicon.cpp" line="111"/>
<source>Syncthing is idling</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="109"/>
<location filename="../gui/trayicon.cpp" line="115"/>
<source>Syncthing is scanning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="113"/>
<location filename="../gui/trayicon.cpp" line="119"/>
<source>Notifications available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="117"/>
<location filename="../gui/trayicon.cpp" line="123"/>
<source>At least one device is paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="121"/>
<location filename="../gui/trayicon.cpp" line="127"/>
<source>Synchronization is ongoing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="131"/>
<location filename="../gui/trayicon.cpp" line="137"/>
<source>Synchronization complete</source>
<translation type="unfinished"></translation>
</message>
@ -817,7 +827,7 @@
</message>
<message>
<location filename="../gui/traywidget.ui" line="107"/>
<location filename="../gui/traywidget.cpp" line="245"/>
<location filename="../gui/traywidget.cpp" line="230"/>
<source>Connect</source>
<translation type="unfinished"></translation>
</message>
@ -841,10 +851,16 @@
<source>Outgoing traffic</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="272"/>
<source>Click to show &lt;i&gt;new&lt;/i&gt; notifications&lt;br&gt;
For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="230"/>
<location filename="../gui/traywidget.ui" line="250"/>
<location filename="../gui/traywidget.cpp" line="378"/>
<location filename="../gui/traywidget.cpp" line="363"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
@ -859,18 +875,18 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="296"/>
<location filename="../gui/traywidget.ui" line="326"/>
<source>Directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="325"/>
<location filename="../gui/traywidget.ui" line="355"/>
<source>Devices</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="80"/>
<location filename="../gui/traywidget.cpp" line="139"/>
<location filename="../gui/traywidget.cpp" line="140"/>
<source>About</source>
<translation type="unfinished"></translation>
</message>
@ -885,7 +901,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="68"/>
<location filename="../gui/traywidget.cpp" line="70"/>
<source>View own device ID</source>
<translation type="unfinished"></translation>
</message>
@ -895,12 +911,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="79"/>
<location filename="../gui/traywidget.cpp" line="80"/>
<source>Show Syncthing log</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="73"/>
<location filename="../gui/traywidget.cpp" line="75"/>
<source>Restart Syncthing</source>
<translation type="unfinished"></translation>
</message>
@ -910,52 +926,58 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="187"/>
<location filename="../gui/traywidget.cpp" line="180"/>
<source>device ID is unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="195"/>
<location filename="../gui/traywidget.cpp" line="188"/>
<source>Copy to clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="246"/>
<location filename="../gui/traywidget.ui" line="276"/>
<location filename="../gui/traywidget.cpp" line="216"/>
<source>New notifications</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="231"/>
<source>Not connected to Syncthing, click to connect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="258"/>
<location filename="../gui/traywidget.cpp" line="243"/>
<source>Pause</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="259"/>
<location filename="../gui/traywidget.cpp" line="244"/>
<source>Syncthing is running, click to pause all devices</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="265"/>
<location filename="../gui/traywidget.cpp" line="250"/>
<source>At least one device is paused, click to resume</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="330"/>
<location filename="../gui/traywidget.cpp" line="315"/>
<source>The directory &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="264"/>
<location filename="../gui/traywidget.cpp" line="249"/>
<source>Continue</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="177"/>
<location filename="../gui/traywidget.cpp" line="170"/>
<source>Own device ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="214"/>
<location filename="../gui/traywidget.cpp" line="202"/>
<source>Log</source>
<translation type="unfinished"></translation>
</message>

View File

@ -4,135 +4,145 @@
<context>
<name>Data::SyncthingConnection</name>
<message>
<location filename="../data/syncthingconnection.cpp" line="147"/>
<location filename="../data/syncthingconnection.cpp" line="148"/>
<source>disconnected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="149"/>
<location filename="../data/syncthingconnection.cpp" line="150"/>
<source>reconnecting</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="151"/>
<location filename="../data/syncthingconnection.cpp" line="152"/>
<source>connected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="153"/>
<location filename="../data/syncthingconnection.cpp" line="154"/>
<source>connected, notifications available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="155"/>
<location filename="../data/syncthingconnection.cpp" line="156"/>
<source>connected, paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="157"/>
<location filename="../data/syncthingconnection.cpp" line="158"/>
<source>connected, synchronizing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="159"/>
<location filename="../data/syncthingconnection.cpp" line="160"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="171"/>
<location filename="../data/syncthingconnection.cpp" line="250"/>
<location filename="../data/syncthingconnection.cpp" line="172"/>
<location filename="../data/syncthingconnection.cpp" line="252"/>
<source>Connection configuration is insufficient.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="519"/>
<location filename="../data/syncthingconnection.cpp" line="532"/>
<source>Unable to parse Syncthing log: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="523"/>
<location filename="../data/syncthingconnection.cpp" line="536"/>
<source>Unable to request system log: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="545"/>
<location filename="../data/syncthingconnection.cpp" line="558"/>
<source>Unable to locate certificate used by Syncthing GUI.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="551"/>
<location filename="../data/syncthingconnection.cpp" line="564"/>
<source>Unable to load certificate used by Syncthing GUI.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="584"/>
<location filename="../data/syncthingconnection.cpp" line="686"/>
<location filename="../data/syncthingconnection.cpp" line="597"/>
<location filename="../data/syncthingconnection.cpp" line="699"/>
<source>Unable to parse Syncthing config: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="590"/>
<location filename="../data/syncthingconnection.cpp" line="692"/>
<location filename="../data/syncthingconnection.cpp" line="603"/>
<location filename="../data/syncthingconnection.cpp" line="705"/>
<source>Unable to request Syncthing config: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="767"/>
<location filename="../data/syncthingconnection.cpp" line="780"/>
<source>Unable to parse connections: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="773"/>
<location filename="../data/syncthingconnection.cpp" line="786"/>
<source>Unable to request connections: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="828"/>
<location filename="../data/syncthingconnection.cpp" line="841"/>
<source>Unable to parse directory statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="834"/>
<location filename="../data/syncthingconnection.cpp" line="847"/>
<source>Unable to request directory statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="871"/>
<location filename="../data/syncthingconnection.cpp" line="884"/>
<source>Unable to parse device statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="877"/>
<location filename="../data/syncthingconnection.cpp" line="890"/>
<source>Unable to request device statistics: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="928"/>
<location filename="../data/syncthingconnection.cpp" line="925"/>
<source>Unable to parse errors: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="936"/>
<source>Unable to request errors: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="987"/>
<source>Unable to parse Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="947"/>
<location filename="../data/syncthingconnection.cpp" line="1006"/>
<source>Unable to request Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="1159"/>
<location filename="../data/syncthingconnection.cpp" line="1218"/>
<source>Unable to request rescan: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="1174"/>
<location filename="../data/syncthingconnection.cpp" line="1233"/>
<source>Unable to request pause/resume: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="1189"/>
<location filename="../data/syncthingconnection.cpp" line="1248"/>
<source>Unable to request restart: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../data/syncthingconnection.cpp" line="487"/>
<location filename="../data/syncthingconnection.cpp" line="503"/>
<source>Unable to request QR-Code: </source>
<translation type="unfinished"></translation>
</message>
@ -753,57 +763,57 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="78"/>
<location filename="../gui/trayicon.cpp" line="84"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="85"/>
<source>Syncthing notification</source>
<location filename="../gui/trayicon.cpp" line="91"/>
<source>Syncthing notification - click to dismiss</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="94"/>
<location filename="../gui/trayicon.cpp" line="100"/>
<source>Not connected to Syncthing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="96"/>
<location filename="../gui/trayicon.cpp" line="102"/>
<source>Disconnected from Syncthing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="101"/>
<location filename="../gui/trayicon.cpp" line="107"/>
<source>Reconnecting ...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="105"/>
<location filename="../gui/trayicon.cpp" line="111"/>
<source>Syncthing is idling</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="109"/>
<location filename="../gui/trayicon.cpp" line="115"/>
<source>Syncthing is scanning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="113"/>
<location filename="../gui/trayicon.cpp" line="119"/>
<source>Notifications available</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="117"/>
<location filename="../gui/trayicon.cpp" line="123"/>
<source>At least one device is paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="121"/>
<location filename="../gui/trayicon.cpp" line="127"/>
<source>Synchronization is ongoing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/trayicon.cpp" line="131"/>
<location filename="../gui/trayicon.cpp" line="137"/>
<source>Synchronization complete</source>
<translation type="unfinished"></translation>
</message>
@ -817,7 +827,7 @@
</message>
<message>
<location filename="../gui/traywidget.ui" line="107"/>
<location filename="../gui/traywidget.cpp" line="245"/>
<location filename="../gui/traywidget.cpp" line="230"/>
<source>Connect</source>
<translation type="unfinished"></translation>
</message>
@ -841,10 +851,16 @@
<source>Outgoing traffic</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="272"/>
<source>Click to show &lt;i&gt;new&lt;/i&gt; notifications&lt;br&gt;
For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="230"/>
<location filename="../gui/traywidget.ui" line="250"/>
<location filename="../gui/traywidget.cpp" line="378"/>
<location filename="../gui/traywidget.cpp" line="363"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
@ -859,18 +875,18 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="296"/>
<location filename="../gui/traywidget.ui" line="326"/>
<source>Directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="325"/>
<location filename="../gui/traywidget.ui" line="355"/>
<source>Devices</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="80"/>
<location filename="../gui/traywidget.cpp" line="139"/>
<location filename="../gui/traywidget.cpp" line="140"/>
<source>About</source>
<translation type="unfinished"></translation>
</message>
@ -885,7 +901,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="68"/>
<location filename="../gui/traywidget.cpp" line="70"/>
<source>View own device ID</source>
<translation type="unfinished"></translation>
</message>
@ -895,12 +911,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="79"/>
<location filename="../gui/traywidget.cpp" line="80"/>
<source>Show Syncthing log</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="73"/>
<location filename="../gui/traywidget.cpp" line="75"/>
<source>Restart Syncthing</source>
<translation type="unfinished"></translation>
</message>
@ -910,52 +926,58 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="187"/>
<location filename="../gui/traywidget.cpp" line="180"/>
<source>device ID is unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="195"/>
<location filename="../gui/traywidget.cpp" line="188"/>
<source>Copy to clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="246"/>
<location filename="../gui/traywidget.ui" line="276"/>
<location filename="../gui/traywidget.cpp" line="216"/>
<source>New notifications</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="231"/>
<source>Not connected to Syncthing, click to connect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="258"/>
<location filename="../gui/traywidget.cpp" line="243"/>
<source>Pause</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="259"/>
<location filename="../gui/traywidget.cpp" line="244"/>
<source>Syncthing is running, click to pause all devices</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="265"/>
<location filename="../gui/traywidget.cpp" line="250"/>
<source>At least one device is paused, click to resume</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="330"/>
<location filename="../gui/traywidget.cpp" line="315"/>
<source>The directory &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="264"/>
<location filename="../gui/traywidget.cpp" line="249"/>
<source>Continue</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="177"/>
<location filename="../gui/traywidget.cpp" line="170"/>
<source>Own device ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="214"/>
<location filename="../gui/traywidget.cpp" line="202"/>
<source>Log</source>
<translation type="unfinished"></translation>
</message>