Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/linux-appimage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
if: ${{ github.event.action != 'closed' && !github.event.pull_request.draft }}
name: Linux Appimage Package
runs-on: ubuntu-latest
container: ghcr.io/nextcloud/continuous-integration-client-appimage-qt6:client-appimage-el8-6.10.2-4
container: ghcr.io/nextcloud/continuous-integration-client-appimage-qt6:client-appimage-el8-6.10.2-6
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down
28 changes: 25 additions & 3 deletions admin/linux/build-appimage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,27 @@ if [ -e "/opt/rh/gcc-toolset-14/enable" ]; then
source /opt/rh/gcc-toolset-14/enable
fi

cd /home
wget https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz
tar xf json.tar.xz
mkdir json/build
cd json/build
cmake .. -G Ninja -DCMAKE_INSTALL_PREFIX=/root/linux-gcc-x86_64 -DCMAKE_BUILD_TYPE=Release -DJSON_BuildTests=OFF
ninja install

cd /home
git clone https://github.com/opencloud-eu/openvfs.git
cd openvfs
git switch --detach 3d72711ebb42ac78ae40ee5fcbd1783abb419e7e
mkdir build
cd build
cmake .. -G Ninja -DCMAKE_INSTALL_PREFIX=/root/linux-gcc-x86_64 -DCMAKE_BUILD_TYPE=Release
ninja && ninja && ninja install

mkdir /app

# Build client
cd ${DESKTOP_CLIENT_ROOT}
mkdir build-client
cd build-client
cmake \
Expand Down Expand Up @@ -80,6 +98,7 @@ rm -rf etc

