Improve various details
This commit is contained in:
parent
4737268e20
commit
2360b2a482
|
@ -19,11 +19,15 @@ set(HEADER_FILES
|
|||
data/syncthingconnection.h
|
||||
data/syncthingdirectorymodel.h
|
||||
data/syncthingdevicemodel.h
|
||||
data/syncthingconfig.h
|
||||
data/utils.h
|
||||
)
|
||||
set(SRC_FILES
|
||||
data/syncthingconnection.cpp
|
||||
data/syncthingdirectorymodel.cpp
|
||||
data/syncthingdevicemodel.cpp
|
||||
data/syncthingconfig.cpp
|
||||
data/utils.cpp
|
||||
)
|
||||
|
||||
set(WIDGETS_HEADER_FILES
|
||||
|
@ -86,6 +90,7 @@ set(REQUIRED_ICONS
|
|||
network-card
|
||||
window-close
|
||||
edit-copy
|
||||
edit-paste
|
||||
preferences-other
|
||||
view-barcode
|
||||
folder-open
|
||||
|
@ -98,6 +103,13 @@ set(REQUIRED_ICONS
|
|||
network-server
|
||||
folder-sync
|
||||
internet-web-browser
|
||||
network-connect
|
||||
system-run
|
||||
system-search
|
||||
preferences-desktop
|
||||
preferences-desktop-notification
|
||||
preferences-desktop-icons
|
||||
preferences-desktop-locale
|
||||
)
|
||||
|
||||
# find c++utilities
|
||||
|
|
21
README.md
21
README.md
|
@ -2,14 +2,27 @@
|
|||
|
||||
Qt 5-based tray application for [Syncthing](https://github.com/syncthing/syncthing)
|
||||
|
||||
* Still under development
|
||||
* Designed to work under any desktop environment with tray icon support
|
||||
* Tested under Plasma 5 and Openbox/qt5ct/Tint2
|
||||
* Could be shown as regular window if no tray icon support is available
|
||||
* Doesn't require desktop environment specific libraries
|
||||
* Provides quick access to most frequently used features but does not intend to replace the official web UI
|
||||
* Check state of directories and devices
|
||||
* Check current traffic statistics
|
||||
* Display further details about direcoties and devices, like last file, last
|
||||
scan, ...
|
||||
* Trigger re-scan of a specific directory
|
||||
* Open a directory with the default file browser
|
||||
* Pause/resume devices
|
||||
* Shows Syncthing notifications
|
||||
* Does *not* allow configuring Syncthing itself (currently I do not intend to add this feature as it could cause more harm than good when not implemented correctly)
|
||||
* Provides quick access to the official web UI
|
||||
* Utilizes either Qt WebKit or Qt WebEngine
|
||||
* Can be built without web view support as well (then the web UI is opened in the regular browser)
|
||||
* Still under development; the following features are planned
|
||||
* Connect to multiple instances of Syncthing at a time
|
||||
* Add option to conveniently add the tray to the applications launched when the desktop environment starts
|
||||
* Add option to launch Syncthing when the tray is started and log stdout/stderr (would make sense for me under Windows, otherwise starting Syncthing via systemd is more preferable of course)
|
||||
|
||||
## Screenshots
|
||||
### Under Openbox/Tint2
|
||||
|
@ -36,3 +49,9 @@ The following Qt 5 modules are requried: core network gui widgets webenginewidge
|
|||
#### Select Qt modules for WebView
|
||||
* If Qt WebKitWidgets is installed on the system, the tray will link against it. Otherwise it will link against Qt WebEngineWidgets.
|
||||
* To force usage of Qt WebKit/Qt WebEngine or to disable both add `-DWEBVIEW_PROVIDER=webkit/webengine/none` to the CMake arguments.
|
||||
|
||||
BTW: I still prefer the deprecated Qt WebKit because
|
||||
* I currently don't know how to allow a particular self-signed certificate in Qt WebEngine. (Currently any self-signed certificate is accepted!)
|
||||
* Qt WebEngine can not be built with mingw-w64.
|
||||
* Qt WebEngine is more buggy in my experience.
|
||||
* security issues are not a concern because no other website than the Syncthing web UI is shown.
|
||||
|
|
|
@ -1,79 +1,87 @@
|
|||
#include "./settings.h"
|
||||
#include "../gui/trayicon.h"
|
||||
#include "../gui/traywidget.h"
|
||||
|
||||
#include "resources/config.h"
|
||||
|
||||
#include <c++utilities/application/argumentparser.h>
|
||||
#include <c++utilities/application/commandlineutils.h>
|
||||
#include <c++utilities/application/failure.h>
|
||||
|
||||
#include <qtutilities/resources/qtconfigarguments.h>
|
||||
#include <qtutilities/resources/resources.h>
|
||||
#include <qtutilities/resources/importplugin.h>
|
||||
#include <qtutilities/settingsdialog/qtsettings.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace ApplicationUtilities;
|
||||
using namespace QtGui;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SET_APPLICATION_INFO;
|
||||
// setup argument parser
|
||||
ArgumentParser parser;
|
||||
HelpArgument helpArg(parser);
|
||||
// Qt configuration arguments
|
||||
QT_CONFIG_ARGUMENTS qtConfigArgs;
|
||||
Argument windowedArg("windowed", 'w', "shows the UI in a regular window");
|
||||
windowedArg.setCombinable(true);
|
||||
qtConfigArgs.qtWidgetsGuiArg().addSubArgument(&windowedArg);
|
||||
parser.setMainArguments({&qtConfigArgs.qtWidgetsGuiArg(), &helpArg});
|
||||
try {
|
||||
parser.parseArgs(argc, argv);
|
||||
if(qtConfigArgs.qtWidgetsGuiArg().isPresent()) {
|
||||
SET_QT_APPLICATION_INFO;
|
||||
QApplication application(argc, argv);
|
||||
Settings::restore();
|
||||
Settings::qtSettings().apply();
|
||||
qtConfigArgs.applySettings(true);
|
||||
LOAD_QT_TRANSLATIONS;
|
||||
QtUtilitiesResources::init();
|
||||
int res;
|
||||
#ifndef QT_NO_SYSTEMTRAYICON
|
||||
if(QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
if(windowedArg.isPresent()) {
|
||||
TrayWidget trayWidget;
|
||||
trayWidget.show();
|
||||
res = application.exec();
|
||||
} else {
|
||||
application.setQuitOnLastWindowClosed(false);
|
||||
TrayIcon trayIcon;
|
||||
trayIcon.show();
|
||||
res = application.exec();
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(nullptr, QApplication::applicationName(), QApplication::translate("main", "The system tray is (currently) not available."));
|
||||
res = -1;
|
||||
}
|
||||
#else
|
||||
QMessageBox::critical(nullptr, QApplication::applicationName(), QApplication::translate("main", "The Qt libraries have not been built with tray icon support."));
|
||||
res = -2;
|
||||
#endif
|
||||
Settings::save();
|
||||
QtUtilitiesResources::cleanup();
|
||||
return res;
|
||||
}
|
||||
} catch(const Failure &ex) {
|
||||
CMD_UTILS_START_CONSOLE;
|
||||
cout << "Unable to parse arguments. " << ex.what() << "\nSee --help for available commands." << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "./settings.h"
|
||||
#include "../gui/trayicon.h"
|
||||
#include "../gui/traywidget.h"
|
||||
|
||||
#include "resources/config.h"
|
||||
|
||||
#include <c++utilities/application/argumentparser.h>
|
||||
#include <c++utilities/application/commandlineutils.h>
|
||||
#include <c++utilities/application/failure.h>
|
||||
|
||||
#include <qtutilities/resources/qtconfigarguments.h>
|
||||
#include <qtutilities/resources/resources.h>
|
||||
#include <qtutilities/resources/importplugin.h>
|
||||
#include <qtutilities/settingsdialog/qtsettings.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace ApplicationUtilities;
|
||||
using namespace QtGui;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SET_APPLICATION_INFO;
|
||||
// setup argument parser
|
||||
ArgumentParser parser;
|
||||
HelpArgument helpArg(parser);
|
||||
// Qt configuration arguments
|
||||
QT_CONFIG_ARGUMENTS qtConfigArgs;
|
||||
Argument windowedArg("windowed", 'w', "opens the tray menu as a regular window");
|
||||
windowedArg.setCombinable(true);
|
||||
qtConfigArgs.qtWidgetsGuiArg().addSubArgument(&windowedArg);
|
||||
parser.setMainArguments({&qtConfigArgs.qtWidgetsGuiArg(), &helpArg});
|
||||
try {
|
||||
parser.parseArgs(argc, argv);
|
||||
if(qtConfigArgs.qtWidgetsGuiArg().isPresent()) {
|
||||
SET_QT_APPLICATION_INFO;
|
||||
QApplication application(argc, argv);
|
||||
Settings::restore();
|
||||
Settings::qtSettings().apply();
|
||||
qtConfigArgs.applySettings(true);
|
||||
LOAD_QT_TRANSLATIONS;
|
||||
QtUtilitiesResources::init();
|
||||
int res;
|
||||
if(windowedArg.isPresent()) {
|
||||
TrayWidget trayWidget;
|
||||
trayWidget.show();
|
||||
res = application.exec();
|
||||
} else {
|
||||
#ifndef QT_NO_SYSTEMTRAYICON
|
||||
if(QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
application.setQuitOnLastWindowClosed(false);
|
||||
TrayIcon trayIcon;
|
||||
trayIcon.show();
|
||||
if(Settings::firstLaunch()) {
|
||||
trayIcon.trayMenu().widget()->showSettingsDialog();
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setText(QCoreApplication::translate("main", "You must configure how to connect to Syncthing when using Syncthing Tray the first time."));
|
||||
msgBox.setInformativeText(QCoreApplication::translate("main", "Note that the settings dialog allows importing URL, credentials and API-key from the local Syncthing configuration."));
|
||||
msgBox.exec();
|
||||
}
|
||||
res = application.exec();
|
||||
} else {
|
||||
QMessageBox::critical(nullptr, QApplication::applicationName(), QApplication::translate("main", "The system tray is (currently) not available. You could open the tray menu as a regular window using the -w flag, though."));
|
||||
res = -1;
|
||||
}
|
||||
#else
|
||||
QMessageBox::critical(nullptr, QApplication::applicationName(), QApplication::translate("main", "The Qt libraries have not been built with tray icon support. You could open the tray menu as a regular window using the -w flag, though."));
|
||||
res = -2;
|
||||
#endif
|
||||
}
|
||||
Settings::save();
|
||||
QtUtilitiesResources::cleanup();
|
||||
return res;
|
||||
}
|
||||
} catch(const Failure &ex) {
|
||||
CMD_UTILS_START_CONSOLE;
|
||||
cout << "Unable to parse arguments. " << ex.what() << "\nSee --help for available commands." << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "./settings.h"
|
||||
|
||||
#include <qtutilities/settingsdialog/qtsettings.h>
|
||||
|
||||
#include <QString>
|
||||
|
@ -10,7 +11,13 @@ using namespace Media;
|
|||
|
||||
namespace Settings {
|
||||
|
||||
// tray
|
||||
bool &firstLaunch()
|
||||
{
|
||||
static bool v = false;
|
||||
return v;
|
||||
}
|
||||
|
||||
// connection
|
||||
QString &syncthingUrl()
|
||||
{
|
||||
static QString v;
|
||||
|
@ -36,12 +43,14 @@ QByteArray &apiKey()
|
|||
static QByteArray v;
|
||||
return v;
|
||||
}
|
||||
|
||||
// notifications
|
||||
bool ¬ifyOnDisconnect()
|
||||
{
|
||||
static bool v = true;
|
||||
return v;
|
||||
}
|
||||
bool ¬ifyOnErrors()
|
||||
bool ¬ifyOnInternalErrors()
|
||||
{
|
||||
static bool v = true;
|
||||
return v;
|
||||
|
@ -56,11 +65,20 @@ bool &showSyncthingNotifications()
|
|||
static bool v = true;
|
||||
return v;
|
||||
}
|
||||
|
||||
// appearance
|
||||
bool &showTraffic()
|
||||
{
|
||||
static bool v = true;
|
||||
return v;
|
||||
}
|
||||
QSize &trayMenuSize()
|
||||
{
|
||||
static QSize v(350, 300);
|
||||
return v;
|
||||
}
|
||||
|
||||
// autostart/launcher
|
||||
bool &launchSynchting()
|
||||
{
|
||||
static bool v = false;
|
||||
|
@ -108,16 +126,18 @@ void restore()
|
|||
QSettings settings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationName());
|
||||
|
||||
settings.beginGroup(QStringLiteral("tray"));
|
||||
firstLaunch() = !settings.contains(QStringLiteral("syncthingUrl"));
|
||||
syncthingUrl() = settings.value(QStringLiteral("syncthingUrl"), QStringLiteral("http://localhost:8080/")).toString();
|
||||
authEnabled() = settings.value(QStringLiteral("authEnabled"), false).toBool();
|
||||
userName() = settings.value(QStringLiteral("userName")).toString();
|
||||
password() = settings.value(QStringLiteral("password")).toString();
|
||||
apiKey() = settings.value(QStringLiteral("apiKey")).toByteArray();
|
||||
notifyOnDisconnect() = settings.value(QStringLiteral("notifyOnDisconnect"), true).toBool();
|
||||
notifyOnErrors() = settings.value(QStringLiteral("notifyOnErrors"), true).toBool();
|
||||
notifyOnInternalErrors() = settings.value(QStringLiteral("notifyOnErrors"), true).toBool();
|
||||
notifyOnSyncComplete() = settings.value(QStringLiteral("notifyOnSyncComplete"), true).toBool();
|
||||
showSyncthingNotifications() = settings.value(QStringLiteral("showSyncthingNotifications"), true).toBool();
|
||||
showTraffic() = settings.value(QStringLiteral("showTraffic"), true).toBool();
|
||||
trayMenuSize() = settings.value(QStringLiteral("trayMenuSize"), trayMenuSize()).toSize();
|
||||
launchSynchting() = settings.value(QStringLiteral("launchSynchting"), false).toBool();
|
||||
syncthingCommand() = settings.value(QStringLiteral("syncthingCommand"), QStringLiteral("syncthing")).toString();
|
||||
settings.endGroup();
|
||||
|
@ -145,10 +165,11 @@ void save()
|
|||
settings.setValue(QStringLiteral("password"), password());
|
||||
settings.setValue(QStringLiteral("apiKey"), apiKey());
|
||||
settings.setValue(QStringLiteral("notifyOnDisconnect"), notifyOnDisconnect());
|
||||
settings.setValue(QStringLiteral("notifyOnErrors"), notifyOnErrors());
|
||||
settings.setValue(QStringLiteral("notifyOnErrors"), notifyOnInternalErrors());
|
||||
settings.setValue(QStringLiteral("notifyOnSyncComplete"), notifyOnSyncComplete());
|
||||
settings.setValue(QStringLiteral("showSyncthingNotifications"), showSyncthingNotifications());
|
||||
settings.setValue(QStringLiteral("showTraffic"), showTraffic());
|
||||
settings.setValue(QStringLiteral("trayMenuSize"), trayMenuSize());
|
||||
settings.setValue(QStringLiteral("launchSynchting"), launchSynchting());
|
||||
settings.setValue(QStringLiteral("syncthingCommand"), syncthingCommand());
|
||||
settings.endGroup();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
QT_FORWARD_DECLARE_CLASS(QByteArray)
|
||||
QT_FORWARD_DECLARE_CLASS(QString)
|
||||
QT_FORWARD_DECLARE_CLASS(QSize)
|
||||
|
||||
namespace Media {
|
||||
enum class TagUsage;
|
||||
|
@ -19,21 +20,30 @@ class QtSettings;
|
|||
|
||||
namespace Settings {
|
||||
|
||||
bool &firstLaunch();
|
||||
|
||||
// connection
|
||||
QString &syncthingUrl();
|
||||
bool &authEnabled();
|
||||
QString &userName();
|
||||
QString &password();
|
||||
QByteArray &apiKey();
|
||||
|
||||
// notifications
|
||||
bool ¬ifyOnDisconnect();
|
||||
bool ¬ifyOnErrors();
|
||||
bool ¬ifyOnInternalErrors();
|
||||
bool ¬ifyOnSyncComplete();
|
||||
bool &showSyncthingNotifications();
|
||||
bool &showTraffic();
|
||||
|
||||
// apprearance
|
||||
bool &showTraffic();
|
||||
QSize &trayMenuSize();
|
||||
|
||||
// autostart/launcher
|
||||
bool &launchSynchting();
|
||||
QString &syncthingCommand();
|
||||
|
||||
// web view
|
||||
#if defined(SYNCTHINGTRAY_USE_WEBENGINE) || defined(SYNCTHINGTRAY_USE_WEBKIT)
|
||||
bool &webViewDisabled();
|
||||
double &webViewZoomFactor();
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
#include "syncthingconfig.h"
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QFile>
|
||||
|
||||
namespace Data {
|
||||
|
||||
/*!
|
||||
* \struct SyncthingConfig
|
||||
* \brief The SyncthingConfig struct holds the configuration of Syncthing itself read from config.xml in the Syncthing home directory.
|
||||
* \remarks Only a few fields are required since most of the Syncthing config can be accessed via SyncthingConnection class.
|
||||
*/
|
||||
|
||||
QString SyncthingConfig::locateConfigFile()
|
||||
{
|
||||
QString path = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("syncthing/config.xml"));
|
||||
if(path.isEmpty()) {
|
||||
path = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("Syncthing/config.xml"));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
QString SyncthingConfig::locateHttpsCertificate()
|
||||
{
|
||||
QString path = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("syncthing/https-cert.pem"));
|
||||
if(path.isEmpty()) {
|
||||
path = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("Syncthing/https-cert.pem"));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
bool SyncthingConfig::restore(const QString &configFilePath)
|
||||
{
|
||||
QFile configFile(configFilePath);
|
||||
if(!configFile.open(QFile::ReadOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QXmlStreamReader xmlReader(&configFile);
|
||||
bool ok = false;
|
||||
#include <qtutilities/misc/xmlparsermacros.h>
|
||||
children {
|
||||
// only version 16 supported, try to parse other versions anyways since the changes might not affect
|
||||
// the few parts read here
|
||||
version = attribute("version").toString();
|
||||
children {
|
||||
iftag("gui") {
|
||||
ok = true;
|
||||
guiEnabled = attributeFlag("enabled");
|
||||
guiEnforcesSecureConnection = attributeFlag("tls");
|
||||
children {
|
||||
iftag("address") {
|
||||
guiAddress = text;
|
||||
} eliftag("user") {
|
||||
guiUser = text;
|
||||
} eliftag("password") {
|
||||
guiPasswordHash = text;
|
||||
} eliftag("apikey") {
|
||||
guiApiKey = text;
|
||||
} else_skip
|
||||
}
|
||||
} else_skip
|
||||
}
|
||||
}
|
||||
#include <qtutilities/misc/undefxmlparsermacros.h>
|
||||
return ok;
|
||||
}
|
||||
|
||||
} // namespace Data
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef DATA_SYNCTHINGCONFIG_H
|
||||
#define DATA_SYNCTHINGCONFIG_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace Data {
|
||||
|
||||
struct SyncthingConfig
|
||||
{
|
||||
QString version;
|
||||
bool guiEnabled = false;
|
||||
bool guiEnforcesSecureConnection = false;
|
||||
QString guiAddress;
|
||||
QString guiUser;
|
||||
QString guiPasswordHash;
|
||||
QString guiApiKey;
|
||||
|
||||
static QString locateConfigFile();
|
||||
static QString locateHttpsCertificate();
|
||||
bool restore(const QString &configFilePath);
|
||||
};
|
||||
|
||||
|
||||
} // namespace Data
|
||||
|
||||
#endif // DATA_SYNCTHINGCONFIG_H
|
|
@ -1,4 +1,5 @@
|
|||
#include "./syncthingconnection.h"
|
||||
#include "./syncthingconfig.h"
|
||||
|
||||
#include <c++utilities/conversion/conversionexception.h>
|
||||
|
||||
|
@ -13,6 +14,7 @@
|
|||
#include <QAuthenticator>
|
||||
#include <QStringBuilder>
|
||||
#include <QTimer>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
@ -56,6 +58,13 @@ bool SyncthingDir::assignStatus(const QString &statusStr)
|
|||
newStatus = DirStatus::Unknown;
|
||||
}
|
||||
if(newStatus != status) {
|
||||
switch(status) {
|
||||
case DirStatus::Scanning:
|
||||
lastScanTime = DateTime::now();
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
status = newStatus;
|
||||
return true;
|
||||
}
|
||||
|
@ -67,6 +76,8 @@ bool SyncthingDir::assignStatus(const QString &statusStr)
|
|||
* \brief The SyncthingConnection class allows Qt applications to access Syncthing.
|
||||
*/
|
||||
|
||||
QList<QSslError> SyncthingConnection::m_expectedCertificateErrors;
|
||||
|
||||
/*!
|
||||
* \brief Constructs a new instance ready to connect. To establish the connection, call connect().
|
||||
*/
|
||||
|
@ -84,10 +95,12 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt
|
|||
m_totalOutgoingRate(0),
|
||||
m_configReply(nullptr),
|
||||
m_statusReply(nullptr),
|
||||
m_connectionsReply(nullptr),
|
||||
m_eventsReply(nullptr),
|
||||
m_unreadNotifications(false),
|
||||
m_hasConfig(false),
|
||||
m_hasStatus(false)
|
||||
m_hasStatus(false),
|
||||
m_lastFileDeleted(false)
|
||||
{}
|
||||
|
||||
/*!
|
||||
|
@ -226,17 +239,21 @@ QNetworkRequest SyncthingConnection::prepareRequest(const QString &path, const Q
|
|||
/*!
|
||||
* \brief Requests asynchronously data using the rest API.
|
||||
*/
|
||||
inline QNetworkReply *SyncthingConnection::requestData(const QString &path, const QUrlQuery &query, bool rest)
|
||||
QNetworkReply *SyncthingConnection::requestData(const QString &path, const QUrlQuery &query, bool rest)
|
||||
{
|
||||
return networkAccessManager().get(prepareRequest(path, query, rest));
|
||||
auto *reply = networkAccessManager().get(prepareRequest(path, query, rest));
|
||||
reply->ignoreSslErrors(m_expectedCertificateErrors);
|
||||
return reply;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Posts asynchronously data using the rest API.
|
||||
*/
|
||||
inline QNetworkReply *SyncthingConnection::postData(const QString &path, const QUrlQuery &query, const QByteArray &data)
|
||||
QNetworkReply *SyncthingConnection::postData(const QString &path, const QUrlQuery &query, const QByteArray &data)
|
||||
{
|
||||
return networkAccessManager().post(prepareRequest(path, query), data);
|
||||
auto *reply = networkAccessManager().post(prepareRequest(path, query), data);
|
||||
reply->ignoreSslErrors(m_expectedCertificateErrors);
|
||||
return reply;
|
||||
}
|
||||
|
||||
SyncthingDir *SyncthingConnection::findDirInfo(const QString &dir, int &row)
|
||||
|
@ -270,6 +287,8 @@ void SyncthingConnection::continueConnecting()
|
|||
{
|
||||
if(m_keepPolling && m_hasConfig && m_hasStatus) {
|
||||
requestConnections();
|
||||
requestDirStatistics();
|
||||
requestDeviceStatistics();
|
||||
// since config and status could be read successfully, let's poll for events
|
||||
m_lastEventId = 0;
|
||||
requestEvents();
|
||||
|
@ -318,13 +337,29 @@ void SyncthingConnection::requestStatus()
|
|||
/*!
|
||||
* \brief Requests current connections asynchronously.
|
||||
*
|
||||
* The signal devStatusChanged() is emitted for each device where the connection status has changed updated; error() is emitted in the error case.
|
||||
* The signal devStatusChanged() is emitted for each device where the connection status has changed; error() is emitted in the error case.
|
||||
*/
|
||||
void SyncthingConnection::requestConnections()
|
||||
{
|
||||
QObject::connect(m_connectionsReply = requestData(QStringLiteral("system/connections"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readConnections);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests directory statistics asynchronously.
|
||||
*/
|
||||
void SyncthingConnection::requestDirStatistics()
|
||||
{
|
||||
QObject::connect(requestData(QStringLiteral("stats/folder"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readDirStatistics);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests device statistics asynchronously.
|
||||
*/
|
||||
void SyncthingConnection::requestDeviceStatistics()
|
||||
{
|
||||
QObject::connect(requestData(QStringLiteral("stats/device"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readDeviceStatistics);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests the Syncthing events (since the last successful call) asynchronously.
|
||||
*
|
||||
|
@ -399,6 +434,37 @@ void SyncthingConnection::requestLog(std::function<void (const std::vector<Synct
|
|||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Locates and loads the (self-signed) certificate used by the Syncthing GUI.
|
||||
*/
|
||||
void SyncthingConnection::loadSelfSignedCertificate()
|
||||
{
|
||||
// only possible if the Syncthing instance is running on the local machine
|
||||
const QString host(QUrl(syncthingUrl()).host());
|
||||
if(host.compare(QLatin1String("localhost"), Qt::CaseInsensitive) != 0 && !QHostAddress().isLoopback()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ensure current exceptions for self-signed certificates are cleared
|
||||
m_expectedCertificateErrors.clear();
|
||||
// find cert
|
||||
const QString certPath = !m_configDir.isEmpty() ? (m_configDir + QStringLiteral("/https-cert.pem")) : SyncthingConfig::locateHttpsCertificate();
|
||||
if(certPath.isEmpty()) {
|
||||
emit error(tr("Unable to locate certificate used by Syncthing GUI."));
|
||||
return;
|
||||
}
|
||||
// add exception
|
||||
const QList<QSslCertificate> cert = QSslCertificate::fromPath(certPath);
|
||||
if(cert.isEmpty()) {
|
||||
emit error(tr("Unable to load certificate used by Syncthing GUI."));
|
||||
return;
|
||||
}
|
||||
m_expectedCertificateErrors << QSslError(QSslError::UnableToGetLocalIssuerCertificate, cert.at(0));
|
||||
m_expectedCertificateErrors << QSslError(QSslError::UnableToVerifyFirstCertificate, cert.at(0));
|
||||
m_expectedCertificateErrors << QSslError(QSslError::SelfSignedCertificate, cert.at(0));
|
||||
m_expectedCertificateErrors << QSslError(QSslError::HostNameMismatch, cert.at(0));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of requestConfig().
|
||||
*/
|
||||
|
@ -556,7 +622,7 @@ void SyncthingConnection::readConnections()
|
|||
double transferTime;
|
||||
if(!m_lastConnectionsUpdate.isNull() && ((transferTime = (DateTime::gmtNow() - m_lastConnectionsUpdate).totalSeconds()) != 0.0)) {
|
||||
m_totalIncomingRate = (totalIncomingTraffic - m_totalIncomingTraffic) * 0.008 / transferTime,
|
||||
m_totalOutgoingRate = (totalOutgoingTraffic - m_totalOutgoingTraffic) * 0.008 / transferTime;
|
||||
m_totalOutgoingRate = (totalOutgoingTraffic - m_totalOutgoingTraffic) * 0.008 / transferTime;
|
||||
} else {
|
||||
m_totalIncomingRate = m_totalOutgoingRate = 0.0;
|
||||
}
|
||||
|
@ -611,6 +677,108 @@ void SyncthingConnection::readConnections()
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of requestDirStatistics().
|
||||
* \remarks TODO
|
||||
*/
|
||||
void SyncthingConnection::readDirStatistics()
|
||||
{
|
||||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
reply->deleteLater();
|
||||
|
||||
switch(reply->error()) {
|
||||
case QNetworkReply::NoError: {
|
||||
QJsonParseError jsonError;
|
||||
const QJsonDocument replyDoc = QJsonDocument::fromJson(reply->readAll(), &jsonError);
|
||||
if(jsonError.error == QJsonParseError::NoError) {
|
||||
const QJsonObject replyObj(replyDoc.object());
|
||||
int index = 0;
|
||||
for(SyncthingDir &dirInfo : m_dirs) {
|
||||
const QJsonObject dirObj(replyObj.value(dirInfo.id).toObject());
|
||||
if(!dirObj.isEmpty()) {
|
||||
bool mod = false;
|
||||
try {
|
||||
dirInfo.lastScanTime = DateTime::fromIsoStringLocal(dirObj.value(QStringLiteral("lastScan")).toString().toUtf8().data());
|
||||
mod = true;
|
||||
} catch(const ConversionException &) {
|
||||
dirInfo.lastScanTime = DateTime();
|
||||
}
|
||||
const QJsonObject lastFileObj(dirObj.value(QStringLiteral("lastFile")).toObject());
|
||||
if(!lastFileObj.isEmpty()) {
|
||||
dirInfo.lastFileName = lastFileObj.value(QStringLiteral("filename")).toString();
|
||||
mod = true;
|
||||
if(!dirInfo.lastFileName.isEmpty()) {
|
||||
dirInfo.lastFileDeleted = lastFileObj.value(QStringLiteral("deleted")).toBool(false);
|
||||
try {
|
||||
dirInfo.lastFileTime = DateTime::fromIsoStringLocal(lastFileObj.value(QStringLiteral("at")).toString().toUtf8().data());
|
||||
if(dirInfo.lastFileTime > m_lastFileTime) {
|
||||
m_lastFileTime = dirInfo.lastFileTime,
|
||||
m_lastFileName = dirInfo.lastFileName,
|
||||
m_lastFileDeleted = dirInfo.lastFileDeleted;
|
||||
}
|
||||
} catch(const ConversionException &) {
|
||||
dirInfo.lastFileTime = DateTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mod) {
|
||||
emit dirStatusChanged(dirInfo, index);
|
||||
}
|
||||
}
|
||||
++index;
|
||||
}
|
||||
} else {
|
||||
emit error(tr("Unable to parse directory statistics: ") + jsonError.errorString());
|
||||
}
|
||||
} case QNetworkReply::OperationCanceledError:
|
||||
return; // intended, not an error
|
||||
default:
|
||||
emit error(tr("Unable to request directory statistics: ") + reply->errorString());
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of requestDeviceStatistics().
|
||||
* \remarks TODO
|
||||
*/
|
||||
void SyncthingConnection::readDeviceStatistics()
|
||||
{
|
||||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
reply->deleteLater();
|
||||
|
||||
switch(reply->error()) {
|
||||
case QNetworkReply::NoError: {
|
||||
QJsonParseError jsonError;
|
||||
const QJsonDocument replyDoc = QJsonDocument::fromJson(reply->readAll(), &jsonError);
|
||||
if(jsonError.error == QJsonParseError::NoError) {
|
||||
const QJsonObject replyObj(replyDoc.object());
|
||||
int index = 0;
|
||||
for(SyncthingDev &devInfo : m_devs) {
|
||||
const QJsonObject devObj(replyObj.value(devInfo.id).toObject());
|
||||
if(!devObj.isEmpty()) {
|
||||
try {
|
||||
devInfo.lastSeen = DateTime::fromIsoStringLocal(devObj.value(QStringLiteral("lastSeen")).toString().toUtf8().data());
|
||||
emit devStatusChanged(devInfo, index);
|
||||
} catch(const ConversionException &) {
|
||||
devInfo.lastSeen = DateTime();
|
||||
}
|
||||
}
|
||||
++index;
|
||||
}
|
||||
// since there seems no event for this data, just request every minute, FIXME: make interval configurable
|
||||
if(m_keepPolling) {
|
||||
QTimer::singleShot(60000, Qt::VeryCoarseTimer, this, SLOT(requestConnections()));
|
||||
}
|
||||
} else {
|
||||
emit error(tr("Unable to parse device statistics: ") + jsonError.errorString());
|
||||
}
|
||||
} case QNetworkReply::OperationCanceledError:
|
||||
return; // intended, not an error
|
||||
default:
|
||||
emit error(tr("Unable to request device statistics: ") + reply->errorString());
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of requestEvents().
|
||||
*/
|
||||
|
@ -635,7 +803,7 @@ void SyncthingConnection::readEvents()
|
|||
m_lastEventId = event.value(QStringLiteral("id")).toInt(m_lastEventId);
|
||||
DateTime eventTime;
|
||||
try {
|
||||
eventTime = DateTime::fromIsoString(event.value(QStringLiteral("time")).toString().toLocal8Bit().data()).first;
|
||||
eventTime = DateTime::fromIsoStringGmt(event.value(QStringLiteral("time")).toString().toLocal8Bit().data());
|
||||
} catch(const ConversionException &) {
|
||||
// ignore conversion error
|
||||
}
|
||||
|
@ -651,6 +819,10 @@ void SyncthingConnection::readEvents()
|
|||
readDirEvent(eventType, eventData);
|
||||
} else if(eventType.startsWith(QLatin1String("Device"))) {
|
||||
readDeviceEvent(eventTime, eventType, eventData);
|
||||
} else if(eventType == QLatin1String("ItemStarted")) {
|
||||
readItemStarted(eventTime, eventData);
|
||||
} else if(eventType == QLatin1String("ItemFinished")) {
|
||||
readItemFinished(eventTime, eventData);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -727,8 +899,13 @@ void SyncthingConnection::readStatusChangedEvent(const QJsonObject &eventData)
|
|||
* \remarks TODO
|
||||
*/
|
||||
void SyncthingConnection::readDownloadProgressEvent(const QJsonObject &eventData)
|
||||
{}
|
||||
{
|
||||
VAR_UNUSED(eventData)
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of requestEvents().
|
||||
*/
|
||||
void SyncthingConnection::readDirEvent(const QString &eventType, const QJsonObject &eventData)
|
||||
{
|
||||
const QString dir(eventData.value(QStringLiteral("folder")).toString());
|
||||
|
@ -743,6 +920,7 @@ void SyncthingConnection::readDirEvent(const QString &eventType, const QJsonObje
|
|||
const QJsonObject error(errorVal.toObject());
|
||||
if(!error.isEmpty()) {
|
||||
dirInfo->errors.emplace_back(error.value(QStringLiteral("error")).toString(), error.value(QStringLiteral("path")).toString());
|
||||
dirInfo->status = DirStatus::OutOfSync;
|
||||
emit newNotification(dirInfo->errors.back().message);
|
||||
}
|
||||
}
|
||||
|
@ -774,9 +952,9 @@ void SyncthingConnection::readDirEvent(const QString &eventType, const QJsonObje
|
|||
}
|
||||
} else if(eventType == QLatin1String("FolderScanProgress")) {
|
||||
// FIXME: for some reason current is always 0
|
||||
int current = eventData.value(QStringLiteral("current")).toInt(0);
|
||||
int total = eventData.value(QStringLiteral("total")).toInt(0);
|
||||
int rate = eventData.value(QStringLiteral("rate")).toInt(0);
|
||||
int current = eventData.value(QStringLiteral("current")).toInt(0),
|
||||
total = eventData.value(QStringLiteral("total")).toInt(0),
|
||||
rate = eventData.value(QStringLiteral("rate")).toInt(0);
|
||||
if(current > 0 && total > 0) {
|
||||
dirInfo->progressPercentage = current * 100 / total;
|
||||
dirInfo->progressRate = rate;
|
||||
|
@ -830,6 +1008,46 @@ void SyncthingConnection::readDeviceEvent(DateTime eventTime, const QString &eve
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of requestEvents().
|
||||
*/
|
||||
void SyncthingConnection::readItemStarted(DateTime eventTime, const QJsonObject &eventData)
|
||||
{
|
||||
VAR_UNUSED(eventTime)
|
||||
VAR_UNUSED(eventData)
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of requestEvents().
|
||||
*/
|
||||
void SyncthingConnection::readItemFinished(DateTime eventTime, const QJsonObject &eventData)
|
||||
{
|
||||
const QString dir(eventData.value(QStringLiteral("folder")).toString());
|
||||
if(!dir.isEmpty()) {
|
||||
int index;
|
||||
if(SyncthingDir *dirInfo = findDirInfo(dir, index)) {
|
||||
const QString error(eventData.value(QStringLiteral("error")).toString()),
|
||||
item(eventData.value(QStringLiteral("item")).toString());
|
||||
if(error.isEmpty()) {
|
||||
if(dirInfo->lastFileTime.isNull() || eventTime < dirInfo->lastFileTime) {
|
||||
dirInfo->lastFileTime = eventTime,
|
||||
dirInfo->lastFileName = item,
|
||||
dirInfo->lastFileDeleted = (eventData.value(QStringLiteral("action")) != QLatin1String("delete"));
|
||||
if(eventTime > m_lastFileTime) {
|
||||
m_lastFileTime = dirInfo->lastFileTime,
|
||||
m_lastFileName = dirInfo->lastFileName,
|
||||
m_lastFileDeleted = dirInfo->lastFileDeleted;
|
||||
}
|
||||
emit dirStatusChanged(*dirInfo, index);
|
||||
}
|
||||
} else {
|
||||
dirInfo->errors.emplace_back(error, item);
|
||||
emit newNotification(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Reads results of rescan().
|
||||
*/
|
||||
|
@ -841,7 +1059,7 @@ void SyncthingConnection::readRescan()
|
|||
case QNetworkReply::NoError:
|
||||
break;
|
||||
default:
|
||||
emit error(tr("Unable to request rescan: ") + reply->errorString());
|
||||
emit error(tr("Unable to request rescan: ") + reply->errorString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,7 +1074,7 @@ void SyncthingConnection::readPauseResume()
|
|||
case QNetworkReply::NoError:
|
||||
break;
|
||||
default:
|
||||
emit error(tr("Unable to request pause/resume: ") + reply->errorString());
|
||||
emit error(tr("Unable to request pause/resume: ") + reply->errorString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <c++utilities/chrono/datetime.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QSslError>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
@ -59,13 +61,17 @@ struct SyncthingDir
|
|||
bool autoNormalize = false;
|
||||
int rescanInterval = 0;
|
||||
int minDiskFreePercentage = 0;
|
||||
DirStatus status = DirStatus::Unknown;
|
||||
DirStatus status = DirStatus::Idle;
|
||||
int progressPercentage = 0;
|
||||
int progressRate = 0;
|
||||
std::vector<DirErrors> errors;
|
||||
int globalBytes = 0, globalDeleted = 0, globalFiles = 0;
|
||||
int localBytes = 0, localDeleted = 0, localFiles = 0;
|
||||
int neededByted = 0, neededFiles = 0;
|
||||
ChronoUtilities::DateTime lastScanTime;
|
||||
ChronoUtilities::DateTime lastFileTime;
|
||||
QString lastFileName;
|
||||
bool lastFileDeleted = false;
|
||||
|
||||
bool assignStatus(const QString &statusStr);
|
||||
};
|
||||
|
@ -98,6 +104,7 @@ struct SyncthingDev
|
|||
QString connectionAddress;
|
||||
QString connectionType;
|
||||
QString clientVersion;
|
||||
ChronoUtilities::DateTime lastSeen;
|
||||
};
|
||||
|
||||
struct SyncthingLogEntry
|
||||
|
@ -141,8 +148,10 @@ public:
|
|||
const std::vector<SyncthingDev> &devInfo() const;
|
||||
void requestQrCode(const QString &text, std::function<void (const QPixmap &)> callback);
|
||||
void requestLog(std::function<void (const std::vector<SyncthingLogEntry> &)> callback);
|
||||
static const QList<QSslError> &expectedCertificateErrors();
|
||||
|
||||
public Q_SLOTS:
|
||||
void loadSelfSignedCertificate();
|
||||
void connect();
|
||||
void disconnect();
|
||||
void reconnect();
|
||||
|
@ -226,6 +235,8 @@ private Q_SLOTS:
|
|||
void requestConfig();
|
||||
void requestStatus();
|
||||
void requestConnections();
|
||||
void requestDirStatistics();
|
||||
void requestDeviceStatistics();
|
||||
void requestEvents();
|
||||
void abortAllRequests();
|
||||
|
||||
|
@ -234,12 +245,16 @@ private Q_SLOTS:
|
|||
void readDevs(const QJsonArray &devs);
|
||||
void readStatus();
|
||||
void readConnections();
|
||||
void readDirStatistics();
|
||||
void readDeviceStatistics();
|
||||
void readEvents();
|
||||
void readStartingEvent(const QJsonObject &eventData);
|
||||
void readStatusChangedEvent(const QJsonObject &eventData);
|
||||
void readDownloadProgressEvent(const QJsonObject &eventData);
|
||||
void readDirEvent(const QString &eventType, const QJsonObject &eventData);
|
||||
void readDeviceEvent(ChronoUtilities::DateTime eventTime, const QString &eventType, const QJsonObject &eventData);
|
||||
void readItemStarted(ChronoUtilities::DateTime eventTime, const QJsonObject &eventData);
|
||||
void readItemFinished(ChronoUtilities::DateTime eventTime, const QJsonObject &eventData);
|
||||
void readRescan();
|
||||
void readPauseResume();
|
||||
|
||||
|
@ -277,6 +292,10 @@ private:
|
|||
std::vector<SyncthingDir> m_dirs;
|
||||
std::vector<SyncthingDev> m_devs;
|
||||
ChronoUtilities::DateTime m_lastConnectionsUpdate;
|
||||
ChronoUtilities::DateTime m_lastFileTime;
|
||||
QString m_lastFileName;
|
||||
bool m_lastFileDeleted;
|
||||
static QList<QSslError> m_expectedCertificateErrors;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -419,6 +438,15 @@ inline const std::vector<SyncthingDev> &SyncthingConnection::devInfo() const
|
|||
return m_devs;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a list of all expected certificate errors.
|
||||
* \remarks This list is shared by all instances and updated via loadSelfSignedCertificate().
|
||||
*/
|
||||
inline const QList<QSslError> &SyncthingConnection::expectedCertificateErrors()
|
||||
{
|
||||
return m_expectedCertificateErrors;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // SYNCTHINGCONNECTION_H
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "./syncthingdevicemodel.h"
|
||||
#include "./syncthingconnection.h"
|
||||
#include "./utils.h"
|
||||
|
||||
using namespace ChronoUtilities;
|
||||
|
||||
namespace Data {
|
||||
|
||||
|
@ -83,9 +86,10 @@ QVariant SyncthingDeviceModel::data(const QModelIndex &index, int role) const
|
|||
switch(index.row()) {
|
||||
case 0: return tr("ID");
|
||||
case 1: return tr("Addresses");
|
||||
case 2: return tr("Compression");
|
||||
case 3: return tr("Certificate");
|
||||
case 4: return tr("Introducer");
|
||||
case 2: return tr("Last seen");
|
||||
case 3: return tr("Compression");
|
||||
case 4: return tr("Certificate");
|
||||
case 5: return tr("Introducer");
|
||||
}
|
||||
break;
|
||||
case 1: // attribute values
|
||||
|
@ -93,13 +97,44 @@ QVariant SyncthingDeviceModel::data(const QModelIndex &index, int role) const
|
|||
switch(index.row()) {
|
||||
case 0: return dev.id;
|
||||
case 1: return dev.addresses.join(QStringLiteral(", "));
|
||||
case 2: return dev.compression;
|
||||
case 3: return dev.certName.isEmpty() ? tr("none") : dev.certName;
|
||||
case 4: return dev.introducer ? tr("yes") : tr("no");
|
||||
case 2: return dev.lastSeen.isNull() ? tr("unknown or own device") : QString::fromLatin1(dev.lastSeen.toString(DateTimeOutputFormat::DateAndTime, true).data());
|
||||
case 3: return dev.compression;
|
||||
case 4: return dev.certName.isEmpty() ? tr("none") : dev.certName;
|
||||
case 5: return dev.introducer ? tr("yes") : tr("no");
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Qt::ForegroundRole:
|
||||
switch(index.column()) {
|
||||
case 1:
|
||||
const SyncthingDev &dev = m_devs[index.parent().row()];
|
||||
switch(index.row()) {
|
||||
case 2:
|
||||
if(dev.lastSeen.isNull()) {
|
||||
return QColor(Qt::gray);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(dev.certName.isEmpty()) {
|
||||
return QColor(Qt::gray);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Qt::ToolTipRole:
|
||||
switch(index.column()) {
|
||||
case 1:
|
||||
switch(index.row()) {
|
||||
case 2:
|
||||
const SyncthingDev &dev = m_devs[index.parent().row()];
|
||||
if(!dev.lastSeen.isNull()) {
|
||||
return agoString(dev.lastSeen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
@ -196,7 +231,7 @@ int SyncthingDeviceModel::rowCount(const QModelIndex &parent) const
|
|||
if(!parent.isValid()) {
|
||||
return m_devs.size();
|
||||
} else if(!parent.parent().isValid()) {
|
||||
return 5;
|
||||
return 6;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "./syncthingdirectorymodel.h"
|
||||
#include "./syncthingconnection.h"
|
||||
#include "./utils.h"
|
||||
|
||||
using namespace ChronoUtilities;
|
||||
|
||||
namespace Data {
|
||||
|
||||
|
@ -86,6 +89,8 @@ QVariant SyncthingDirectoryModel::data(const QModelIndex &index, int role) const
|
|||
case 2: return tr("Devices");
|
||||
case 3: return tr("Read-only");
|
||||
case 4: return tr("Rescan interval");
|
||||
case 5: return tr("Last scan");
|
||||
case 6: return tr("Last file");
|
||||
}
|
||||
break;
|
||||
case 1: // attribute values
|
||||
|
@ -96,10 +101,53 @@ QVariant SyncthingDirectoryModel::data(const QModelIndex &index, int role) const
|
|||
case 2: return dir.devices.join(QStringLiteral(", "));
|
||||
case 3: return dir.readOnly ? tr("yes") : tr("no");
|
||||
case 4: return QStringLiteral("%1 s").arg(dir.rescanInterval);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Qt::ForegroundRole:
|
||||
switch(index.column()) {
|
||||
case 1:
|
||||
const SyncthingDir &dir = m_dirs[index.parent().row()];
|
||||
switch(index.row()) {
|
||||
case 5:
|
||||
if(dir.lastScanTime.isNull()) {
|
||||
return QColor(Qt::gray);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if(dir.lastFileName.isEmpty()) {
|
||||
return QColor(Qt::gray);
|
||||
} else if(dir.lastFileDeleted) {
|
||||
return QColor(Qt::red);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Qt::ToolTipRole:
|
||||
switch(index.column()) {
|
||||
case 1:
|
||||
const SyncthingDir &dir = m_dirs[index.parent().row()];
|
||||
switch(index.row()) {
|
||||
case 5:
|
||||
if(!dir.lastScanTime.isNull()) {
|
||||
return agoString(dir.lastScanTime);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if(!dir.lastFileTime.isNull()) {
|
||||
if(dir.lastFileDeleted) {
|
||||
return tr("Deleted at %1").arg(QString::fromLatin1(dir.lastFileTime.toString(DateTimeOutputFormat::DateAndTime, true).data()));
|
||||
} else {
|
||||
return tr("Updated at %1").arg(QString::fromLatin1(dir.lastFileTime.toString(DateTimeOutputFormat::DateAndTime, true).data()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
@ -177,7 +225,7 @@ int SyncthingDirectoryModel::rowCount(const QModelIndex &parent) const
|
|||
if(!parent.isValid()) {
|
||||
return m_dirs.size();
|
||||
} else if(!parent.parent().isValid()) {
|
||||
return 5;
|
||||
return 7;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#include "utils.h"
|
||||
|
||||
#include <c++utilities/chrono/datetime.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace ChronoUtilities;
|
||||
|
||||
namespace Data {
|
||||
|
||||
QString agoString(DateTime dateTime)
|
||||
{
|
||||
const TimeSpan delta(DateTime::now() - dateTime);
|
||||
if(!delta.isNegative() && static_cast<uint64>(delta.totalTicks()) > (TimeSpan::ticksPerMinute / 4uL)) {
|
||||
return QCoreApplication::translate("Data::Utils", "%1 ago").arg(QString::fromLatin1(delta.toString(TimeSpanOutputFormat::WithMeasures, true).data()));
|
||||
} else {
|
||||
return QCoreApplication::translate("Data::Utils", "right now");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef DATA_UTILS_H
|
||||
#define DATA_UTILS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QString)
|
||||
|
||||
namespace ChronoUtilities {
|
||||
class DateTime;
|
||||
}
|
||||
|
||||
namespace Data {
|
||||
|
||||
QString agoString(ChronoUtilities::DateTime dateTime);
|
||||
|
||||
}
|
||||
|
||||
#endif // DATA_UTILS_H
|
|
@ -2,29 +2,85 @@
|
|||
<ui version="4.0">
|
||||
<class>QtGui::AppearanceOptionPage</class>
|
||||
<widget class="QWidget" name="QtGui::AppearanceOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>283</width>
|
||||
<height>74</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Appearance</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showTrafficCheckBox">
|
||||
<property name="windowIcon">
|
||||
<iconset theme="preferences-desktop"/>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="sizeLabel">
|
||||
<property name="text">
|
||||
<string>Show traffic</string>
|
||||
<string>Menu size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="guiElementsLabel">
|
||||
<property name="text">
|
||||
<string>Optional GUI elements</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="showTrafficCheckBox">
|
||||
<property name="text">
|
||||
<string>Traffic statistics</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="widthSpinBox">
|
||||
<property name="minimum">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sizeTimesLabel">
|
||||
<property name="text">
|
||||
<string>x</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="heightSpinBox">
|
||||
<property name="minimum">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sizePxLabel">
|
||||
<property name="text">
|
||||
<string>px</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
@ -2,9 +2,20 @@
|
|||
<ui version="4.0">
|
||||
<class>QtGui::AutostartOptionPage</class>
|
||||
<widget class="QWidget" name="QtGui::AutostartOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>575</width>
|
||||
<height>52</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Autostart</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset theme="system-run"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
|
|
|
@ -2,17 +2,12 @@
|
|||
<ui version="4.0">
|
||||
<class>QtGui::ConnectionOptionPage</class>
|
||||
<widget class="QWidget" name="QtGui::ConnectionOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>433</width>
|
||||
<height>267</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Connection</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset theme="network-connect"/>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="urlLabel">
|
||||
|
@ -71,28 +66,21 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="11" column="1">
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="text">
|
||||
<string>disconnected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="statusTextLabel">
|
||||
<property name="text">
|
||||
<string>Status</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="12" column="1">
|
||||
<widget class="QPushButton" name="connectPushButton">
|
||||
<property name="text">
|
||||
<string>Apply connection settings and try to reconnect</string>
|
||||
|
@ -113,6 +101,33 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QPushButton" name="insertFromConfigFilePushButton">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font-weight: bold;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Insert values from local Syncthing configuration</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="edit-paste">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="Line" name="line">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
|
|
@ -2,43 +2,46 @@
|
|||
<ui version="4.0">
|
||||
<class>QtGui::NotificationsOptionPage</class>
|
||||
<widget class="QWidget" name="QtGui::NotificationsOptionPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>175</width>
|
||||
<height>156</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Notifications</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset theme="preferences-desktop-notification">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="notifyOnLabel">
|
||||
<property name="text">
|
||||
<string>Notify on</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnDisconnectCheckBox">
|
||||
<property name="text">
|
||||
<string>Notify on disconnect</string>
|
||||
<string>disconnect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnErrorsCheckBox">
|
||||
<property name="text">
|
||||
<string>Notify on internal errors</string>
|
||||
<string>internal errors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showSyncthingNotificationsCheckBox">
|
||||
<property name="text">
|
||||
<string>Notify on Syncthing errors</string>
|
||||
<string>errors/notifications from Syncthing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="notifyOnSyncCompleteCheckBox">
|
||||
<property name="text">
|
||||
<string>Notify on sync complete</string>
|
||||
<string>sync complete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../application/settings.h"
|
||||
#include "../data/syncthingconnection.h"
|
||||
#include "../data/syncthingconfig.h"
|
||||
|
||||
#include "ui_connectionoptionpage.h"
|
||||
#include "ui_notificationsoptionpage.h"
|
||||
|
@ -9,6 +10,8 @@
|
|||
#include "ui_autostartoptionpage.h"
|
||||
#include "ui_webviewoptionpage.h"
|
||||
|
||||
#include "resources/config.h"
|
||||
|
||||
#include <tagparser/mediafileinfo.h>
|
||||
#include <tagparser/backuphelper.h>
|
||||
|
||||
|
@ -16,6 +19,10 @@
|
|||
#include <qtutilities/settingsdialog/optioncategorymodel.h>
|
||||
#include <qtutilities/settingsdialog/qtsettings.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace std;
|
||||
|
@ -40,12 +47,49 @@ QWidget *ConnectionOptionPage::setupWidget()
|
|||
updateConnectionStatus();
|
||||
QObject::connect(m_connection, &SyncthingConnection::statusChanged, bind(&ConnectionOptionPage::updateConnectionStatus, this));
|
||||
QObject::connect(ui()->connectPushButton, &QPushButton::clicked, bind(&ConnectionOptionPage::applyAndReconnect, this));
|
||||
QObject::connect(ui()->insertFromConfigFilePushButton, &QPushButton::clicked, bind(&ConnectionOptionPage::insertFromConfigFile, this));
|
||||
return w;
|
||||
}
|
||||
|
||||
void ConnectionOptionPage::insertFromConfigFile()
|
||||
{
|
||||
if(hasBeenShown()) {
|
||||
QString configFile = SyncthingConfig::locateConfigFile();
|
||||
if(configFile.isEmpty()) {
|
||||
// allow user to select config file manually if it could not be located
|
||||
configFile = QFileDialog::getOpenFileName(widget(), QCoreApplication::translate("QtGui::ConnectionOptionPage", "Select Syncthing config file") + QStringLiteral(" - " APP_NAME));
|
||||
}
|
||||
if(configFile.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SyncthingConfig config;
|
||||
if(!config.restore(configFile)) {
|
||||
QMessageBox::critical(widget(), widget()->windowTitle() + QStringLiteral(" - " APP_NAME), QCoreApplication::translate("QtGui::ConnectionOptionPage", "Unable to parse the Syncthing config file."));
|
||||
return;
|
||||
}
|
||||
if(!config.guiAddress.isEmpty()) {
|
||||
ui()->urlLineEdit->selectAll();
|
||||
ui()->urlLineEdit->insert(((config.guiEnforcesSecureConnection || !QHostAddress(config.guiAddress.mid(0, config.guiAddress.indexOf(QChar(':')))).isLoopback()) ? QStringLiteral("https://") : QStringLiteral("http://")) + config.guiAddress);
|
||||
}
|
||||
if(!config.guiUser.isEmpty() || !config.guiPasswordHash.isEmpty()) {
|
||||
ui()->authCheckBox->setChecked(true);
|
||||
ui()->userNameLineEdit->selectAll();
|
||||
ui()->userNameLineEdit->insert(config.guiUser);
|
||||
} else {
|
||||
ui()->authCheckBox->setChecked(false);
|
||||
}
|
||||
if(!config.guiApiKey.isEmpty()) {
|
||||
ui()->apiKeyLineEdit->selectAll();
|
||||
ui()->apiKeyLineEdit->insert(config.guiApiKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionOptionPage::updateConnectionStatus()
|
||||
{
|
||||
ui()->statusLabel->setText(m_connection->statusText());
|
||||
if(hasBeenShown()) {
|
||||
ui()->statusLabel->setText(m_connection->statusText());
|
||||
}
|
||||
}
|
||||
|
||||
bool ConnectionOptionPage::apply()
|
||||
|
@ -97,7 +141,7 @@ bool NotificationsOptionPage::apply()
|
|||
{
|
||||
if(hasBeenShown()) {
|
||||
notifyOnDisconnect() = ui()->notifyOnDisconnectCheckBox->isChecked();
|
||||
notifyOnErrors() = ui()->notifyOnErrorsCheckBox->isChecked();
|
||||
notifyOnInternalErrors() = ui()->notifyOnErrorsCheckBox->isChecked();
|
||||
notifyOnSyncComplete() = ui()->notifyOnSyncCompleteCheckBox->isChecked();
|
||||
showSyncthingNotifications() = ui()->showSyncthingNotificationsCheckBox->isChecked();
|
||||
}
|
||||
|
@ -108,7 +152,7 @@ void NotificationsOptionPage::reset()
|
|||
{
|
||||
if(hasBeenShown()) {
|
||||
ui()->notifyOnDisconnectCheckBox->setChecked(notifyOnDisconnect());
|
||||
ui()->notifyOnErrorsCheckBox->setChecked(notifyOnErrors());
|
||||
ui()->notifyOnErrorsCheckBox->setChecked(notifyOnInternalErrors());
|
||||
ui()->notifyOnSyncCompleteCheckBox->setChecked(notifyOnSyncComplete());
|
||||
ui()->showSyncthingNotificationsCheckBox->setChecked(showSyncthingNotifications());
|
||||
}
|
||||
|
@ -125,6 +169,8 @@ AppearanceOptionPage::~AppearanceOptionPage()
|
|||
bool AppearanceOptionPage::apply()
|
||||
{
|
||||
if(hasBeenShown()) {
|
||||
trayMenuSize().setWidth(ui()->widthSpinBox->value());
|
||||
trayMenuSize().setHeight(ui()->heightSpinBox->value());
|
||||
showTraffic() = ui()->showTrafficCheckBox->isChecked();
|
||||
}
|
||||
return true;
|
||||
|
@ -133,6 +179,8 @@ bool AppearanceOptionPage::apply()
|
|||
void AppearanceOptionPage::reset()
|
||||
{
|
||||
if(hasBeenShown()) {
|
||||
ui()->widthSpinBox->setValue(trayMenuSize().width());
|
||||
ui()->heightSpinBox->setValue(trayMenuSize().height());
|
||||
ui()->showTrafficCheckBox->setChecked(showTraffic());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ public:
|
|||
ConnectionOptionPage(Data::SyncthingConnection *connection, QWidget *parentWidget = nullptr);
|
||||
private:
|
||||
DECLARE_SETUP_WIDGETS
|
||||
void insertFromConfigFile();
|
||||
void updateConnectionStatus();
|
||||
void applyAndReconnect();
|
||||
Data::SyncthingConnection *m_connection;
|
||||
|
|
|
@ -43,7 +43,7 @@ TrayIcon::TrayIcon(QObject *parent) :
|
|||
// connect signals and slots
|
||||
SyncthingConnection *connection = &(m_trayMenu.widget()->connection());
|
||||
connect(this, &TrayIcon::activated, this, &TrayIcon::handleActivated);
|
||||
connect(connection, &SyncthingConnection::error, this, &TrayIcon::showSyncthingError);
|
||||
connect(connection, &SyncthingConnection::error, this, &TrayIcon::showInternalError);
|
||||
connect(connection, &SyncthingConnection::newNotification, this, &TrayIcon::showSyncthingNotification);
|
||||
connect(connection, &SyncthingConnection::statusChanged, this, &TrayIcon::updateStatusIconAndText);
|
||||
}
|
||||
|
@ -72,17 +72,17 @@ void TrayIcon::handleActivated(QSystemTrayIcon::ActivationReason reason)
|
|||
}
|
||||
}
|
||||
|
||||
void TrayIcon::showSyncthingError(const QString &errorMsg)
|
||||
void TrayIcon::showInternalError(const QString &errorMsg)
|
||||
{
|
||||
if(Settings::notifyOnErrors()) {
|
||||
showMessage(tr("Syncthing error"), errorMsg, QSystemTrayIcon::Critical);
|
||||
if(Settings::notifyOnInternalErrors()) {
|
||||
showMessage(tr("Error"), errorMsg, QSystemTrayIcon::Critical);
|
||||
}
|
||||
}
|
||||
|
||||
void TrayIcon::showSyncthingNotification(const QString &message)
|
||||
{
|
||||
if(Settings::showSyncthingNotifications()) {
|
||||
showMessage(tr("Syncthing notification"), message, QSystemTrayIcon::Information);
|
||||
showMessage(tr("Syncthing notification"), message, QSystemTrayIcon::Warning);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,10 +22,11 @@ class TrayIcon : public QSystemTrayIcon
|
|||
|
||||
public:
|
||||
TrayIcon(QObject *parent = nullptr);
|
||||
TrayMenu &trayMenu();
|
||||
|
||||
private slots:
|
||||
void handleActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
void showSyncthingError(const QString &errorMsg);
|
||||
void showInternalError(const QString &errorMsg);
|
||||
void showSyncthingNotification(const QString &message);
|
||||
void updateStatusIconAndText(Data::SyncthingStatus status);
|
||||
|
||||
|
@ -43,6 +44,11 @@ private:
|
|||
Data::SyncthingStatus m_status;
|
||||
};
|
||||
|
||||
inline TrayMenu &TrayIcon::trayMenu()
|
||||
{
|
||||
return m_trayMenu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TRAY_ICON_H
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "./traymenu.h"
|
||||
#include "./traywidget.h"
|
||||
|
||||
#include "../application/settings.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
namespace QtGui {
|
||||
|
@ -17,7 +19,7 @@ TrayMenu::TrayMenu(QWidget *parent) :
|
|||
|
||||
QSize TrayMenu::sizeHint() const
|
||||
{
|
||||
return QSize(350, 300);
|
||||
return Settings::trayMenuSize();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ TrayWidget::TrayWidget(TrayMenu *parent) :
|
|||
connect(m_ui->settingsPushButton, &QPushButton::clicked, this, &TrayWidget::showSettingsDialog);
|
||||
connect(&m_connection, &SyncthingConnection::statusChanged, this, &TrayWidget::updateStatusButton);
|
||||
connect(&m_connection, &SyncthingConnection::trafficChanged, this, &TrayWidget::updateTraffic);
|
||||
connect(&m_connection, &SyncthingConnection::newNotification, this, &TrayWidget::handleNewNotification);
|
||||
connect(m_ui->dirsTreeView, &DirView::openDir, this, &TrayWidget::openDir);
|
||||
connect(m_ui->dirsTreeView, &DirView::scanDir, this, &TrayWidget::scanDir);
|
||||
connect(m_ui->devsTreeView, &DevView::pauseResumeDev, this, &TrayWidget::pauseResumeDev);
|
||||
|
@ -109,7 +110,7 @@ void TrayWidget::showSettingsDialog()
|
|||
{
|
||||
if(!m_settingsDlg) {
|
||||
m_settingsDlg = new SettingsDialog(&m_connection, this);
|
||||
m_settingsDlg->setWindowTitle(tr("Settings - Syncthing tray"));
|
||||
m_settingsDlg->setWindowTitle(tr("Settings") + QStringLiteral(" - " APP_NAME));
|
||||
connect(m_settingsDlg, &SettingsDialog::applied, this, &TrayWidget::applySettings);
|
||||
#ifndef SYNCTHINGTRAY_NO_WEBVIEW
|
||||
if(m_webViewDlg) {
|
||||
|
@ -128,8 +129,8 @@ void TrayWidget::showSettingsDialog()
|
|||
void TrayWidget::showAboutDialog()
|
||||
{
|
||||
if(!m_aboutDlg) {
|
||||
m_aboutDlg = new AboutDialog(this, QString(), QStringLiteral(APP_AUTHOR "\nfallback icons from KDE/Breeze project\nSyncthing icons from Syncthing project"), QString(), QString(), tr("Tray application for Syncthing"), QImage(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
|
||||
m_aboutDlg->setWindowTitle(tr("About - Syncthing Tray"));
|
||||
m_aboutDlg = new AboutDialog(this, QString(), QStringLiteral(APP_AUTHOR "\nfallback icons from KDE/Breeze project\nSyncthing icons from Syncthing project"), QString(), QString(), QStringLiteral(APP_DESCRIPTION), QImage(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
|
||||
m_aboutDlg->setWindowTitle(tr("About") + QStringLiteral(" - " APP_NAME));
|
||||
m_aboutDlg->setWindowIcon(QIcon(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
|
||||
}
|
||||
m_aboutDlg->show();
|
||||
|
@ -167,7 +168,7 @@ void TrayWidget::showWebUi()
|
|||
void TrayWidget::showOwnDeviceId()
|
||||
{
|
||||
auto *dlg = new QDialog(this);
|
||||
dlg->setWindowTitle(tr("Own device ID - Syncthing Tray"));
|
||||
dlg->setWindowTitle(tr("Own device ID") + QStringLiteral(" - " APP_NAME));
|
||||
dlg->setWindowIcon(QIcon(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg")));
|
||||
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dlg->setBackgroundRole(QPalette::Background);
|
||||
|
@ -201,7 +202,7 @@ void TrayWidget::showOwnDeviceId()
|
|||
void TrayWidget::showLog()
|
||||
{
|
||||
auto *dlg = new QDialog(this);
|
||||
dlg->setWindowTitle(tr("Log - Syncthing"));
|
||||
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);
|
||||
|
@ -255,6 +256,7 @@ void TrayWidget::applySettings()
|
|||
} else {
|
||||
m_connection.setCredentials(QString(), QString());
|
||||
}
|
||||
m_connection.loadSelfSignedCertificate();
|
||||
m_connection.reconnect();
|
||||
m_ui->trafficFrame->setVisible(Settings::showTraffic());
|
||||
if(Settings::showTraffic()) {
|
||||
|
@ -268,7 +270,7 @@ void TrayWidget::openDir(const QModelIndex &dirIndex)
|
|||
if(QDir(dir->path).exists()) {
|
||||
DesktopUtils::openLocalFileOrDir(dir->path);
|
||||
} else {
|
||||
QMessageBox::warning(this, QCoreApplication::applicationName(), tr("The directly <i>%1</i> does not exist on the local machine.").arg(dir->path));
|
||||
QMessageBox::warning(this, QCoreApplication::applicationName(), tr("The directory <i>%1</i> does not exist on the local machine.").arg(dir->path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -335,4 +337,9 @@ void TrayWidget::handleWebViewDeleted()
|
|||
m_webViewDlg = nullptr;
|
||||
}
|
||||
|
||||
void TrayWidget::handleNewNotification(const QString &msg)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ private slots:
|
|||
void changeStatus();
|
||||
void updateTraffic();
|
||||
void handleWebViewDeleted();
|
||||
void handleNewNotification(const QString &msg);
|
||||
|
||||
private:
|
||||
TrayMenu *m_menu;
|
||||
|
|
|
@ -13,12 +13,16 @@
|
|||
#if defined(SYNCTHINGTRAY_USE_WEBENGINE)
|
||||
# include <QWebEngineSettings>
|
||||
# include <QWebEngineView>
|
||||
# include <QWebEngineCertificateError>
|
||||
#elif defined(SYNCTHINGTRAY_USE_WEBKIT)
|
||||
# include <QWebSettings>
|
||||
# include <QWebView>
|
||||
# include <QWebFrame>
|
||||
# include <QSslError>
|
||||
#endif
|
||||
|
||||
using namespace Data;
|
||||
|
||||
namespace QtGui {
|
||||
|
||||
WebPage::WebPage(WEB_VIEW_PROVIDER *view) :
|
||||
|
@ -32,6 +36,7 @@ WebPage::WebPage(WEB_VIEW_PROVIDER *view) :
|
|||
settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
|
||||
setNetworkAccessManager(&Data::networkAccessManager());
|
||||
connect(&Data::networkAccessManager(), &QNetworkAccessManager::authenticationRequired, this, static_cast<void(WebPage::*)(QNetworkReply *, QAuthenticator *)>(&WebPage::supplyCredentials));
|
||||
connect(&Data::networkAccessManager(), &QNetworkAccessManager::sslErrors, this, static_cast<void(WebPage::*)(QNetworkReply *, const QList<QSslError> &errors)>(&WebPage::handleSslErrors));
|
||||
#endif
|
||||
if(!m_view) {
|
||||
// delegate to external browser if no view is assigned
|
||||
|
@ -50,9 +55,24 @@ WEB_PAGE_PROVIDER *WebPage::createWindow(WEB_PAGE_PROVIDER::WebWindowType type)
|
|||
return new WebPage;
|
||||
}
|
||||
|
||||
#ifdef SYNCTHINGTRAY_USE_WEBENGINE
|
||||
bool WebPage::certificateError(const QWebEngineCertificateError &certificateError)
|
||||
{
|
||||
switch(certificateError.error()) {
|
||||
case QWebEngineCertificateError::CertificateCommonNameInvalid:
|
||||
case QWebEngineCertificateError::CertificateAuthorityInvalid:
|
||||
// FIXME: only ignore the error if the used certificate matches the certificate
|
||||
// known to be used by the Syncthing GUI
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebPage::delegateToExternalBrowser(const QUrl &url)
|
||||
{
|
||||
openUrlExternal(url);
|
||||
QDesktopServices::openUrl(url);
|
||||
// this page and the associated view are useless
|
||||
m_view->deleteLater();
|
||||
deleteLater();
|
||||
|
@ -78,10 +98,14 @@ void WebPage::supplyCredentials(QAuthenticator *authenticator)
|
|||
}
|
||||
}
|
||||
|
||||
void WebPage::openUrlExternal(const QUrl &url)
|
||||
#ifdef SYNCTHINGTRAY_USE_WEBKIT
|
||||
void WebPage::handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
|
||||
{
|
||||
QDesktopServices::openUrl(url);
|
||||
if(reply->request().url().host() == m_view->url().host()) {
|
||||
reply->ignoreSslErrors(SyncthingConnection::expectedCertificateErrors());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
QT_FORWARD_DECLARE_CLASS(WEB_VIEW_PROVIDER)
|
||||
QT_FORWARD_DECLARE_CLASS(QAuthenticator)
|
||||
QT_FORWARD_DECLARE_CLASS(QNetworkReply)
|
||||
QT_FORWARD_DECLARE_CLASS(QSslError)
|
||||
|
||||
namespace QtGui {
|
||||
|
||||
|
@ -22,17 +23,20 @@ class WebPage : public WEB_PAGE_PROVIDER
|
|||
public:
|
||||
WebPage(WEB_VIEW_PROVIDER *view = nullptr);
|
||||
|
||||
public slots:
|
||||
void openUrlExternal(const QUrl &url);
|
||||
|
||||
protected:
|
||||
WEB_PAGE_PROVIDER *createWindow(WebWindowType type);
|
||||
#ifdef SYNCTHINGTRAY_USE_WEBENGINE
|
||||
bool certificateError(const QWebEngineCertificateError &certificateError);
|
||||
#endif
|
||||
|
||||
private slots:
|
||||
void delegateToExternalBrowser(const QUrl &url);
|
||||
void supplyCredentials(const QUrl &requestUrl, QAuthenticator *authenticator);
|
||||
void supplyCredentials(QNetworkReply *reply, QAuthenticator *authenticator);
|
||||
void supplyCredentials(QAuthenticator *authenticator);
|
||||
#ifdef SYNCTHINGTRAY_USE_WEBKIT
|
||||
void handleSslErrors(QNetworkReply *, const QList<QSslError> &errors);
|
||||
#endif
|
||||
|
||||
private:
|
||||
WEB_VIEW_PROVIDER *m_view;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "./webpage.h"
|
||||
|
||||
#include "../application/settings.h"
|
||||
#include "../data/syncthingconnection.h"
|
||||
|
||||
#include <qtutilities/misc/dialogutils.h>
|
||||
|
||||
|
@ -29,6 +28,7 @@ WebViewDialog::WebViewDialog(QWidget *parent) :
|
|||
|
||||
m_view->setPage(new WebPage(m_view));
|
||||
|
||||
|
||||
applySettings();
|
||||
|
||||
if(Settings::webViewGeometry().isEmpty()) {
|
||||
|
@ -60,4 +60,4 @@ void QtGui::WebViewDialog::closeEvent(QCloseEvent *event)
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // SYNCTHINGTRAY_NO_WEBVIEW
|
||||
|
|
|
@ -29,5 +29,5 @@ private:
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // SYNCTHINGTRAY_NO_WEBVIEW
|
||||
#endif // WEBVIEW_DIALOG_H
|
||||
|
|
|
@ -4,89 +4,119 @@
|
|||
<context>
|
||||
<name>Data::SyncthingConnection</name>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="108"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="120"/>
|
||||
<source>disconnected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="110"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="122"/>
|
||||
<source>connected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="112"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="124"/>
|
||||
<source>connected, notifications available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="114"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="126"/>
|
||||
<source>connected, paused</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="116"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="128"/>
|
||||
<source>connected, synchronizing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="118"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="130"/>
|
||||
<source>unknown</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="393"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="427"/>
|
||||
<source>Unable to parse Syncthing log: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="397"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="431"/>
|
||||
<source>Unable to request system log: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="425"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="525"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="452"/>
|
||||
<source>Unable to locate certificate used by Syncthing GUI.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="458"/>
|
||||
<source>Unable to load certificate used by Syncthing GUI.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="490"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="590"/>
|
||||
<source>Unable to parse Syncthing config: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="430"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="530"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="495"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="595"/>
|
||||
<source>Unable to request Syncthing config: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="605"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="670"/>
|
||||
<source>Unable to parse connections: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="610"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="675"/>
|
||||
<source>Unable to request connections: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="657"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="725"/>
|
||||
<source>Unable to parse directory statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="730"/>
|
||||
<source>Unable to request directory statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="767"/>
|
||||
<source>Unable to parse device statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="772"/>
|
||||
<source>Unable to request device statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="823"/>
|
||||
<source>Unable to parse Syncthing events: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="679"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="845"/>
|
||||
<source>Unable to request Syncthing events: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="844"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="1051"/>
|
||||
<source>Unable to request rescan: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="859"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="1066"/>
|
||||
<source>Unable to request pause/resume: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="361"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="395"/>
|
||||
<source>Unable to request QR-Code: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -94,93 +124,103 @@
|
|||
<context>
|
||||
<name>Data::SyncthingDeviceModel</name>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="58"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="84"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="61"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="87"/>
|
||||
<source>ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="59"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="62"/>
|
||||
<source>Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="85"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="88"/>
|
||||
<source>Addresses</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="86"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="89"/>
|
||||
<source>Last seen</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="90"/>
|
||||
<source>Compression</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="87"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="91"/>
|
||||
<source>Certificate</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="88"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="92"/>
|
||||
<source>Introducer</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="97"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="102"/>
|
||||
<source>none</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="98"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="103"/>
|
||||
<source>yes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="98"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="103"/>
|
||||
<source>no</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="120"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="155"/>
|
||||
<source>Unknown status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="122"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="157"/>
|
||||
<source>Idle</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="123"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="158"/>
|
||||
<source>Disconnected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="124"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="159"/>
|
||||
<source>Synchronizing (%1 %)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="124"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="159"/>
|
||||
<source>Synchronizing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="121"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="156"/>
|
||||
<source>Own device</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="117"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="100"/>
|
||||
<source>unknown or own device</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="152"/>
|
||||
<source>Paused</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="125"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="160"/>
|
||||
<source>Out of sync</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="126"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="161"/>
|
||||
<source>Rejected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -188,109 +228,168 @@
|
|||
<context>
|
||||
<name>Data::SyncthingDirectoryModel</name>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="58"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="84"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="61"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="87"/>
|
||||
<source>ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="59"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="62"/>
|
||||
<source>Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="85"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="88"/>
|
||||
<source>Path</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="86"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="89"/>
|
||||
<source>Devices</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="88"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="91"/>
|
||||
<source>Rescan interval</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="97"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="92"/>
|
||||
<source>Last scan</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="93"/>
|
||||
<source>Last file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="102"/>
|
||||
<source>yes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="97"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="102"/>
|
||||
<source>no</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="118"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="104"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="105"/>
|
||||
<source>unknown</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="143"/>
|
||||
<source>Deleted at %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="145"/>
|
||||
<source>Updated at %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="166"/>
|
||||
<source>Idle</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="119"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="167"/>
|
||||
<source>Scanning (%1 %)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="120"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="168"/>
|
||||
<source>Synchronizing (%1 %)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="122"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="170"/>
|
||||
<source>Out of sync</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="119"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="167"/>
|
||||
<source>Scanning</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="87"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="90"/>
|
||||
<source>Read-only</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="117"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="165"/>
|
||||
<source>Unknown status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="120"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="168"/>
|
||||
<source>Synchronizing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="121"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="169"/>
|
||||
<source>Paused</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Data::Utils</name>
|
||||
<message>
|
||||
<location filename="../data/utils.cpp" line="16"/>
|
||||
<source>%1 ago</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/utils.cpp" line="18"/>
|
||||
<source>right now</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::AppearanceOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="6"/>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="14"/>
|
||||
<source>Appearance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="12"/>
|
||||
<source>Show traffic</source>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="23"/>
|
||||
<source>Menu size</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="30"/>
|
||||
<source>Optional GUI elements</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="37"/>
|
||||
<source>Traffic statistics</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="56"/>
|
||||
<source>x</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="76"/>
|
||||
<source>px</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::AutostartOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="6"/>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="14"/>
|
||||
<source>Autostart</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="12"/>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="23"/>
|
||||
<source><html><head/><body><p><span style=" font-weight:600;">Not implemented yet</span></p><p>This will allow launching the tray when the desktop environment starts and to launch Syncthing when the tray is started.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -298,50 +397,65 @@
|
|||
<context>
|
||||
<name>QtGui::ConnectionOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="14"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="6"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="20"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="15"/>
|
||||
<source>Syncthing URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="30"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="25"/>
|
||||
<source>Authentication</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="43"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="38"/>
|
||||
<source>User</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="84"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="72"/>
|
||||
<source>disconnected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="91"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="79"/>
|
||||
<source>Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="98"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="86"/>
|
||||
<source>Apply connection settings and try to reconnect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="112"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="100"/>
|
||||
<source>API key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="53"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="110"/>
|
||||
<source>Insert values from local Syncthing configuration</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="48"/>
|
||||
<source>Password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="60"/>
|
||||
<source>Select Syncthing config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="67"/>
|
||||
<source>Unable to parse the Syncthing config file.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::DevView</name>
|
||||
|
@ -387,35 +501,40 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="20"/>
|
||||
<source>Notify on disconnect</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="23"/>
|
||||
<source>Notify on</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="27"/>
|
||||
<source>Notify on internal errors</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="30"/>
|
||||
<source>disconnect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="34"/>
|
||||
<source>Notify on Syncthing errors</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="37"/>
|
||||
<source>internal errors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="41"/>
|
||||
<source>Notify on sync complete</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="44"/>
|
||||
<source>Syncthing errors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="51"/>
|
||||
<source>sync complete</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::SettingsDialog</name>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="211"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="259"/>
|
||||
<source>Tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="219"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="267"/>
|
||||
<source>Web view</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -524,8 +643,8 @@
|
|||
<message>
|
||||
<location filename="../gui/traywidget.ui" line="230"/>
|
||||
<location filename="../gui/traywidget.ui" line="250"/>
|
||||
<location filename="../gui/traywidget.cpp" line="321"/>
|
||||
<location filename="../gui/traywidget.cpp" line="328"/>
|
||||
<location filename="../gui/traywidget.cpp" line="322"/>
|
||||
<location filename="../gui/traywidget.cpp" line="329"/>
|
||||
<source>unknown</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -551,11 +670,13 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.ui" line="80"/>
|
||||
<location filename="../gui/traywidget.cpp" line="132"/>
|
||||
<source>About</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.ui" line="134"/>
|
||||
<location filename="../gui/traywidget.cpp" line="112"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -569,16 +690,6 @@
|
|||
<source>View own device ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="112"/>
|
||||
<source>Settings - Syncthing tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="131"/>
|
||||
<source>Tray application for Syncthing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="81"/>
|
||||
<source>Rescan all directories</source>
|
||||
|
@ -589,16 +700,6 @@
|
|||
<source>Show Syncthing log</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="132"/>
|
||||
<source>About - Syncthing Tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="170"/>
|
||||
<source>Own device ID - Syncthing Tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="180"/>
|
||||
<source>device ID is unknown</source>
|
||||
|
@ -609,11 +710,6 @@
|
|||
<source>Copy to clipboard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="204"/>
|
||||
<source>Log - Syncthing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="231"/>
|
||||
<source>Not connected to Syncthing, click to connect</source>
|
||||
|
@ -640,7 +736,17 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="271"/>
|
||||
<location filename="../gui/traywidget.cpp" line="170"/>
|
||||
<source>Own device ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="204"/>
|
||||
<source>Log</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="272"/>
|
||||
<source>The directly <i>%1</i> does not exist on the local machine.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -648,7 +754,7 @@
|
|||
<context>
|
||||
<name>QtGui::WebViewDialog</name>
|
||||
<message>
|
||||
<location filename="../gui/webviewdialog.cpp" line="26"/>
|
||||
<location filename="../gui/webviewdialog.cpp" line="25"/>
|
||||
<source>Syncthing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -657,7 +763,7 @@
|
|||
<name>QtGui::WebViewOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/webviewoptionpage.ui" line="14"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="173"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="221"/>
|
||||
<source>General</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -687,7 +793,7 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="175"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="223"/>
|
||||
<source>Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine.
|
||||
The Web UI will be opened in the default web browser instead.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -696,13 +802,23 @@ The Web UI will be opened in the default web browser instead.</source>
|
|||
<context>
|
||||
<name>main</name>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="61"/>
|
||||
<source>The system tray is (currently) not available.</source>
|
||||
<location filename="../application/main.cpp" line="62"/>
|
||||
<source>You must configure how to connect to Syncthing when using Syncthing Tray the first time.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="65"/>
|
||||
<source>The Qt libraries have not been built with tray icon support.</source>
|
||||
<location filename="../application/main.cpp" line="63"/>
|
||||
<source>Note that the settings dialog allows importing URL, credentials and API-key from the local Syncthing configuration.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="68"/>
|
||||
<source>The system tray is (currently) not available. You could open the tray menu as a regular window using the -w flag, though.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="72"/>
|
||||
<source>The Qt libraries have not been built with tray icon support. You could open the tray menu as a regular window using the -w flag, though.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
|
|
@ -4,89 +4,119 @@
|
|||
<context>
|
||||
<name>Data::SyncthingConnection</name>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="108"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="120"/>
|
||||
<source>disconnected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="110"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="122"/>
|
||||
<source>connected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="112"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="124"/>
|
||||
<source>connected, notifications available</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="114"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="126"/>
|
||||
<source>connected, paused</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="116"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="128"/>
|
||||
<source>connected, synchronizing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="118"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="130"/>
|
||||
<source>unknown</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="393"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="427"/>
|
||||
<source>Unable to parse Syncthing log: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="397"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="431"/>
|
||||
<source>Unable to request system log: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="425"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="525"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="452"/>
|
||||
<source>Unable to locate certificate used by Syncthing GUI.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="458"/>
|
||||
<source>Unable to load certificate used by Syncthing GUI.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="490"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="590"/>
|
||||
<source>Unable to parse Syncthing config: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="430"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="530"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="495"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="595"/>
|
||||
<source>Unable to request Syncthing config: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="605"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="670"/>
|
||||
<source>Unable to parse connections: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="610"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="675"/>
|
||||
<source>Unable to request connections: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="657"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="725"/>
|
||||
<source>Unable to parse directory statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="730"/>
|
||||
<source>Unable to request directory statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="767"/>
|
||||
<source>Unable to parse device statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="772"/>
|
||||
<source>Unable to request device statistics: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="823"/>
|
||||
<source>Unable to parse Syncthing events: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="679"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="845"/>
|
||||
<source>Unable to request Syncthing events: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="844"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="1051"/>
|
||||
<source>Unable to request rescan: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="859"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="1066"/>
|
||||
<source>Unable to request pause/resume: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingconnection.cpp" line="361"/>
|
||||
<location filename="../data/syncthingconnection.cpp" line="395"/>
|
||||
<source>Unable to request QR-Code: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -94,93 +124,103 @@
|
|||
<context>
|
||||
<name>Data::SyncthingDeviceModel</name>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="58"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="84"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="61"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="87"/>
|
||||
<source>ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="59"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="62"/>
|
||||
<source>Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="85"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="88"/>
|
||||
<source>Addresses</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="86"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="89"/>
|
||||
<source>Last seen</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="90"/>
|
||||
<source>Compression</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="87"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="91"/>
|
||||
<source>Certificate</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="88"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="92"/>
|
||||
<source>Introducer</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="97"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="102"/>
|
||||
<source>none</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="98"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="103"/>
|
||||
<source>yes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="98"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="103"/>
|
||||
<source>no</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="120"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="155"/>
|
||||
<source>Unknown status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="122"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="157"/>
|
||||
<source>Idle</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="123"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="158"/>
|
||||
<source>Disconnected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="124"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="159"/>
|
||||
<source>Synchronizing (%1 %)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="124"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="159"/>
|
||||
<source>Synchronizing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="121"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="156"/>
|
||||
<source>Own device</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="117"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="100"/>
|
||||
<source>unknown or own device</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="152"/>
|
||||
<source>Paused</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="125"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="160"/>
|
||||
<source>Out of sync</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="126"/>
|
||||
<location filename="../data/syncthingdevicemodel.cpp" line="161"/>
|
||||
<source>Rejected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -188,109 +228,168 @@
|
|||
<context>
|
||||
<name>Data::SyncthingDirectoryModel</name>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="58"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="84"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="61"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="87"/>
|
||||
<source>ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="59"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="62"/>
|
||||
<source>Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="85"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="88"/>
|
||||
<source>Path</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="86"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="89"/>
|
||||
<source>Devices</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="88"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="91"/>
|
||||
<source>Rescan interval</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="97"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="92"/>
|
||||
<source>Last scan</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="93"/>
|
||||
<source>Last file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="102"/>
|
||||
<source>yes</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="97"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="102"/>
|
||||
<source>no</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="118"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="104"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="105"/>
|
||||
<source>unknown</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="143"/>
|
||||
<source>Deleted at %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="145"/>
|
||||
<source>Updated at %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="166"/>
|
||||
<source>Idle</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="119"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="167"/>
|
||||
<source>Scanning (%1 %)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="120"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="168"/>
|
||||
<source>Synchronizing (%1 %)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="122"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="170"/>
|
||||
<source>Out of sync</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="119"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="167"/>
|
||||
<source>Scanning</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="87"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="90"/>
|
||||
<source>Read-only</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="117"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="165"/>
|
||||
<source>Unknown status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="120"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="168"/>
|
||||
<source>Synchronizing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="121"/>
|
||||
<location filename="../data/syncthingdirectorymodel.cpp" line="169"/>
|
||||
<source>Paused</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Data::Utils</name>
|
||||
<message>
|
||||
<location filename="../data/utils.cpp" line="16"/>
|
||||
<source>%1 ago</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../data/utils.cpp" line="18"/>
|
||||
<source>right now</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::AppearanceOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="6"/>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="14"/>
|
||||
<source>Appearance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="12"/>
|
||||
<source>Show traffic</source>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="23"/>
|
||||
<source>Menu size</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="30"/>
|
||||
<source>Optional GUI elements</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="37"/>
|
||||
<source>Traffic statistics</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="56"/>
|
||||
<source>x</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/appearanceoptionpage.ui" line="76"/>
|
||||
<source>px</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::AutostartOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="6"/>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="14"/>
|
||||
<source>Autostart</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="12"/>
|
||||
<location filename="../gui/autostartoptionpage.ui" line="23"/>
|
||||
<source><html><head/><body><p><span style=" font-weight:600;">Not implemented yet</span></p><p>This will allow launching the tray when the desktop environment starts and to launch Syncthing when the tray is started.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -298,50 +397,65 @@
|
|||
<context>
|
||||
<name>QtGui::ConnectionOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="14"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="6"/>
|
||||
<source>Connection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="20"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="15"/>
|
||||
<source>Syncthing URL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="30"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="25"/>
|
||||
<source>Authentication</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="43"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="38"/>
|
||||
<source>User</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="84"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="72"/>
|
||||
<source>disconnected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="91"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="79"/>
|
||||
<source>Status</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="98"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="86"/>
|
||||
<source>Apply connection settings and try to reconnect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="112"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="100"/>
|
||||
<source>API key</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="53"/>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="110"/>
|
||||
<source>Insert values from local Syncthing configuration</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/connectionoptionpage.ui" line="48"/>
|
||||
<source>Password</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="60"/>
|
||||
<source>Select Syncthing config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="67"/>
|
||||
<source>Unable to parse the Syncthing config file.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::DevView</name>
|
||||
|
@ -387,35 +501,40 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="20"/>
|
||||
<source>Notify on disconnect</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="23"/>
|
||||
<source>Notify on</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="27"/>
|
||||
<source>Notify on internal errors</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="30"/>
|
||||
<source>disconnect</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="34"/>
|
||||
<source>Notify on Syncthing errors</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="37"/>
|
||||
<source>internal errors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="41"/>
|
||||
<source>Notify on sync complete</source>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="44"/>
|
||||
<source>Syncthing errors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/notificationsoptionpage.ui" line="51"/>
|
||||
<source>sync complete</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QtGui::SettingsDialog</name>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="211"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="259"/>
|
||||
<source>Tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="219"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="267"/>
|
||||
<source>Web view</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -524,8 +643,8 @@
|
|||
<message>
|
||||
<location filename="../gui/traywidget.ui" line="230"/>
|
||||
<location filename="../gui/traywidget.ui" line="250"/>
|
||||
<location filename="../gui/traywidget.cpp" line="321"/>
|
||||
<location filename="../gui/traywidget.cpp" line="328"/>
|
||||
<location filename="../gui/traywidget.cpp" line="322"/>
|
||||
<location filename="../gui/traywidget.cpp" line="329"/>
|
||||
<source>unknown</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -551,11 +670,13 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.ui" line="80"/>
|
||||
<location filename="../gui/traywidget.cpp" line="132"/>
|
||||
<source>About</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.ui" line="134"/>
|
||||
<location filename="../gui/traywidget.cpp" line="112"/>
|
||||
<source>Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -569,16 +690,6 @@
|
|||
<source>View own device ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="112"/>
|
||||
<source>Settings - Syncthing tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="131"/>
|
||||
<source>Tray application for Syncthing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="81"/>
|
||||
<source>Rescan all directories</source>
|
||||
|
@ -589,16 +700,6 @@
|
|||
<source>Show Syncthing log</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="132"/>
|
||||
<source>About - Syncthing Tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="170"/>
|
||||
<source>Own device ID - Syncthing Tray</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="180"/>
|
||||
<source>device ID is unknown</source>
|
||||
|
@ -609,11 +710,6 @@
|
|||
<source>Copy to clipboard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="204"/>
|
||||
<source>Log - Syncthing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="231"/>
|
||||
<source>Not connected to Syncthing, click to connect</source>
|
||||
|
@ -640,7 +736,17 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="271"/>
|
||||
<location filename="../gui/traywidget.cpp" line="170"/>
|
||||
<source>Own device ID</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="204"/>
|
||||
<source>Log</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/traywidget.cpp" line="272"/>
|
||||
<source>The directly <i>%1</i> does not exist on the local machine.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -648,7 +754,7 @@
|
|||
<context>
|
||||
<name>QtGui::WebViewDialog</name>
|
||||
<message>
|
||||
<location filename="../gui/webviewdialog.cpp" line="26"/>
|
||||
<location filename="../gui/webviewdialog.cpp" line="25"/>
|
||||
<source>Syncthing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -657,7 +763,7 @@
|
|||
<name>QtGui::WebViewOptionPage</name>
|
||||
<message>
|
||||
<location filename="../gui/webviewoptionpage.ui" line="14"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="173"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="221"/>
|
||||
<source>General</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -687,7 +793,7 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settingsdialog.cpp" line="175"/>
|
||||
<location filename="../gui/settingsdialog.cpp" line="223"/>
|
||||
<source>Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine.
|
||||
The Web UI will be opened in the default web browser instead.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -696,13 +802,23 @@ The Web UI will be opened in the default web browser instead.</source>
|
|||
<context>
|
||||
<name>main</name>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="61"/>
|
||||
<source>The system tray is (currently) not available.</source>
|
||||
<location filename="../application/main.cpp" line="62"/>
|
||||
<source>You must configure how to connect to Syncthing when using Syncthing Tray the first time.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="65"/>
|
||||
<source>The Qt libraries have not been built with tray icon support.</source>
|
||||
<location filename="../application/main.cpp" line="63"/>
|
||||
<source>Note that the settings dialog allows importing URL, credentials and API-key from the local Syncthing configuration.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="68"/>
|
||||
<source>The system tray is (currently) not available. You could open the tray menu as a regular window using the -w flag, though.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../application/main.cpp" line="72"/>
|
||||
<source>The Qt libraries have not been built with tray icon support. You could open the tray menu as a regular window using the -w flag, though.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
|
Loading…
Reference in New Issue