Compare commits

...

21 Commits

Author SHA1 Message Date
Martchus 864690be00 Fix bugtracker URL after changing the app URL
The bugtracker URL can now no longer be automatically deduced from the app
URL.
2024-05-15 18:20:07 +02:00
Martchus 0e86549ef0 Avoid code duplication for fetching items in file model 2024-05-14 21:05:56 +02:00
Martchus 1b5ce7bee5 Add installation/uninstallation section on README
See https://github.com/Martchus/syncthingtray/issues/260
2024-05-12 15:56:54 +02:00
Martchus fea37bbb97 Bump patch version 2024-05-12 15:55:34 +02:00
Martchus 744c78f64f Fix compilation against Qt 5 2024-05-08 12:42:28 +02:00
Martchus 3a5472e6e6 Update release date 2024-05-08 11:26:21 +02:00
Martchus f55d3431ff Update translations
Translations for experimental/WIP features are still unfinished.
2024-05-08 11:24:24 +02:00
Martchus 495efb0365 Update libsyncthing to v1.27.7 2024-05-08 11:07:25 +02:00
Martchus 3f6f3f631e Insert/delete loading items in file model correctly 2024-05-07 19:40:21 +02:00
Martchus 9e4208fc0d Add simple view for showing ignore patterns 2024-05-05 14:47:50 +02:00
Martchus a309926839 Show tooltip for error/loading items in file browser 2024-05-05 13:54:53 +02:00
Martchus fa2a8e27be Add documentation for `SyncthingConnection::readSetIgnores()` 2024-05-05 13:40:39 +02:00
Martchus 5ac40a2924 Fix error message of requests with callback 2024-05-05 13:39:05 +02:00
Martchus c5d3c7745a Add error/loading indications in file browser and simplify path handling 2024-05-05 13:24:37 +02:00
Martchus 506f2a295c Delete QNetworkReply correctly when destroying SyncthingFileModel
When disconnecting the callback we need to destroy the QNetworkReply
manually (as this is no longer done by the usual handler). This will also
close any network connections (if still open).
2024-05-05 12:48:01 +02:00
Martchus 5f995055b0 Improve comments of browse-API-related types 2024-05-05 12:44:14 +02:00
Martchus c65586dab7 Add function to change ignore patterns 2024-05-04 23:12:53 +02:00
Martchus 2ebfdb2cc2 Add function to query ignore patterns 2024-05-04 23:00:13 +02:00
Martchus 83e1dd6d8a Improve file browser 2024-05-04 22:44:00 +02:00
Martchus 93c9ffe5ca Fix comment about usage of qtutilities in syncthingmodels 2024-05-04 22:36:19 +02:00
Martchus 047a4e461e Allow refreshing root in file browser 2024-05-01 15:58:09 +02:00
43 changed files with 1376 additions and 631 deletions

View File

@ -6,13 +6,14 @@ set(META_APP_AUTHOR "Martchus")
set(META_APP_AUTHOR_MAIL "martchus@gmx.net")
set(META_APP_URL "https://${META_APP_AUTHOR}.github.io/${META_PROJECT_NAME}")
set(META_APP_URL_RAW "https://raw.githubusercontent.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}/master")
set(META_APP_BUGTRACKER_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}/issues")
set(META_APP_DESCRIPTION "Tray application for Syncthing")
set(META_APP_CATEGORIES "Network;FileTransfer")
set(META_GUI_OPTIONAL false)
set(META_VERSION_MAJOR 1)
set(META_VERSION_MINOR 5)
set(META_VERSION_PATCH 3)
set(META_RELEASE_DATE "2024-04-09")
set(META_VERSION_PATCH 4)
set(META_RELEASE_DATE "2024-05-08")
set(META_SOVERSION 14)
set(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION ON)
set(NETWORK_INFORMATION_SUPPORT ON)

View File

@ -118,6 +118,19 @@ Syncthing installation. You might consider different configurations:
* Checkout the *Configuring the built-in launcher* section for further details.
* It is also possible to let Syncthing Tray connect to a Syncthing instance running on a different machine.
## Installation and deinstallation
Checkout [the website](https://martchus.github.io/syncthingtray/#downloads-section) for obtaining the executable.
This README also lists more options and instructions for building from sources.
If you are using one of the package manager options you should follow the usual workflow of that package manager.
Otherwise, you just have to extract the archive and launch the contained executable. Especially on Windows, please
read the notes on the website before filing any issues. Note that automatic updates haven't been implemented yet.
To uninstall, just delete the executable again.
For further cleanup you may ensure that autostart is disabled (to avoid a dangling autostart entry). You may also
delete the configuration files (see "Location of the configuration file" section below).
## Screenshots
The screenshots are not up-to-date.

View File

@ -524,12 +524,20 @@ void SyncthingApplet::showDirectoryErrors(const QString &dirId)
void SyncthingApplet::browseRemoteFiles(const QString &dirId)
{
auto row = 0;
auto *const dir = m_connection.findDirInfo(dirId, row);
if (!dir) {
return;
if (auto row = 0; auto *const dir = m_connection.findDirInfo(dirId, row)) {
showCenteredDialog(QtGui::browseRemoteFilesDialog(m_connection, *dir));
}
auto *const dlg = QtGui::browseRemoteFilesDialog(m_connection, *dir);
}
void SyncthingApplet::showIgnorePatterns(const QString &dirId)
{
if (auto row = 0; auto *const dir = m_connection.findDirInfo(dirId, row)) {
showCenteredDialog(QtGui::ignorePatternsDialog(m_connection, *dir));
}
}
void SyncthingApplet::showCenteredDialog(QWidget *dlg)
{
dlg->resize(600, 500);
centerWidget(dlg);
dlg->show();

View File

@ -149,6 +149,7 @@ public Q_SLOTS:
void showInternalErrorsDialog();
void showDirectoryErrors(const QString &dirId);
void browseRemoteFiles(const QString &dirId);
void showIgnorePatterns(const QString &dirId);
void copyToClipboard(const QString &text);
void updateStatusIconAndTooltip();
void saveSettings();
@ -207,6 +208,8 @@ private Q_SLOTS:
void concludeWizard(const QString &errorMessage = QString());
private:
void showCenteredDialog(QWidget *dlg);
Plasma::Theme m_theme;
QString m_faUrl;
QPalette m_palette;

View File

@ -189,6 +189,14 @@ ColumnLayout {
"browseRemoteFiles", "dirId_")
visible: plasmoid.wipFeaturesEnabled
}
PlasmaExtras.MenuItem {
id: showIgnorePatternsItem
text: qsTr("Show ignore patterns")
icon: "selection-symbolic"
onClicked: directoryView.triggerNativeActionWithCurrentItemData(
"showIgnorePatterns", "dirId_")
visible: plasmoid.wipFeaturesEnabled
}
}
}
}

View File

@ -100,6 +100,11 @@
<source>Browse remote files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../package6/contents/ui/DirectoriesPage.qml" line="194"/>
<source>Show ignore patterns</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadsPage</name>
@ -353,12 +358,12 @@
<translation>Neue Benachrichtigungen</translation>
</message>
<message>
<location filename="../lib/syncthingapplet.cpp" line="565"/>
<location filename="../lib/syncthingapplet.cpp" line="573"/>
<source>Unable to establish connection to Syncthing.</source>
<translation>Verbindung zu Syncthing kann nicht hergestellt werden.</translation>
</message>
<message>
<location filename="../lib/syncthingapplet.cpp" line="633"/>
<location filename="../lib/syncthingapplet.cpp" line="641"/>
<source>D-Bus error - unable to </source>
<translation>D-Bus-Fehler bei Aktion </translation>
</message>

View File

@ -100,6 +100,11 @@
<source>Browse remote files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../package6/contents/ui/DirectoriesPage.qml" line="194"/>
<source>Show ignore patterns</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DownloadsPage</name>
@ -287,12 +292,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../lib/syncthingapplet.cpp" line="565"/>
<location filename="../lib/syncthingapplet.cpp" line="573"/>
<source>Unable to establish connection to Syncthing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../lib/syncthingapplet.cpp" line="633"/>
<location filename="../lib/syncthingapplet.cpp" line="641"/>
<source>D-Bus error - unable to </source>
<translation type="unfinished"></translation>
</message>

View File

@ -6,7 +6,7 @@ set(META_PROJECT_TYPE library)
set(META_APP_NAME "Syncthing library")
set(META_APP_DESCRIPTION "Syncthing itself, built as a shared or static library")
set(META_PROJECT_VARNAME_UPPER LIB_SYNCTHING)
set(META_SYNCTHING_VERSION "v1.27.6")
set(META_SYNCTHING_VERSION "v1.27.7")
# use testfiles directory from syncthingconnector
set(META_SRCDIR_REFS "${CMAKE_CURRENT_SOURCE_DIR}\n${CMAKE_CURRENT_SOURCE_DIR}/../syncthingconnector")

@ -1 +1 @@
Subproject commit 5aaf77f2765623bf9c387b6f301bb59b55c1aed8
Subproject commit 388f287fcbb3212879033c2c2d19faa51e48dd7c

View File