# com.nextcloud.desktopclient.nextcloud.desktop
DESKTOP_FILE=$(ls /app/usr/share/applications/*.desktop)
OPENVFS_VFS_PLUGIN=$(ls /app/usr/lib64/*sync_vfs_openvfs.so)

# Use linuxdeploy to deploy
export APPIMAGE_NAME=linuxdeploy-x86_64.AppImage
Expand All @@ -89,8 +108,11 @@ chmod a+x ${APPIMAGE_NAME}
rm ./${APPIMAGE_NAME}
cp -r ./squashfs-root ./linuxdeploy-squashfs-root

export LD_LIBRARY_PATH=${QT_BASE_DIR}/lib:/app/usr/lib64:/app/usr/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/lib:/usr/local/lib64
./linuxdeploy-squashfs-root/AppRun --desktop-file=${DESKTOP_FILE} --icon-file=usr/share/icons/hicolor/512x512/apps/Nextcloud.png --executable=usr/bin/${EXECUTABLE_NAME} --appdir=AppDir
export LD_LIBRARY_PATH=${QT_BASE_DIR}/lib:${QT_BASE_DIR}/lib64:/app/usr/lib64:/app/usr/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/lib:/usr/local/lib64
./linuxdeploy-squashfs-root/AppRun --desktop-file=${DESKTOP_FILE} --icon-file=usr/share/icons/hicolor/512x512/apps/Nextcloud.png --library=${OPENVFS_VFS_PLUGIN} --executable=usr/bin/${EXECUTABLE_NAME} --appdir=AppDir

mv AppDir/usr/lib/*sync_vfs_openvfs.so AppDir/usr/plugins
mv /root/linux-gcc-x86_64/bin/openvfs /root/linux-gcc-x86_64/bin/openvfs_stat AppDir/usr/bin

# Use linuxdeploy-plugin-qt to deploy qt dependencies
export APPIMAGE_NAME=linuxdeploy-plugin-qt-x86_64.AppImage
Expand All @@ -108,7 +130,7 @@ export QML_SOURCES_PATHS=${DESKTOP_CLIENT_ROOT}/src/gui
--library=/root/linux-gcc-x86_64/lib/libharfbuzz.so.0 --library=/root/linux-gcc-x86_64/lib/libharfbuzz-subset.so.0 \
--library=/usr/lib64/libOpenGL.so.0 --library=/usr/lib64/libGLX.so.0 --library=/usr/lib64/libEGL.so.1 --library=/usr/lib64/libGLdispatch.so.0 --library=/usr/lib64/libdrm.so.2 --library=/usr/lib64/libgbm.so.1 \
--library=/root/linux-gcc-x86_64/lib/libuuid.so.1 --library=/root/linux-gcc-x86_64/lib/libgpg-error.so.0 --library=/root/linux-gcc-x86_64/lib/libz.so.1 --library=/root/linux-gcc-x86_64/lib/libpcre2-8.so.0 --library=/root/linux-gcc-x86_64/lib/libexpat.so.1 \
--library=/root/linux-gcc-x86_64/lib/libfreetype.so.6 --library=/root/linux-gcc-x86_64/lib/libglib-2.0.so.0 --library=/root/linux-gcc-x86_64/lib/libsoftokn3.so \
--library=/root/linux-gcc-x86_64/lib/libfreetype.so.6 --library=/root/linux-gcc-x86_64/lib/libglib-2.0.so.0 --library=/root/linux-gcc-x86_64/lib/libsoftokn3.so --library=/root/linux-gcc-x86_64/lib64/libopenvfs.so \
--icon-file=usr/share/icons/hicolor/512x512/apps/Nextcloud.png --executable=usr/bin/${EXECUTABLE_NAME} --appdir=AppDir --output appimage

# Workaround issue #103 and #7231
Expand Down
38 changes: 38 additions & 0 deletions admin/linux/flatpak/com.nextcloud.desktopclient.nextcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,44 @@ modules:
stable-only: true
project-id: 1699

- name: nlohmann_json
buildsystem: cmake-ninja
config-opts:
- -DJSON_BuildTests=OFF
sources:
- type: archive
url: https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz
sha256: 42f6e95cad6ec532fd372391373363b62a14af6d771056dbfc86160e6dfff7aa
x-checker-data:
type: anitya
url-template: https://github.com/nlohmann/json/releases/download/v$version/json.tar.xz
stable-only: true

- name: libfuse
buildsystem: meson
config-opts:
- -Dinitscriptdir=""
- -Dudevrulesdir=""
- -Duseroot=false
sources:
- type: archive
url: https://github.com/libfuse/libfuse/releases/download/fuse-3.18.2/fuse-3.18.2.tar.gz
sha256: f01de85717e20adf5f98aff324acd85dd73d61a5ca3834d573dcf0bd6e54a298
x-checker-data:
type: anitya
url-template: https://github.com/libfuse/libfuse/releases/download/fuse-$version/fuse-$version.tar.gz
stable-only: true

- name: openvfs
buildsystem: cmake-ninja
builddir: true
config-opts:
- -DCMAKE_BUILD_TYPE=Release
sources:
- type: git
url: https://github.com/opencloud-eu/openvfs.git
commit: 3d72711ebb42ac78ae40ee5fcbd1783abb419e7e

- name: KDSingleApplication
buildsystem: cmake-ninja
builddir: true
Expand Down
3 changes: 3 additions & 0 deletions src/common/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ set(common_SOURCES
${CMAKE_CURRENT_LIST_DIR}/syncjournalfilerecord.cpp
${CMAKE_CURRENT_LIST_DIR}/utility.cpp
${CMAKE_CURRENT_LIST_DIR}/remotepermissions.cpp
${CMAKE_CURRENT_LIST_DIR}/vfs.h
${CMAKE_CURRENT_LIST_DIR}/vfs.cpp
${CMAKE_CURRENT_LIST_DIR}/path.h
${CMAKE_CURRENT_LIST_DIR}/path.cpp
${CMAKE_CURRENT_LIST_DIR}/pinstate.cpp
${CMAKE_CURRENT_LIST_DIR}/plugin.cpp
${CMAKE_CURRENT_LIST_DIR}/syncfilestatus.cpp
Expand Down
66 changes: 66 additions & 0 deletions src/common/filesystembase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,33 @@

Q_LOGGING_CATEGORY(lcFileSystem, "nextcloud.sync.filesystem", QtInfoMsg)

std::filesystem::path FileSystem::toFilesystemPath(const QString &path)
{
#ifdef Q_OS_WIN
return QtPrivate::toFilesystemPath(FileSystem::longWinPath(path));
#else
return QtPrivate::toFilesystemPath(path);
#endif
}

QString FileSystem::fromFilesystemPath(const std::filesystem::path &path)
{
#ifdef Q_OS_WIN
constexpr std::wstring_view prefix = LR"(\\?\)";
std::wstring nativePath = path.native();
auto view = std::wstring_view(nativePath);
if (nativePath.starts_with(prefix)) {
view = view.substr(prefix.size());
}
return QDir::fromNativeSeparators(QString::fromWCharArray(view.data(), view.length()));
#elif defined(Q_OS_MACOS)
// based on QFile::decodeName
return QtPrivate::fromFilesystemPath(path).normalized(QString::NormalizationForm_C);
#else
return QtPrivate::fromFilesystemPath(path);
#endif
}

QString FileSystem::longWinPath(const QString &inpath)
{
#ifdef Q_OS_WIN
Expand Down Expand Up @@ -800,6 +827,45 @@
#endif
}


FileSystem::ChildResults FileSystem::isChildPathOf2(QStringView child, QStringView parent)

Check warning on line 831 in src/common/filesystembase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "parent" of type "class QStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6f4UDiqwBWciLV&open=AaCG1l6f4UDiqwBWciLV&pullRequest=10635

Check warning on line 831 in src/common/filesystembase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "child" of type "class QStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6f4UDiqwBWciLU&open=AaCG1l6f4UDiqwBWciLU&pullRequest=10635
{
// if it is a relative path assume a local file, resolve it based on root
const auto sensitivity = Utility::fsCaseSensitivity();

// Fast-path the 3 common cases in this if-else statement:
if (parent.isEmpty()) {
// The empty parent is often used as the sync root, as (child) items do not start with a `/`
return ChildResult::IsChild | ChildResult::IsParentEmpty;
}
if (child.compare(parent, sensitivity) == 0) {
return ChildResult::IsChild | ChildResult::IsEqual;
}
const auto isSeparator = [](QChar c) { return c == QLatin1Char('/') || (Utility::isWindows() && c == QLatin1Char('\\')); };
if (isSeparator(parent.back())) {

Check warning on line 845 in src/common/filesystembase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use the init-statement to declare "isSeparator" inside the if statement.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6f4UDiqwBWciLT&open=AaCG1l6f4UDiqwBWciLT&pullRequest=10635
// Here we can do a normal prefix check, because the parent is "terminated" with a slash,
// and we can't walk into the case in the else below.
if (child.startsWith(parent, sensitivity)) {

Check warning on line 848 in src/common/filesystembase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge this "if" statement with the enclosing one.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6f4UDiqwBWciLW&open=AaCG1l6f4UDiqwBWciLW&pullRequest=10635
return ChildResult::IsChild;
}
// else: do the `cleanPath` version below
}

// Slow path (`QDir::cleanPath` does lots of string operations):
const QString cleanParent = QDir::cleanPath(parent.toString());
const QString cleanChild = QDir::cleanPath(child.toString());
// both paths are the same /root/foo == /root/foo
if (cleanChild.compare(cleanParent, sensitivity) == 0) {
return ChildResult::IsChild | ChildResult::IsEqual;
}
// cleanPath removes trailing slashes, add one to parent to be sure we handle a child path
// /root/foo/bar is not a child of /root/fo, therefore, the trailing slash is important
if (cleanChild.startsWith(cleanParent + QLatin1Char('/'), sensitivity)) {
return ChildResult::IsChild;
}
return ChildResult::IsNoChild;
}

#ifdef Q_OS_WIN
QString FileSystem::pathtoUNC(const QString &_str)
{
Expand Down
17 changes: 17 additions & 0 deletions src/common/filesystembase.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#pragma once

#include "config.h"

Check failure on line 9 in src/common/filesystembase.h

View workflow job for this annotation

GitHub Actions / build

src/common/filesystembase.h:9:10 [clang-diagnostic-error]

'config.h' file not found

#include "csync/ocsynclib.h"

Expand Down Expand Up @@ -37,6 +37,9 @@
namespace FileSystem {
OCSYNC_EXPORT Q_NAMESPACE;

OCSYNC_EXPORT std::filesystem::path toFilesystemPath(const QString &path);
OCSYNC_EXPORT QString fromFilesystemPath(const std::filesystem::path &path);

enum class FolderPermissions {
ReadOnly,
ReadWrite,
Expand Down Expand Up @@ -206,6 +209,20 @@
* Returns whether the file is a junction (windows only)
*/
bool OCSYNC_EXPORT isJunction(const QString &filename);

/**
* Returns whether a Path is a child of another
*/

Check warning on line 215 in src/common/filesystembase.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l8L4UDiqwBWciLk&open=AaCG1l8L4UDiqwBWciLk&pullRequest=10635
enum class ChildResult : uint8_t { IsNoChild = 0, IsChild = 0x1 << 0, IsEqual = 0x1 << 1, IsParentEmpty = 0x1 << 2 };
Q_FLAG_NS(ChildResult);
Q_DECLARE_FLAGS(ChildResults, ChildResult)
Q_DECLARE_OPERATORS_FOR_FLAGS(ChildResults)

ChildResults OCSYNC_EXPORT isChildPathOf2(QStringView child, QStringView parent);
inline bool isChildPathOf(QStringView child, QStringView parent)

Check warning on line 222 in src/common/filesystembase.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "child" of type "class QStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l8L4UDiqwBWciLl&open=AaCG1l8L4UDiqwBWciLl&pullRequest=10635

Check warning on line 222 in src/common/filesystembase.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "parent" of type "class QStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l8L4UDiqwBWciLm&open=AaCG1l8L4UDiqwBWciLm&pullRequest=10635
{
return isChildPathOf2(child, parent) & ChildResult::IsChild;
}
}

