From 9fa2a028e8bd03312c4254333998d58469e6bd16 Mon Sep 17 00:00:00 2001 From: Martchus Date: Tue, 4 Oct 2016 23:42:17 +0200 Subject: [PATCH] Show out of sync directory state --- cli/application.cpp | 7 + connector/syncthingconnection.cpp | 91 +++++--- connector/syncthingconnection.h | 27 ++- model/syncthingdirectorymodel.cpp | 4 +- tray/gui/dirview.cpp | 29 ++- tray/gui/trayicon.cpp | 52 +++-- tray/gui/trayicon.h | 1 + tray/gui/traywidget.cpp | 4 +- tray/translations/syncthingtray_de_DE.ts | 270 ++++++++++++----------- tray/translations/syncthingtray_en_US.ts | 270 ++++++++++++----------- 10 files changed, 425 insertions(+), 330 deletions(-) diff --git a/cli/application.cpp b/cli/application.cpp index df76ada..efeb671 100644 --- a/cli/application.cpp +++ b/cli/application.cpp @@ -321,6 +321,13 @@ void Application::printStatus(const ArgumentOccurrence &) printProperty("Auto-normalize", dir->autoNormalize); printProperty("Rescan interval", TimeSpan::fromSeconds(dir->rescanInterval)); printProperty("Min. free disk percentage", dir->minDiskFreePercentage); + if(!dir->errors.empty()) { + cout << " Errors\n"; + for(const DirError &error : dir->errors) { + printProperty(" - Message", error.message); + printProperty(" File", error.path); + } + } cout << '\n'; } } diff --git a/connector/syncthingconnection.cpp b/connector/syncthingconnection.cpp index a26db5d..aa78d21 100644 --- a/connector/syncthingconnection.cpp +++ b/connector/syncthingconnection.cpp @@ -48,7 +48,7 @@ bool SyncthingDir::assignStatus(const QString &statusStr, ChronoUtilities::DateT DirStatus newStatus; if(statusStr == QLatin1String("idle")) { progressPercentage = 0; - newStatus = DirStatus::Idle; + newStatus = errors.empty() ? DirStatus::Idle : DirStatus::OutOfSync; } else if(statusStr == QLatin1String("scanning")) { newStatus = DirStatus::Scanning; } else if(statusStr == QLatin1String("syncing")) { @@ -61,7 +61,7 @@ bool SyncthingDir::assignStatus(const QString &statusStr, ChronoUtilities::DateT progressPercentage = 0; newStatus = DirStatus::OutOfSync; } else { - newStatus = DirStatus::Unknown; + newStatus = errors.empty() ? DirStatus::Idle : DirStatus::OutOfSync; } if(newStatus != status) { switch(status) { @@ -84,6 +84,16 @@ bool SyncthingDir::assignStatus(DirStatus newStatus, DateTime time) } else { lastStatusUpdate = time; } + switch(newStatus) { + case DirStatus::Idle: + case DirStatus::Unknown: + if(!errors.empty()) { + newStatus = DirStatus::OutOfSync; + } + break; + default: + ; + } if(newStatus != status) { switch(status) { case DirStatus::Scanning: @@ -174,8 +184,6 @@ QString SyncthingConnection::statusText() const return tr("reconnecting"); case SyncthingStatus::Idle: return tr("connected"); - case SyncthingStatus::NotificationsAvailable: - return tr("connected, notifications available"); case SyncthingStatus::Paused: return tr("connected, paused"); case SyncthingStatus::Synchronizing: @@ -185,6 +193,19 @@ QString SyncthingConnection::statusText() const } } +/*! + * \brief Returns whether there is at least one directory out-of-sync. + */ +bool SyncthingConnection::hasOutOfSyncDirs() const +{ + for(const SyncthingDir &dir : m_dirs) { + if(dir.status == DirStatus::OutOfSync) { + return true; + } + } + return false; +} + /*! * \brief Connects asynchronously to Syncthing. Does nothing if already connected. */ @@ -1222,9 +1243,13 @@ void SyncthingConnection::readDirEvent(DateTime eventTime, const QString &eventT for(const QJsonValue &errorVal : errors) { const QJsonObject error(errorVal.toObject()); if(!error.isEmpty()) { - dirInfo->errors.emplace_back(error.value(QStringLiteral("error")).toString(), error.value(QStringLiteral("path")).toString()); - dirInfo->assignStatus(DirStatus::OutOfSync, eventTime); - emitNotification(eventTime, dirInfo->errors.back().message); + auto &errors = dirInfo->errors; + DirError dirError(error.value(QStringLiteral("error")).toString(), error.value(QStringLiteral("path")).toString()); + if(find(errors.cbegin(), errors.cend(), dirError) == errors.cend()) { + errors.emplace_back(move(dirError)); + dirInfo->assignStatus(DirStatus::OutOfSync, eventTime); + emitNotification(eventTime, dirInfo->errors.back().message); + } } } emit dirStatusChanged(*dirInfo, index); @@ -1349,6 +1374,8 @@ 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); + dirInfo->status = DirStatus::OutOfSync; + emit dirStatusChanged(*dirInfo, index); emitNotification(eventTime, error); } } @@ -1438,38 +1465,34 @@ void SyncthingConnection::setStatus(SyncthingStatus status) case SyncthingStatus::Reconnecting: break; default: - if(m_unreadNotifications) { - status = SyncthingStatus::NotificationsAvailable; + // check whether at least one directory is scanning or synchronizing + bool scanning = false; + bool synchronizing = false; + 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; + } else if(scanning) { + status = SyncthingStatus::Scanning; } else { - // check whether at least one directory is scanning or synchronizing - bool scanning = false; - bool synchronizing = false; - for(const SyncthingDir &dir : m_dirs) { - if(dir.status == DirStatus::Synchronizing) { - synchronizing = true; + // check whether at least one device is paused + bool paused = false; + for(const SyncthingDev &dev : m_devs) { + if(dev.paused) { + paused = true; break; - } else if(dir.status == DirStatus::Scanning) { - scanning = true; } } - if(synchronizing) { - status = SyncthingStatus::Synchronizing; - } else if(scanning) { - status = SyncthingStatus::Scanning; + if(paused) { + status = SyncthingStatus::Paused; } else { - // check whether at least one device is paused - bool paused = false; - for(const SyncthingDev &dev : m_devs) { - if(dev.paused) { - paused = true; - break; - } - } - if(paused) { - status = SyncthingStatus::Paused; - } else { - status = SyncthingStatus::Idle; - } + status = SyncthingStatus::Idle; } } } diff --git a/connector/syncthingconnection.h b/connector/syncthingconnection.h index 2944003..76197c8 100644 --- a/connector/syncthingconnection.h +++ b/connector/syncthingconnection.h @@ -32,9 +32,9 @@ enum class SyncthingStatus Reconnecting, Idle, Scanning, - NotificationsAvailable, Paused, Synchronizing, + OutOfSync, BeingDestroyed }; @@ -48,12 +48,18 @@ enum class DirStatus OutOfSync }; -struct LIB_SYNCTHING_CONNECTOR_EXPORT DirErrors +struct LIB_SYNCTHING_CONNECTOR_EXPORT DirError { - DirErrors(const QString &message, const QString &path) : + DirError(const QString &message, const QString &path) : message(message), path(path) {} + + bool operator ==(const DirError &other) const + { + return message == other.message && path == other.path; + } + QString message; QString path; }; @@ -92,7 +98,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingDir ChronoUtilities::DateTime lastStatusUpdate; int progressPercentage = 0; int progressRate = 0; - std::vector errors; + std::vector errors; int globalBytes = 0, globalDeleted = 0, globalFiles = 0; int localBytes = 0, localDeleted = 0, localFiles = 0; int neededByted = 0, neededFiles = 0; @@ -157,6 +163,8 @@ class LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnection : public QObject Q_PROPERTY(QString syncthingUrl READ syncthingUrl WRITE setSyncthingUrl) Q_PROPERTY(QByteArray apiKey READ apiKey WRITE setApiKey) Q_PROPERTY(SyncthingStatus status READ status NOTIFY statusChanged) + Q_PROPERTY(bool hasUnreadNotifications READ hasUnreadNotifications) + Q_PROPERTY(bool hasOutOfSyncDirs READ hasOutOfSyncDirs) Q_PROPERTY(int trafficPollInterval READ trafficPollInterval WRITE setTrafficPollInterval) Q_PROPERTY(int devStatsPollInterval READ devStatsPollInterval WRITE setDevStatsPollInterval) Q_PROPERTY(QString configDir READ configDir NOTIFY configDirChanged) @@ -180,6 +188,8 @@ public: SyncthingStatus status() const; QString statusText() const; bool isConnected() const; + bool hasUnreadNotifications() const; + bool hasOutOfSyncDirs() const; int trafficPollInterval() const; void setTrafficPollInterval(int trafficPollInterval); int devStatsPollInterval() const; @@ -383,6 +393,15 @@ inline bool SyncthingConnection::isConnected() const return m_status != SyncthingStatus::Disconnected && m_status != SyncthingStatus::Reconnecting; } +/*! + * \brief Returns whether there are unread notifications available. + * \remarks This flag is set to true when new notifications become available. It can be unset again by calling considerAllNotificationsRead(). + */ +inline bool SyncthingConnection::hasUnreadNotifications() const +{ + return m_unreadNotifications; +} + /*! * \brief Returns the interval for polling traffic status (which currently can not be received via event API) in milliseconds. * \remarks Default value is 2000 milliseconds. diff --git a/model/syncthingdirectorymodel.cpp b/model/syncthingdirectorymodel.cpp index 18615b0..259cbc4 100644 --- a/model/syncthingdirectorymodel.cpp +++ b/model/syncthingdirectorymodel.cpp @@ -92,6 +92,7 @@ QVariant SyncthingDirectoryModel::data(const QModelIndex &index, int role) const case 4: return tr("Rescan interval"); case 5: return tr("Last scan"); case 6: return tr("Last file"); + case 7: return tr("Errors"); } break; case 1: // attribute values @@ -104,6 +105,7 @@ QVariant SyncthingDirectoryModel::data(const QModelIndex &index, int role) const case 4: return QString::fromLatin1(TimeSpan::fromSeconds(dir.rescanInterval).toString(TimeSpanOutputFormat::WithMeasures, true).data()); case 5: return dir.lastScanTime.isNull() ? tr("unknown") : QString::fromLatin1(dir.lastScanTime.toString(DateTimeOutputFormat::DateAndTime, true).data()); case 6: return dir.lastFileName.isEmpty() ? tr("unknown") : dir.lastFileName; + case 7: return dir.errors.empty() ? tr("none") : tr("%1 item(s) out of sync", nullptr, static_cast(dir.errors.size())).arg(dir.errors.size()); } break; } @@ -227,7 +229,7 @@ int SyncthingDirectoryModel::rowCount(const QModelIndex &parent) const if(!parent.isValid()) { return static_cast(m_dirs.size()); } else if(!parent.parent().isValid()) { - return 7; + return parent.parent().row() >= 0 && static_cast(parent.parent().row()) < m_dirs.size() && m_dirs[static_cast(parent.parent().row())].errors.empty() ? 6 : 7; } else { return 0; } diff --git a/tray/gui/dirview.cpp b/tray/gui/dirview.cpp index 5cd6c19..bf1d45c 100644 --- a/tray/gui/dirview.cpp +++ b/tray/gui/dirview.cpp @@ -1,7 +1,9 @@ #include "./dirview.h" #include "./dirbuttonsitemdelegate.h" +#include "./textviewdialog.h" #include "../../model/syncthingdirectorymodel.h" +#include "../../connector/syncthingconnection.h" #include #include @@ -9,6 +11,8 @@ #include #include #include +#include +#include using namespace Data; @@ -30,15 +34,26 @@ void DirView::mouseReleaseEvent(QMouseEvent *event) if(const SyncthingDirectoryModel *dirModel = qobject_cast(model())) { const QPoint pos(event->pos()); const QModelIndex clickedIndex(indexAt(event->pos())); - if(clickedIndex.isValid() && clickedIndex.column() == 1 && !clickedIndex.parent().isValid()) { + if(clickedIndex.isValid() && clickedIndex.column() == 1) { if(const SyncthingDir *dir = dirModel->dirInfo(clickedIndex)) { - const QRect itemRect(visualRect(clickedIndex)); - if(pos.x() > itemRect.right() - 34) { - if(pos.x() > itemRect.right() - 17) { - emit openDir(*dir); - } else { - emit scanDir(*dir); + if(!clickedIndex.parent().isValid()) { + // open/scan dir buttons + const QRect itemRect(visualRect(clickedIndex)); + if(pos.x() > itemRect.right() - 34) { + if(pos.x() > itemRect.right() - 17) { + emit openDir(*dir); + } else { + emit scanDir(*dir); + } } + } else if(clickedIndex.row() == 7) { + // show errors + auto *textViewDlg = new TextViewDialog(tr("Errors of %1").arg(dir->label.isEmpty() ? dir->id : dir->label)); + auto *browser = textViewDlg->browser(); + for(const DirError &error : dir->errors) { + browser->append(error.path % QChar(':') % QChar(' ') % QChar('\n') % error.message % QChar('\n')); + } + textViewDlg->show(); } } } diff --git a/tray/gui/trayicon.cpp b/tray/gui/trayicon.cpp index 897584e..757c2b0 100644 --- a/tray/gui/trayicon.cpp +++ b/tray/gui/trayicon.cpp @@ -29,6 +29,7 @@ TrayIcon::TrayIcon(QObject *parent) : m_statusIconNotify(QIcon(renderSvgImage(QStringLiteral(":/icons/hicolor/scalable/status/syncthing-notify.svg")))), m_statusIconPause(QIcon(renderSvgImage(QStringLiteral(":/icons/hicolor/scalable/status/syncthing-pause.svg")))), m_statusIconSync(QIcon(renderSvgImage(QStringLiteral(":/icons/hicolor/scalable/status/syncthing-sync.svg")))), + m_statusIconOutOfSync(QIcon(renderSvgImage(QStringLiteral(":/icons/hicolor/scalable/status/syncthing-error.svg")))), m_trayMenu(this), m_status(SyncthingStatus::Disconnected) { @@ -97,6 +98,7 @@ void TrayIcon::showSyncthingNotification(ChronoUtilities::DateTime when, const Q void TrayIcon::updateStatusIconAndText(SyncthingStatus status) { + const SyncthingConnection &connection = trayMenu().widget()->connection(); switch(status) { case SyncthingStatus::Disconnected: setIcon(m_statusIconDisconnected); @@ -109,26 +111,35 @@ void TrayIcon::updateStatusIconAndText(SyncthingStatus status) setIcon(m_statusIconDisconnected); setToolTip(tr("Reconnecting ...")); break; - case SyncthingStatus::Idle: - setIcon(m_statusIconIdling); - setToolTip(tr("Syncthing is idling")); - break; - case SyncthingStatus::Scanning: - setIcon(m_statusIconScanning); - setToolTip(tr("Syncthing is scanning")); - break; - case SyncthingStatus::NotificationsAvailable: - setIcon(m_statusIconNotify); - setToolTip(tr("Notifications available")); - break; - case SyncthingStatus::Paused: - setIcon(m_statusIconPause); - setToolTip(tr("At least one device is paused")); - break; - case SyncthingStatus::Synchronizing: - setIcon(m_statusIconSync); - setToolTip(tr("Synchronization is ongoing")); - break; + default: + if(connection.hasOutOfSyncDirs()) { + setIcon(m_statusIconOutOfSync); + setToolTip(tr("At least one directory is out of sync")); + } else if(connection.hasUnreadNotifications()) { + setIcon(m_statusIconNotify); + setToolTip(tr("Notifications available")); + } else { + switch(status) { + case SyncthingStatus::Idle: + setIcon(m_statusIconIdling); + setToolTip(tr("Syncthing is idling")); + break; + case SyncthingStatus::Scanning: + setIcon(m_statusIconScanning); + setToolTip(tr("Syncthing is scanning")); + break; + case SyncthingStatus::Paused: + setIcon(m_statusIconPause); + setToolTip(tr("At least one device is paused")); + break; + case SyncthingStatus::Synchronizing: + setIcon(m_statusIconSync); + setToolTip(tr("Synchronization is ongoing")); + break; + default: + ; + } + } } switch(status) { case SyncthingStatus::Disconnected: @@ -140,7 +151,6 @@ void TrayIcon::updateStatusIconAndText(SyncthingStatus status) showMessage(QCoreApplication::applicationName(), tr("Synchronization complete"), QSystemTrayIcon::Information); } } - m_status = status; } diff --git a/tray/gui/trayicon.h b/tray/gui/trayicon.h index 7fa5736..0d6bb06 100644 --- a/tray/gui/trayicon.h +++ b/tray/gui/trayicon.h @@ -41,6 +41,7 @@ private: const QIcon m_statusIconNotify; const QIcon m_statusIconPause; const QIcon m_statusIconSync; + const QIcon m_statusIconOutOfSync; TrayMenu m_trayMenu; QMenu m_contextMenu; Data::SyncthingStatus m_status; diff --git a/tray/gui/traywidget.cpp b/tray/gui/traywidget.cpp index e2cd51c..72331b2 100644 --- a/tray/gui/traywidget.cpp +++ b/tray/gui/traywidget.cpp @@ -275,7 +275,6 @@ void TrayWidget::handleStatusChanged(SyncthingStatus status) break; case SyncthingStatus::Idle: case SyncthingStatus::Scanning: - case SyncthingStatus::NotificationsAvailable: case SyncthingStatus::Synchronizing: m_ui->statusPushButton->setText(tr("Pause")); m_ui->statusPushButton->setToolTip(tr("Syncthing is running, click to pause all devices")); @@ -319,8 +318,8 @@ void TrayWidget::applySettings() if(!instance->m_selectedConnection) { instance->m_selectedConnection = &Settings::primaryConnectionSettings(); instance->m_connectionsMenu->actions().at(0)->setChecked(true); - instance->m_ui->connectionsPushButton->setText(instance->m_selectedConnection->label); } + instance->m_ui->connectionsPushButton->setText(instance->m_selectedConnection->label); instance->m_connection.reconnect(*instance->m_selectedConnection); @@ -392,7 +391,6 @@ void TrayWidget::changeStatus() break; case SyncthingStatus::Idle: case SyncthingStatus::Scanning: - case SyncthingStatus::NotificationsAvailable: case SyncthingStatus::Synchronizing: m_connection.pauseAllDevs(); break; diff --git a/tray/translations/syncthingtray_de_DE.ts b/tray/translations/syncthingtray_de_DE.ts index a965631..8b8c91c 100644 --- a/tray/translations/syncthingtray_de_DE.ts +++ b/tray/translations/syncthingtray_de_DE.ts @@ -159,6 +159,11 @@ Remove currently selected secondary instance + + + It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. + + Syncthing URL @@ -174,67 +179,62 @@ User + + + Password + + + + + API key + + + + + HTTPS certificate + + + + + Insert values from local Syncthing configuration + + + + + Status + + disconnected + + + Apply connection settings and try to reconnect with the currently selected config + + Poll interval + + + Traffic + + ms - - - Apply connection settings and try to reconnect with the currently selected config - - - - - Traffic - - Device statistics - - - It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. - - - - - HTTPS certificate - - - - - Status - - - - - API key - - - - - Insert values from local Syncthing configuration - - - - - Password - - Auto-detected for local instance @@ -282,17 +282,22 @@ QtGui::DirView - + + Errors of %1 + + + + Copy value - + Copy label/ID - + Copy path @@ -410,6 +415,11 @@ Tray + + + Web view + + Startup @@ -420,108 +430,129 @@ Settings - - - Web view - - QtGui::TrayIcon - + Web UI - + Settings - + Rescan all - + About - + Close - + Error - + Syncthing notification - click to dismiss - + Not connected to Syncthing - + Disconnected from Syncthing - + Reconnecting ... - + + At least one directory is out of sync + + + + Syncthing is idling - + Syncthing is scanning - + Notifications available - + At least one device is paused - + Synchronization is ongoing - + Synchronization complete QtGui::TrayWidget + + + Syncthing Tray + + Close + + + + About + + Connect + + + Settings + + + + + Web UI + + Traffic @@ -537,6 +568,18 @@ Incoming traffic + + + + + unknown + + + + + Out + + Outgoing traffic @@ -549,25 +592,9 @@ For <i>all</i> notifications, checkout the log - - Downloads - - - - - - - unknown - - - - - Syncthing Tray - - - - - Out + + + New notifications @@ -581,19 +608,8 @@ For <i>all</i> notifications, checkout the log - - - About - - - - - Settings - - - - - Web UI + + Downloads @@ -602,8 +618,8 @@ For <i>all</i> notifications, checkout the log - - Rescan all directories + + Restart Syncthing @@ -612,8 +628,8 @@ For <i>all</i> notifications, checkout the log - - Restart Syncthing + + Rescan all directories @@ -621,6 +637,11 @@ For <i>all</i> notifications, checkout the log Connection + + + Own device ID + + device ID is unknown @@ -632,9 +653,8 @@ For <i>all</i> notifications, checkout the log - - - New notifications + + Log @@ -643,43 +663,33 @@ For <i>all</i> notifications, checkout the log - + Pause - + Syncthing is running, click to pause all devices - - At least one device is paused, click to resume - - - - - The directory <i>%1</i> does not exist on the local machine. - - - - - The file <i>%1</i> does not exist on the local machine. - - - - + Continue - - Own device ID + + At least one device is paused, click to resume - - Log + + The directory <i>%1</i> does not exist on the local machine. + + + + + The file <i>%1</i> does not exist on the local machine. @@ -709,11 +719,6 @@ For <i>all</i> notifications, checkout the log Disable web view (open regular web browser instead) - - - Keep web view running when currently not shown - - Zoom factor @@ -724,6 +729,11 @@ For <i>all</i> notifications, checkout the log Hiding + + + Keep web view running when currently not shown + + Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine. diff --git a/tray/translations/syncthingtray_en_US.ts b/tray/translations/syncthingtray_en_US.ts index 902cdb3..406a457 100644 --- a/tray/translations/syncthingtray_en_US.ts +++ b/tray/translations/syncthingtray_en_US.ts @@ -159,6 +159,11 @@ Remove currently selected secondary instance + + + It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. + + Syncthing URL @@ -174,67 +179,62 @@ User + + + Password + + + + + API key + + + + + HTTPS certificate + + + + + Insert values from local Syncthing configuration + + + + + Status + + disconnected + + + Apply connection settings and try to reconnect with the currently selected config + + Poll interval + + + Traffic + + ms - - - Apply connection settings and try to reconnect with the currently selected config - - - - - Traffic - - Device statistics - - - It is possible to save multiple configurations. This allows switching quickly between multiple Syncthing instances using the connection button in the right corner of the tray menu. The config label is an arbitrary name to identify a configuration and does not have to match the name of the corresponding Syncthing device. - - - - - HTTPS certificate - - - - - Status - - - - - API key - - - - - Insert values from local Syncthing configuration - - - - - Password - - Auto-detected for local instance @@ -282,17 +282,22 @@ QtGui::DirView - + + Errors of %1 + + + + Copy value - + Copy label/ID - + Copy path @@ -410,6 +415,11 @@ Tray + + + Web view + + Startup @@ -420,108 +430,129 @@ Settings - - - Web view - - QtGui::TrayIcon - + Web UI - + Settings - + Rescan all - + About - + Close - + Error - + Syncthing notification - click to dismiss - + Not connected to Syncthing - + Disconnected from Syncthing - + Reconnecting ... - + + At least one directory is out of sync + + + + Syncthing is idling - + Syncthing is scanning - + Notifications available - + At least one device is paused - + Synchronization is ongoing - + Synchronization complete QtGui::TrayWidget + + + Syncthing Tray + + Close + + + + About + + Connect + + + Settings + + + + + Web UI + + Traffic @@ -537,6 +568,18 @@ Incoming traffic + + + + + unknown + + + + + Out + + Outgoing traffic @@ -549,25 +592,9 @@ For <i>all</i> notifications, checkout the log - - Downloads - - - - - - - unknown - - - - - Syncthing Tray - - - - - Out + + + New notifications @@ -581,19 +608,8 @@ For <i>all</i> notifications, checkout the log - - - About - - - - - Settings - - - - - Web UI + + Downloads @@ -602,8 +618,8 @@ For <i>all</i> notifications, checkout the log - - Rescan all directories + + Restart Syncthing @@ -612,8 +628,8 @@ For <i>all</i> notifications, checkout the log - - Restart Syncthing + + Rescan all directories @@ -621,6 +637,11 @@ For <i>all</i> notifications, checkout the log Connection + + + Own device ID + + device ID is unknown @@ -632,9 +653,8 @@ For <i>all</i> notifications, checkout the log - - - New notifications + + Log @@ -643,43 +663,33 @@ For <i>all</i> notifications, checkout the log - + Pause - + Syncthing is running, click to pause all devices - - At least one device is paused, click to resume - - - - - The directory <i>%1</i> does not exist on the local machine. - - - - - The file <i>%1</i> does not exist on the local machine. - - - - + Continue - - Own device ID + + At least one device is paused, click to resume - - Log + + The directory <i>%1</i> does not exist on the local machine. + + + + + The file <i>%1</i> does not exist on the local machine. @@ -709,11 +719,6 @@ For <i>all</i> notifications, checkout the log Disable web view (open regular web browser instead) - - - Keep web view running when currently not shown - - Zoom factor @@ -724,6 +729,11 @@ For <i>all</i> notifications, checkout the log Hiding + + + Keep web view running when currently not shown + + Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine.