cli: Add shortcut for current working directory

syncthingctl pwd status/rescan/resume/pause
This commit is contained in:
Martchus 2017-03-29 23:17:53 +02:00
parent 4d7c6b5a61
commit 1168e31f55
9 changed files with 214 additions and 110 deletions

View File

@ -12,6 +12,7 @@
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QDir>
#include <functional>
#include <iostream>
@ -46,7 +47,9 @@ inline QString argToQString(const char *arg, int size = -1)
}
Application::Application() :
m_expectedResponse(0)
m_expectedResponse(0),
m_preventDisconnect(false),
m_callbacksInvoked(false)
{
// take ownership over the global QNetworkAccessManager
networkAccessManager().setParent(this);
@ -66,6 +69,7 @@ Application::Application() :
m_args.resumeAllDevs.setCallback(bind(&Application::requestResumeAllDevs, this, _1));
m_args.resumeAllDirs.setCallback(bind(&Application::requestResumeAllDirs, this, _1));
m_args.waitForIdle.setCallback(bind(&Application::initWaitForIdle, this, _1));
m_args.pwd.setCallback(bind(&Application::operateOnPwd, this, _1));
// connect signals and slots
connect(&m_connection, &SyncthingConnection::statusChanged, this, &Application::handleStatusChanged);
@ -143,7 +147,7 @@ int Application::exec(int argc, const char * const *argv)
// finally to request / establish connection
if(m_args.status.isPresent() || m_args.rescanAll.isPresent() || m_args.pauseAllDirs.isPresent() || m_args.pauseAllDevs.isPresent()
|| m_args.resumeAllDirs.isPresent() || m_args.resumeAllDevs.isPresent() || m_args.pause.isPresent()
|| m_args.resume.isPresent() || m_args.waitForIdle.isPresent()) {
|| m_args.resume.isPresent() || m_args.waitForIdle.isPresent() || m_args.pwd.isPresent()) {
// those arguments rquire establishing a connection first, the actual handler is called by handleStatusChanged() when
// the connection has been established
m_connection.reconnect(m_settings);
@ -167,11 +171,15 @@ int Application::exec(int argc, const char * const *argv)
void Application::handleStatusChanged(SyncthingStatus newStatus)
{
Q_UNUSED(newStatus)
if(m_callbacksInvoked) {
return;
}
if(m_connection.isConnected()) {
eraseLine(cout);
cout << '\r';
m_callbacksInvoked = true;
m_args.parser.invokeCallbacks();
if(!m_args.waitForIdle.isPresent()) {
if(!m_preventDisconnect) {
m_connection.disconnect();
}
}
@ -203,7 +211,7 @@ void Application::findRelevantDirsAndDevs()
void Application::requestLog(const ArgumentOccurrence &)
{
m_connection.requestLog(bind(&Application::printLog, this, _1));
m_connection.requestLog(&Application::printLog);
cerr << "Request log from " << m_settings.syncthingUrl.toLocal8Bit().data() << " ...";
cerr.flush();
}
@ -374,6 +382,59 @@ void Application::findRelevantDirsAndDevs(OperationType operationType)
}
}
void Application::printDir(const SyncthingDir *dir)
{
cout << " - ";
setStyle(cout, TextAttribute::Bold);
cout << dir->id.toLocal8Bit().data() << '\n';
setStyle(cout);
printProperty("Label", dir->label);
printProperty("Path", dir->path);
printProperty("Status", dir->statusString());
printProperty("Last scan time", dir->lastScanTime);
printProperty("Last file time", dir->lastFileTime);
printProperty("Last file name", dir->lastFileName);
printProperty("Download progress", dir->downloadLabel);
printProperty("Devices", dir->devices);
printProperty("Read-only", dir->readOnly);
printProperty("Ignore permissions", dir->ignorePermissions);
printProperty("Auto-normalize", dir->autoNormalize);
printProperty("Rescan interval", TimeSpan::fromSeconds(dir->rescanInterval));
printProperty("Min. free disk percentage", dir->minDiskFreePercentage);
if(!dir->errors.empty()) {
cout << " Errors\n";
for(const SyncthingDirError &error : dir->errors) {
printProperty(" - Message", error.message);
printProperty(" File", error.path);
}
}
cout << '\n';
}
void Application::printDev(const SyncthingDev *dev)
{
cout << " - ";
setStyle(cout, TextAttribute::Bold);
cout << dev->name.toLocal8Bit().data() << '\n';
setStyle(cout);
printProperty("ID", dev->id);
printProperty("Status", dev->statusString());
printProperty("Addresses", dev->addresses);
printProperty("Compression", dev->compression);
printProperty("Cert name", dev->certName);
printProperty("Connection address", dev->connectionAddress);
printProperty("Connection type", dev->connectionType);
printProperty("Client version", dev->clientVersion);
printProperty("Last seen", dev->lastSeen);
if(dev->totalIncomingTraffic > 0) {
printProperty("Incoming traffic", dataSizeToString(static_cast<uint64>(dev->totalIncomingTraffic)).data());
}
if(dev->totalOutgoingTraffic > 0) {
printProperty("Outgoing traffic", dataSizeToString(static_cast<uint64>(dev->totalOutgoingTraffic)).data());
}
cout << '\n';
}
void Application::printStatus(const ArgumentOccurrence &)
{
findRelevantDirsAndDevs();
@ -383,33 +444,7 @@ void Application::printStatus(const ArgumentOccurrence &)
setStyle(cout, TextAttribute::Bold);
cout << "Directories\n";
setStyle(cout);
for(const SyncthingDir *dir : m_relevantDirs) {
cout << " - ";
setStyle(cout, TextAttribute::Bold);
cout << dir->id.toLocal8Bit().data() << '\n';
setStyle(cout);
printProperty("Label", dir->label);
printProperty("Path", dir->path);
printProperty("Status", dir->statusString());
printProperty("Last scan time", dir->lastScanTime);
printProperty("Last file time", dir->lastFileTime);
printProperty("Last file name", dir->lastFileName);
printProperty("Download progress", dir->downloadLabel);
printProperty("Devices", dir->devices);
printProperty("Read-only", dir->readOnly);
printProperty("Ignore permissions", dir->ignorePermissions);
printProperty("Auto-normalize", dir->autoNormalize);
printProperty("Rescan interval", TimeSpan::fromSeconds(dir->rescanInterval));
printProperty("Min. free disk percentage", dir->minDiskFreePercentage);
if(!dir->errors.empty()) {
cout << " Errors\n";
for(const SyncthingDirError &error : dir->errors) {
printProperty(" - Message", error.message);
printProperty(" File", error.path);
}
}
cout << '\n';
}
for_each(m_relevantDirs.cbegin(), m_relevantDirs.cend(), &Application::printDir);
}
// display devs
@ -417,28 +452,7 @@ void Application::printStatus(const ArgumentOccurrence &)
setStyle(cout, TextAttribute::Bold);
cout << "Devices\n";
setStyle(cout);
for(const SyncthingDev *dev : m_relevantDevs) {
cout << " - ";
setStyle(cout, TextAttribute::Bold);
cout << dev->name.toLocal8Bit().data() << '\n';
setStyle(cout);
printProperty("ID", dev->id);
printProperty("Status", dev->statusString());
printProperty("Addresses", dev->addresses);
printProperty("Compression", dev->compression);
printProperty("Cert name", dev->certName);
printProperty("Connection address", dev->connectionAddress);
printProperty("Connection type", dev->connectionType);
printProperty("Client version", dev->clientVersion);
printProperty("Last seen", dev->lastSeen);
if(dev->totalIncomingTraffic > 0) {
printProperty("Incoming traffic", dataSizeToString(static_cast<uint64>(dev->totalIncomingTraffic)).data());
}
if(dev->totalOutgoingTraffic > 0) {
printProperty("Outgoing traffic", dataSizeToString(static_cast<uint64>(dev->totalOutgoingTraffic)).data());
}
cout << '\n';
}
for_each(m_relevantDevs.cbegin(), m_relevantDevs.cend(), &Application::printDev);
}
cout.flush();
@ -459,6 +473,8 @@ void Application::printLog(const std::vector<SyncthingLogEntry> &logEntries)
void Application::initWaitForIdle(const ArgumentOccurrence &)
{
m_preventDisconnect = true;
findRelevantDirsAndDevs();
// might idle already
@ -499,4 +515,67 @@ void Application::waitForIdle()
QCoreApplication::exit();
}
void Application::operateOnPwd(const ArgumentOccurrence &occurrence)
{
// find SyncthingDir for pwd
const QString pwd(QDir::currentPath());
const SyncthingDir *relatedDir = nullptr;
QString relativePath;
for(const SyncthingDir &dir : m_connection.dirInfo()) {
if(pwd == dir.pathWithoutTrailingSlash()) {
relatedDir = &dir;
} else if(pwd.startsWith(dir.path)) {
relatedDir = &dir;
relativePath = pwd.mid(dir.path.size());
}
}
if(!relatedDir) {
cerr << "Error: The current working directory \"" << pwd.toLocal8Bit().data() << "\" is not (part of) a Syncthing directory." << endl;
QCoreApplication::exit(2);
return;
}
// do specified operation
const char *operation = occurrence.values.front();
if(!strcmp(operation, "status")) {
printDir(relatedDir);
} else if(!strcmp(operation, "rescan")) {
if(relativePath.isEmpty()) {
cerr << "Request rescanning directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
} else {
cerr << "Request rescanning item \"" << relativePath.toLocal8Bit().data() << "\" in directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
}
m_connection.rescan(relatedDir->id, relativePath);
connect(&m_connection, &SyncthingConnection::rescanTriggered, this, &Application::handleResponse);
m_expectedResponse = 1;
return;
} else if(!strcmp(operation, "pause")) {
if(m_connection.pauseDirectories(QStringList(relatedDir->id))) {
cerr << "Request pausing directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
connect(&m_connection, &SyncthingConnection::directoryPauseTriggered, this, &Application::handleResponse);
m_preventDisconnect = true;
m_expectedResponse = 1;
return;
} else {
cerr << "Directory \"" << relatedDir->path.toLocal8Bit().data() << " already paused" << endl;
}
} else if(!strcmp(operation, "resume")) {
if(m_connection.resumeDirectories(QStringList(relatedDir->id))) {
cerr << "Request resuming directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
connect(&m_connection, &SyncthingConnection::directoryResumeTriggered, this, &Application::handleResponse);
m_preventDisconnect = true;
m_expectedResponse = 1;
return;
} else {
cerr << "Directory \"" << relatedDir->path.toLocal8Bit().data() << " not paused" << endl;
}
} else {
cerr << "Error: The specified operation \"" << operation << "\" is invalid." << endl;
QCoreApplication::exit(1);
return;
}
QCoreApplication::quit();
}
} // namespace Cli