@ -1073,7 +1073,7 @@ void SyncthingConnection::emitError(const QString &message, const QJsonParseErro
}
/*!
* \brief Internally called to emit a network error (server replied error code are connection or server could not be reached at all).
* \brief Internally called to emit a network error (server replied error code or server could not be reached at all).
*/
void SyncthingConnection::emitError(const QString &message, SyncthingErrorCategory category, QNetworkReply *reply)
{
@ -1083,6 +1083,19 @@ void SyncthingConnection::emitError(const QString &message, SyncthingErrorCatego
emit error(message + reply->errorString(), category, reply->error(), reply->request(), reply->bytesAvailable() ? reply->readAll() : QByteArray());
}
/*!
* \brief Internally called to emit a network error for a specific request (server replied error code or server could not be reached at all).
* \remarks The \a message is supposed to already contain the error string of the reply.
*/
void SyncthingConnection::emitError(const QString &message, QNetworkReply *reply)
{
if (loggingFlags() & SyncthingConnectionLoggingFlags::ApiReplies) {
cerr << Phrases::Error << "Syncthing API error: " << message.toLocal8Bit().data() << reply->errorString().toLocal8Bit().data() << endl;
}
emit error(message, SyncthingErrorCategory::SpecificRequest, reply->error(), reply->request(),
reply->bytesAvailable() ? reply->readAll() : QByteArray());
}
/*!
* \brief Internally called to emit myIdChanged() signal.
*/

View File

@ -49,19 +49,58 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingLogEntry {
QString message;
};
enum class SyncthingItemType { Unknown, File, Directory };
enum class SyncthingItemType {
Unknown, /**< the type is unknown */
File, /**< the item is a regular file */
Directory, /**< the item is a directory */
Symlink, /**< the item is a symlink (pointing to a file or directory) */
Error, /**< the item represents an error message (e.g. the API query ran into an error); used by SyncthingFileModel */
Loading, /**< the item represents a loading indication; used by SyncthingFileModel */
};
struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingItem {
/// \brief The name of the filesystem item or error/loading message in case of those item types.
QString name;
CppUtilities::DateTime modificationTime;
/// \brief The modification time. Only populated with a meaningful value for files and directories.
CppUtilities::DateTime modificationTime = CppUtilities::DateTime();
/// \brief The file size. Only populated with a meaningful value for files.
std::size_t size = std::size_t();
/// \brief The type of the item.
SyncthingItemType type = SyncthingItemType::Unknown;
std::vector<SyncthingItem> children;
SyncthingItem *parent = nullptr; // not populated but might be set as needed (take care in case the pointer gets invalidated)
/// \brief The child items, if populated as indicated by childrenPopulated.
std::vector<std::unique_ptr<SyncthingItem>> children;
/// \brief The parent item; not populated by default but might be set as needed (take care in case the pointer gets invalidated).
SyncthingItem *parent = nullptr;
/// \brief The path of the item; not populated by default but might be set as needed.
QString path;
/// \brief The index of the item within its parent.
std::size_t index = std::size_t();
int level = 0; // the level of nesting, does *not* include levels of the prefix
bool childrenPopulated = false; // populated depending on requested level
bool checked = false; // not populated but might be set to flag an item for some mass-action
/// \brief The level of nesting, does *not* include levels of the prefix.
int level = 0;
/// \brief Whether children are populated (depends on the requested level).
bool childrenPopulated = false;
/// \brief Whether the item is "checked"; not set by default but might be set to flag an item for some mass-action.
bool checked = false;
bool isFilesystemItem() const;
};
/// \brief Returns whether the item is actually a filesystem item.
inline bool SyncthingItem::isFilesystemItem() const
{
switch (type) {
case Data::SyncthingItemType::File:
case Data::SyncthingItemType::Directory:
case Data::SyncthingItemType::Symlink:
return true;
default:
return false;
}
}
struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingIgnores {
QStringList ignore;
QStringList expanded;
};
class LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnection : public QObject {
@ -115,6 +154,11 @@ public:
SyncthingConnectionLoggingFlags loggingFlags = SyncthingConnectionLoggingFlags::FromEnvironment, QObject *parent = nullptr);
~SyncthingConnection() override;
struct QueryResult {
QNetworkReply *reply = nullptr;
QMetaObject::Connection connection;
};
// getter/setter for
const QString &syncthingUrl() const;
void setSyncthingUrl(const QString &url);
@ -253,8 +297,10 @@ public Q_SLOTS:
public:
// methods to GET or POST information from/to Syncthing (non-slots)
QMetaObject::Connection browse(
const QString &dirId, const QString &prefix, int level, std::function<void(std::vector<SyncthingItem> &&)> &&callback);
QueryResult browse(const QString &dirId, const QString &prefix, int level,
std::function<void(std::vector<std::unique_ptr<SyncthingItem>> &&, QString &&)> &&callback);
QueryResult ignores(const QString &dirId, std::function<void(SyncthingIgnores &&, QString &&)> &&callback);
QueryResult setIgnores(const QString &dirId, const SyncthingIgnores &ignores, std::function<void(QString &&)> &&callback);
Q_SIGNALS:
void newConfig(const QJsonObject &rawConfig);
@ -357,6 +403,7 @@ private Q_SLOTS:
void emitNotification(CppUtilities::DateTime when, const QString &message);
void emitError(const QString &message, const QJsonParseError &jsonError, QNetworkReply *reply, const QByteArray &response = QByteArray());
void emitError(const QString &message, Data::SyncthingErrorCategory category, QNetworkReply *reply);
void emitError(const QString &message, QNetworkReply *reply);
void emitMyIdChanged(const QString &newId);
void emitTildeChanged(const QString &newTilde, const QString &newPathSeparator);
void emitDirStatisticsChanged();
@ -369,7 +416,9 @@ private Q_SLOTS:
private:
// handler to evaluate results from request...() methods
void readBrowse(const QString &dirId, int levels, std::function<void(std::vector<SyncthingItem> &&)> &&callback);
void readBrowse(const QString &dirId, int levels, std::function<void(std::vector<std::unique_ptr<SyncthingItem>> &&, QString &&)> &&callback);
void readIgnores(const QString &dirId, std::function<void(SyncthingIgnores &&, QString &&)> &&callback);
void readSetIgnores(const QString &dirId, std::function<void(QString &&)> &&callback);
// internal helper methods
struct Reply {

View File

@ -1586,12 +1586,12 @@ void SyncthingConnection::readRevert()
* \brief Lists items in the directory with the specified \a dirId down to \a levels (or fully if \a levels is 0) as of \a prefix.
* \sa https://docs.syncthing.net/rest/db-browse-get.html
* \remarks
* In contrast to other functions, this one uses a \a callback to return results (instead of a signal). This makes it easier to
* consume results of a specific request. Errors are still reported via the error() signal so there's no extra error handling
* required. Note that \a callback is *not* invoked in the error case.
* In contrast to most other functions, this one uses a \a callback to return results (instead of a signal). This makes it easier
* to consume results of a specific request. Errors are still reported via the error() signal so there's no extra error handling
* required. Note that in case of an error \a callback is invoked with a non-empty string containing the error message.
*/
QMetaObject::Connection SyncthingConnection::browse(
const QString &dirId, const QString &prefix, int levels, std::function<void(std::vector<SyncthingItem> &&)> &&callback)
SyncthingConnection::QueryResult SyncthingConnection::browse(const QString &dirId, const QString &prefix, int levels,
std::function<void(std::vector<std::unique_ptr<SyncthingItem>> &&, QString &&)> &&callback)
{
auto query = QUrlQuery();
query.addQueryItem(QStringLiteral("folder"), formatQueryItem(dirId));
@ -1601,13 +1601,62 @@ QMetaObject::Connection SyncthingConnection::browse(
if (levels > 0) {
query.addQueryItem(QStringLiteral("levels"), QString::number(levels));
}
return QObject::connect(
requestData(QStringLiteral("db/browse"), query), &QNetworkReply::finished, this,
[this, id = dirId, l = levels, cb = std::move(callback)]() mutable { readBrowse(id, l, std::move(cb)); }, Qt::QueuedConnection);
auto *const reply = requestData(QStringLiteral("db/browse"), query);
return { reply,
QObject::connect(
reply, &QNetworkReply::finished, this,
[this, id = dirId, l = levels, cb = std::move(callback)]() mutable { readBrowse(id, l, std::move(cb)); }, Qt::QueuedConnection) };
}
/*!
* \brief Queries the contents of ".stignore" and expansions of the directory with the specified \a dirId.
* \sa https://docs.syncthing.net/rest/db-ignores-get.html
* \remarks
* In contrast to most other functions, this one uses a \a callback to return results (instead of a signal). This makes it easier
* to consume results of a specific request. Errors are still reported via the error() signal so there's no extra error handling
* required. Note that in case of an error \a callback is invoked with a non-empty string containing the error message.
*/
SyncthingConnection::QueryResult SyncthingConnection::ignores(const QString &dirId, std::function<void(SyncthingIgnores &&, QString &&)> &&callback)
{
auto query = QUrlQuery();
query.addQueryItem(QStringLiteral("folder"), formatQueryItem(dirId));
auto *const reply = requestData(QStringLiteral("db/ignores"), query);
return { reply,
QObject::connect(
reply, &QNetworkReply::finished, this, [this, id = dirId, cb = std::move(callback)]() mutable { readIgnores(id, std::move(cb)); },
Qt::QueuedConnection) };
}
/*!
* \brief Sets the contents of ".stignore" of the directory with the specified \a dirId.
* \sa https://docs.syncthing.net/rest/db-ignores-post.html
* \remarks
* In contrast to most other functions, this one uses a \a callback to return results (instead of a signal). This makes it easier
* to consume results of a specific request. Errors are still reported via the error() signal so there's no extra error handling
* required. Note that in case of an error \a callback is invoked with a non-empty string containing the error message.
*/
SyncthingConnection::QueryResult SyncthingConnection::setIgnores(
const QString &dirId, const SyncthingIgnores &ignores, std::function<void(QString &&)> &&callback)
{
auto query = QUrlQuery();
query.addQueryItem(QStringLiteral("folder"), formatQueryItem(dirId));
auto ignoreArray = QJsonArray();
for (const auto &ignore : ignores.ignore) {
ignoreArray.append(ignore);
}
auto jsonObj = QJsonObject();
jsonObj.insert(QLatin1String("ignore"), ignoreArray);
auto jsonDoc = QJsonDocument();
jsonDoc.setObject(jsonObj);
auto *const reply = postData(QStringLiteral("db/ignores"), query, jsonDoc.toJson(QJsonDocument::Compact));
return { reply,
QObject::connect(
reply, &QNetworkReply::finished, this, [this, id = dirId, cb = std::move(callback)]() mutable { readSetIgnores(id, std::move(cb)); },
Qt::QueuedConnection) };
}
/// \cond
static void readSyncthingItems(const QJsonArray &array, std::vector<SyncthingItem> &into, int level, int levels)
static void readSyncthingItems(const QJsonArray &array, std::vector<std::unique_ptr<SyncthingItem>> &into, int level, int levels)
{
into.reserve(static_cast<std::size_t>(array.size()));
for (const auto &jsonItem : array) {
@ -1618,57 +1667,142 @@ static void readSyncthingItems(const QJsonArray &array, std::vector<SyncthingIte
const auto type = jsonItemObj.value(QLatin1String("type")).toString();
const auto index = into.size();
const auto children = jsonItemObj.value(QLatin1String("children"));
auto &item = into.emplace_back();
item.name = jsonItemObj.value(QLatin1String("name")).toString();
item.modificationTime = CppUtilities::DateTime::fromIsoStringGmt(jsonItemObj.value(QLatin1String("modTime")).toString().toUtf8().data());
item.size = static_cast<std::size_t>(jsonItemObj
.value(QLatin1String("size"))
auto &item = into.emplace_back(std::make_unique<SyncthingItem>());
item->name = jsonItemObj.value(QLatin1String("name")).toString();
item->modificationTime = CppUtilities::DateTime::fromIsoStringGmt(jsonItemObj.value(QLatin1String("modTime")).toString().toUtf8().data());
item->size = static_cast<std::size_t>(jsonItemObj
.value(QLatin1String("size"))
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
.toInteger()
.toInteger()
#else
.toDouble()
.toDouble()
#endif
);
item.index = index;
item.level = level;
item->index = index;
item->level = level;
if (type == QLatin1String("FILE_INFO_TYPE_FILE")) {
item.type = SyncthingItemType::File;
item->type = SyncthingItemType::File;
} else if (type == QLatin1String("FILE_INFO_TYPE_DIRECTORY")) {
item.type = SyncthingItemType::Directory;
item->type = SyncthingItemType::Directory;
} else if (type == QLatin1String("FILE_INFO_TYPE_SYMLINK")) {
item->type = SyncthingItemType::Symlink;
}
readSyncthingItems(children.toArray(), item.children, level + 1, levels);
item.childrenPopulated = !levels || level < levels;
readSyncthingItems(children.toArray(), item->children, level + 1, levels);
item->childrenPopulated = !levels || level < levels;
}
}
/// \endcond
/*!
* \brief Reads the response of browse() and reports results via the specified \a callback or emits error() in case of an error.
* \brief Reads the response of browse() and reports results via the specified \a callback. Emits error() in case of an error.
* \remarks The \a callback is also emitted in the error case (with the error message as second parameter and an empty list of items).
*/
void SyncthingConnection::readBrowse(const QString &dirId, int levels, std::function<void(std::vector<SyncthingItem> &&)> &&callback)
void SyncthingConnection::readBrowse(
const QString &dirId, int levels, std::function<void(std::vector<std::unique_ptr<SyncthingItem>> &&, QString &&)> &&callback)
{
auto const [reply, response] = prepareReply();
if (!reply) {
return;
}
auto items = std::vector<SyncthingItem>();
auto items = std::vector<std::unique_ptr<SyncthingItem>>();
switch (reply->error()) {
case QNetworkReply::NoError: {
auto jsonError = QJsonParseError();
const auto replyDoc = QJsonDocument::fromJson(response, &jsonError);
if (jsonError.error != QJsonParseError::NoError) {
emit error(tr("Unable to parse response for browsing \"%1\": ").arg(dirId) + jsonError.errorString(), SyncthingErrorCategory::Parsing,
QNetworkReply::NoError);
auto errorMessage = tr("Unable to parse response for browsing \"%1\": ").arg(dirId) + jsonError.errorString();
emit error(errorMessage, SyncthingErrorCategory::Parsing, QNetworkReply::NoError);
if (callback) {
callback(std::move(items), std::move(errorMessage));
}
return;
}
readSyncthingItems(replyDoc.array(), items, 0, levels);
if (callback) {
callback(std::move(items));
callback(std::move(items), QString());
}
break;
}
default:
emitError(tr("Unable to browse \"%1\": ").arg(dirId), SyncthingErrorCategory::SpecificRequest, reply);
auto errorMessage = tr("Unable to browse \"%1\": ").arg(dirId) + reply->errorString();
emitError(errorMessage, reply);
if (callback) {
callback(std::move(items), std::move(errorMessage));
}
}
}
/*!
* \brief Reads the response of ignores() and reports results via the specified \a callback. Emits error() in case of an error.
* \remarks The \a callback is also emitted in the error case (with the error message as second parameter and an empty list of items).
*/
void SyncthingConnection::readIgnores(const QString &dirId, std::function<void(SyncthingIgnores &&, QString &&)> &&callback)
{
auto const [reply, response] = prepareReply();
if (!reply) {
return;
}
auto res = SyncthingIgnores();
switch (reply->error()) {
case QNetworkReply::NoError: {
auto jsonError = QJsonParseError();
const auto replyDoc = QJsonDocument::fromJson(response, &jsonError);
if (jsonError.error != QJsonParseError::NoError) {
auto errorMessage = tr("Unable to query ignore patterns of \"%1\": ").arg(dirId) + jsonError.errorString();
emit error(errorMessage, SyncthingErrorCategory::Parsing, QNetworkReply::NoError);
if (callback) {
callback(std::move(res), std::move(errorMessage));
}
return;
}
const auto docObj = replyDoc.object();
const auto ignores = docObj.value(QLatin1String("ignore")).toArray();
const auto expanded = docObj.value(QLatin1String("expanded")).toArray();
res.ignore.reserve(ignores.size());
res.expanded.reserve(expanded.size());
for (const auto &ignore : ignores) {
res.ignore.append(ignore.toString());
}
for (const auto &expand : expanded) {
res.expanded.append(expand.toString());
}
if (callback) {
callback(std::move(res), QString());
}
break;
}
default:
auto errorMessage = tr("Unable to query ignore patterns of \"%1\": ").arg(dirId) + reply->errorString();
emitError(errorMessage, reply);
if (callback) {
callback(std::move(res), std::move(errorMessage));
}
}
}
/*!
* \brief Reads the response of setIgnores() and reports results via the specified \a callback. Emits error() in case of an error.
* \remarks The \a callback is also emitted in the error case (with the error message as second parameter and an empty list of items).
*/
void SyncthingConnection::readSetIgnores(const QString &dirId, std::function<void(QString &&)> &&callback)
{
auto const [reply, response] = prepareReply();
if (!reply) {
return;
}
switch (reply->error()) {
case QNetworkReply::NoError: {
if (callback) {
callback(QString());
}
break;
}
default:
auto errorMessage = tr("Unable to change ignore patterns of \"%1\": ").arg(dirId) + reply->errorString();
emitError(errorMessage, reply);
if (callback) {
callback(std::move(errorMessage));
}
}
}

View File

@ -24,7 +24,7 @@ namespace Data {
*/
namespace TestData {
static bool initialized = false;
static std::string config, status, folderStats, deviceStats, errors, folderStatus, folderStatus2, folderStatus3, pullErrors, connections, version, empty;
static std::string config, status, folderStats, deviceStats, errors, folderStatus, folderStatus2, folderStatus3, pullErrors, connections, version, empty, browse;
static std::string events[7];
} // namespace TestData
@ -62,10 +62,10 @@ void setupTestData()
// read mock files for REST-API
const char *const fileNames[] = { "config", "status", "folderstats", "devicestats", "errors", "folderstatus-01", "folderstatus-02",
"folderstatus-03", "pullerrors-01", "connections", "version", "empty" };
"folderstatus-03", "pullerrors-01", "connections", "version", "empty", "browse" };
const char *const *fileName = fileNames;
for (auto *const testDataVariable : { &config, &status, &folderStats, &deviceStats, &errors, &folderStatus, &folderStatus2, &folderStatus3,
&pullErrors, &connections, &version, &empty }) {
&pullErrors, &connections, &version, &empty, &browse }) {
*testDataVariable = readMockFile(testApp.testFilePath(argsToString("mocks/", *fileName, ".json")));
++fileName;
}
@ -171,6 +171,11 @@ MockedReply *MockedReply::forRequest(const QString &method, const QString &path,
} else if (folder == QLatin1String("forever-alone")) {
buffer = &folderStatus3;
}
} else if (path == QLatin1String("db/browse") && !query.hasQueryItem(QStringLiteral("prefix"))) {
const auto folder = query.queryItemValue(QStringLiteral("folder"));
if (folder == QLatin1String("GXWxf-3zgnU")) {
buffer = &browse;
}
} else if (path == QLatin1String("folder/pullerrors")) {
const QString folder(query.queryItemValue(QStringLiteral("folder")));
if (folder == QLatin1String("GXWxf-3zgnU") && s_eventIndex >= 6) {

View File

@ -0,0 +1,46 @@
[
{
"modTime" : "2020-10-02T23:48:52.076996974+02:00",
"name" : "100ANDRO",
"size" : 128,
"type" : "FILE_INFO_TYPE_DIRECTORY"
},
{
"modTime" : "2020-10-09T13:04:42.4410738+02:00",
"name" : "Camera",
"size" : 128,
"type" : "FILE_INFO_TYPE_DIRECTORY",
"children" : [
{
"modTime" : "2020-12-16T23:31:34.5009668+01:00",
"name" : "IMG_20201114_124821.jpg",
"size" : 10682189,
"type" : "FILE_INFO_TYPE_FILE"
},
{
"modTime" : "2020-12-16T23:31:35.0106367+01:00",
"name" : "IMG_20201213_122451.jpg",
"size" : 7936351,
"type" : "FILE_INFO_TYPE_FILE"
},
{
"modTime" : "2020-12-13T12:25:05.017097469+01:00",
"name" : "IMG_20201213_122504.jpg",
"size" : 8406507,
"type" : "FILE_INFO_TYPE_FILE"
},
{
"modTime" : "2020-12-13T12:25:06.127097469+01:00",
"name" : "IMG_20201213_122505.jpg",
"size" : 8381931,
"type" : "FILE_INFO_TYPE_FILE"
},
{
"modTime" : "2020-12-13T12:53:29.707298401+01:00",
"name" : "IMG_20201213_125329.jpg",
"size" : 4388331,
"type" : "FILE_INFO_TYPE_FILE"
}
]
}
]

View File

@ -4,42 +4,42 @@
<context>
<name>Data::SyncthingConnection</name>
<message>
<location filename="../syncthingconnection.cpp" line="175"/>
<location filename="../syncthingconnection.cpp" line="177"/>
<source>disconnected</source>
<translation>odpojeno</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="177"/>
<location filename="../syncthingconnection.cpp" line="179"/>
<source>reconnecting</source>
<translation>znovu se připojuje</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="179"/>
<location filename="../syncthingconnection.cpp" line="181"/>
<source>connected</source>
<translation>spojeno</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="181"/>
<location filename="../syncthingconnection.cpp" line="183"/>
<source>connected, scanning</source>
<translation>spojeno, skenování</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="183"/>
<location filename="../syncthingconnection.cpp" line="185"/>
<source>connected, paused</source>
<translation>spojeno, pozastaveno</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="185"/>
<location filename="../syncthingconnection.cpp" line="187"/>
<source>connected, synchronizing</source>
<translation>spojeno, synchronizuje se</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="187"/>
<location filename="../syncthingconnection.cpp" line="189"/>
<source>connected, remote not in sync</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="798"/>
<location filename="../syncthingconnection.cpp" line="799"/>
<source>Unable to parse timestamp &quot;%1&quot; (%2): %3</source>
<translation type="unfinished"></translation>
</message>
@ -48,13 +48,13 @@
<translation type="vanished">spojeno, nesesynchronizováno</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="189"/>
<location filename="../syncthingconnection.cpp" line="191"/>
<source>unknown</source>
<translation>neznámý stav spojení</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="340"/>
<location filename="../syncthingconnection.cpp" line="530"/>
<location filename="../syncthingconnection.cpp" line="341"/>
<location filename="../syncthingconnection.cpp" line="531"/>
<source>Connection configuration is insufficient.</source>
<translation>Nastavení spojení není dostačující.</translation>
</message>
@ -89,12 +89,12 @@
<translation>Nedaří se vyžádat si záznamy událostí v Syncthing: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="871"/>
<location filename="../syncthingconnection.cpp" line="872"/>
<source>Unable to locate certificate used by Syncthing.</source>
<translation>Nedaří se nalézt certifikát, používaný Syncthing.</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="877"/>
<location filename="../syncthingconnection.cpp" line="878"/>
<source>Unable to load certificate used by Syncthing.</source>
<translation>Nedaří se načíst certifikát, používaný Syncthing.</translation>
</message>
@ -165,17 +165,17 @@
<translation>Nedaří se vyžádat si vyčištění chyb: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1894"/>
<location filename="../syncthingconnection_requests.cpp" line="2021"/>
<source>Unable to parse Syncthing events: </source>
<translation>Nedaří se zpracovat události v Syncthing: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1921"/>
<location filename="../syncthingconnection_requests.cpp" line="2048"/>
<source>Unable to request Syncthing events: </source>
<translation>Nedaří se vyžádat si události v Syncthing: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1718"/>
<location filename="../syncthingconnection_requests.cpp" line="1845"/>
<source>Unable to post config: </source>
<translation>Nedaří se odeslat nové nastavení: </translation>
</message>
@ -250,27 +250,38 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1660"/>
<location filename="../syncthingconnection_requests.cpp" line="1713"/>
<source>Unable to parse response for browsing &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1674"/>
<location filename="../syncthingconnection_requests.cpp" line="1727"/>
<source>Unable to browse &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2502"/>
<location filename="../syncthingconnection_requests.cpp" line="1751"/>
<location filename="../syncthingconnection_requests.cpp" line="1775"/>
<source>Unable to query ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1801"/>
<source>Unable to change ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2629"/>
<source>Unable to parse disk events: </source>
<translation>Nedaří se zpracovat události úložiště: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2525"/>
<location filename="../syncthingconnection_requests.cpp" line="2652"/>
<source>Unable to request disk events: </source>
<translation>Nedaří se vyžádat si události úložiště: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1070"/>
<location filename="../syncthingconnection.cpp" line="1071"/>
<source>at offset %1</source>
<translation>na posunu %1</translation>
</message>
@ -330,27 +341,27 @@
<context>
<name>Data::SyncthingService</name>
<message>
<location filename="../syncthingservice.cpp" line="378"/>
<location filename="../syncthingservice.cpp" line="394"/>
<source>start unit</source>
<translation>spustit jednotku</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="380"/>
<location filename="../syncthingservice.cpp" line="396"/>
<source>stop unit</source>
<translation>zastavit jednotku</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="395"/>
<location filename="../syncthingservice.cpp" line="411"/>
<source>enable unit</source>
<translation>zapnout jednotku</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="397"/>
<location filename="../syncthingservice.cpp" line="413"/>
<source>disable unit</source>
<translation>vypnout jednotku</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="407"/>
<location filename="../syncthingservice.cpp" line="423"/>
<source>reload all unit files</source>
<translation type="unfinished"></translation>
</message>
@ -358,22 +369,22 @@
<context>
<name>Data::Utils</name>
<message>
<location filename="../utils.cpp" line="30"/>
<location filename="../utils.cpp" line="37"/>
<source>%1 ago</source>
<translation>před %1</translation>
</message>
<message>
<location filename="../utils.cpp" line="33"/>
<location filename="../utils.cpp" line="40"/>
<source>right now</source>
<translation>právě teď</translation>
</message>
<message>
<location filename="../utils.cpp" line="44"/>
<location filename="../utils.cpp" line="51"/>
<source>unknown</source>
<translation>neznámé</translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="60"/>
<location filename="../utils.cpp" line="67"/>
<source>%1 file(s)</source>
<translation>
<numerusform>%1 soubor</numerusform>
@ -382,7 +393,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="61"/>
<location filename="../utils.cpp" line="68"/>
<source>%1 dir(s)</source>
<translation>
<numerusform>%1 adr.</numerusform>
@ -391,44 +402,44 @@
</translation>
</message>
<message>
<location filename="../utils.cpp" line="76"/>
<location filename="../utils.cpp" line="83"/>
<source>Synchronization of local folder %1 complete</source>
<translation>Synchronizace místního adresáře %1 dokončena</translation>
</message>
<message>
<location filename="../utils.cpp" line="84"/>
<location filename="../utils.cpp" line="91"/>
<source>Synchronization of the following local folders complete:
</source>
<translation>Synchronizace následujících místních adresářů dokončena:
</translation>
</message>
<message>
<location filename="../utils.cpp" line="98"/>
<location filename="../utils.cpp" line="105"/>
<source>file system watcher and periodic rescan disabled</source>
<translation>sledování souborového systému a periodické skenování vypnuto</translation>
</message>
<message>
<location filename="../utils.cpp" line="100"/>
<location filename="../utils.cpp" line="107"/>
<source>file system watcher active, periodic rescan disabled</source>
<translation>sledování souborového systému zapnuto, periodické skenování vypnuto</translation>
</message>
<message>
<location filename="../utils.cpp" line="103"/>
<location filename="../utils.cpp" line="110"/>
<source>, file system watcher enabled</source>
<translation>, sledování souborového systému zapnuto</translation>
</message>
<message>
<location filename="../utils.cpp" line="104"/>
<location filename="../utils.cpp" line="111"/>
<source>, file system watcher disabled</source>
<translation>, sledování souborového systému vypnuto</translation>
</message>
<message>
<location filename="../utils.cpp" line="79"/>
<location filename="../utils.cpp" line="86"/>
<source>Synchronization of %1 on %2 complete</source>
<translation>Synchronizace %1 na %2 dokončena</translation>
</message>
<message>
<location filename="../utils.cpp" line="87"/>
<location filename="../utils.cpp" line="94"/>
<source>Synchronization of the following folders on %1 complete:
</source>
<translation>Synchronizace následujících adresářů na %1 dokončena:

View File

@ -4,42 +4,42 @@
<context>
<name>Data::SyncthingConnection</name>
<message>
<location filename="../syncthingconnection.cpp" line="175"/>
<location filename="../syncthingconnection.cpp" line="177"/>
<source>disconnected</source>
<translation>Verbindung getrennt</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="177"/>
<location filename="../syncthingconnection.cpp" line="179"/>
<source>reconnecting</source>
<translation>Verbindung wird hergestellt</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="179"/>
<location filename="../syncthingconnection.cpp" line="181"/>
<source>connected</source>
<translation>verbunden</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="181"/>
<location filename="../syncthingconnection.cpp" line="183"/>
<source>connected, scanning</source>
<translation>verbunden, scannt</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="183"/>
<location filename="../syncthingconnection.cpp" line="185"/>
<source>connected, paused</source>
<translation>verbunden, pausiert</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="185"/>
<location filename="../syncthingconnection.cpp" line="187"/>
<source>connected, synchronizing</source>
<translation>verbunden, am Synchronisieren</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="187"/>
<location filename="../syncthingconnection.cpp" line="189"/>
<source>connected, remote not in sync</source>
<translation>verbunden, entferntes Gerät nicht synchronisiert</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="798"/>
<location filename="../syncthingconnection.cpp" line="799"/>
<source>Unable to parse timestamp &quot;%1&quot; (%2): %3</source>
<translation>Fehler beim Parsen des Zeitstempels &quot;%1&quot; (Kontext: &quot;%2&quot;): %3</translation>
</message>
@ -48,13 +48,13 @@
<translation type="vanished">verbunden, nicht synchronisiert</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="189"/>
<location filename="../syncthingconnection.cpp" line="191"/>
<source>unknown</source>
<translation>Verbindungsstatus unbekannt</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="340"/>
<location filename="../syncthingconnection.cpp" line="530"/>
<location filename="../syncthingconnection.cpp" line="341"/>
<location filename="../syncthingconnection.cpp" line="531"/>
<source>Connection configuration is insufficient.</source>
<translation>Verbindungskonfiguration is ungenügend</translation>
</message>
@ -89,12 +89,12 @@
<translation>Fehler beim Abfragen des Syncthing-Logs: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="871"/>
<location filename="../syncthingconnection.cpp" line="872"/>
<source>Unable to locate certificate used by Syncthing.</source>
<translation>Das SSL-Zertifikat von Syncthing kann nicht gefunden werden.</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="877"/>
<location filename="../syncthingconnection.cpp" line="878"/>
<source>Unable to load certificate used by Syncthing.</source>
<translation>Das SSL-Zertifikat von Syncthing kann nicht ausgelesen werden.</translation>
</message>
@ -165,17 +165,17 @@
<translation>Fehler beim Löschen der Fehlermeldungen: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1894"/>
<location filename="../syncthingconnection_requests.cpp" line="2021"/>
<source>Unable to parse Syncthing events: </source>
<translation>Fehler beim Auslesen der Syncthing-Ereignisse: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1921"/>
<location filename="../syncthingconnection_requests.cpp" line="2048"/>
<source>Unable to request Syncthing events: </source>
<translation>Fehler beim Abfragen der Syncthing-Ereignisse: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1718"/>
<location filename="../syncthingconnection_requests.cpp" line="1845"/>
<source>Unable to post config: </source>
<translation>Fehler beim Senden der neuen Konfiguration: </translation>
</message>
@ -250,27 +250,38 @@
<translation>Fehler beim Zurücksetzen: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1660"/>
<location filename="../syncthingconnection_requests.cpp" line="1713"/>
<source>Unable to parse response for browsing &quot;%1&quot;: </source>
<translation>Fehler beim Auslesen der Inhalte des Ordners &quot;%1&quot;: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1674"/>
<location filename="../syncthingconnection_requests.cpp" line="1727"/>
<source>Unable to browse &quot;%1&quot;: </source>
<translation>Fehler beim Durchsuchen des Ordners &quot;%1&quot;: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2502"/>
<location filename="../syncthingconnection_requests.cpp" line="1751"/>
<location filename="../syncthingconnection_requests.cpp" line="1775"/>
<source>Unable to query ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1801"/>
<source>Unable to change ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2629"/>
<source>Unable to parse disk events: </source>
<translation>Fehler beim Auslesen der letzten Änderungen: </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2525"/>
<location filename="../syncthingconnection_requests.cpp" line="2652"/>
<source>Unable to request disk events: </source>
<translation>Fehler beim Anfordern der letzten Änderungen: </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1070"/>
<location filename="../syncthingconnection.cpp" line="1071"/>
<source>at offset %1</source>
<translation>bei Zeichen %1</translation>
</message>
@ -330,27 +341,27 @@
<context>
<name>Data::SyncthingService</name>
<message>
<location filename="../syncthingservice.cpp" line="378"/>
<location filename="../syncthingservice.cpp" line="394"/>
<source>start unit</source>
<translation>Starten der Unit</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="380"/>
<location filename="../syncthingservice.cpp" line="396"/>
<source>stop unit</source>
<translation>Stoppen der Unit</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="395"/>
<location filename="../syncthingservice.cpp" line="411"/>
<source>enable unit</source>
<translation>Aktivieren der Unit</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="397"/>
<location filename="../syncthingservice.cpp" line="413"/>
<source>disable unit</source>
<translation>Deaktivieren der Unit</translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="407"/>
<location filename="../syncthingservice.cpp" line="423"/>
<source>reload all unit files</source>
<translation>Aktualisieren aller Unit-Dateien</translation>
</message>
@ -358,22 +369,22 @@
<context>
<name>Data::Utils</name>
<message>
<location filename="../utils.cpp" line="30"/>
<location filename="../utils.cpp" line="37"/>
<source>%1 ago</source>
<translation>vor %1</translation>
</message>
<message>
<location filename="../utils.cpp" line="33"/>
<location filename="../utils.cpp" line="40"/>
<source>right now</source>
<translation>gerade eben</translation>
</message>
<message>
<location filename="../utils.cpp" line="44"/>
<location filename="../utils.cpp" line="51"/>
<source>unknown</source>
<translation>unbekannt</translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="60"/>
<location filename="../utils.cpp" line="67"/>
<source>%1 file(s)</source>
<translation>
<numerusform>%1 Datei</numerusform>
@ -381,7 +392,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="61"/>
<location filename="../utils.cpp" line="68"/>
<source>%1 dir(s)</source>
<translation>
<numerusform>%1 Verz.</numerusform>
@ -389,44 +400,44 @@
</translation>
</message>
<message>
<location filename="../utils.cpp" line="76"/>
<location filename="../utils.cpp" line="83"/>
<source>Synchronization of local folder %1 complete</source>
<translation>%1 wurde lokal synchronisiert</translation>
</message>
<message>
<location filename="../utils.cpp" line="84"/>
<location filename="../utils.cpp" line="91"/>
<source>Synchronization of the following local folders complete:
</source>
<translation>Folgende Ordner wurden lokal synchronisiert:
</translation>
</message>
<message>
<location filename="../utils.cpp" line="98"/>
<location filename="../utils.cpp" line="105"/>
<source>file system watcher and periodic rescan disabled</source>
<translation>Dateisystemüberwachung und periodischer Scan deaktiviert</translation>
</message>
<message>
<location filename="../utils.cpp" line="100"/>
<location filename="../utils.cpp" line="107"/>
<source>file system watcher active, periodic rescan disabled</source>
<translation>Dateisystemüberwachung aktiv, periodischer Scan deaktiviert</translation>
</message>
<message>
<location filename="../utils.cpp" line="103"/>
<location filename="../utils.cpp" line="110"/>
<source>, file system watcher enabled</source>
<translation>, Dateisystemüberwachung aktiviert</translation>
</message>
<message>
<location filename="../utils.cpp" line="104"/>
<location filename="../utils.cpp" line="111"/>
<source>, file system watcher disabled</source>
<translation>, Dateisystemüberwachung deaktiviert</translation>
</message>
<message>
<location filename="../utils.cpp" line="79"/>
<location filename="../utils.cpp" line="86"/>
<source>Synchronization of %1 on %2 complete</source>
<translation>%1 wurde auf %2 synchronisiert</translation>
</message>
<message>
<location filename="../utils.cpp" line="87"/>
<location filename="../utils.cpp" line="94"/>
<source>Synchronization of the following folders on %1 complete:
</source>
<translation>Folgende Ordner wurden auf %1 synchronisiert:

View File

@ -4,53 +4,53 @@
<context>
<name>Data::SyncthingConnection</name>
<message>
<location filename="../syncthingconnection.cpp" line="175"/>
<location filename="../syncthingconnection.cpp" line="177"/>
<source>disconnected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="177"/>
<location filename="../syncthingconnection.cpp" line="179"/>
<source>reconnecting</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="179"/>
<location filename="../syncthingconnection.cpp" line="181"/>
<source>connected</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="181"/>
<location filename="../syncthingconnection.cpp" line="183"/>
<source>connected, scanning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="183"/>
<location filename="../syncthingconnection.cpp" line="185"/>
<source>connected, paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="185"/>
<location filename="../syncthingconnection.cpp" line="187"/>
<source>connected, synchronizing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="187"/>
<location filename="../syncthingconnection.cpp" line="189"/>
<source>connected, remote not in sync</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="189"/>
<location filename="../syncthingconnection.cpp" line="191"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="340"/>
<location filename="../syncthingconnection.cpp" line="530"/>
<location filename="../syncthingconnection.cpp" line="341"/>
<location filename="../syncthingconnection.cpp" line="531"/>
<source>Connection configuration is insufficient.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="798"/>
<location filename="../syncthingconnection.cpp" line="799"/>
<source>Unable to parse timestamp &quot;%1&quot; (%2): %3</source>
<translation type="unfinished"></translation>
</message>
@ -85,12 +85,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="871"/>
<location filename="../syncthingconnection.cpp" line="872"/>
<source>Unable to locate certificate used by Syncthing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="877"/>
<location filename="../syncthingconnection.cpp" line="878"/>
<source>Unable to load certificate used by Syncthing.</source>
<translation type="unfinished"></translation>
</message>
@ -161,17 +161,17 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1894"/>
<location filename="../syncthingconnection_requests.cpp" line="2021"/>
<source>Unable to parse Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1921"/>
<location filename="../syncthingconnection_requests.cpp" line="2048"/>
<source>Unable to request Syncthing events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1718"/>
<location filename="../syncthingconnection_requests.cpp" line="1845"/>
<source>Unable to post config: </source>
<translation type="unfinished"></translation>
</message>
@ -246,27 +246,38 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1660"/>
<location filename="../syncthingconnection_requests.cpp" line="1713"/>
<source>Unable to parse response for browsing &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1674"/>
<location filename="../syncthingconnection_requests.cpp" line="1727"/>
<source>Unable to browse &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2502"/>
<location filename="../syncthingconnection_requests.cpp" line="1751"/>
<location filename="../syncthingconnection_requests.cpp" line="1775"/>
<source>Unable to query ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1801"/>
<source>Unable to change ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2629"/>
<source>Unable to parse disk events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2525"/>
<location filename="../syncthingconnection_requests.cpp" line="2652"/>
<source>Unable to request disk events: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1070"/>
<location filename="../syncthingconnection.cpp" line="1071"/>
<source>at offset %1</source>
<translation type="unfinished"></translation>
</message>
@ -322,27 +333,27 @@
<context>
<name>Data::SyncthingService</name>
<message>
<location filename="../syncthingservice.cpp" line="378"/>
<location filename="../syncthingservice.cpp" line="394"/>
<source>start unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="380"/>
<location filename="../syncthingservice.cpp" line="396"/>
<source>stop unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="395"/>
<location filename="../syncthingservice.cpp" line="411"/>
<source>enable unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="397"/>
<location filename="../syncthingservice.cpp" line="413"/>
<source>disable unit</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="407"/>
<location filename="../syncthingservice.cpp" line="423"/>
<source>reload all unit files</source>
<translation type="unfinished"></translation>
</message>
@ -350,22 +361,22 @@
<context>
<name>Data::Utils</name>
<message>
<location filename="../utils.cpp" line="30"/>
<location filename="../utils.cpp" line="37"/>
<source>%1 ago</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="33"/>
<location filename="../utils.cpp" line="40"/>
<source>right now</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="44"/>
<location filename="../utils.cpp" line="51"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="60"/>
<location filename="../utils.cpp" line="67"/>
<source>%1 file(s)</source>
<translation>
<numerusform>%1 file</numerusform>
@ -373,7 +384,7 @@
</translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="61"/>
<location filename="../utils.cpp" line="68"/>
<source>%1 dir(s)</source>
<translation>
<numerusform>%1 dir</numerusform>
@ -381,43 +392,43 @@
</translation>
</message>
<message>
<location filename="../utils.cpp" line="76"/>
<location filename="../utils.cpp" line="83"/>
<source>Synchronization of local folder %1 complete</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="84"/>
<location filename="../utils.cpp" line="91"/>
<source>Synchronization of the following local folders complete:
</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="98"/>
<location filename="../utils.cpp" line="105"/>
<source>file system watcher and periodic rescan disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="100"/>
<location filename="../utils.cpp" line="107"/>
<source>file system watcher active, periodic rescan disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="103"/>
<location filename="../utils.cpp" line="110"/>
<source>, file system watcher enabled</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="104"/>
<location filename="../utils.cpp" line="111"/>
<source>, file system watcher disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="79"/>
<location filename="../utils.cpp" line="86"/>
<source>Synchronization of %1 on %2 complete</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../utils.cpp" line="87"/>
<location filename="../utils.cpp" line="94"/>
<source>Synchronization of the following folders on %1 complete:
</source>
<translation type="unfinished"></translation>

View File

@ -170,103 +170,114 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1660"/>
<location filename="../syncthingconnection_requests.cpp" line="1713"/>
<source>Unable to parse response for browsing &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1674"/>
<location filename="../syncthingconnection_requests.cpp" line="1727"/>
<source>Unable to browse &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1718"/>
<location filename="../syncthingconnection_requests.cpp" line="1751"/>
<location filename="../syncthingconnection_requests.cpp" line="1775"/>
<source>Unable to query ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1801"/>
<source>Unable to change ignore patterns of &quot;%1&quot;: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1845"/>
<source>Unable to post config: </source>
<translation> </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1894"/>
<location filename="../syncthingconnection_requests.cpp" line="2021"/>
<source>Unable to parse Syncthing events: </source>
<translation> Syncthing </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="1921"/>
<location filename="../syncthingconnection_requests.cpp" line="2048"/>
<source>Unable to request Syncthing events: </source>
<translation> Syncthing </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2502"/>
<location filename="../syncthingconnection_requests.cpp" line="2629"/>
<source>Unable to parse disk events: </source>
<translation> </translation>
</message>
<message>
<location filename="../syncthingconnection_requests.cpp" line="2525"/>
<location filename="../syncthingconnection_requests.cpp" line="2652"/>
<source>Unable to request disk events: </source>
<translation> </translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="175"/>
<location filename="../syncthingconnection.cpp" line="177"/>
<source>disconnected</source>
<translation>线</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="177"/>
<location filename="../syncthingconnection.cpp" line="179"/>
<source>reconnecting</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="179"/>
<location filename="../syncthingconnection.cpp" line="181"/>
<source>connected</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="181"/>
<location filename="../syncthingconnection.cpp" line="183"/>
<source>connected, scanning</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="183"/>
<location filename="../syncthingconnection.cpp" line="185"/>
<source>connected, paused</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="185"/>
<location filename="../syncthingconnection.cpp" line="187"/>
<source>connected, synchronizing</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="187"/>
<location filename="../syncthingconnection.cpp" line="189"/>
<source>connected, remote not in sync</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="189"/>
<location filename="../syncthingconnection.cpp" line="191"/>
<source>unknown</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="340"/>
<location filename="../syncthingconnection.cpp" line="530"/>
<location filename="../syncthingconnection.cpp" line="341"/>
<location filename="../syncthingconnection.cpp" line="531"/>
<source>Connection configuration is insufficient.</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="798"/>
<location filename="../syncthingconnection.cpp" line="799"/>
<source>Unable to parse timestamp &quot;%1&quot; (%2): %3</source>
<translation> &quot;%1&quot; (%2): %3</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="871"/>
<location filename="../syncthingconnection.cpp" line="872"/>
<source>Unable to locate certificate used by Syncthing.</source>
<translation> Syncthing 使</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="877"/>
<location filename="../syncthingconnection.cpp" line="878"/>
<source>Unable to load certificate used by Syncthing.</source>
<translation> Syncthing 使</translation>
</message>
<message>
<location filename="../syncthingconnection.cpp" line="1070"/>
<location filename="../syncthingconnection.cpp" line="1071"/>
<source>at offset %1</source>
<translation> %1 </translation>
</message>
@ -322,27 +333,27 @@
<context>
<name>Data::SyncthingService</name>
<message>
<location filename="../syncthingservice.cpp" line="378"/>
<location filename="../syncthingservice.cpp" line="394"/>
<source>start unit</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="380"/>
<location filename="../syncthingservice.cpp" line="396"/>
<source>stop unit</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="395"/>
<location filename="../syncthingservice.cpp" line="411"/>
<source>enable unit</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="397"/>
<location filename="../syncthingservice.cpp" line="413"/>
<source>disable unit</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingservice.cpp" line="407"/>
<location filename="../syncthingservice.cpp" line="423"/>
<source>reload all unit files</source>
<translation type="unfinished"></translation>
</message>
@ -350,75 +361,75 @@
<context>
<name>Data::Utils</name>
<message>
<location filename="../utils.cpp" line="30"/>
<location filename="../utils.cpp" line="37"/>
<source>%1 ago</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../utils.cpp" line="33"/>
<location filename="../utils.cpp" line="40"/>
<source>right now</source>
<translation></translation>
</message>
<message>
<location filename="../utils.cpp" line="44"/>
<location filename="../utils.cpp" line="51"/>
<source>unknown</source>
<translation></translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="60"/>
<location filename="../utils.cpp" line="67"/>
<source>%1 file(s)</source>
<translation>
<numerusform>%1 </numerusform>
</translation>
</message>
<message numerus="yes">
<location filename="../utils.cpp" line="61"/>
<location filename="../utils.cpp" line="68"/>
<source>%1 dir(s)</source>
<translation>
<numerusform>%1 </numerusform>
</translation>
</message>
<message>
<location filename="../utils.cpp" line="76"/>
<location filename="../utils.cpp" line="83"/>
<source>Synchronization of local folder %1 complete</source>
<translation> %1 </translation>
</message>
<message>
<location filename="../utils.cpp" line="79"/>
<location filename="../utils.cpp" line="86"/>
<source>Synchronization of %1 on %2 complete</source>
<translation> %1 %2 </translation>
</message>
<message>
<location filename="../utils.cpp" line="84"/>
<location filename="../utils.cpp" line="91"/>
<source>Synchronization of the following local folders complete:
</source>
<translation>
</translation>
</message>
<message>
<location filename="../utils.cpp" line="87"/>
<location filename="../utils.cpp" line="94"/>
<source>Synchronization of the following folders on %1 complete:
</source>
<translation> %1
</translation>
</message>
<message>
<location filename="../utils.cpp" line="98"/>
<location filename="../utils.cpp" line="105"/>
<source>file system watcher and periodic rescan disabled</source>
<translation></translation>
</message>
<message>
<location filename="../utils.cpp" line="100"/>
<location filename="../utils.cpp" line="107"/>
<source>file system watcher active, periodic rescan disabled</source>
<translation></translation>
</message>
<message>
<location filename="../utils.cpp" line="103"/>
<location filename="../utils.cpp" line="110"/>
<source>, file system watcher enabled</source>
<translation></translation>
</message>
<message>
<location filename="../utils.cpp" line="104"/>
<location filename="../utils.cpp" line="111"/>
<source>, file system watcher disabled</source>
<translation></translation>
</message>

View File

@ -39,13 +39,14 @@ set(TS_FILES translations/${META_PROJECT_NAME}_zh_CN.ts translations/${META_PROJ
translations/${META_PROJECT_NAME}_de_DE.ts translations/${META_PROJECT_NAME}_en_US.ts)
set(QT_TESTS models)
set(QT_TEST_SRC_FILES_models syncthingicons.cpp syncthingmodel.cpp syncthingdirectorymodel.cpp syncthingdevicemodel.cpp)
set(QT_TEST_SRC_FILES_models syncthingicons.cpp syncthingmodel.cpp syncthingdirectorymodel.cpp syncthingdevicemodel.cpp
syncthingfilemodel.cpp)
# find c++utilities
find_package(${PACKAGE_NAMESPACE_PREFIX}c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.0.0 REQUIRED)
use_cpp_utilities()
# find qtutilities (only CMake modules used)
# find qtutilities
find_package(${PACKAGE_NAMESPACE_PREFIX}qtutilities${CONFIGURATION_PACKAGE_SUFFIX_QTUTILITIES} 6.3.0 REQUIRED)
use_qt_utilities()

View File

@ -4,8 +4,13 @@
#include <syncthingconnector/syncthingconnection.h>
#include <syncthingconnector/utils.h>
#include <qtutilities/misc/desktoputils.h>
#include <c++utilities/conversion/stringconversion.h>
#include <QClipboard>
#include <QGuiApplication>
#include <QNetworkReply>
#include <QStringBuilder>
using namespace std;
@ -13,22 +18,65 @@ using namespace CppUtilities;
namespace Data {
SyncthingFileModel::SyncthingFileModel(SyncthingConnection &connection, const QString &dirId, QObject *parent)
/// \cond
static void populatePath(const QString &root, std::vector<std::unique_ptr<SyncthingItem>> &items)
{
if (root.isEmpty()) {
for (auto &item : items) {
populatePath(item->path = item->name, item->children);
}
} else {
for (auto &item : items) {
populatePath(item->path = root % QChar('/') % item->name, item->children);
}
}
}
static void addErrorItem(std::vector<std::unique_ptr<SyncthingItem>> &items, QString &&errorMessage)
{
if (errorMessage.isEmpty()) {
return;
}
auto &errorItem = items.emplace_back(std::make_unique<SyncthingItem>());
errorItem->name = std::move(errorMessage);
errorItem->type = SyncthingItemType::Error;
errorItem->childrenPopulated = true;
}
static void addLoadingItem(std::vector<std::unique_ptr<SyncthingItem>> &items)
{
if (!items.empty()) {
return;
}
auto &loadingItem = items.emplace_back(std::make_unique<SyncthingItem>());
loadingItem->name = QStringLiteral("Loading…");
loadingItem->type = SyncthingItemType::Loading;
loadingItem->childrenPopulated = true;
}
/// \endcond
SyncthingFileModel::SyncthingFileModel(SyncthingConnection &connection, const SyncthingDir &dir, QObject *parent)
: SyncthingModel(connection, parent)
, m_connection(connection)
, m_dirId(dirId)
, m_dirId(dir.id)
, m_root(std::make_unique<SyncthingItem>())
{
m_connection.browse(m_dirId, QString(), 1, [this](std::vector<SyncthingItem> &&items) {
const auto last = items.size() - 1;
beginInsertRows(QModelIndex(), 0, last < std::numeric_limits<int>::max() ? static_cast<int>(last) : std::numeric_limits<int>::max());
m_items = std::move(items);
endInsertRows();
});
if (m_connection.isLocal()) {
m_localPath = dir.pathWithoutTrailingSlash().toString();
}
m_root->name = dir.displayName();
m_root->modificationTime = dir.lastFileTime;
m_root->size = dir.globalStats.bytes;
m_root->type = SyncthingItemType::Directory;
m_root->path = QStringLiteral(""); // assign an empty QString that is not null
m_fetchQueue.append(QString());
processFetchQueue();
}
SyncthingFileModel::~SyncthingFileModel()
{
QObject::disconnect(m_pendingRequest);
QObject::disconnect(m_pendingRequest.connection);
delete m_pendingRequest.reply;
}
QHash<int, QByteArray> SyncthingFileModel::roleNames() const
@ -37,6 +85,7 @@ QHash<int, QByteArray> SyncthingFileModel::roleNames() const
{ NameRole, "name" },
{ SizeRole, "size" },
{ ModificationTimeRole, "modificationTime" },
{ PathRole, "path" },
{ Actions, "actions" },
{ ActionNames, "actionNames" },
{ ActionIcons, "actionIcons" },
@ -46,46 +95,57 @@ QHash<int, QByteArray> SyncthingFileModel::roleNames() const
QModelIndex SyncthingFileModel::index(int row, int column, const QModelIndex &parent) const
{
if (row < 0 || column < 0 || column > 2) {
if (row < 0 || column < 0 || column > 2 || parent.column() > 0) {
return QModelIndex();
}
if (!parent.isValid()) {
if (static_cast<std::size_t>(row) >= m_items.size()) {
return QModelIndex();
}
return createIndex(row, column, &m_items[static_cast<std::size_t>(row)]);
return static_cast<std::size_t>(row) ? QModelIndex() : createIndex(row, column, m_root.get());
}
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
if (!parentItem) {
return QModelIndex();
}
auto &items = parentItem->children;
if (static_cast<std::size_t>(row) >= items.size()) {
return QModelIndex();
}
auto &item = items[static_cast<std::size_t>(row)];
item.parent = parentItem;
return createIndex(row, column, &item);
item->parent = parentItem;
return createIndex(row, column, item.get());
}
QModelIndex SyncthingFileModel::index(const QString &path) const
{
auto parts = path.split(QChar('/'), Qt::SkipEmptyParts);
auto *parent = m_root.get();
auto res = createIndex(0, 0, parent);
for (const auto &part : parts) {
auto index = 0;
for (const auto &child : parent->children) {
if (child->name == part) {
child->parent = parent;
parent = child.get();
res = createIndex(index, 0, parent);
index = -1;
break;
}
++index;
}
if (index >= 0) {
res = QModelIndex();
return res;
}
}
return res;
}
QString SyncthingFileModel::path(const QModelIndex &index) const
{
auto res = QString();
if (!index.isValid()) {
return res;
return QString();
}
auto parts = QStringList();
auto size = QString::size_type();
parts.reserve(reinterpret_cast<SyncthingItem *>(index.internalPointer())->level + 1);
for (auto i = index; i.isValid(); i = i.parent()) {
parts.append(reinterpret_cast<SyncthingItem *>(i.internalPointer())->name);
size += parts.back().size();
}
res.reserve(size + parts.size());
for (auto i = parts.rbegin(), end = parts.rend(); i != end; ++i) {
res += *i;
res += QChar('/');
}
return res;
auto *item = reinterpret_cast<SyncthingItem *>(index.internalPointer());
return item->isFilesystemItem() ? item->path : QString();
}
QModelIndex SyncthingFileModel::parent(const QModelIndex &child) const
@ -94,10 +154,10 @@ QModelIndex SyncthingFileModel::parent(const QModelIndex &child) const
return QModelIndex();
}
auto *const childItem = reinterpret_cast<SyncthingItem *>(child.internalPointer());
if (!childItem->parent) {
if (!childItem) {
return QModelIndex();
}
return createIndex(static_cast<int>(childItem->index), 0, childItem->parent);
return !childItem->parent ? QModelIndex() : createIndex(static_cast<int>(childItem->parent->index), 0, childItem->parent);
}
QVariant SyncthingFileModel::headerData(int section, Qt::Orientation orientation, int role) const
@ -135,9 +195,22 @@ QVariant SyncthingFileModel::data(const QModelIndex &index, int role) const
case 0:
return item->name;
case 1:
return QString::fromStdString(CppUtilities::dataSizeToString(item->size));
switch (item->type) {
case SyncthingItemType::File:
return QString::fromStdString(CppUtilities::dataSizeToString(item->size));
case SyncthingItemType::Directory:
return item->childrenPopulated ? tr("%1 elements").arg(item->children.size()) : QString();
default:
return QString();
}
case 2:
return QString::fromStdString(item->modificationTime.toString());
switch (item->type) {
case SyncthingItemType::File:
case SyncthingItemType::Directory:
return QString::fromStdString(item->modificationTime.toString());
default:
return QString();
}
}
break;
case Qt::DecorationRole: {
@ -149,33 +222,66 @@ QVariant SyncthingFileModel::data(const QModelIndex &index, int role) const
return icons.file;
case SyncthingItemType::Directory:
return icons.folder;
case SyncthingItemType::Symlink:
return icons.link;
case SyncthingItemType::Error:
return icons.exclamationTriangle;
default:
return icons.cogs;
}
}
break;
}
case Qt::ToolTipRole:
switch (index.column()) {
case 0:
return item->isFilesystemItem() ? item->path : item->name;
case 2:
return agoString(item->modificationTime);
}
break;
case NameRole:
return item->name;
case SizeRole:
return static_cast<qsizetype>(item->size);
case ModificationTimeRole:
return QString::fromStdString(item->modificationTime.toString());
case Actions:
case PathRole:
return item->isFilesystemItem() ? item->path : QString();
case Actions: {
auto res = QStringList();
res.reserve(3);
if (item->type == SyncthingItemType::Directory) {
return QStringList({ QStringLiteral("refresh") });
res << QStringLiteral("refresh");
}
break;
case ActionNames:
if (!m_localPath.isEmpty() && item->isFilesystemItem()) {
res << QStringLiteral("open") << QStringLiteral("copy-path");
}
return res;
}
case ActionNames: {
auto res = QStringList();
res.reserve(3);
if (item->type == SyncthingItemType::Directory) {
return QStringList({ tr("Refresh") });
res << tr("Refresh");
}
break;
case ActionIcons:
if (!m_localPath.isEmpty() && item->isFilesystemItem()) {
res << (item->type == SyncthingItemType::Directory ? tr("Browse locally") : tr("Open local version")) << tr("Copy local path");
}
return res;
}
case ActionIcons: {
auto res = QVariantList();
res.reserve(3);
if (item->type == SyncthingItemType::Directory) {
return QStringList({ QStringLiteral("view-refresh") });
res << QIcon::fromTheme(QStringLiteral("view-refresh"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/view-refresh.svg")));
}
break;
if (!m_localPath.isEmpty() && item->isFilesystemItem()) {
res << QIcon::fromTheme(QStringLiteral("folder"), QIcon(QStringLiteral(":/icons/hicolor/scalable/places/folder-open.svg")));
res << QIcon::fromTheme(QStringLiteral("edit-copy"), QIcon(QStringLiteral(":/icons/hicolor/scalable/places/edit-copy.svg")));
}
return res;
}
}
return QVariant();
}
@ -192,7 +298,7 @@ int SyncthingFileModel::rowCount(const QModelIndex &parent) const
{
auto res = std::size_t();
if (!parent.isValid()) {
res = m_items.size();
res = 1;
} else {
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
res = parentItem->childrenPopulated || parentItem->type != SyncthingItemType::Directory ? parentItem->children.size() : 1;
@ -215,22 +321,13 @@ bool SyncthingFileModel::canFetchMore(const QModelIndex &parent) const
return !parentItem->childrenPopulated && parentItem->type == SyncthingItemType::Directory;
}
/// \cond
static void addLevel(std::vector<SyncthingItem> &items, int level)
{
for (auto &item : items) {
item.level += level;
addLevel(item.children, level);
}
}
/// \endcond
void SyncthingFileModel::fetchMore(const QModelIndex &parent)
{
if (!parent.isValid()) {
const auto parentPath = path(parent);
if (parentPath.isNull() || m_fetchQueue.contains(parentPath)) {
return;
}
m_fetchQueue.append(parent);
m_fetchQueue.append(parentPath);
if (m_fetchQueue.size() == 1) {
processFetchQueue();
}
@ -241,6 +338,18 @@ void SyncthingFileModel::triggerAction(const QString &action, const QModelIndex
if (action == QLatin1String("refresh")) {
fetchMore(index);
}
if (m_localPath.isEmpty()) {
return;
}
const auto relPath = index.data(PathRole).toString();
const auto path = relPath.isEmpty() ? m_localPath : QString(m_localPath % QChar('/') % relPath);
if (action == QLatin1String("open")) {
QtUtilities::openLocalFileOrDir(path);
} else if (action == QLatin1String("copy-path")) {
if (auto *const clipboard = QGuiApplication::clipboard()) {
clipboard->setText(path);
}
}
}
void SyncthingFileModel::handleConfigInvalidated()
@ -261,21 +370,57 @@ void SyncthingFileModel::processFetchQueue()
if (m_fetchQueue.isEmpty()) {
return;
}
const auto &parent = m_fetchQueue.front();
m_pendingRequest = m_connection.browse(m_dirId, path(parent), 1, [this, parent](std::vector<SyncthingItem> &&items) {
auto *const parentItem = reinterpret_cast<SyncthingItem *>(parent.internalPointer());
addLevel(items, parentItem->level);
beginRemoveRows(parent, 0, static_cast<int>(parentItem->children.size() - 1));
parentItem->children.clear();
endRemoveRows();
const auto last = items.size() - 1;
beginInsertRows(parent, 0, last < std::numeric_limits<int>::max() ? static_cast<int>(last) : std::numeric_limits<int>::max());
parentItem->children = std::move(items);
parentItem->childrenPopulated = true;
endInsertRows();
m_fetchQueue.removeAll(parent);
const auto &path = m_fetchQueue.front();
const auto rootIndex = index(path);
if (!rootIndex.isValid()) {
m_fetchQueue.removeAll(path);
processFetchQueue();
});
return;
}
// add loading item if there are items yet at all
auto *rootItem = reinterpret_cast<SyncthingItem *>(rootIndex.internalPointer());
if (rootItem->children.empty()) {
beginInsertRows(rootIndex, 0, 0);
addLoadingItem(rootItem->children);
endInsertRows();
}
m_pendingRequest = m_connection.browse(
m_dirId, path, 1, [this, p = path](std::vector<std::unique_ptr<SyncthingItem>> &&items, QString &&errorMessage) mutable {
m_pendingRequest.reply = nullptr;
m_fetchQueue.removeAll(p);
addErrorItem(items, std::move(errorMessage));
const auto refreshedIndex = index(p);
if (!refreshedIndex.isValid()) {
processFetchQueue();
return;
}
auto *const refreshedItem = reinterpret_cast<SyncthingItem *>(refreshedIndex.internalPointer());
const auto previousChildCount = refreshedItem->children.size();
if (previousChildCount) {
beginRemoveRows(refreshedIndex, 0, static_cast<int>(refreshedItem->children.size() - 1));
refreshedItem->children.clear();
endRemoveRows();
}
if (!items.empty()) {
const auto last = items.size() - 1;
for (auto &item : items) {
item->parent = refreshedItem;
}
populatePath(refreshedItem->path, items);
beginInsertRows(refreshedIndex, 0, last < std::numeric_limits<int>::max() ? static_cast<int>(last) : std::numeric_limits<int>::max());
refreshedItem->children = std::move(items);
refreshedItem->childrenPopulated = true;
endInsertRows();
}
if (refreshedItem->children.size() != previousChildCount) {
const auto sizeIndex = refreshedIndex.siblingAtColumn(1);
emit dataChanged(sizeIndex, sizeIndex, QVector<int>{ Qt::DisplayRole });
}
processFetchQueue();
});
}
} // namespace Data

View File

@ -3,23 +3,32 @@
#include "./syncthingmodel.h"
#include <vector>
#include <syncthingconnector/syncthingconnection.h>
#include <memory>
namespace Data {
struct SyncthingItem;
class LIB_SYNCTHING_MODEL_EXPORT SyncthingFileModel : public SyncthingModel {
Q_OBJECT
public:
enum SyncthingFileModelRole { NameRole = SyncthingModelUserRole + 1, SizeRole, ModificationTimeRole, Actions, ActionNames, ActionIcons };
enum SyncthingFileModelRole {
NameRole = SyncthingModelUserRole + 1,
SizeRole,
ModificationTimeRole,
PathRole,
Actions,
ActionNames,
ActionIcons
};
explicit SyncthingFileModel(SyncthingConnection &connection, const QString &dirId, QObject *parent = nullptr);
explicit SyncthingFileModel(SyncthingConnection &connection, const SyncthingDir &dir, QObject *parent = nullptr);
~SyncthingFileModel() override;
public Q_SLOTS:
QHash<int, QByteArray> roleNames() const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex index(const QString &path) const;
QModelIndex parent(const QModelIndex &child) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@ -44,9 +53,10 @@ private:
private:
SyncthingConnection &m_connection;
QString m_dirId;
QModelIndexList m_fetchQueue;
QMetaObject::Connection m_pendingRequest;
mutable std::vector<SyncthingItem> m_items;
QString m_localPath;
QStringList m_fetchQueue;
SyncthingConnection::QueryResult m_pendingRequest;
std::unique_ptr<SyncthingItem> m_root;
};
} // namespace Data

View File

@ -278,7 +278,7 @@ QString StatusIconSettings::toString() const
StatusIcons::StatusIcons(const StatusIconSettings &settings)
: disconnected(
QIcon(renderSvgImage(makeSyncthingIcon(settings.disconnectedColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize)))
QIcon(renderSvgImage(makeSyncthingIcon(settings.disconnectedColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize)))
, idling(QIcon(renderSvgImage(makeSyncthingIcon(settings.idleColor, StatusEmblem::None, settings.strokeWidth), settings.renderSize)))
, scanninig(QIcon(renderSvgImage(makeSyncthingIcon(settings.scanningColor, StatusEmblem::Scanning, settings.strokeWidth), settings.renderSize)))
, notify(QIcon(renderSvgImage(makeSyncthingIcon(settings.warningColor, StatusEmblem::Alert, settings.strokeWidth), settings.renderSize)))

View File

@ -1,13 +1,14 @@
#include "../syncthingdirectorymodel.h"
#include "../syncthingdevicemodel.h"
#include "../syncthingdirectorymodel.h"
#include "../syncthingfilemodel.h"
#include <syncthingconnector/syncthingconnection.h>
#include <QtTest/QtTest>
#include <QEventLoop>
#include <QTimer>
#include <QLocale>
#include <QTimer>
#include <qtutilities/misc/compat.h>
@ -20,6 +21,7 @@ private Q_SLOTS:
void testDirectoryModel();
void testDevicesModel();
void testFileModel();
private:
QTimer m_timeout;
@ -38,7 +40,7 @@ void ModelTests::initTestCase()
m_timeout.start();
connect(&m_timeout, &QTimer::timeout, this, [this] {
m_loop.quit();
QFAIL("Timeout exceeded when loading mocked config/status for test");
QFAIL("Timeout exceeded");
});
// request config and status and wait until available
@ -97,5 +99,91 @@ void ModelTests::testDevicesModel()
QCOMPARE(model.index(1, 1, dev2Idx).data(), QStringLiteral("dynamic, tcp://192.168.1.3:22000"));
}
void ModelTests::testFileModel()
{
auto row = 0;
const auto *dirInfo = m_connection.findDirInfo(QStringLiteral("GXWxf-3zgnU"), row);
QVERIFY(dirInfo);
// test behavior of empty/unpopulated model
auto model = Data::SyncthingFileModel(m_connection, *dirInfo);
QCOMPARE(model.rowCount(QModelIndex()), 1);
const auto rootIdx = QPersistentModelIndex(model.index(0, 0));
QVERIFY(rootIdx.isValid());
QVERIFY(!model.index(1, 0).isValid());
QCOMPARE(model.rowCount(rootIdx), 1);
QCOMPARE(model.index(0, 0, rootIdx).data(), QStringLiteral("Loading…"));
QCOMPARE(model.index(1, 0, rootIdx).data(), QVariant());
QVERIFY(model.canFetchMore(rootIdx));
// wait until the root has been updated
connect(&model, &QAbstractItemModel::rowsInserted, this, [this](const QModelIndex &parent, int first, int last) {
Q_UNUSED(first)
Q_UNUSED(last)
if (!parent.parent().isValid() && parent.row() == 0 && parent.column() == 0) {
m_timeout.stop();
m_loop.quit();
}
});
m_timeout.start();
m_loop.exec();
QVERIFY(rootIdx.isValid());
QCOMPARE(model.rowCount(rootIdx), 2);
// test access to nested folders
const auto androidIdx = QPersistentModelIndex(model.index(0, 0, rootIdx));
const auto cameraIdx = QPersistentModelIndex(model.index(1, 0, rootIdx));
const auto nestedIdx = QPersistentModelIndex(model.index(0, 0, cameraIdx));
const auto initialAndroidPtr = androidIdx.internalPointer();
const auto initialCameraPtr = cameraIdx.internalPointer();
QVERIFY(androidIdx.isValid());
QVERIFY(cameraIdx.isValid());
QCOMPARE(androidIdx.parent(), rootIdx);
QCOMPARE(cameraIdx.parent(), rootIdx);
QCOMPARE(nestedIdx.parent(), cameraIdx);
QCOMPARE(model.rowCount(androidIdx), 0);
QCOMPARE(model.rowCount(cameraIdx), 5);
QCOMPARE(androidIdx.data(), QStringLiteral("100ANDRO"));
QCOMPARE(cameraIdx.data(), QStringLiteral("Camera"));
QCOMPARE(model.index(0, 0, cameraIdx).data(), QStringLiteral("IMG_20201114_124821.jpg"));
QCOMPARE(model.index(0, 1, cameraIdx).data(), QStringLiteral("10.19 MiB"));
QCOMPARE(model.index(0, 2, cameraIdx).data(), QStringLiteral("2020-12-16 22:31:34.500"));
QCOMPARE(model.index(1, 0, cameraIdx).data(), QStringLiteral("IMG_20201213_122451.jpg"));
QCOMPARE(model.index(2, 0, cameraIdx).data(), QStringLiteral("IMG_20201213_122504.jpg"));
QCOMPARE(model.index(3, 0, cameraIdx).data(), QStringLiteral("IMG_20201213_122505.jpg"));
QCOMPARE(model.index(4, 0, cameraIdx).data(), QStringLiteral("IMG_20201213_125329.jpg"));
QCOMPARE(model.index(5, 0, cameraIdx).data(), QVariant());
QCOMPARE(model.index(5, 1, cameraIdx).data(), QVariant());
QCOMPARE(model.index(5, 2, cameraIdx).data(), QVariant());
QCOMPARE(model.index(5, 3, cameraIdx).data(), QVariant());
// test conversion of indexes to/from paths
const auto testPath = QStringLiteral("Camera/IMG_20201213_122504.jpg");
const auto testPathIdx = model.index(2, 0, cameraIdx);
QCOMPARE(model.path(testPathIdx), testPath);
QCOMPARE(model.index(testPath), testPathIdx);
// re-load the data again and wait for the update
model.fetchMore(rootIdx);
m_timeout.start();
m_loop.exec();
// verify that only the root index is still valid (all other indexes have been invalidated)
QVERIFY(rootIdx.isValid());
QCOMPARE(model.rowCount(rootIdx), 2);
QVERIFY(androidIdx.internalPointer() != initialAndroidPtr);
QVERIFY(!androidIdx.isValid());
QVERIFY(cameraIdx.internalPointer() != initialCameraPtr);
QVERIFY(!cameraIdx.isValid());
QVERIFY(!nestedIdx.isValid());
// verify that data was re-loaded
const auto androidIdx2 = QPersistentModelIndex(model.index(0, 0, rootIdx));
const auto cameraIdx2 = QPersistentModelIndex(model.index(1, 0, rootIdx));
QCOMPARE(androidIdx2.data(), QStringLiteral("100ANDRO"));
QCOMPARE(cameraIdx2.data(), QStringLiteral("Camera"));
}
QTEST_MAIN(ModelTests)
#include "models.moc"

View File

@ -4,42 +4,42 @@
<context>
<name>Data::StatusIconSettings</name>
<message>
<location filename="../syncthingicons.cpp" line="229"/>
<location filename="../syncthingicons.cpp" line="231"/>
<source>Misc. notifications</source>
<translation>Různá oznámení</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="230"/>
<location filename="../syncthingicons.cpp" line="232"/>
<source>Error</source>
<translation>Chyba</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="231"/>
<location filename="../syncthingicons.cpp" line="233"/>
<source>Warning</source>
<translation>Varování</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="232"/>
<location filename="../syncthingicons.cpp" line="234"/>
<source>Idle</source>
<translation>Nečinné</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="233"/>
<location filename="../syncthingicons.cpp" line="235"/>
<source>Scanning</source>
<translation>Skenuje</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="234"/>
<location filename="../syncthingicons.cpp" line="236"/>
<source>Synchronizing</source>
<translation>Synchronizuje</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="235"/>
<location filename="../syncthingicons.cpp" line="237"/>
<source>Paused</source>
<translation>Pozastaveno</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="236"/>
<location filename="../syncthingicons.cpp" line="238"/>
<source>Disconnected</source>
<translation>Odpojeno</translation>
</message>
@ -382,25 +382,45 @@
<context>
<name>Data::SyncthingFileModel</name>
<message>
<location filename="../syncthingfilemodel.cpp" line="111"/>
<location filename="../syncthingfilemodel.cpp" line="194"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="113"/>
<location filename="../syncthingfilemodel.cpp" line="196"/>
<source>Size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="115"/>
<location filename="../syncthingfilemodel.cpp" line="198"/>
<source>Last modified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="171"/>
<location filename="../syncthingfilemodel.cpp" line="225"/>
<source>%1 elements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="289"/>
<source>Refresh</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Open local version</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Copy local path</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Browse locally</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Data::SyncthingRecentChangesModel</name>

View File

@ -4,42 +4,42 @@
<context>
<name>Data::StatusIconSettings</name>
<message>
<location filename="../syncthingicons.cpp" line="229"/>
<location filename="../syncthingicons.cpp" line="231"/>
<source>Misc. notifications</source>
<translation>Benachrichtigungen</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="230"/>
<location filename="../syncthingicons.cpp" line="232"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="231"/>
<location filename="../syncthingicons.cpp" line="233"/>
<source>Warning</source>
<translation>Warnungen</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="232"/>
<location filename="../syncthingicons.cpp" line="234"/>
<source>Idle</source>
<translation>Leerlauf</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="233"/>
<location filename="../syncthingicons.cpp" line="235"/>
<source>Scanning</source>
<translation>Scannen</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="234"/>
<location filename="../syncthingicons.cpp" line="236"/>
<source>Synchronizing</source>
<translation>Synchronisieren</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="235"/>
<location filename="../syncthingicons.cpp" line="237"/>
<source>Paused</source>
<translation>Pausiert</translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="236"/>
<location filename="../syncthingicons.cpp" line="238"/>
<source>Disconnected</source>
<translation>Getrennt</translation>
</message>
@ -380,25 +380,45 @@
<context>
<name>Data::SyncthingFileModel</name>
<message>
<location filename="../syncthingfilemodel.cpp" line="111"/>
<location filename="../syncthingfilemodel.cpp" line="194"/>
<source>Name</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="113"/>
<location filename="../syncthingfilemodel.cpp" line="196"/>
<source>Size</source>
<translation>Größe</translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="115"/>
<location filename="../syncthingfilemodel.cpp" line="198"/>
<source>Last modified</source>
<translation>Zuletzt geändert</translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="171"/>
<location filename="../syncthingfilemodel.cpp" line="225"/>
<source>%1 elements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="289"/>
<source>Refresh</source>
<translation>Aktualisieren</translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Open local version</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Copy local path</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Browse locally</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Data::SyncthingRecentChangesModel</name>

View File

@ -4,42 +4,42 @@
<context>
<name>Data::StatusIconSettings</name>
<message>
<location filename="../syncthingicons.cpp" line="229"/>
<location filename="../syncthingicons.cpp" line="231"/>
<source>Misc. notifications</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="230"/>
<location filename="../syncthingicons.cpp" line="232"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="231"/>
<location filename="../syncthingicons.cpp" line="233"/>
<source>Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="232"/>
<location filename="../syncthingicons.cpp" line="234"/>
<source>Idle</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="233"/>
<location filename="../syncthingicons.cpp" line="235"/>
<source>Scanning</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="234"/>
<location filename="../syncthingicons.cpp" line="236"/>
<source>Synchronizing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="235"/>
<location filename="../syncthingicons.cpp" line="237"/>
<source>Paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="236"/>
<location filename="../syncthingicons.cpp" line="238"/>
<source>Disconnected</source>
<translation type="unfinished"></translation>
</message>
@ -380,25 +380,45 @@
<context>
<name>Data::SyncthingFileModel</name>
<message>
<location filename="../syncthingfilemodel.cpp" line="111"/>
<location filename="../syncthingfilemodel.cpp" line="194"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="113"/>
<location filename="../syncthingfilemodel.cpp" line="196"/>
<source>Size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="115"/>
<location filename="../syncthingfilemodel.cpp" line="198"/>
<source>Last modified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="171"/>
<location filename="../syncthingfilemodel.cpp" line="225"/>
<source>%1 elements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="289"/>
<source>Refresh</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Open local version</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Copy local path</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Browse locally</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Data::SyncthingRecentChangesModel</name>

View File

@ -4,42 +4,42 @@
<context>
<name>Data::StatusIconSettings</name>
<message>
<location filename="../syncthingicons.cpp" line="229"/>
<location filename="../syncthingicons.cpp" line="231"/>
<source>Misc. notifications</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="230"/>
<location filename="../syncthingicons.cpp" line="232"/>
<source>Error</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="231"/>
<location filename="../syncthingicons.cpp" line="233"/>
<source>Warning</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="232"/>
<location filename="../syncthingicons.cpp" line="234"/>
<source>Idle</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="233"/>
<location filename="../syncthingicons.cpp" line="235"/>
<source>Scanning</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="234"/>
<location filename="../syncthingicons.cpp" line="236"/>
<source>Synchronizing</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="235"/>
<location filename="../syncthingicons.cpp" line="237"/>
<source>Paused</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingicons.cpp" line="236"/>
<location filename="../syncthingicons.cpp" line="238"/>
<source>Disconnected</source>
<translation></translation>
</message>
@ -378,25 +378,45 @@
<context>
<name>Data::SyncthingFileModel</name>
<message>
<location filename="../syncthingfilemodel.cpp" line="111"/>
<location filename="../syncthingfilemodel.cpp" line="194"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="113"/>
<location filename="../syncthingfilemodel.cpp" line="196"/>
<source>Size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="115"/>
<location filename="../syncthingfilemodel.cpp" line="198"/>
<source>Last modified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="171"/>
<location filename="../syncthingfilemodel.cpp" line="225"/>
<source>%1 elements</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="289"/>
<source>Refresh</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Open local version</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Copy local path</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfilemodel.cpp" line="292"/>
<source>Browse locally</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Data::SyncthingRecentChangesModel</name>

View File

@ -1,4 +1,5 @@
#include "./otherdialogs.h"
#include "./textviewdialog.h"
#include <syncthingconnector/syncthingconnection.h>
#include <syncthingconnector/syncthingdir.h>
@ -15,8 +16,10 @@
#include <QIcon>
#include <QLabel>
#include <QMenu>
#include <QNetworkReply>
#include <QPixmap>
#include <QPushButton>
#include <QTextBrowser>
#include <QTreeView>
#include <QVBoxLayout>
@ -88,7 +91,7 @@ QDialog *browseRemoteFilesDialog(Data::SyncthingConnection &connection, const Da
dlg->setAttribute(Qt::WA_DeleteOnClose);
// setup model/view
auto model = new Data::SyncthingFileModel(connection, dir.id, &connection);
auto model = new Data::SyncthingFileModel(connection, dir, &connection);
auto view = new QTreeView(dlg);
view->setModel(model);
view->setContextMenuPolicy(Qt::CustomContextMenu);
@ -102,11 +105,11 @@ QDialog *browseRemoteFilesDialog(Data::SyncthingConnection &connection, const Da
return;
}
const auto actionNames = model->data(index, SyncthingFileModel::ActionNames).toStringList();
const auto actionIcons = model->data(index, SyncthingFileModel::ActionIcons).toStringList();
const auto actionIcons = model->data(index, SyncthingFileModel::ActionIcons).toList();
auto menu = QMenu(view);
auto actionIndex = qsizetype();
for (const auto &action : actions) {
QObject::connect(menu.addAction(actionIndex < actionIcons.size() ? QIcon::fromTheme(actionIcons.at(actionIndex)) : QIcon(),
QObject::connect(menu.addAction(actionIndex < actionIcons.size() ? actionIcons.at(actionIndex).value<QIcon>() : QIcon(),
actionIndex < actionNames.size() ? actionNames.at(actionIndex) : action),
&QAction::triggered, model, [model, action, index]() { model->triggerAction(action, index); });
++actionIndex;
@ -125,4 +128,24 @@ QDialog *browseRemoteFilesDialog(Data::SyncthingConnection &connection, const Da
return dlg;
}
TextViewDialog *ignorePatternsDialog(Data::SyncthingConnection &connection, const Data::SyncthingDir &dir, QWidget *parent)
{
auto *const dlg
= new TextViewDialog(QCoreApplication::translate("QtGui::OtherDialogs", "Ignore patterns of folder \"%1\"").arg(dir.displayName()), parent);
dlg->browser()->setText(QStringLiteral("Loading…"));
auto res = connection.ignores(dir.id, [dlg](Data::SyncthingIgnores &&ignores, QString &&errorMessage) {
auto *const browser = dlg->browser();
browser->clear();
if (!errorMessage.isEmpty()) {
browser->setText(errorMessage);
return;
}
for (const auto &ignore : ignores.ignore) {
browser->append(ignore);
}
});
QObject::connect(dlg, &QObject::destroyed, res.reply, &QNetworkReply::deleteLater);
return dlg;
}
} // namespace QtGui

View File

@ -14,11 +14,15 @@ struct SyncthingDir;
} // namespace Data
namespace QtGui {
class TextViewDialog;
SYNCTHINGWIDGETS_EXPORT QDialog *ownDeviceIdDialog(Data::SyncthingConnection &connection);
SYNCTHINGWIDGETS_EXPORT QWidget *ownDeviceIdWidget(Data::SyncthingConnection &connection, int size, QWidget *parent = nullptr);
SYNCTHINGWIDGETS_EXPORT QDialog *browseRemoteFilesDialog(
Data::SyncthingConnection &connection, const Data::SyncthingDir &dir, QWidget *parent = nullptr);
SYNCTHINGWIDGETS_EXPORT TextViewDialog *ignorePatternsDialog(
Data::SyncthingConnection &connection, const Data::SyncthingDir &dir, QWidget *parent = nullptr);
} // namespace QtGui
#endif // SYNCTHINGWIDGETS_OTHERDIALOGS_H

View File

@ -374,32 +374,32 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="817"/>
<location filename="../settings/settingsdialog.cpp" line="822"/>
<source>This is achieved by adding a *.desktop file under &lt;i&gt;~/.config/autostart&lt;/i&gt; so the setting only affects the current user.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="820"/>
<location filename="../settings/settingsdialog.cpp" line="825"/>
<source>This is achieved by adding a registry key under &lt;i&gt;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&lt;/i&gt; so the setting only affects the current user. Note that the startup entry is invalidated when moving &lt;i&gt;syncthingtray.exe&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="824"/>
<location filename="../settings/settingsdialog.cpp" line="829"/>
<source>This is achieved by adding a *.plist file under &lt;i&gt;~/Library/LaunchAgents&lt;/i&gt; so the setting only affects the current user.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="828"/>
<location filename="../settings/settingsdialog.cpp" line="833"/>
<source>This feature has not been implemented for your platform (yet).</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1036"/>
<location filename="../settings/settingsdialog.cpp" line="1041"/>
<source>unable to modify startup entry</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1066"/>
<location filename="../settings/settingsdialog.cpp" line="1071"/>
<source>There is already an autostart entry for &quot;%1&quot;. It will not be overridden when applying changes unless you delete it first.</source>
<translation type="unfinished"></translation>
</message>
@ -462,7 +462,7 @@
<name>QtGui::BuiltinWebViewOptionPage</name>
<message>
<location filename="../settings/builtinwebviewoptionpage.ui" line="12"/>
<location filename="../settings/settingsdialog.cpp" line="1659"/>
<location filename="../settings/settingsdialog.cpp" line="1664"/>
<source>Built-in web view</source>
<translation type="unfinished"></translation>
</message>
@ -482,7 +482,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1661"/>
<location filename="../settings/settingsdialog.cpp" line="1666"/>
<source>Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine.</source>
<translation type="unfinished"></translation>
</message>
@ -965,12 +965,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1635"/>
<location filename="../settings/settingsdialog.cpp" line="1640"/>
<source>Custom command to launch Syncthing&apos;s UI - </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1636"/>
<location filename="../settings/settingsdialog.cpp" line="1641"/>
<source>&lt;p&gt;Enter a custom command to launch Syncthing&apos;s UI. The expression &lt;code&gt;%SYNCTHING_URL%&lt;/code&gt; will be replaced with the Syncthing-URL.&lt;/p&gt;&lt;p&gt;Leave the command empty to use the auto-detection.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
@ -1235,7 +1235,7 @@
</message>
<message>
<location filename="../settings/launcheroptionpage.ui" line="209"/>
<location filename="../settings/settingsdialog.cpp" line="1246"/>
<location filename="../settings/settingsdialog.cpp" line="1251"/>
<source>Stop launched instance</source>
<translation type="unfinished"></translation>
</message>
@ -1250,82 +1250,82 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1107"/>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<source>%1-launcher</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1108"/>
<location filename="../settings/settingsdialog.cpp" line="1113"/>
<source>Launch %1 when starting the tray icon</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1111"/>
<location filename="../settings/settingsdialog.cpp" line="1116"/>
<source>%1 executable</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<location filename="../settings/settingsdialog.cpp" line="1117"/>
<source>%1 log (interleaved stdout/stderr)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1129"/>
<location filename="../settings/settingsdialog.cpp" line="1134"/>
<source>Restore default</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1135"/>
<location filename="../settings/settingsdialog.cpp" line="1140"/>
<source>Show Syncthing releases/downloads</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1281"/>
<location filename="../settings/settingsdialog.cpp" line="1286"/>
<source>%1 exited with exit code %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1284"/>
<location filename="../settings/settingsdialog.cpp" line="1289"/>
<source>%1 crashed with exit code %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1317"/>
<location filename="../settings/settingsdialog.cpp" line="1322"/>
<source>failed to start (e.g. executable does not exist or not permission error)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1320"/>
<location filename="../settings/settingsdialog.cpp" line="1325"/>
<source>process crashed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1323"/>
<location filename="../settings/settingsdialog.cpp" line="1328"/>
<source>timeout error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1326"/>
<location filename="../settings/settingsdialog.cpp" line="1331"/>
<source>read error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1329"/>
<location filename="../settings/settingsdialog.cpp" line="1334"/>
<source>write error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1332"/>
<location filename="../settings/settingsdialog.cpp" line="1337"/>
<source>unknown process error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1335"/>
<location filename="../settings/settingsdialog.cpp" line="1340"/>
<source>An error occurred when running %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1388"/>
<location filename="../settings/settingsdialog.cpp" line="1393"/>
<source>Kill launched instance</source>
<translation type="unfinished"></translation>
</message>
@ -1524,60 +1524,65 @@
<context>
<name>QtGui::OtherDialogs</name>
<message>
<location filename="../misc/otherdialogs.cpp" line="30"/>
<location filename="../misc/otherdialogs.cpp" line="33"/>
<source>Own device ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="40"/>
<location filename="../misc/otherdialogs.cpp" line="43"/>
<source>device ID is unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="48"/>
<location filename="../misc/otherdialogs.cpp" line="51"/>
<source>Copy to clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="85"/>
<location filename="../misc/otherdialogs.cpp" line="88"/>
<source>Remote/global tree of folder &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="134"/>
<source>Ignore patterns of folder &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::SettingsDialog</name>
<message>
<location filename="../settings/settingsdialog.cpp" line="1710"/>
<location filename="../settings/settingsdialog.cpp" line="1715"/>
<source>Tray</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1718"/>
<location filename="../settings/settingsdialog.cpp" line="1723"/>
<source>Web view</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1725"/>
<location filename="../settings/settingsdialog.cpp" line="1730"/>
<source>Startup</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>additional tool</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>Extra launcher</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1750"/>
<location filename="../settings/settingsdialog.cpp" line="1755"/>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1756"/>
<location filename="../settings/settingsdialog.cpp" line="1761"/>
<source>Start wizard</source>
<translation type="unfinished"></translation>
</message>
@ -1743,8 +1748,8 @@ This dialog closes automatically when the process finally terminates.</source>
<location filename="../settings/systemdoptionpage.ui" line="117"/>
<location filename="../settings/systemdoptionpage.ui" line="172"/>
<location filename="../settings/systemdoptionpage.ui" line="261"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<location filename="../settings/settingsdialog.cpp" line="1543"/>
<location filename="../settings/settingsdialog.cpp" line="1539"/>
<location filename="../settings/settingsdialog.cpp" line="1548"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
@ -1784,27 +1789,27 @@ This dialog closes automatically when the process finally terminates.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1424"/>
<location filename="../settings/settingsdialog.cpp" line="1429"/>
<source>Reload all unit files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1469"/>
<location filename="../settings/settingsdialog.cpp" line="1474"/>
<source>It is not possible to show the start/stop button for the systemd service and the internal launcher at the same time. The systemd service precedes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1475"/>
<location filename="../settings/settingsdialog.cpp" line="1480"/>
<source>It is not possible to consider the systemd service and the internal launcher for reconnects at the same time. The systemd service precedes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1507"/>
<location filename="../settings/settingsdialog.cpp" line="1512"/>
<source>specified unit is either inactive or doesn&apos;t exist</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1529"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<source>since </source>
<translation type="unfinished"></translation>
</message>

View File

@ -470,32 +470,32 @@
<translation>Lösche existierenden Eintrag</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="817"/>
<location filename="../settings/settingsdialog.cpp" line="822"/>
<source>This is achieved by adding a *.desktop file under &lt;i&gt;~/.config/autostart&lt;/i&gt; so the setting only affects the current user.</source>
<translation>Durch das Hinzufügen einer *.desktop-Datei unter &lt;i&gt;~/.config/autostart&lt;/i&gt; realisiert - betrifft also nur den aktuellen Benutzer.</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="820"/>
<location filename="../settings/settingsdialog.cpp" line="825"/>
<source>This is achieved by adding a registry key under &lt;i&gt;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&lt;/i&gt; so the setting only affects the current user. Note that the startup entry is invalidated when moving &lt;i&gt;syncthingtray.exe&lt;/i&gt;.</source>
<translation>Durch das Hinzufügen eines Registry-Schlüssels unter &lt;i&gt;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&lt;/i&gt; realisiert - betrifft also nur den aktuellen Benutzer.</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="824"/>
<location filename="../settings/settingsdialog.cpp" line="829"/>
<source>This is achieved by adding a *.plist file under &lt;i&gt;~/Library/LaunchAgents&lt;/i&gt; so the setting only affects the current user.</source>
<translation>Durch das Hinzufügen einer *.plist-Datei unter &lt;i&gt;~/Library/LaunchAgents&lt;/i&gt; realisiert - betrifft also nur den aktuellen Benutzer.</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="828"/>
<location filename="../settings/settingsdialog.cpp" line="833"/>
<source>This feature has not been implemented for your platform (yet).</source>
<translation>Diese Funktion wurde für die aktuelle Plattform nicht nicht implementiert.</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1036"/>
<location filename="../settings/settingsdialog.cpp" line="1041"/>
<source>unable to modify startup entry</source>
<translation>Fehler beim aktualisieren des Auto-Start-Eintrags</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1066"/>
<location filename="../settings/settingsdialog.cpp" line="1071"/>
<source>There is already an autostart entry for &quot;%1&quot;. It will not be overridden when applying changes unless you delete it first.</source>
<translation>Es gibt bereits einen Autostart-Eintrag für &quot;%1&quot;. Dieser Eintrag wird beim Anwenden der Einstellungen nicht verändert außer er wird zuvor gelöscht.</translation>
</message>
@ -606,7 +606,7 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
</message>
<message>
<location filename="../settings/builtinwebviewoptionpage.ui" line="12"/>
<location filename="../settings/settingsdialog.cpp" line="1659"/>
<location filename="../settings/settingsdialog.cpp" line="1664"/>
<source>Built-in web view</source>
<translation>Eingebaute Webanzeige</translation>
</message>
@ -626,7 +626,7 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
<translation>Lasse Weboberfläche im Hintgergrund weiter offen, wenn Fenster nicht offen</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1661"/>
<location filename="../settings/settingsdialog.cpp" line="1666"/>
<source>Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine.</source>
<translation>Syncthing Tray wurde nicht mit Unterstützung für die eingebaute Anzeige der Weboberfläche unter Verwendung von Qt WebKit oder Qt WebEngine gebaut.</translation>
</message>
@ -1120,12 +1120,12 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1635"/>
<location filename="../settings/settingsdialog.cpp" line="1640"/>
<source>Custom command to launch Syncthing&apos;s UI - </source>
<translation>Befehl zum Starten der Syncthing-Oberfläche - </translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1636"/>
<location filename="../settings/settingsdialog.cpp" line="1641"/>
<source>&lt;p&gt;Enter a custom command to launch Syncthing&apos;s UI. The expression &lt;code&gt;%SYNCTHING_URL%&lt;/code&gt; will be replaced with the Syncthing-URL.&lt;/p&gt;&lt;p&gt;Leave the command empty to use the auto-detection.&lt;/p&gt;</source>
<translation>&lt;p&gt;Gib den Befehl ein, mit dem die Syncthing-Oberfläche gestartet werden soll. Der Ausdruck &lt;code&gt;%SYNCTHING_URL%&lt;/code&gt; wird durch die Syncthing-URL ersetzt.&lt;/p&gt;&lt;p&gt;Lasse den Befehl leer, um die automatische Erkennung zu verwenden.&lt;/p&gt;</translation>
</message>
@ -1419,7 +1419,7 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
</message>
<message>
<location filename="../settings/launcheroptionpage.ui" line="209"/>
<location filename="../settings/settingsdialog.cpp" line="1246"/>
<location filename="../settings/settingsdialog.cpp" line="1251"/>
<source>Stop launched instance</source>
<translation>Stoppen</translation>
</message>
@ -1434,12 +1434,12 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
<translation>Log folgen</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1107"/>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<source>%1-launcher</source>
<translation>%1-Starter</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1108"/>
<location filename="../settings/settingsdialog.cpp" line="1113"/>
<source>Launch %1 when starting the tray icon</source>
<translation>Starte %1 beim Starten des Tray-Icons</translation>
</message>
@ -1448,72 +1448,72 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
<translation type="obsolete">%1-Starter {1 ?}</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1111"/>
<location filename="../settings/settingsdialog.cpp" line="1116"/>
<source>%1 executable</source>
<translation>Ausführbare Datei von %1</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<location filename="../settings/settingsdialog.cpp" line="1117"/>
<source>%1 log (interleaved stdout/stderr)</source>
<translation>Log von %1 (stdout/stderr)</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1129"/>
<location filename="../settings/settingsdialog.cpp" line="1134"/>
<source>Restore default</source>
<translation>Auf Vorgabe zurücksetzen</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1135"/>
<location filename="../settings/settingsdialog.cpp" line="1140"/>
<source>Show Syncthing releases/downloads</source>
<translation>Syncthing Releases/Downloads zeigen</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1281"/>
<location filename="../settings/settingsdialog.cpp" line="1286"/>
<source>%1 exited with exit code %2</source>
<translation>%1 wurde mit dem Statuscode %2 beendet</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1284"/>
<location filename="../settings/settingsdialog.cpp" line="1289"/>
<source>%1 crashed with exit code %2</source>
<translation>%1 ist mit dem Statuscode %2 abgestürzt</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1317"/>
<location filename="../settings/settingsdialog.cpp" line="1322"/>
<source>failed to start (e.g. executable does not exist or not permission error)</source>
<translation>Start fehlgeschlagen (z. B. weil Programmdatei nicht existiert oder nicht ausführbar ist)</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1320"/>
<location filename="../settings/settingsdialog.cpp" line="1325"/>
<source>process crashed</source>
<translation>Prozess ist abgestürzt</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1323"/>
<location filename="../settings/settingsdialog.cpp" line="1328"/>
<source>timeout error</source>
<translation>Time-out</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1326"/>
<location filename="../settings/settingsdialog.cpp" line="1331"/>
<source>read error</source>
<translation>Lesefehler</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1329"/>
<location filename="../settings/settingsdialog.cpp" line="1334"/>
<source>write error</source>
<translation>Schreibfehler</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1332"/>
<location filename="../settings/settingsdialog.cpp" line="1337"/>
<source>unknown process error</source>
<translation>unbekannter Fehler</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1335"/>
<location filename="../settings/settingsdialog.cpp" line="1340"/>
<source>An error occurred when running %1: %2</source>
<translation>Beim Ausführen von %1 ist ein Fehler aufgetreten: %2</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1388"/>
<location filename="../settings/settingsdialog.cpp" line="1393"/>
<source>Kill launched instance</source>
<translation>Töten</translation>
</message>
@ -1720,35 +1720,40 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
<context>
<name>QtGui::OtherDialogs</name>
<message>
<location filename="../misc/otherdialogs.cpp" line="30"/>
<location filename="../misc/otherdialogs.cpp" line="33"/>
<source>Own device ID</source>
<translation>Eigene Geräte-ID</translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="40"/>
<location filename="../misc/otherdialogs.cpp" line="43"/>
<source>device ID is unknown</source>
<translation>Geräte-ID ist unbekannt</translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="48"/>
<location filename="../misc/otherdialogs.cpp" line="51"/>
<source>Copy to clipboard</source>
<translation>In Zwischenablage kopieren</translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="85"/>
<location filename="../misc/otherdialogs.cpp" line="88"/>
<source>Remote/global tree of folder &quot;%1&quot;</source>
<translation>Globale Dateistruktur von &quot;%1&quot;</translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="134"/>
<source>Ignore patterns of folder &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::SettingsDialog</name>
<message>
<location filename="../settings/settingsdialog.cpp" line="1718"/>
<location filename="../settings/settingsdialog.cpp" line="1723"/>
<source>Web view</source>
<translation>Webanzeige</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1725"/>
<location filename="../settings/settingsdialog.cpp" line="1730"/>
<source>Startup</source>
<translation>Starten</translation>
</message>
@ -1757,27 +1762,27 @@ Die Weboberfläche wird stattdessen im Standardwebrowser geöffnet.</translation
<translation type="vanished">Zusatztool</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1710"/>
<location filename="../settings/settingsdialog.cpp" line="1715"/>
<source>Tray</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>Extra launcher</source>
<translation>Extra-Starter</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>additional tool</source>
<translation>Zusatztool</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1750"/>
<location filename="../settings/settingsdialog.cpp" line="1755"/>
<source>Settings</source>
<translation>Einstellungen</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1756"/>
<location filename="../settings/settingsdialog.cpp" line="1761"/>
<source>Start wizard</source>
<translation>Einrichtungsassistenten öffnen</translation>
</message>
@ -1975,8 +1980,8 @@ Dieser Dialog schließt sich automatisch, wenn der Prozess beendet wird.</transl
<location filename="../settings/systemdoptionpage.ui" line="117"/>
<location filename="../settings/systemdoptionpage.ui" line="172"/>
<location filename="../settings/systemdoptionpage.ui" line="261"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<location filename="../settings/settingsdialog.cpp" line="1543"/>
<location filename="../settings/settingsdialog.cpp" line="1539"/>
<location filename="../settings/settingsdialog.cpp" line="1548"/>
<source>unknown</source>
<translation>unbekannt</translation>
</message>
@ -2009,27 +2014,27 @@ Dieser Dialog schließt sich automatisch, wenn der Prozess beendet wird.</transl
<translation>Stoppen</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1424"/>
<location filename="../settings/settingsdialog.cpp" line="1429"/>
<source>Reload all unit files</source>
<translation>Alle Unit-Dateien neu laden</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1469"/>
<location filename="../settings/settingsdialog.cpp" line="1474"/>
<source>It is not possible to show the start/stop button for the systemd service and the internal launcher at the same time. The systemd service precedes.</source>
<translation>Es ist nicht möglich, den Start-/Stop-Button für den Systemd-Dienst und den internen Starter gleichzeitig anzugeigen. Wenn verfügbar, wird der Button den Systemd-Dienst kontrollieren.</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1475"/>
<location filename="../settings/settingsdialog.cpp" line="1480"/>
<source>It is not possible to consider the systemd service and the internal launcher for reconnects at the same time. The systemd service precedes.</source>
<translation>Es ist nicht möglich, den Status des Systemd-Dienstes und den des internen Starters gleichzeitig für Verbindungsveruche einzubeziehen. Wenn verfügbar, wird der Status des Systemd-Dienstes verwendet.</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1507"/>
<location filename="../settings/settingsdialog.cpp" line="1512"/>
<source>specified unit is either inactive or doesn&apos;t exist</source>
<translation>angegebene Unit entweder nicht geladen oder existiert nicht</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1529"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<source>since </source>
<translation>seit </translation>
</message>

View File

@ -374,32 +374,32 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="817"/>
<location filename="../settings/settingsdialog.cpp" line="822"/>
<source>This is achieved by adding a *.desktop file under &lt;i&gt;~/.config/autostart&lt;/i&gt; so the setting only affects the current user.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="820"/>
<location filename="../settings/settingsdialog.cpp" line="825"/>
<source>This is achieved by adding a registry key under &lt;i&gt;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&lt;/i&gt; so the setting only affects the current user. Note that the startup entry is invalidated when moving &lt;i&gt;syncthingtray.exe&lt;/i&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="824"/>
<location filename="../settings/settingsdialog.cpp" line="829"/>
<source>This is achieved by adding a *.plist file under &lt;i&gt;~/Library/LaunchAgents&lt;/i&gt; so the setting only affects the current user.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="828"/>
<location filename="../settings/settingsdialog.cpp" line="833"/>
<source>This feature has not been implemented for your platform (yet).</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1036"/>
<location filename="../settings/settingsdialog.cpp" line="1041"/>
<source>unable to modify startup entry</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1066"/>
<location filename="../settings/settingsdialog.cpp" line="1071"/>
<source>There is already an autostart entry for &quot;%1&quot;. It will not be overridden when applying changes unless you delete it first.</source>
<translation type="unfinished"></translation>
</message>
@ -462,7 +462,7 @@
<name>QtGui::BuiltinWebViewOptionPage</name>
<message>
<location filename="../settings/builtinwebviewoptionpage.ui" line="12"/>
<location filename="../settings/settingsdialog.cpp" line="1659"/>
<location filename="../settings/settingsdialog.cpp" line="1664"/>
<source>Built-in web view</source>
<translation type="unfinished"></translation>
</message>
@ -482,7 +482,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1661"/>
<location filename="../settings/settingsdialog.cpp" line="1666"/>
<source>Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine.</source>
<translation type="unfinished"></translation>
</message>
@ -964,12 +964,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1635"/>
<location filename="../settings/settingsdialog.cpp" line="1640"/>
<source>Custom command to launch Syncthing&apos;s UI - </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1636"/>
<location filename="../settings/settingsdialog.cpp" line="1641"/>
<source>&lt;p&gt;Enter a custom command to launch Syncthing&apos;s UI. The expression &lt;code&gt;%SYNCTHING_URL%&lt;/code&gt; will be replaced with the Syncthing-URL.&lt;/p&gt;&lt;p&gt;Leave the command empty to use the auto-detection.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
@ -1233,7 +1233,7 @@
</message>
<message>
<location filename="../settings/launcheroptionpage.ui" line="209"/>
<location filename="../settings/settingsdialog.cpp" line="1246"/>
<location filename="../settings/settingsdialog.cpp" line="1251"/>
<source>Stop launched instance</source>
<translation type="unfinished"></translation>
</message>
@ -1248,82 +1248,82 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1107"/>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<source>%1-launcher</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1108"/>
<location filename="../settings/settingsdialog.cpp" line="1113"/>
<source>Launch %1 when starting the tray icon</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1111"/>
<location filename="../settings/settingsdialog.cpp" line="1116"/>
<source>%1 executable</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<location filename="../settings/settingsdialog.cpp" line="1117"/>
<source>%1 log (interleaved stdout/stderr)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1129"/>
<location filename="../settings/settingsdialog.cpp" line="1134"/>
<source>Restore default</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1135"/>
<location filename="../settings/settingsdialog.cpp" line="1140"/>
<source>Show Syncthing releases/downloads</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1281"/>
<location filename="../settings/settingsdialog.cpp" line="1286"/>
<source>%1 exited with exit code %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1284"/>
<location filename="../settings/settingsdialog.cpp" line="1289"/>
<source>%1 crashed with exit code %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1317"/>
<location filename="../settings/settingsdialog.cpp" line="1322"/>
<source>failed to start (e.g. executable does not exist or not permission error)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1320"/>
<location filename="../settings/settingsdialog.cpp" line="1325"/>
<source>process crashed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1323"/>
<location filename="../settings/settingsdialog.cpp" line="1328"/>
<source>timeout error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1326"/>
<location filename="../settings/settingsdialog.cpp" line="1331"/>
<source>read error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1329"/>
<location filename="../settings/settingsdialog.cpp" line="1334"/>
<source>write error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1332"/>
<location filename="../settings/settingsdialog.cpp" line="1337"/>
<source>unknown process error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1335"/>
<location filename="../settings/settingsdialog.cpp" line="1340"/>
<source>An error occurred when running %1: %2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1388"/>
<location filename="../settings/settingsdialog.cpp" line="1393"/>
<source>Kill launched instance</source>
<translation type="unfinished"></translation>
</message>
@ -1522,60 +1522,65 @@
<context>
<name>QtGui::OtherDialogs</name>
<message>
<location filename="../misc/otherdialogs.cpp" line="30"/>
<location filename="../misc/otherdialogs.cpp" line="33"/>
<source>Own device ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="40"/>
<location filename="../misc/otherdialogs.cpp" line="43"/>
<source>device ID is unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="48"/>
<location filename="../misc/otherdialogs.cpp" line="51"/>
<source>Copy to clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="85"/>
<location filename="../misc/otherdialogs.cpp" line="88"/>
<source>Remote/global tree of folder &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="134"/>
<source>Ignore patterns of folder &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::SettingsDialog</name>
<message>
<location filename="../settings/settingsdialog.cpp" line="1710"/>
<location filename="../settings/settingsdialog.cpp" line="1715"/>
<source>Tray</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1718"/>
<location filename="../settings/settingsdialog.cpp" line="1723"/>
<source>Web view</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1725"/>
<location filename="../settings/settingsdialog.cpp" line="1730"/>
<source>Startup</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>additional tool</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>Extra launcher</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1750"/>
<location filename="../settings/settingsdialog.cpp" line="1755"/>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1756"/>
<location filename="../settings/settingsdialog.cpp" line="1761"/>
<source>Start wizard</source>
<translation type="unfinished"></translation>
</message>
@ -1745,8 +1750,8 @@ This dialog closes automatically when the process finally terminates.</source>
<location filename="../settings/systemdoptionpage.ui" line="117"/>
<location filename="../settings/systemdoptionpage.ui" line="172"/>
<location filename="../settings/systemdoptionpage.ui" line="261"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<location filename="../settings/settingsdialog.cpp" line="1543"/>
<location filename="../settings/settingsdialog.cpp" line="1539"/>
<location filename="../settings/settingsdialog.cpp" line="1548"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
@ -1786,27 +1791,27 @@ This dialog closes automatically when the process finally terminates.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1424"/>
<location filename="../settings/settingsdialog.cpp" line="1429"/>
<source>Reload all unit files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1469"/>
<location filename="../settings/settingsdialog.cpp" line="1474"/>
<source>It is not possible to show the start/stop button for the systemd service and the internal launcher at the same time. The systemd service precedes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1475"/>
<location filename="../settings/settingsdialog.cpp" line="1480"/>
<source>It is not possible to consider the systemd service and the internal launcher for reconnects at the same time. The systemd service precedes.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1507"/>
<location filename="../settings/settingsdialog.cpp" line="1512"/>
<source>specified unit is either inactive or doesn&apos;t exist</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1529"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<source>since </source>
<translation type="unfinished"></translation>
</message>

View File

@ -382,32 +382,32 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="817"/>
<location filename="../settings/settingsdialog.cpp" line="822"/>
<source>This is achieved by adding a *.desktop file under &lt;i&gt;~/.config/autostart&lt;/i&gt; so the setting only affects the current user.</source>
<translation> &lt;i&gt;~/.config/autostart&lt;/i&gt; *.desktop </translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="820"/>
<location filename="../settings/settingsdialog.cpp" line="825"/>
<source>This is achieved by adding a registry key under &lt;i&gt;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&lt;/i&gt; so the setting only affects the current user. Note that the startup entry is invalidated when moving &lt;i&gt;syncthingtray.exe&lt;/i&gt;.</source>
<translation> &lt;i&gt;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run&lt;/i&gt; 下添加注册表项来实现的,因此该设置仅影响当前用户。 请注意,移动 &lt;i&gt;syncthingtray.exe&lt;/i&gt; </translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="824"/>
<location filename="../settings/settingsdialog.cpp" line="829"/>
<source>This is achieved by adding a *.plist file under &lt;i&gt;~/Library/LaunchAgents&lt;/i&gt; so the setting only affects the current user.</source>
<translation> &lt;i&gt;~/Library/LaunchAgents&lt;/i&gt; *.plist </translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="828"/>
<location filename="../settings/settingsdialog.cpp" line="833"/>
<source>This feature has not been implemented for your platform (yet).</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1036"/>
<location filename="../settings/settingsdialog.cpp" line="1041"/>
<source>unable to modify startup entry</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1066"/>
<location filename="../settings/settingsdialog.cpp" line="1071"/>
<source>There is already an autostart entry for &quot;%1&quot;. It will not be overridden when applying changes unless you delete it first.</source>
<translation type="unfinished"></translation>
</message>
@ -480,7 +480,7 @@ The Web UI will be opened in the default web browser instead.</source>
</message>
<message>
<location filename="../settings/builtinwebviewoptionpage.ui" line="12"/>
<location filename="../settings/settingsdialog.cpp" line="1659"/>
<location filename="../settings/settingsdialog.cpp" line="1664"/>
<source>Built-in web view</source>
<translation type="unfinished"></translation>
</message>
@ -500,7 +500,7 @@ The Web UI will be opened in the default web browser instead.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1661"/>
<location filename="../settings/settingsdialog.cpp" line="1666"/>
<source>Syncthing Tray has not been built with vieb view support utilizing either Qt WebKit or Qt WebEngine.</source>
<translation type="unfinished"></translation>
</message>
@ -985,12 +985,12 @@ The Web UI will be opened in the default web browser instead.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1635"/>
<location filename="../settings/settingsdialog.cpp" line="1640"/>
<source>Custom command to launch Syncthing&apos;s UI - </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1636"/>
<location filename="../settings/settingsdialog.cpp" line="1641"/>
<source>&lt;p&gt;Enter a custom command to launch Syncthing&apos;s UI. The expression &lt;code&gt;%SYNCTHING_URL%&lt;/code&gt; will be replaced with the Syncthing-URL.&lt;/p&gt;&lt;p&gt;Leave the command empty to use the auto-detection.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
@ -1261,7 +1261,7 @@ The Web UI will be opened in the default web browser instead.</source>
</message>
<message>
<location filename="../settings/launcheroptionpage.ui" line="209"/>
<location filename="../settings/settingsdialog.cpp" line="1246"/>
<location filename="../settings/settingsdialog.cpp" line="1251"/>
<source>Stop launched instance</source>
<translation></translation>
</message>
@ -1276,82 +1276,82 @@ The Web UI will be opened in the default web browser instead.</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1107"/>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<source>%1-launcher</source>
<translation>%1-</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1108"/>
<location filename="../settings/settingsdialog.cpp" line="1113"/>
<source>Launch %1 when starting the tray icon</source>
<translation> %1</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1111"/>
<location filename="../settings/settingsdialog.cpp" line="1116"/>
<source>%1 executable</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1112"/>
<location filename="../settings/settingsdialog.cpp" line="1117"/>
<source>%1 log (interleaved stdout/stderr)</source>
<translation>%1 /</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1129"/>
<location filename="../settings/settingsdialog.cpp" line="1134"/>
<source>Restore default</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1135"/>
<location filename="../settings/settingsdialog.cpp" line="1140"/>
<source>Show Syncthing releases/downloads</source>
<translation> Syncthing /</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1281"/>
<location filename="../settings/settingsdialog.cpp" line="1286"/>
<source>%1 exited with exit code %2</source>
<translation>%1 退退 %2</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1284"/>
<location filename="../settings/settingsdialog.cpp" line="1289"/>
<source>%1 crashed with exit code %2</source>
<translation>%1 退 %2</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1317"/>
<location filename="../settings/settingsdialog.cpp" line="1322"/>
<source>failed to start (e.g. executable does not exist or not permission error)</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1320"/>
<location filename="../settings/settingsdialog.cpp" line="1325"/>
<source>process crashed</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1323"/>
<location filename="../settings/settingsdialog.cpp" line="1328"/>
<source>timeout error</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1326"/>
<location filename="../settings/settingsdialog.cpp" line="1331"/>
<source>read error</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1329"/>
<location filename="../settings/settingsdialog.cpp" line="1334"/>
<source>write error</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1332"/>
<location filename="../settings/settingsdialog.cpp" line="1337"/>
<source>unknown process error</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1335"/>
<location filename="../settings/settingsdialog.cpp" line="1340"/>
<source>An error occurred when running %1: %2</source>
<translation> %1 : %2</translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1388"/>
<location filename="../settings/settingsdialog.cpp" line="1393"/>
<source>Kill launched instance</source>
<translation></translation>
</message>
@ -1558,60 +1558,65 @@ The Web UI will be opened in the default web browser instead.</source>
<context>
<name>QtGui::OtherDialogs</name>
<message>
<location filename="../misc/otherdialogs.cpp" line="30"/>
<location filename="../misc/otherdialogs.cpp" line="33"/>
<source>Own device ID</source>
<translation> ID</translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="40"/>
<location filename="../misc/otherdialogs.cpp" line="43"/>
<source>device ID is unknown</source>
<translation> ID </translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="48"/>
<location filename="../misc/otherdialogs.cpp" line="51"/>
<source>Copy to clipboard</source>
<translation></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="85"/>
<location filename="../misc/otherdialogs.cpp" line="88"/>
<source>Remote/global tree of folder &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../misc/otherdialogs.cpp" line="134"/>
<source>Ignore patterns of folder &quot;%1&quot;</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::SettingsDialog</name>
<message>
<location filename="../settings/settingsdialog.cpp" line="1710"/>
<location filename="../settings/settingsdialog.cpp" line="1715"/>
<source>Tray</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1718"/>
<location filename="../settings/settingsdialog.cpp" line="1723"/>
<source>Web view</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1725"/>
<location filename="../settings/settingsdialog.cpp" line="1730"/>
<source>Startup</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>additional tool</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1727"/>
<location filename="../settings/settingsdialog.cpp" line="1732"/>
<source>Extra launcher</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1750"/>
<location filename="../settings/settingsdialog.cpp" line="1755"/>
<source>Settings</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1756"/>
<location filename="../settings/settingsdialog.cpp" line="1761"/>
<source>Start wizard</source>
<translation type="unfinished"></translation>
</message>
@ -1800,8 +1805,8 @@ This dialog closes automatically when the process finally terminates.</source>
<location filename="../settings/systemdoptionpage.ui" line="117"/>
<location filename="../settings/systemdoptionpage.ui" line="172"/>
<location filename="../settings/systemdoptionpage.ui" line="261"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<location filename="../settings/settingsdialog.cpp" line="1543"/>
<location filename="../settings/settingsdialog.cpp" line="1539"/>
<location filename="../settings/settingsdialog.cpp" line="1548"/>
<source>unknown</source>
<translation></translation>
</message>
@ -1836,27 +1841,27 @@ This dialog closes automatically when the process finally terminates.</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1424"/>
<location filename="../settings/settingsdialog.cpp" line="1429"/>
<source>Reload all unit files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1469"/>
<location filename="../settings/settingsdialog.cpp" line="1474"/>
<source>It is not possible to show the start/stop button for the systemd service and the internal launcher at the same time. The systemd service precedes.</source>
<translation> systemd / systemd </translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1475"/>
<location filename="../settings/settingsdialog.cpp" line="1480"/>
<source>It is not possible to consider the systemd service and the internal launcher for reconnects at the same time. The systemd service precedes.</source>
<translation> systemd systemd </translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1507"/>
<location filename="../settings/settingsdialog.cpp" line="1512"/>
<source>specified unit is either inactive or doesn&apos;t exist</source>
<translation></translation>
</message>
<message>
<location filename="../settings/settingsdialog.cpp" line="1529"/>
<location filename="../settings/settingsdialog.cpp" line="1534"/>
<source>since </source>
<translation> </translation>
</message>

View File

@ -178,7 +178,8 @@ public:
#endif
}
// register own handler to detect whether signal has been emitted
m_emittedConnection = QObject::connect(sender, signal, sender, [this] { m_signalEmitted = true; }, Qt::DirectConnection);
m_emittedConnection = QObject::connect(
sender, signal, sender, [this] { m_signalEmitted = true; }, Qt::DirectConnection);
#ifndef SYNCTHINGTESTHELPER_FOR_CLI
if (!m_emittedConnection) {
CPPUNIT_FAIL(argsToString("Unable to connect signal ", signalName().data(), " to check for signal emmitation"));

View File

@ -89,6 +89,7 @@ set(REQUIRED_ICONS
preferences-other
process-stop
qtcreator
selection-symbolic
system-run
system-search
system-file-manager

View File

@ -108,6 +108,8 @@ void DirView::showContextMenu(const QPoint &position)
QIcon(QStringLiteral(":/icons/hicolor/scalable/places/document-open-remote.svg"))),
tr("Browse remote files")),
&QAction::triggered, triggerActionForSelectedRow(this, &DirView::browseRemoteFiles));
connect(menu.addAction(QIcon::fromTheme(QStringLiteral("selection-symbolic")), tr("Show ignore patterns")), &QAction::triggered,
triggerActionForSelectedRow(this, &DirView::showIgnorePatterns));
}
}
showViewMenu(position, *this, menu);

View File

@ -24,6 +24,7 @@ Q_SIGNALS:
void scanDir(const Data::SyncthingDir &dir);
void pauseResumeDir(const Data::SyncthingDir &dir);
void browseRemoteFiles(const Data::SyncthingDir &dir);
void showIgnorePatterns(const Data::SyncthingDir &dir);
protected:
void mouseReleaseEvent(QMouseEvent *event) override;

View File

@ -204,6 +204,7 @@ TrayWidget::TrayWidget(TrayMenu *parent)
connect(m_ui->dirsTreeView, &DirView::pauseResumeDir, this, &TrayWidget::pauseResumeDir);
connect(m_ui->devsTreeView, &DevView::pauseResumeDev, this, &TrayWidget::pauseResumeDev);
connect(m_ui->dirsTreeView, &DirView::browseRemoteFiles, this, &TrayWidget::browseRemoteFiles);
connect(m_ui->dirsTreeView, &DirView::showIgnorePatterns, this, &TrayWidget::showIgnorePatterns);
connect(m_ui->downloadsTreeView, &DownloadView::openDir, this, &TrayWidget::openDir);
connect(m_ui->downloadsTreeView, &DownloadView::openItemDir, this, &TrayWidget::openItemDir);
connect(m_ui->recentChangesTreeView, &QTreeView::customContextMenuRequested, this, &TrayWidget::showRecentChangesContextMenu);
@ -711,10 +712,12 @@ void TrayWidget::pauseResumeDir(const SyncthingDir &dir)
void TrayWidget::browseRemoteFiles(const Data::SyncthingDir &dir)
{
auto *const dlg = browseRemoteFilesDialog(m_connection, dir, this);
dlg->resize(600, 500);
centerWidget(dlg);
dlg->show();
showCenteredDialog(browseRemoteFilesDialog(m_connection, dir, this), QSize(600, 500));
}
void TrayWidget::showIgnorePatterns(const Data::SyncthingDir &dir)
{
showCenteredDialog(ignorePatternsDialog(m_connection, dir, this), QSize(600, 500));
}
void TrayWidget::showRecentChangesContextMenu(const QPoint &position)
@ -963,6 +966,16 @@ void TrayWidget::showDialog(QWidget *dlg, bool maximized)
dlg->activateWindow();
}
void TrayWidget::showCenteredDialog(QWidget *dlg, const QSize &size)
{
if (m_menu && m_menu->windowType() != TrayMenu::WindowType::NormalWindow) {
m_menu->close();
}
dlg->resize(size);
centerWidget(dlg);
dlg->show();
}
void TrayWidget::setBrightColorsOfModelsAccordingToPalette()
{
auto &qtSettings = Settings::values().qt;

View File

@ -96,6 +96,7 @@ private Q_SLOTS:
void pauseResumeDev(const Data::SyncthingDev &dev);
void pauseResumeDir(const Data::SyncthingDir &dir);
void browseRemoteFiles(const Data::SyncthingDir &dir);
void showIgnorePatterns(const Data::SyncthingDir &dir);
void showRecentChangesContextMenu(const QPoint &position);
void changeStatus();
void updateTraffic();
@ -115,6 +116,7 @@ private Q_SLOTS:
void handleConnectionSelected(QAction *connectionAction);
void concludeWizard(const QString &errorMessage = QString());
void showDialog(QWidget *dlg, bool maximized = false);
void showCenteredDialog(QWidget *dlg, const QSize &size);
void setBrightColorsOfModelsAccordingToPalette();
void setLabelPixmaps();
void setTrafficPixmaps(bool recompute = false);

View File

@ -71,6 +71,11 @@
<source>Browse remote files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/dirview.cpp" line="111"/>
<source>Show ignore patterns</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::DownloadView</name>
@ -167,20 +172,20 @@
</message>
<message>
<location filename="../gui/traywidget.ui" line="99"/>
<location filename="../gui/traywidget.cpp" line="342"/>
<location filename="../gui/traywidget.cpp" line="343"/>
<source>About</source>
<translation>O Syncthing Tray</translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="58"/>
<location filename="../gui/traywidget.cpp" line="471"/>
<location filename="../gui/traywidget.cpp" line="472"/>
<source>Connect</source>
<translation>Připojit</translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="72"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<location filename="../gui/traywidget.cpp" line="902"/>
<location filename="../gui/traywidget.cpp" line="863"/>
<location filename="../gui/traywidget.cpp" line="905"/>
<source>Start</source>
<translation>Spustit</translation>
</message>
@ -252,7 +257,7 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<message>
<location filename="../gui/traywidget.ui" line="357"/>
<location filename="../gui/traywidget.cpp" line="155"/>
<location filename="../gui/traywidget.cpp" line="382"/>
<location filename="../gui/traywidget.cpp" line="383"/>
<source>New notifications</source>
<translation>Nová oznámení</translation>
</message>
@ -322,93 +327,93 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<translation>Ukončit Syncthing Tray</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="439"/>
<location filename="../gui/traywidget.cpp" line="440"/>
<source>Do you really want to restart Syncthing?</source>
<translation>Opravdu chcete Syncthing restartovat?</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="466"/>
<location filename="../gui/traywidget.cpp" line="467"/>
<source>Connecting </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="467"/>
<location filename="../gui/traywidget.cpp" line="468"/>
<source>Establishing connection to Syncthing </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="472"/>
<location filename="../gui/traywidget.cpp" line="473"/>
<source>Not connected to Syncthing, click to connect</source>
<translation>Nepřipojeno k Syncthing, klikněte pro připojení se</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="477"/>
<location filename="../gui/traywidget.cpp" line="478"/>
<source>Unable to establish connection to Syncthing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="485"/>
<location filename="../gui/traywidget.cpp" line="486"/>
<source>Pause</source>
<translation>Pozastavit</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="486"/>
<location filename="../gui/traywidget.cpp" line="487"/>
<source>Syncthing is running, click to pause all devices</source>
<translation>Syncthing je spuštěné, kliknutím pozastavíte veškerá zařízení</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="491"/>
<location filename="../gui/traywidget.cpp" line="492"/>
<source>Continue</source>
<translation>Pokračovat</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="492"/>
<location filename="../gui/traywidget.cpp" line="493"/>
<source>At least one device is paused, click to resume</source>
<translation>Přinejmenším jedno zařízení je pozastaveno, kliknutím pokračujte</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="615"/>
<location filename="../gui/traywidget.cpp" line="616"/>
<source>The specified connection configuration &lt;em&gt;%1&lt;/em&gt; is not defined and hence ignored.</source>
<translation>Zadané nastavení spojení &lt;em&gt;%1&lt;/em&gt; není definováno a proto je ignorováno.</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="674"/>
<location filename="../gui/traywidget.cpp" line="675"/>
<source>The folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation>Adresář &lt;i&gt;%1&lt;/i&gt; neexistuje místně.</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="685"/>
<location filename="../gui/traywidget.cpp" line="686"/>
<source>The containing folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation>Obsažený adresář &lt;i&gt;%1&lt;/i&gt; neexistuje místně.</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="736"/>
<location filename="../gui/traywidget.cpp" line="739"/>
<source>Copy path</source>
<translation type="unfinished">Zkopírovat popis umístění</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="740"/>
<location filename="../gui/traywidget.cpp" line="743"/>
<source>Copy device ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="743"/>
<location filename="../gui/traywidget.cpp" line="746"/>
<source>Copy folder ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="856"/>
<location filename="../gui/traywidget.cpp" line="896"/>
<location filename="../gui/traywidget.cpp" line="859"/>
<location filename="../gui/traywidget.cpp" line="899"/>
<source>Stop</source>
<translation>Zastavit</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="857"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<source>Stop Syncthing instance launched via tray icon</source>
<translation>Zastavit instanci Syncthing spuštěnou prostřednictvím ikony v oznamovací oblasti</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="861"/>
<location filename="../gui/traywidget.cpp" line="864"/>
<source>Start Syncthing with the built-in launcher configured in the settings</source>
<translation>Spustit Syncthing s vestavěným spouštěčem nastaveným v nastaveních</translation>
</message>

View File

@ -71,6 +71,11 @@
<source>Browse remote files</source>
<translation>Globale Dateistruktur durchsuchen</translation>
</message>
<message>
<location filename="../gui/dirview.cpp" line="111"/>
<source>Show ignore patterns</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::DownloadView</name>
@ -167,20 +172,20 @@
</message>
<message>
<location filename="../gui/traywidget.ui" line="99"/>
<location filename="../gui/traywidget.cpp" line="342"/>
<location filename="../gui/traywidget.cpp" line="343"/>
<source>About</source>
<translation>Über Syncthing Tray</translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="58"/>
<location filename="../gui/traywidget.cpp" line="471"/>
<location filename="../gui/traywidget.cpp" line="472"/>
<source>Connect</source>
<translation>Verbinden</translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="72"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<location filename="../gui/traywidget.cpp" line="902"/>
<location filename="../gui/traywidget.cpp" line="863"/>
<location filename="../gui/traywidget.cpp" line="905"/>
<source>Start</source>
<translation>Starten</translation>
</message>
@ -256,7 +261,7 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<message>
<location filename="../gui/traywidget.ui" line="357"/>
<location filename="../gui/traywidget.cpp" line="155"/>
<location filename="../gui/traywidget.cpp" line="382"/>
<location filename="../gui/traywidget.cpp" line="383"/>
<source>New notifications</source>
<translation>Neue Benachrichtigungen</translation>
</message>
@ -327,93 +332,93 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<translation>Syncthing Tray schließen</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="439"/>
<location filename="../gui/traywidget.cpp" line="440"/>
<source>Do you really want to restart Syncthing?</source>
<translation>Soll Syncthing wirklich neu gestartet werden?</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="466"/>
<location filename="../gui/traywidget.cpp" line="467"/>
<source>Connecting </source>
<translation>Verbinde </translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="467"/>
<location filename="../gui/traywidget.cpp" line="468"/>
<source>Establishing connection to Syncthing </source>
<translation>Stelle Verbindung zu Syncthing her </translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="472"/>
<location filename="../gui/traywidget.cpp" line="473"/>
<source>Not connected to Syncthing, click to connect</source>
<translation>Verbindung zu Syncthing getrennt, klicke um zu verbinden</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="477"/>
<location filename="../gui/traywidget.cpp" line="478"/>
<source>Unable to establish connection to Syncthing.</source>
<translation>Verbindung zu Syncthing kann nicht hergestellt werden.</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="485"/>
<location filename="../gui/traywidget.cpp" line="486"/>
<source>Pause</source>
<translation>Pausieren</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="486"/>
<location filename="../gui/traywidget.cpp" line="487"/>
<source>Syncthing is running, click to pause all devices</source>
<translation>Syncthing läuft, klicke um alle Geräte zu pausieren</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="491"/>
<location filename="../gui/traywidget.cpp" line="492"/>
<source>Continue</source>
<translation>Fortsetzen</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="492"/>
<location filename="../gui/traywidget.cpp" line="493"/>
<source>At least one device is paused, click to resume</source>
<translation>Mind. ein Gerät ist pausiert, klicke um fortzusetzen</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="615"/>
<location filename="../gui/traywidget.cpp" line="616"/>
<source>The specified connection configuration &lt;em&gt;%1&lt;/em&gt; is not defined and hence ignored.</source>
<translation>Die angegebene Verbindungskonfiguration &lt;em&gt;%1&lt;/em&gt; ist nicht definiert und wird daher ignoriert.</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="674"/>
<location filename="../gui/traywidget.cpp" line="675"/>
<source>The folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation>Der Ordner &lt;i&gt;%1&lt;/i&gt; existiert nicht lokal.</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="685"/>
<location filename="../gui/traywidget.cpp" line="686"/>
<source>The containing folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation>Der beinhaltende Ordner &lt;i&gt;%1&lt;/i&gt; existiert nicht lokal.</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="736"/>
<location filename="../gui/traywidget.cpp" line="739"/>
<source>Copy path</source>
<translation>Pfad kopieren</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="740"/>
<location filename="../gui/traywidget.cpp" line="743"/>
<source>Copy device ID</source>
<translation>Geräte-ID kopieren</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="743"/>
<location filename="../gui/traywidget.cpp" line="746"/>
<source>Copy folder ID</source>
<translation>Ordner-ID kopieren</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="856"/>
<location filename="../gui/traywidget.cpp" line="896"/>
<location filename="../gui/traywidget.cpp" line="859"/>
<location filename="../gui/traywidget.cpp" line="899"/>
<source>Stop</source>
<translation>Stoppen</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="857"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<source>Stop Syncthing instance launched via tray icon</source>
<translation>Stoppe Syncthing-Instanz, die mit dem internen Starter gestartet wurde</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="861"/>
<location filename="../gui/traywidget.cpp" line="864"/>
<source>Start Syncthing with the built-in launcher configured in the settings</source>
<translation>Starte Syncthing mit dem eingebauten Starter, der in den Einstellungen konfiguriert wird</translation>
</message>

View File

@ -71,6 +71,11 @@
<source>Browse remote files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/dirview.cpp" line="111"/>
<source>Show ignore patterns</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::DownloadView</name>
@ -167,20 +172,20 @@
</message>
<message>
<location filename="../gui/traywidget.ui" line="99"/>
<location filename="../gui/traywidget.cpp" line="342"/>
<location filename="../gui/traywidget.cpp" line="343"/>
<source>About</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="58"/>
<location filename="../gui/traywidget.cpp" line="471"/>
<location filename="../gui/traywidget.cpp" line="472"/>
<source>Connect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="72"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<location filename="../gui/traywidget.cpp" line="902"/>
<location filename="../gui/traywidget.cpp" line="863"/>
<location filename="../gui/traywidget.cpp" line="905"/>
<source>Start</source>
<translation type="unfinished"></translation>
</message>
@ -251,7 +256,7 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<message>
<location filename="../gui/traywidget.ui" line="357"/>
<location filename="../gui/traywidget.cpp" line="155"/>
<location filename="../gui/traywidget.cpp" line="382"/>
<location filename="../gui/traywidget.cpp" line="383"/>
<source>New notifications</source>
<translation type="unfinished"></translation>
</message>
@ -321,93 +326,93 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="439"/>
<location filename="../gui/traywidget.cpp" line="440"/>
<source>Do you really want to restart Syncthing?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="466"/>
<location filename="../gui/traywidget.cpp" line="467"/>
<source>Connecting </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="467"/>
<location filename="../gui/traywidget.cpp" line="468"/>
<source>Establishing connection to Syncthing </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="472"/>
<location filename="../gui/traywidget.cpp" line="473"/>
<source>Not connected to Syncthing, click to connect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="477"/>
<location filename="../gui/traywidget.cpp" line="478"/>
<source>Unable to establish connection to Syncthing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="485"/>
<location filename="../gui/traywidget.cpp" line="486"/>
<source>Pause</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="486"/>
<location filename="../gui/traywidget.cpp" line="487"/>
<source>Syncthing is running, click to pause all devices</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="491"/>
<location filename="../gui/traywidget.cpp" line="492"/>
<source>Continue</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="492"/>
<location filename="../gui/traywidget.cpp" line="493"/>
<source>At least one device is paused, click to resume</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="615"/>
<location filename="../gui/traywidget.cpp" line="616"/>
<source>The specified connection configuration &lt;em&gt;%1&lt;/em&gt; is not defined and hence ignored.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="674"/>
<location filename="../gui/traywidget.cpp" line="675"/>
<source>The folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="685"/>
<location filename="../gui/traywidget.cpp" line="686"/>
<source>The containing folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="736"/>
<location filename="../gui/traywidget.cpp" line="739"/>
<source>Copy path</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="740"/>
<location filename="../gui/traywidget.cpp" line="743"/>
<source>Copy device ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="743"/>
<location filename="../gui/traywidget.cpp" line="746"/>
<source>Copy folder ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="856"/>
<location filename="../gui/traywidget.cpp" line="896"/>
<location filename="../gui/traywidget.cpp" line="859"/>
<location filename="../gui/traywidget.cpp" line="899"/>
<source>Stop</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="857"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<source>Stop Syncthing instance launched via tray icon</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="861"/>
<location filename="../gui/traywidget.cpp" line="864"/>
<source>Start Syncthing with the built-in launcher configured in the settings</source>
<translation type="unfinished"></translation>
</message>

View File

@ -71,6 +71,11 @@
<source>Browse remote files</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/dirview.cpp" line="111"/>
<source>Show ignore patterns</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QtGui::DownloadView</name>
@ -167,20 +172,20 @@
</message>
<message>
<location filename="../gui/traywidget.ui" line="58"/>
<location filename="../gui/traywidget.cpp" line="471"/>
<location filename="../gui/traywidget.cpp" line="472"/>
<source>Connect</source>
<translation></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="72"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<location filename="../gui/traywidget.cpp" line="902"/>
<location filename="../gui/traywidget.cpp" line="863"/>
<location filename="../gui/traywidget.cpp" line="905"/>
<source>Start</source>
<translation></translation>
</message>
<message>
<location filename="../gui/traywidget.ui" line="99"/>
<location filename="../gui/traywidget.cpp" line="342"/>
<location filename="../gui/traywidget.cpp" line="343"/>
<source>About</source>
<translation></translation>
</message>
@ -252,7 +257,7 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<message>
<location filename="../gui/traywidget.ui" line="357"/>
<location filename="../gui/traywidget.cpp" line="155"/>
<location filename="../gui/traywidget.cpp" line="382"/>
<location filename="../gui/traywidget.cpp" line="383"/>
<source>New notifications</source>
<translation></translation>
</message>
@ -322,93 +327,93 @@ For &lt;i&gt;all&lt;/i&gt; notifications, checkout the log</source>
<translation>退 Syncthing Tray</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="439"/>
<location filename="../gui/traywidget.cpp" line="440"/>
<source>Do you really want to restart Syncthing?</source>
<translation> Syncthing </translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="466"/>
<location filename="../gui/traywidget.cpp" line="467"/>
<source>Connecting </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="467"/>
<location filename="../gui/traywidget.cpp" line="468"/>
<source>Establishing connection to Syncthing </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="472"/>
<location filename="../gui/traywidget.cpp" line="473"/>
<source>Not connected to Syncthing, click to connect</source>
<translation> Syncthing</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="477"/>
<location filename="../gui/traywidget.cpp" line="478"/>
<source>Unable to establish connection to Syncthing.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="485"/>
<location filename="../gui/traywidget.cpp" line="486"/>
<source>Pause</source>
<translation></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="486"/>
<location filename="../gui/traywidget.cpp" line="487"/>
<source>Syncthing is running, click to pause all devices</source>
<translation>Syncthing </translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="491"/>
<location filename="../gui/traywidget.cpp" line="492"/>
<source>Continue</source>
<translation></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="492"/>
<location filename="../gui/traywidget.cpp" line="493"/>
<source>At least one device is paused, click to resume</source>
<translation></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="615"/>
<location filename="../gui/traywidget.cpp" line="616"/>
<source>The specified connection configuration &lt;em&gt;%1&lt;/em&gt; is not defined and hence ignored.</source>
<translation> &lt;em&gt;%1&lt;/em&gt; </translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="674"/>
<location filename="../gui/traywidget.cpp" line="675"/>
<source>The folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation> &lt;i&gt;%1&lt;/i&gt;</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="685"/>
<location filename="../gui/traywidget.cpp" line="686"/>
<source>The containing folder &lt;i&gt;%1&lt;/i&gt; does not exist on the local machine.</source>
<translation> &lt;i&gt;%1&lt;/i&gt;</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="736"/>
<location filename="../gui/traywidget.cpp" line="739"/>
<source>Copy path</source>
<translation></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="740"/>
<location filename="../gui/traywidget.cpp" line="743"/>
<source>Copy device ID</source>
<translation> ID</translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="743"/>
<location filename="../gui/traywidget.cpp" line="746"/>
<source>Copy folder ID</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="856"/>
<location filename="../gui/traywidget.cpp" line="896"/>
<location filename="../gui/traywidget.cpp" line="859"/>
<location filename="../gui/traywidget.cpp" line="899"/>
<source>Stop</source>
<translation></translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="857"/>
<location filename="../gui/traywidget.cpp" line="860"/>
<source>Stop Syncthing instance launched via tray icon</source>
<translation> Syncthing </translation>
</message>
<message>
<location filename="../gui/traywidget.cpp" line="861"/>
<location filename="../gui/traywidget.cpp" line="864"/>
<source>Start Syncthing with the built-in launcher configured in the settings</source>
<translation>使 Syncthing</translation>
</message>