/** @} */
Expand Down
53 changes: 53 additions & 0 deletions src/common/path.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2025 Hannah von Reth <h.vonreth@opencloud.eu>

#include "path.h"

#include "common/filesystembase.h"

OCC::FileSystem::Path::Path(QStringView path)

Check warning on line 8 in src/common/path.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "path" of type "class QStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6y4UDiqwBWciLh&open=AaCG1l6y4UDiqwBWciLh&pullRequest=10635
: _path(toFilesystemPath(path.toString()))
{
}

OCC::FileSystem::Path::Path(const std::filesystem::path &path)
: _path(path)
{
}

OCC::FileSystem::Path::Path(std::filesystem::path &&path)
: _path(std::move(path))
{
}

OCC::FileSystem::Path OCC::FileSystem::Path::relative(QAnyStringView path)

Check warning on line 23 in src/common/path.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "path" of type "class QAnyStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6y4UDiqwBWciLi&open=AaCG1l6y4UDiqwBWciLi&pullRequest=10635
{
return QtPrivate::toFilesystemPath(path.toString());
}

QString OCC::FileSystem::Path::toString() const
{
if (_path.empty()) {
return {};
}
return fromFilesystemPath(_path);
}

bool OCC::FileSystem::Path::exists() const
{
if (_path.empty()) {
return false;
}
std::error_code ec;
const bool exists = std::filesystem::exists(_path, ec);
if (ec) {
qCCritical(lcFileSystem) << u"Error checking existence of" << _path.native() << ec.value() << ec.message();
return false;
}
return exists;
}