View File

@ -46,15 +46,20 @@ private:
void requestPauseAllDirs(const ArgumentOccurrence &);
void requestResumeAllDevs(const ArgumentOccurrence &);
void requestResumeAllDirs(const ArgumentOccurrence &);
static void printDir(const Data::SyncthingDir *dir);
static void printDev(const Data::SyncthingDev *dev);
void printStatus(const ArgumentOccurrence &);
void printLog(const std::vector<Data::SyncthingLogEntry> &logEntries);
static void printLog(const std::vector<Data::SyncthingLogEntry> &logEntries);
void initWaitForIdle(const ArgumentOccurrence &);
void waitForIdle();
void operateOnPwd(const ArgumentOccurrence &occurrence);
Args m_args;
Data::SyncthingConnectionSettings m_settings;
Data::SyncthingConnection m_connection;
size_t m_expectedResponse;
bool m_preventDisconnect;
bool m_callbacksInvoked;
std::vector<const Data::SyncthingDir *> m_relevantDirs;
std::vector<const Data::SyncthingDev *> m_relevantDevs;

View File

@ -17,6 +17,7 @@ Args::Args() :
resumeAllDevs("resume-all-devs", '\0', "resumes all devices"),
resumeAllDirs("resume-all-dirs", '\0', "resumes all directories"),
waitForIdle("wait-for-idle", 'w', "waits until the specified dirs/devs are idling"),
pwd("pwd", 'p', "operates in the current working directory"),
statusDir("dir", 'd', "specifies the directoies (default is all dirs)", {"ID"}),
statusDev("dev", '\0', "specifies the devices (default is all devs)", {"ID"}),
pauseDir("dir", 'd', "specifies the directories", {"ID"}),
@ -32,6 +33,8 @@ Args::Args() :
}
status.setSubArguments({&statusDir, &statusDev});
waitForIdle.setSubArguments({&statusDir, &statusDev});
pwd.setValueNames({"status/rescan/pause/resume"});
pwd.setRequiredValueCount(1);
rescan.setValueNames({"dir ID"});
rescan.setRequiredValueCount(-1);
@ -39,7 +42,7 @@ Args::Args() :
resume.setSubArguments({&pauseDir, &pauseDev});
parser.setMainArguments({&status, &log, &stop, &restart, &rescan, &rescanAll, &pause, &pauseAllDevs, &pauseAllDirs, &resume, &resumeAllDevs,
&resumeAllDirs, &waitForIdle, &configFile, &apiKey, &url, &credentials, &certificate, &help});
&resumeAllDirs, &waitForIdle, &pwd, &configFile, &apiKey, &url, &credentials, &certificate, &help});
// allow setting default values via environment
configFile.setEnvironmentVariable("SYNCTHING_CTL_CONFIG_FILE");

