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/devbuttonsitemdelegate.h
gui/dirview.h gui/dirview.h
gui/devview.h gui/devview.h
gui/textviewdialog.h
) )
set(WIDGETS_SRC_FILES set(WIDGETS_SRC_FILES
application/main.cpp application/main.cpp
@ -59,6 +60,7 @@ set(WIDGETS_SRC_FILES
gui/devbuttonsitemdelegate.cpp gui/devbuttonsitemdelegate.cpp
gui/dirview.cpp gui/dirview.cpp
gui/devview.cpp gui/devview.cpp
gui/textviewdialog.cpp
resources/icons.qrc resources/icons.qrc
) )
set(WIDGETS_UI_FILES set(WIDGETS_UI_FILES

View File

@ -122,6 +122,7 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt
m_configReply(nullptr), m_configReply(nullptr),
m_statusReply(nullptr), m_statusReply(nullptr),
m_connectionsReply(nullptr), m_connectionsReply(nullptr),
m_errorsReply(nullptr),
m_eventsReply(nullptr), m_eventsReply(nullptr),
m_unreadNotifications(false), m_unreadNotifications(false),
m_hasConfig(false), m_hasConfig(false),
@ -197,7 +198,7 @@ void SyncthingConnection::reconnect()
m_hasConfig = m_hasStatus = false; m_hasConfig = m_hasStatus = false;
abortAllRequests(); abortAllRequests();
} else { } else {
continueReconnect(); continueReconnecting();
} }
} }
@ -224,7 +225,7 @@ void SyncthingConnection::reconnect(Settings::ConnectionSettings &connectionSett
/*! /*!
* \brief Internally called to reconnect; ensures currently cached config is cleared. * \brief Internally called to reconnect; ensures currently cached config is cleared.
*/ */
void SyncthingConnection::continueReconnect() void SyncthingConnection::continueReconnecting()
{ {
emit newConfig(QJsonObject()); // configuration will be invalidated emit newConfig(QJsonObject()); // configuration will be invalidated
setStatus(SyncthingStatus::Reconnecting); setStatus(SyncthingStatus::Reconnecting);
@ -244,6 +245,7 @@ void SyncthingConnection::continueReconnect()
m_devs.clear(); m_devs.clear();
m_lastConnectionsUpdate = DateTime(); m_lastConnectionsUpdate = DateTime();
m_lastFileTime = DateTime(); m_lastFileTime = DateTime();
m_lastErrorTime = DateTime();
m_lastFileName.clear(); m_lastFileName.clear();
m_lastFileDeleted = false; m_lastFileDeleted = false;
if(m_apiKey.isEmpty() || m_syncthingUrl.isEmpty()) { if(m_apiKey.isEmpty() || m_syncthingUrl.isEmpty()) {
@ -380,6 +382,7 @@ void SyncthingConnection::continueConnecting()
requestConnections(); requestConnections();
requestDirStatistics(); requestDirStatistics();
requestDeviceStatistics(); requestDeviceStatistics();
requestErrors();
// since config and status could be read successfully, let's poll for events // since config and status could be read successfully, let's poll for events
m_lastEventId = 0; m_lastEventId = 0;
requestEvents(); requestEvents();
@ -400,6 +403,9 @@ void SyncthingConnection::abortAllRequests()
if(m_connectionsReply) { if(m_connectionsReply) {
m_connectionsReply->abort(); m_connectionsReply->abort();
} }
if(m_errorsReply) {
m_errorsReply->abort();
}
if(m_eventsReply) { if(m_eventsReply) {
m_eventsReply->abort(); m_eventsReply->abort();
} }
@ -435,6 +441,16 @@ void SyncthingConnection::requestConnections()
QObject::connect(m_connectionsReply = requestData(QStringLiteral("system/connections"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readConnections); 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. * \brief Requests directory statistics asynchronously.
*/ */
@ -509,10 +525,7 @@ QMetaObject::Connection SyncthingConnection::requestLog(std::function<void (cons
logEntries.reserve(log.size()); logEntries.reserve(log.size());
for(const QJsonValue &logVal : log) { for(const QJsonValue &logVal : log) {
const QJsonObject logObj(logVal.toObject()); const QJsonObject logObj(logVal.toObject());
SyncthingLogEntry entry; logEntries.emplace_back(logObj.value(QStringLiteral("when")).toString(), logObj.value(QStringLiteral("message")).toString());
entry.when = logObj.value(QStringLiteral("when")).toString();
entry.message = logObj.value(QStringLiteral("message")).toString();
logEntries.emplace_back(move(entry));
} }
callback(logEntries); callback(logEntries);
} else { } 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(). * \brief Reads results of requestEvents().
*/ */
@ -937,7 +996,7 @@ void SyncthingConnection::readEvents()
// intended disconnect, not an error // intended disconnect, not an error
if(m_reconnecting) { if(m_reconnecting) {
// if reconnection flag is set, instantly etstablish a new connection ... // if reconnection flag is set, instantly etstablish a new connection ...
continueReconnect(); continueReconnecting();
} else { } else {
// ... otherwise keep disconnected // ... otherwise keep disconnected
setStatus(SyncthingStatus::Disconnected); setStatus(SyncthingStatus::Disconnected);
@ -1017,7 +1076,7 @@ void SyncthingConnection::readDirEvent(DateTime eventTime, const QString &eventT
if(!error.isEmpty()) { if(!error.isEmpty()) {
dirInfo->errors.emplace_back(error.value(QStringLiteral("error")).toString(), error.value(QStringLiteral("path")).toString()); dirInfo->errors.emplace_back(error.value(QStringLiteral("error")).toString(), error.value(QStringLiteral("path")).toString());
dirInfo->assignStatus(DirStatus::OutOfSync, eventTime); dirInfo->assignStatus(DirStatus::OutOfSync, eventTime);
emit newNotification(dirInfo->errors.back().message); emitNotification(eventTime, dirInfo->errors.back().message);
} }
} }
emit dirStatusChanged(*dirInfo, index); 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 } else if(dirInfo->status == DirStatus::OutOfSync) { // FIXME: find better way to check whether the event is still relevant
dirInfo->errors.emplace_back(error, item); 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 // check whether at least one directory is scanning or synchronizing
bool scanning = false; bool scanning = false;
bool synchronizing = false; bool synchronizing = false;
for(const SyncthingDir &dir : m_dirs) for(const SyncthingDir &dir : m_dirs) {
if(dir.status == DirStatus::Synchronizing) { if(dir.status == DirStatus::Synchronizing) {
synchronizing = true; synchronizing = true;
break; break;
} else if(dir.status == DirStatus::Scanning) { } else if(dir.status == DirStatus::Scanning) {
scanning = true; scanning = true;
}
} }
if(synchronizing) { if(synchronizing) {
status = SyncthingStatus::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 struct SyncthingLogEntry
{ {
SyncthingLogEntry(const QString &when, const QString &message) :
when(when),
message(message)
{}
QString when; QString when;
QString message; QString message;
}; };
@ -214,7 +218,7 @@ Q_SIGNALS:
/*! /*!
* \brief Indicates a new Syncthing notification is available. * \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. * \brief Indicates a request (for configuration, events, ...) failed.
@ -245,6 +249,7 @@ private Q_SLOTS:
void requestConfig(); void requestConfig();
void requestStatus(); void requestStatus();
void requestConnections(); void requestConnections();
void requestErrors();
void requestDirStatistics(); void requestDirStatistics();
void requestDeviceStatistics(); void requestDeviceStatistics();
void requestEvents(); void requestEvents();
@ -257,6 +262,7 @@ private Q_SLOTS:
void readConnections(); void readConnections();
void readDirStatistics(); void readDirStatistics();
void readDeviceStatistics(); void readDeviceStatistics();
void readErrors();
void readEvents(); void readEvents();
void readStartingEvent(const QJsonObject &eventData); void readStartingEvent(const QJsonObject &eventData);
void readStatusChangedEvent(ChronoUtilities::DateTime eventTime, const QJsonObject &eventData); void readStatusChangedEvent(ChronoUtilities::DateTime eventTime, const QJsonObject &eventData);
@ -269,8 +275,10 @@ private Q_SLOTS:
void readPauseResume(); void readPauseResume();
void readRestart(); void readRestart();
void continueReconnect(); void continueConnecting();
void continueReconnecting();
void setStatus(SyncthingStatus status); void setStatus(SyncthingStatus status);
void emitNotification(ChronoUtilities::DateTime when, const QString &message);
private: private:
QNetworkRequest prepareRequest(const QString &path, const QUrlQuery &query, bool rest = true); 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()); QNetworkReply *postData(const QString &path, const QUrlQuery &query, const QByteArray &data = QByteArray());
SyncthingDir *findDirInfo(const QString &dir, int &row); SyncthingDir *findDirInfo(const QString &dir, int &row);
SyncthingDev *findDevInfo(const QString &dev, int &row); SyncthingDev *findDevInfo(const QString &dev, int &row);
void continueConnecting();
QString m_syncthingUrl; QString m_syncthingUrl;
QByteArray m_apiKey; QByteArray m_apiKey;
@ -297,6 +304,7 @@ private:
QNetworkReply *m_configReply; QNetworkReply *m_configReply;
QNetworkReply *m_statusReply; QNetworkReply *m_statusReply;
QNetworkReply *m_connectionsReply; QNetworkReply *m_connectionsReply;
QNetworkReply *m_errorsReply;
QNetworkReply *m_eventsReply; QNetworkReply *m_eventsReply;
bool m_unreadNotifications; bool m_unreadNotifications;
bool m_hasConfig; bool m_hasConfig;
@ -305,6 +313,7 @@ private:
std::vector<SyncthingDev> m_devs; std::vector<SyncthingDev> m_devs;
ChronoUtilities::DateTime m_lastConnectionsUpdate; ChronoUtilities::DateTime m_lastConnectionsUpdate;
ChronoUtilities::DateTime m_lastFileTime; ChronoUtilities::DateTime m_lastFileTime;
ChronoUtilities::DateTime m_lastErrorTime;
QString m_lastFileName; QString m_lastFileName;
bool m_lastFileDeleted; bool m_lastFileDeleted;
QList<QSslError> m_expectedSslErrors; 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 // connect signals and slots
SyncthingConnection *connection = &(m_trayMenu.widget()->connection()); SyncthingConnection *connection = &(m_trayMenu.widget()->connection());
connect(this, &TrayIcon::activated, this, &TrayIcon::handleActivated); connect(this, &TrayIcon::activated, this, &TrayIcon::handleActivated);
connect(this, &TrayIcon::messageClicked, this, &TrayIcon::handleMessageClicked);
connect(connection, &SyncthingConnection::error, this, &TrayIcon::showInternalError); connect(connection, &SyncthingConnection::error, this, &TrayIcon::showInternalError);
connect(connection, &SyncthingConnection::newNotification, this, &TrayIcon::showSyncthingNotification); connect(connection, &SyncthingConnection::newNotification, this, &TrayIcon::showSyncthingNotification);
connect(connection, &SyncthingConnection::statusChanged, this, &TrayIcon::updateStatusIconAndText); 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) void TrayIcon::showInternalError(const QString &errorMsg)
{ {
if(Settings::notifyOnInternalErrors()) { 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()) { 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) QT_FORWARD_DECLARE_CLASS(QPixmap)
namespace ChronoUtilities {
class DateTime;
}
namespace Data { namespace Data {
enum class SyncthingStatus; enum class SyncthingStatus;
} }
@ -26,8 +30,9 @@ public:
private slots: private slots:
void handleActivated(QSystemTrayIcon::ActivationReason reason); void handleActivated(QSystemTrayIcon::ActivationReason reason);
void handleMessageClicked();
void showInternalError(const QString &errorMsg); void showInternalError(const QString &errorMsg);
void showSyncthingNotification(const QString &message); void showSyncthingNotification(ChronoUtilities::DateTime when, const QString &message);
void updateStatusIconAndText(Data::SyncthingStatus status); void updateStatusIconAndText(Data::SyncthingStatus status);
private: private:

View File

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

View File

@ -160,7 +160,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QFrame" name="trafficFrame"> <widget class="QFrame" name="infoFrame">
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
@ -254,6 +254,35 @@
</layout> </layout>
</widget> </widget>
</item> </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> <item>
<widget class="QPushButton" name="connectionsPushButton"> <widget class="QPushButton" name="connectionsPushButton">
<property name="sizePolicy"> <property name="sizePolicy">
@ -263,7 +292,8 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="icon"> <property name="icon">
<iconset theme="network-connect"/> <iconset theme="network-connect">
<normaloff>.</normaloff>.</iconset>
</property> </property>
<property name="flat"> <property name="flat">
<bool>true</bool> <bool>true</bool>

View File

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

View File

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