### Build and Install Syncthing Tray Source: https://github.com/martchus/syncthingtray/blob/master/docs/devel.md Build and install all components in a single step using Ninja. If the install directory is not writable, use `DESTDIR` to specify a temporary writable location. ```bash cd "$BUILD_DIR" ninja install ``` -------------------------------- ### Build and Install Syncthing Tray Source: https://context7.com/martchus/syncthingtray/llms.txt Build and install Syncthing Tray using Ninja after CMake configuration. ```bash ninja install ``` -------------------------------- ### Install Specific Go Version for Building Syncthing Source: https://github.com/martchus/syncthingtray/blob/master/docs/devel.md Use this command to download and install a specific Go version into your GOPATH. This is useful when the system's default Go version is not suitable for building Syncthing as a library. ```bash go install golang.org/dl/go1.22.11@latest && $GOPATH/src/go/bin/go1.22.11 download ``` -------------------------------- ### Configure Syncthing Tray Build with CMake Source: https://github.com/martchus/syncthingtray/blob/master/docs/devel.md Configure the build using CMake, specifying installation prefix, ForkAwesome font and definitions, and Qt/KF package prefixes. Ensure `CMAKE_BUILD_TYPE` is set to `Release` for production builds. ```bash cd "$BUILD_DIR" cmake \ -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX="/install/prefix" \ -DFORK_AWESOME_FONT_FILE="$SOURCES/forkawesome/fonts/forkawesome-webfont.woff2" \ -DFORK_AWESOME_ICON_DEFINITIONS="$SOURCES/forkawesome/src/icons/icons.yml" \ -DQT_PACKAGE_PREFIX:STRING=Qt6 \ -DKF_PACKAGE_PREFIX:STRING=KF6 \ -DBUILTIN_TRANSLATIONS:BOOL=ON \ "$SOURCES/subdirs/syncthingtray" ``` -------------------------------- ### Launch and Manage Syncthing Process Source: https://context7.com/martchus/syncthingtray/llms.txt Launches Syncthing as a child process, sets up signal handlers for start, finish, and errors, and includes logic for graceful restarts. Use this to manage the Syncthing lifecycle within the application. ```cpp #include #include #include void launchSyncthing(Data::SyncthingConnection &connection) { auto *process = new Data::SyncthingProcess; Data::SyncthingProcess::setMainInstance(process); QObject::connect(process, &Data::SyncthingProcess::started, []() { qDebug() << "Syncthing process started."; }); QObject::connect(process, &Data::SyncthingProcess::finished, [](int exitCode, QProcess::ExitStatus status) { qDebug() << "Syncthing exited, code:" << exitCode << (status == QProcess::CrashExit ? "(crash)" : "(normal)"); }); QObject::connect(process, &Data::SyncthingProcess::errorOccurred, [](QProcess::ProcessError err) { qDebug() << "Process error:" << Data::SyncthingProcess::genericErrorString(err); }); // Start Syncthing binary process->startSyncthing(QStringLiteral("/usr/bin/syncthing"), { QStringLiteral("serve"), QStringLiteral("--no-browser") }); // Restart gracefully after 60 s (e.g. after a config update) QTimer::singleShot(60000, [&connection, process]() { if (process->isRunning()) { qDebug() << "Uptime:" << (process->isActiveFor(60) ? ">= 60s" : "< 60s"); process->restartSyncthing( QStringLiteral("/usr/bin/syncthing"), { QStringLiteral("serve"), QStringLiteral("--no-browser") }, &connection // gracefully stop via connection before killing ); } }); // Parse argument strings safely QStringList args = Data::SyncthingProcess::splitArguments( QStringLiteral("serve --no-browser --gui-address=127.0.0.1:9999")); qDebug() << "Parsed args:" << args; // ["serve", "--no-browser", "--gui-address=127.0.0.1:9999"] } ``` -------------------------------- ### Install Syncthing Internal Static Library Source: https://github.com/martchus/syncthingtray/blob/master/syncthing/CMakeLists.txt Installs the Syncthing internal static library to the designated installation directory. This is conditional on not building shared libraries, not disabling install targets, and enabling install targets. ```cmake if (NOT BUILD_SHARED_LIBS AND NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) install( FILES "${SYNCTHINGINTERNAL_LIBRARY_PATH}" DESTINATION "${CMAKE_INSTALL_LIBDIR}${SELECTED_LIB_SUFFIX}" COMPONENT binary) endif () ``` -------------------------------- ### Create and Use SyncthingDirectoryModel Source: https://context7.com/martchus/syncthingtray/llms.txt Demonstrates how to create a SyncthingDirectoryModel, set SD card paths, and populate a QTreeView. It also shows how to access custom roles for directory status, ID, path, and child details, as well as retrieving raw directory information. ```cpp #include #include #include #include void createDirectoryView(Data::SyncthingConnection &connection, QWidget *parent) { auto *model = new Data::SyncthingDirectoryModel(connection, parent); // Mark SD card paths so the model can show a storage icon model->setSdCardPaths({ QStringLiteral("/mnt/sdcard") }); auto *view = new QTreeView(parent); view->setModel(model); view->setHeaderHidden(false); view->show(); // Read custom roles programmatically QModelIndex first = model->index(0, 0); if (first.isValid()) { auto status = model->data(first, Data::SyncthingDirectoryModel::DirectoryStatus).toInt(); auto statusStr = model->data(first, Data::SyncthingDirectoryModel::DirectoryStatusString).toString(); auto dirId = model->data(first, Data::SyncthingDirectoryModel::DirectoryId).toString(); auto path = model->data(first, Data::SyncthingDirectoryModel::DirectoryPath).toString(); qDebug() << "First folder:" << dirId << path << "status:" << status << statusStr; // e.g.: "default" "/home/user/Sync" status: 1 "Idle" // Access child details (second level) int children = model->rowCount(first); for (int i = 0; i < children; ++i) { QModelIndex child = model->index(i, 0, first); qDebug() << " detail:" << model->data(child).toString() << " icon tooltip:" << model->data(child, Data::SyncthingDirectoryModel::DirectoryDetailTooltip).toString(); } // Retrieve the raw SyncthingDir struct const Data::SyncthingDir *dir = model->dirInfo(first); if (dir) { qDebug() << "Pull errors:" << dir->pullErrorCount; qDebug() << "Files:" << dir->globalStats.files; } } } ``` -------------------------------- ### Configure Built-in Syncthing Library Source: https://github.com/martchus/syncthingtray/blob/master/docs/devel.md Enable building Syncthing as a library and configuring the launcher to use it. Requires a Go build environment. ```bash -DNO_LIBSYNCTHING=OFF -DUSE_LIBSYNCTHING=ON ``` -------------------------------- ### Initialize and Configure SyncthingConnection Source: https://context7.com/martchus/syncthingtray/llms.txt Demonstrates setting up a SyncthingConnection instance, configuring its URL, API key, polling intervals, and event subscription flags. Connects to the Syncthing API and sets up signal handlers for various events. ```cpp #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); // --- Create and configure the connection --- Data::SyncthingConnection connection; // Basic URL + API key setup connection.setSyncthingUrl(QStringLiteral("http://127.0.0.1:8384")); connection.setApiKey(QByteArrayLiteral("your-api-key-here")); // Poll traffic stats every 5 s, device stats every 60 s, errors every 30 s connection.setTrafficPollInterval(5000); connection.setDevStatsPollInterval(60000); connection.setErrorsPollInterval(30000); // Auto-reconnect every 30 s on disconnect connection.setAutoReconnectInterval(30000); // Only request main events + download progress (skip disk events) connection.setPollingFlags(Data::SyncthingConnection::PollingFlags::MainEvents | Data::SyncthingConnection::PollingFlags::DownloadProgress | Data::SyncthingConnection::PollingFlags::TrafficStatistics); // --- React to status changes --- QObject::connect(&connection, &Data::SyncthingConnection::statusChanged, [&](Data::SyncthingStatus status) { qDebug() << "Connection status:" << connection.statusText(); if (connection.isConnected()) { qDebug() << "Syncthing version:" << connection.syncthingVersion(); qDebug() << "My device ID: " << connection.myId(); qDebug() << "Config dir: " << connection.configDir(); qDebug() << "Directories: " << connection.directoryIds().join(", "); qDebug() << "Devices: " << connection.deviceIds().join(", "); } }); // --- React to directory status changes --- QObject::connect(&connection, &Data::SyncthingConnection::dirStatusChanged, [&](const Data::SyncthingDir &dir, int /*index*/) { qDebug() << "Dir" << dir.displayName() << "status:" << dir.statusString() << "completion:" << dir.computeCompletionPercentage() << "%\n"; }); // --- React to errors --- QObject::connect(&connection, &Data::SyncthingConnection::newErrors, [&](const std::vector &errors) { for (const auto &err : errors) { qDebug() << "Syncthing error:" << err.message; } }); // --- React to traffic updates --- QObject::connect(&connection, &Data::SyncthingConnection::trafficChanged, [&](quint64 in, quint64 out) { qDebug() << "Traffic - in:" << in << "bytes out:" << out << "bytes"; qDebug() << "Rate in:" << connection.totalIncomingRate() << "kbit/s" << " out:" << connection.totalOutgoingRate() << "kbit/s"; }); // --- Connect (non-blocking, uses Qt event loop) --- connection.connect(); return app.exec(); // Expected output (once connected): // Connection status: "idle" // Syncthing version: "v2.x.y" // My device ID: "XXXX-XXXX-..." // Config dir: "/home/user/.local/share/syncthing" // Directories: "default, docs, music" // Devices: "AAAA-..., BBBB-..." } ``` -------------------------------- ### Get Syncthing Status Source: https://context7.com/martchus/syncthingtray/llms.txt Retrieve the status of a Syncthing instance using `syncthingctl`. ```bash syncthingctl --url https://localhost:8384 status ``` -------------------------------- ### Force First-Launch Wizard Source: https://context7.com/martchus/syncthingtray/llms.txt Force Syncthing Tray to display the first-launch wizard by setting an environment variable. ```bash export SYNCTHINGTRAY_FAKE_FIRST_LAUNCH=1 syncthingtray ``` -------------------------------- ### Get Folder Path with syncthingtray cli Source: https://github.com/martchus/syncthingtray/blob/master/docs/cli.md Retrieves the path of a specific folder using Syncthing's own CLI client, targeting a folder by its ID. ```bash syncthingtray cli config folders docs-books-recent path get ``` -------------------------------- ### Get Folder Path via JSON dump and jq Source: https://github.com/martchus/syncthingtray/blob/master/docs/cli.md Dumps folder configuration as JSON using `syncthingtray cli` and then uses `jq` to extract the path. ```bash syncthingtray cli config folders docs-books-recent dump-json | jq -r .path ``` -------------------------------- ### Filter Syncthing Status Display Source: https://github.com/martchus/syncthingtray/blob/master/docs/cli.md Filter the `status` command output to display information only for specific directories or devices. This is useful for focusing on particular parts of your Syncthing setup. ```bash syncthingctl status --dir dir1 --dir dir2 --dev dev1 --dev dev2 ``` -------------------------------- ### Select Qt Web View Provider Source: https://github.com/martchus/syncthingtray/blob/master/docs/devel.md Choose the web view provider for the Qt Widgets UI. Options include Qt WebKit, Qt WebEngine, or none. If none is selected, the Syncthing web UI opens in the default browser. ```bash -DWEBVIEW_PROVIDER:STRING=webkit/webengine/none ``` -------------------------------- ### Pause Multiple Folders with JavaScript Source: https://github.com/martchus/syncthingtray/blob/master/docs/cli.md Uses `syncthingctl` with JavaScript to pause all folders whose IDs start with 'docs-'. It's recommended to use `--dry-run` first. ```bash syncthingctl edit --js-lines \ 'config.folders.filter(f => f.id.startsWith("docs-")).forEach(f => f.paused = !f.paused)' ``` -------------------------------- ### Query Plugin Directory with qmake Source: https://github.com/martchus/syncthingtray/blob/master/docs/devel.md Use qmake to determine the correct directory for installing Qt plugins. This is crucial for KDE integration components like Plasmoids and Dolphin integration. ```bash qmake-qt5 -query QT_INSTALL_PLUGINS ``` ```bash qmake6 -query QT_INSTALL_PLUGINS ``` -------------------------------- ### Configure Syncthing Tray Build (Qt 6 / KDE 6) Source: https://context7.com/martchus/syncthingtray/llms.txt Configure the Syncthing Tray build using CMake with options for Qt 6, KDE Frameworks 6, and all components enabled. This includes specifying paths for Fork Awesome and enabling GUI features. ```bash cmake -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX="/usr/local" \ -DQT_PACKAGE_PREFIX:STRING=Qt6 \ -DKF_PACKAGE_PREFIX:STRING=KF6 \ -DFORK_AWESOME_FONT_FILE="$SOURCES/forkawesome/fonts/forkawesome-webfont.woff2" \ -DFORK_AWESOME_ICON_DEFINITIONS="$SOURCES/forkawesome/src/icons/icons.yml" \ -DBUILTIN_TRANSLATIONS:BOOL=ON \ -DWIDGETS_GUI:BOOL=ON \ -DQUICK_GUI:BOOL=ON \ -DNO_FILE_ITEM_ACTION_PLUGIN:BOOL=OFF \ -DNO_PLASMOID:BOOL=OFF \ -DNO_LIBSYNCTHING:BOOL=OFF \ -DUSE_LIBSYNCTHING:BOOL=ON \ -DWEBVIEW_PROVIDER:STRING=webengine \ -DJS_PROVIDER:STRING=qml \ "$SOURCES/subdirs/syncthingtray" ``` -------------------------------- ### Find c++utilities Package Source: https://github.com/martchus/syncthingtray/blob/master/syncthing/CMakeLists.txt Finds the 'c++utilities' package with a specific version and adds its module directories to the CMake module path. It also appends include directories, distinguishing between build and install interfaces. ```cmake find_package(${PACKAGE_NAMESPACE_PREFIX}c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.34.0 REQUIRED) list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS}) if (CPP_UTILITIES_SOURCE_DIR) list(APPEND PRIVATE_INCLUDE_DIRS $ $) else () list(APPEND PRIVATE_INCLUDE_DIRS ${CPP_UTILITIES_INCLUDE_DIRS}) endif () ``` -------------------------------- ### Configure Qt Quick GUI Source: https://github.com/martchus/syncthingtray/blob/master/syncthingwidgets/CMakeLists.txt Includes necessary Qt Quick configuration files and sets up project-wide variables for GUI features. ```cmake include(QtGuiConfig) include(QtLinkage) set(${META_PROJECT_VARNAME_UPPER}_HAS_WEBVIEW OFF PARENT_SCOPE) set(${META_PROJECT_VARNAME_UPPER}_HAS_WEBVIEW_PAGE OFF PARENT_SCOPE) ```