QDebug operator<<(QDebug debug, const OCC::FileSystem::Path &path)

Check warning on line 50 in src/common/path.cpp

View workflow job for this annotation

GitHub Actions / build

src/common/path.cpp:50:8 [modernize-use-trailing-return-type]

use a trailing return type for this function
{
return debug << u"Path(" << path.toString() << u")";
}
82 changes: 82 additions & 0 deletions src/common/path.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2025 Hannah von Reth <h.vonreth@opencloud.eu>

#pragma once

#include "ocsynclib.h"

Check failure on line 6 in src/common/path.h

View workflow job for this annotation

GitHub Actions / build

src/common/path.h:6:10 [clang-diagnostic-error]

'ocsynclib.h' file not found

#include <QString>

#include <filesystem>

namespace OCC {

Check warning on line 12 in src/common/path.h

View workflow job for this annotation

GitHub Actions / build

src/common/path.h:12:11 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'OCC' is non-const and globally accessible, consider making it const

Check warning on line 12 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Concatenate this namespace with the nested one.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6o4UDiqwBWciLa&open=AaCG1l6o4UDiqwBWciLa&pullRequest=10635
namespace FileSystem {
class OCSYNC_EXPORT Path
{
public:
Path() = default;
/**
* Will create an absolute path from the given QString.
* On Windows it will create a UNC path starting with "\\?\".
* For path segments use Path::relative.
* @param path
*/

Check warning on line 23 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6o4UDiqwBWciLY&open=AaCG1l6o4UDiqwBWciLY&pullRequest=10635
explicit Path(QStringView path);

Path(const std::filesystem::path &path);

Check failure on line 26 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add the "explicit" keyword to this constructor.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6p4UDiqwBWciLb&open=AaCG1l6p4UDiqwBWciLb&pullRequest=10635

Path(std::filesystem::path &&path);

Check failure on line 28 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add the "explicit" keyword to this constructor.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6p4UDiqwBWciLc&open=AaCG1l6p4UDiqwBWciLc&pullRequest=10635

/**
* Creates a relative path segment
* @param path
* @return A relative path
*/

Check warning on line 34 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6o4UDiqwBWciLZ&open=AaCG1l6o4UDiqwBWciLZ&pullRequest=10635
static Path relative(QAnyStringView path);

[[nodiscard]] const std::filesystem::path &get() const
{
return _path;
}

[[nodiscard]] operator std::filesystem::path() const { return _path; }

Check failure on line 42 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this conversion operator with a function or (C++11) add the "explicit" keyword.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6p4UDiqwBWciLd&open=AaCG1l6p4UDiqwBWciLd&pullRequest=10635
[[nodiscard]] operator const std::filesystem::path &() const { return _path; }

Check failure on line 43 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this conversion operator with a function or (C++11) add the "explicit" keyword.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6p4UDiqwBWciLe&open=AaCG1l6p4UDiqwBWciLe&pullRequest=10635
const std::filesystem::path *operator->() const { return &_path; }

explicit operator QString() const { return toString(); }

Path operator/(const Path &other) const { return _path / other._path; }
Path operator/(const std::filesystem::path &other) const { return _path / other; }
Path operator/(QStringView other) const { return _path / relative(other); }

Check warning on line 50 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "other" of type "class QStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6p4UDiqwBWciLf&open=AaCG1l6p4UDiqwBWciLf&pullRequest=10635

Path &operator/=(const Path &other)
{
_path /= other._path;
return *this;
}

Path &operator/=(const std::filesystem::path &other)
{
_path /= other;
return *this;
}


Path &operator/=(QStringView other)

Check warning on line 65 in src/common/path.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "other" of type "class QStringView" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AaCG1l6p4UDiqwBWciLg&open=AaCG1l6p4UDiqwBWciLg&pullRequest=10635
{
_path /= relative(other);
return *this;
}

[[nodiscard]] QString toString() const;

[[nodiscard]] bool exists() const;

private:
std::filesystem::path _path;
};
}
}


OCSYNC_EXPORT QDebug operator<<(QDebug debug, const OCC::FileSystem::Path &path);
5 changes: 5 additions & 0 deletions src/common/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace OCC {

PluginFactory::~PluginFactory() = default;

bool PluginFactory::checkAvailability() const
{
return true;
}

QString pluginFileName(const QString &type, const QString &name)
{
return QStringLiteral("%1sync_%2_%3")
Expand Down
Loading
Loading