View File

@ -12,7 +12,7 @@ struct Args
Args();
ArgumentParser parser;
HelpArgument help;
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, pauseAllDevs, pauseAllDirs, resume, resumeAllDevs, resumeAllDirs, waitForIdle;
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, pauseAllDevs, pauseAllDirs, resume, resumeAllDevs, resumeAllDirs, waitForIdle, pwd;
ConfigValueArgument statusDir, statusDev, pauseDir, pauseDev;
ConfigValueArgument configFile, apiKey, url, credentials, certificate;
};

View File

@ -130,6 +130,19 @@ QString SyncthingDir::statusString() const
}
}
QStringRef SyncthingDir::pathWithoutTrailingSlash() const
{
QStringRef dirPath(&path);
while(dirPath.endsWith(QChar('/'))) {
#if QT_VERSION_MAJOR >= 5 && QT_VERSION_MINOR >= 8
dirPath.chop(1);
#else
dirPath = dirPath.left(dirPath.size() - 1);
#endif
}
return dirPath;
}
SyncthingItemDownloadProgress::SyncthingItemDownloadProgress(const QString &containingDirPath, const QString &relativeItemPath, const QJsonObject &values) :
relativePath(relativeItemPath),
fileInfo(containingDirPath % QChar('/') % QString(relativeItemPath).replace(QChar('\\'), QChar('/'))),

View File

@ -66,6 +66,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingDir
bool assignStatus(SyncthingDirStatus newStatus, ChronoUtilities::DateTime time);
QString displayName() const;
QString statusString() const;
QStringRef pathWithoutTrailingSlash() const;
QString id;
QString label;

View File

@ -278,14 +278,7 @@ QList<QAction *> SyncthingFileItemAction::createActions(const KFileItemListPrope
QList<SyncthingItem> detectedItems;
const SyncthingDir *lastDir;
for(const SyncthingDir &dir : dirs) {
QStringRef dirPath(&dir.path);
while(dirPath.endsWith(QChar('/'))) {
#if QT_VERSION_MAJOR >= 5 && QT_VERSION_MINOR >= 8
dirPath.chop(1);
#else
dirPath = dirPath.left(dirPath.size() - 1);
#endif
}
QStringRef dirPath(dir.pathWithoutTrailingSlash());
for(const QString &path : paths) {
if(path == dirPath) {
lastDir = &dir;

View File

@ -8,27 +8,27 @@
<translation type="vanished">nicht mehr verfügbar</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="106"/>
<location filename="../syncthingfileitemaction.cpp" line="107"/>
<source>Status: not available anymore</source>
<translation>Status: nicht mehr verfügbar</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="115"/>
<location filename="../syncthingfileitemaction.cpp" line="116"/>
<source>Directory info for %1</source>
<translation>Verzeichnisinfo für %1</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="117"/>
<location filename="../syncthingfileitemaction.cpp" line="118"/>
<source>Status: </source>
<translation>Status: </translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="140"/>
<location filename="../syncthingfileitemaction.cpp" line="141"/>
<source>Last scan time: </source>
<translation>Letzter Scan: </translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="142"/>
<location filename="../syncthingfileitemaction.cpp" line="143"/>
<source>Rescan interval: %1 seconds</source>
<translation>Scanintervall: %1 Sekunden</translation>
</message>
@ -36,60 +36,65 @@
<context>
<name>SyncthingFileItemAction</name>
<message>
<location filename="../syncthingfileitemaction.cpp" line="302"/>
<location filename="../syncthingfileitemaction.cpp" line="303"/>
<source>Rescan %1 (in %2)</source>
<translation>&quot;%1&quot; neu scannen (in &quot;%2&quot;)</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="303"/>
<location filename="../syncthingfileitemaction.cpp" line="304"/>
<source>Rescan selected items</source>
<translation>Auswahl neu scannen</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="321"/>
<location filename="../syncthingfileitemaction.cpp" line="322"/>
<source>Rescan selected directories</source>
<translation>Ausgewählte Verzeichnisse neu scannen</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="348"/>
<location filename="../syncthingfileitemaction.cpp" line="349"/>
<source>Resume selected directories</source>
<translation>Ausgewählte verzeichnisse fortsetzen</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="320"/>
<location filename="../syncthingfileitemaction.cpp" line="371"/>
<location filename="../syncthingfileitemaction.cpp" line="321"/>
<location filename="../syncthingfileitemaction.cpp" line="372"/>
<source>Rescan %1</source>
<translation>&quot;%1&quot; neu scannen</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="347"/>
<location filename="../syncthingfileitemaction.cpp" line="397"/>
<location filename="../syncthingfileitemaction.cpp" line="233"/>
<source>Syncthing connection error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="348"/>
<location filename="../syncthingfileitemaction.cpp" line="398"/>
<source>Resume %1</source>
<translation>&quot;%1&quot; fortsetzen</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="354"/>
<location filename="../syncthingfileitemaction.cpp" line="404"/>
<location filename="../syncthingfileitemaction.cpp" line="355"/>
<location filename="../syncthingfileitemaction.cpp" line="405"/>
<source>Pause %1</source>
<translation>&quot;%1&quot; pausieren</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="355"/>
<location filename="../syncthingfileitemaction.cpp" line="356"/>
<source>Pause selected directories</source>
<translation>Ausgewählte Verzeichnisse pausieren</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="372"/>
<location filename="../syncthingfileitemaction.cpp" line="373"/>
<source>Rescan containing directories</source>
<translation>Beinhaltendes Verzeichnis neu scannen</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="398"/>
<location filename="../syncthingfileitemaction.cpp" line="399"/>
<source>Resume containing directories</source>
<translation>Beinhaltendes Verzeichnis fortsetzen</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="405"/>
<location filename="../syncthingfileitemaction.cpp" line="406"/>
<source>Pause containing directories</source>
<translation>Beinhaltendes Verzeichnis pausieren</translation>
</message>
@ -106,8 +111,8 @@
<translation type="vanished">Scanintervall: %1 Sekunden</translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="240"/>
<location filename="../syncthingfileitemaction.cpp" line="431"/>
<location filename="../syncthingfileitemaction.cpp" line="248"/>
<location filename="../syncthingfileitemaction.cpp" line="432"/>
<source>About</source>
<translation>Über</translation>
</message>
@ -115,12 +120,12 @@
<context>
<name>SyncthingMenuAction</name>
<message>
<location filename="../syncthingfileitemaction.cpp" line="68"/>
<location filename="../syncthingfileitemaction.cpp" line="69"/>
<source>Syncthing</source>
<translation></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="82"/>
<location filename="../syncthingfileitemaction.cpp" line="83"/>
<source>Syncthing - connecting</source>
<translation>Syncthing - verbinde</translation>
</message>

View File

@ -4,27 +4,27 @@
<context>
<name>SyncthingDirActions</name>
<message>
<location filename="../syncthingfileitemaction.cpp" line="106"/>
<location filename="../syncthingfileitemaction.cpp" line="107"/>
<source>Status: not available anymore</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="115"/>
<location filename="../syncthingfileitemaction.cpp" line="116"/>
<source>Directory info for %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="117"/>
<location filename="../syncthingfileitemaction.cpp" line="118"/>
<source>Status: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="140"/>
<location filename="../syncthingfileitemaction.cpp" line="141"/>
<source>Last scan time: </source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="142"/>
<location filename="../syncthingfileitemaction.cpp" line="143"/>
<source>Rescan interval: %1 seconds</source>
<translation type="unfinished"></translation>
</message>
@ -32,66 +32,71 @@
<context>
<name>SyncthingFileItemAction</name>
<message>
<location filename="../syncthingfileitemaction.cpp" line="302"/>
<location filename="../syncthingfileitemaction.cpp" line="303"/>
<source>Rescan %1 (in %2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="303"/>
<location filename="../syncthingfileitemaction.cpp" line="304"/>
<source>Rescan selected items</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="321"/>
<location filename="../syncthingfileitemaction.cpp" line="322"/>
<source>Rescan selected directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="348"/>
<location filename="../syncthingfileitemaction.cpp" line="349"/>
<source>Resume selected directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="320"/>
<location filename="../syncthingfileitemaction.cpp" line="371"/>
<location filename="../syncthingfileitemaction.cpp" line="321"/>
<location filename="../syncthingfileitemaction.cpp" line="372"/>
<source>Rescan %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="347"/>
<location filename="../syncthingfileitemaction.cpp" line="397"/>
<location filename="../syncthingfileitemaction.cpp" line="233"/>
<source>Syncthing connection error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="348"/>
<location filename="../syncthingfileitemaction.cpp" line="398"/>
<source>Resume %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="354"/>
<location filename="../syncthingfileitemaction.cpp" line="404"/>
<location filename="../syncthingfileitemaction.cpp" line="355"/>
<location filename="../syncthingfileitemaction.cpp" line="405"/>
<source>Pause %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="355"/>
<location filename="../syncthingfileitemaction.cpp" line="356"/>
<source>Pause selected directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="372"/>
<location filename="../syncthingfileitemaction.cpp" line="373"/>
<source>Rescan containing directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="398"/>
<location filename="../syncthingfileitemaction.cpp" line="399"/>
<source>Resume containing directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="405"/>
<location filename="../syncthingfileitemaction.cpp" line="406"/>
<source>Pause containing directories</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="240"/>
<location filename="../syncthingfileitemaction.cpp" line="431"/>
<location filename="../syncthingfileitemaction.cpp" line="248"/>
<location filename="../syncthingfileitemaction.cpp" line="432"/>
<source>About</source>
<translation type="unfinished"></translation>
</message>
@ -99,12 +104,12 @@
<context>
<name>SyncthingMenuAction</name>
<message>
<location filename="../syncthingfileitemaction.cpp" line="68"/>
<location filename="../syncthingfileitemaction.cpp" line="69"/>
<source>Syncthing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../syncthingfileitemaction.cpp" line="82"/>
<location filename="../syncthingfileitemaction.cpp" line="83"/>
<source>Syncthing - connecting</source>
<translation type="unfinished"></translation>
</message>