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 .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ InsertBraces: true

AllowShortEnumsOnASingleLine: false

EnumTrailingComma: ETC_Insert
EnumTrailingComma: Insert

# CrlInstruction *a;
PointerAlignment: Right
Expand Down
18 changes: 18 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Mirrors the checks enabled in .github/workflows/clang-tidy-review.yml
Checks: >
-*,
modernize-use-auto,
modernize-use-using,
modernize-use-nodiscard,
modernize-use-nullptr,
modernize-use-override,
modernize-loop-convert,
modernize-use-equals-default,
cppcoreguidelines-pro-type-static-cast-downcast,
readability-braces-around-statements
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none
3 changes: 1 addition & 2 deletions .github/workflows/clang-tidy-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
- name: Prepare compile_commands.json
run: |
cmake -G Ninja -B build -DQT_MAJOR_VERSION=6 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1
cd build && ninja
- name: Create results directory
run: |
mkdir clang-tidy-result
Expand All @@ -27,7 +26,7 @@ jobs:
/usr/bin/git config --global --add safe.directory "$GITHUB_WORKSPACE"
# Header-only test helper: clang-tidy-diff has no target compile command for it.
# Its consumer test targets compile it with the required GUI include paths.
/usr/bin/git diff -U0 HEAD^ -- ':(exclude)test/macOS/*' ':(exclude)test/systraysynccontroltesthelper.h' ':(exclude)*macOS*' | clang-tidy-diff-21.py -checks='-*,modernize-use-auto,modernize-use-using,modernize-use-nodiscard,modernize-use-nullptr,modernize-use-override,cppcoreguidelines-pro-type-static-cast-downcast' -p1 -path build -regex '^(?!.*/macOS/)(?!.*/MacOSX/).*\.(cpp|cc|cxx|c|h|hpp|hxx)$' -export-fixes clang-tidy-result/fixes.yml
run-clang-tidy -p build -header-filter='.*' -config-file .clang-tidy -export-fixes clang-tidy-result/fixes.yml || true
- name: Run clang-tidy-pr-comments action
uses: platisd/clang-tidy-pr-comments@28cfb84edafa771c044bde7e4a2a3fae57463818 # v1.6.1 # >1.4.3 switches to composite method w/ a forced python version and breaks things: https://github.com/actions/setup-python/issues/871
with:
Expand Down
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ Our C++ code should can make use of C++ 20 standard features whenever possible.

Do not use C++ modules. Use standard header inclusion instead.

After editing or adding C++ source files under `./src`, run `clang-format -i` on the touched files before considering the task done.
After editing or adding any C++ source files, anywhere in the repository, run `clang-format -i` on the touched files before considering the task done.

After editing or adding any C++ source files, anywhere in the repository, run `run-clang-tidy -p build -header-filter='.*' -config-file .clang-tidy -fix` from the repository root and confirm it produces no further changes. This is a mandatory step: apply any fixes the tool makes, review them, re-run the command, and repeat until it reports no changes before considering the task done. Do not skip or silently waive this step; if `run-clang-tidy` cannot be run (for example because `./build` is not configured), state that explicitly rather than proceeding as if it passed.

## macOS Specifics

Expand Down
18 changes: 12 additions & 6 deletions shell_integration/dolphin/ownclouddolphinactionplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
QList<QAction*> actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) override
{
auto helper = OwncloudDolphinPluginHelper::instance();
if (!helper->isConnected() || !fileItemInfos.isLocal())
if (!helper->isConnected() || !fileItemInfos.isLocal()) {
return {};
}

// If any of the url is outside of a sync folder, return an empty menu.
const QList<QUrl> urls = fileItemInfos.urlList();
Expand All @@ -38,11 +39,13 @@ class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
auto localFile = localPath.canonicalPath();
if (!std::any_of(paths.begin(), paths.end(), [&](const QString &s) {
return localFile.startsWith(s);
}))
})) {
return {};
}

if (!files.isEmpty())
if (!files.isEmpty()) {
files += '\x1e'; // Record separator
}
files += localFile.toUtf8();
}

Expand All @@ -57,11 +60,13 @@ class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
loop.quit();
} else if (cmd.startsWith("MENU_ITEM:")) {
auto args = QString::fromUtf8(cmd).split(QLatin1Char(':'));
if (args.size() < 4)
if (args.size() < 4) {
return;
}
auto action = menu->addAction(args.mid(3).join(QLatin1Char(':')));
if (args.value(2).contains(QLatin1Char('d')))
if (args.value(2).contains(QLatin1Char('d'))) {
action->setDisabled(true);
}
auto call = args.value(1).toLatin1();
connect(action, &QAction::triggered, [helper, call, files] {
helper->sendCommand(QByteArray(call + ":" + files + "\n").constData());
Expand All @@ -86,8 +91,9 @@ class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
QList<QAction *> legacyActions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget)
{
QList<QUrl> urls = fileItemInfos.urlList();
if (urls.count() != 1)
if (urls.count() != 1) {
return {};
}
QDir localPath(urls.first().toLocalFile());
auto localFile = localPath.canonicalPath();
auto helper = OwncloudDolphinPluginHelper::instance();
Expand Down
36 changes: 24 additions & 12 deletions shell_integration/dolphin/ownclouddolphinoverlayplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ class OwncloudDolphinPlugin : public KOverlayIconPlugin

QStringList getOverlays(const QUrl& url) override {
auto helper = OwncloudDolphinPluginHelper::instance();
if (!helper->isConnected())
if (!helper->isConnected()) {
return QStringList();
if (!url.isLocalFile())
}
if (!url.isLocalFile()) {
return QStringList();
}
QDir localPath(url.toLocalFile());
const QByteArray localFile = localPath.canonicalPath().toUtf8();

Expand All @@ -49,40 +51,50 @@ class OwncloudDolphinPlugin : public KOverlayIconPlugin
private:
QStringList overlaysForString(const QByteArray &status) {
QStringList r;
if (status.startsWith("NOP"))
if (status.startsWith("NOP")) {
return r;
}

if (status.startsWith("OK"))
if (status.startsWith("OK")) {
r << QStringLiteral("vcs-normal");
if (status.startsWith("SYNC") || status.startsWith("NEW"))
}
if (status.startsWith("SYNC") || status.startsWith("NEW")) {
r << QStringLiteral("vcs-update-required");
if (status.startsWith("IGNORE") || status.startsWith("WARN"))
}
if (status.startsWith("IGNORE") || status.startsWith("WARN")) {
r << QStringLiteral("vcs-locally-modified-unstaged");
if (status.startsWith("ERROR"))
}
if (status.startsWith("ERROR")) {
r << QStringLiteral("vcs-conflicting");
}

if (status.contains("+SWM"))
if (status.contains("+SWM")) {
r << QStringLiteral("document-share");
}

return r;
}

void slotCommandRecieved(const QByteArray &line) {

QList<QByteArray> tokens = line.split(':');
if (tokens.count() < 3)
if (tokens.count() < 3) {
return;
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
}
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST") {
return;
if (tokens[2].isEmpty())
}
if (tokens[2].isEmpty()) {
return;
}

// We can't use tokens[2] because the filename might contain ':'
int secondColon = line.indexOf(":", line.indexOf(":") + 1);
const QByteArray name = line.mid(secondColon + 1);
QByteArray &status = m_status[name]; // reference to the item in the hash
if (status == tokens[1])
if (status == tokens[1]) {
return;
}
status = tokens[1];

Q_EMIT overlaysChanged(QUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
Expand Down
9 changes: 6 additions & 3 deletions shell_integration/dolphin/ownclouddolphinpluginhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ void OwncloudDolphinPluginHelper::tryConnect()
QString socketPath = QStandardPaths::locate(QStandardPaths::RuntimeLocation,
QStringLiteral(APPLICATION_SHORTNAME),
QStandardPaths::LocateDirectory);
if(socketPath.isEmpty())
if (socketPath.isEmpty()) {
return;
}

_socket.connectToServer(socketPath + QLatin1String("/socket"));
}
Expand All @@ -69,13 +70,15 @@ void OwncloudDolphinPluginHelper::slotReadyRead()
{
while (_socket.bytesAvailable()) {
_line += _socket.readLine();
if (!_line.endsWith("\n"))
if (!_line.endsWith("\n")) {
continue;
}
QByteArray line;
qSwap(line, _line);
line.chop(1);
if (line.isEmpty())
if (line.isEmpty()) {
continue;
}

if (line.startsWith("REGISTER_PATH:")) {
auto col = line.indexOf(':');
Expand Down
4 changes: 1 addition & 3 deletions src/3rdparty/kirigami/wheelhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ KirigamiWheelEvent::KirigamiWheelEvent(QObject *parent)
{
}

KirigamiWheelEvent::~KirigamiWheelEvent()
{
}
KirigamiWheelEvent::~KirigamiWheelEvent() = default;

void KirigamiWheelEvent::initializeFromEvent(QWheelEvent *event)
{
Expand Down
26 changes: 13 additions & 13 deletions src/3rdparty/kirigami/wheelhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@ class KirigamiWheelEvent : public QObject

void initializeFromEvent(QWheelEvent *event);

qreal x() const;
qreal y() const;
QPointF angleDelta() const;
QPointF pixelDelta() const;
int buttons() const;
int modifiers() const;
bool inverted() const;
[[nodiscard]] qreal x() const;
[[nodiscard]] qreal y() const;
[[nodiscard]] QPointF angleDelta() const;
[[nodiscard]] QPointF pixelDelta() const;
[[nodiscard]] int buttons() const;
[[nodiscard]] int modifiers() const;
[[nodiscard]] bool inverted() const;
bool isAccepted();
void setAccepted(bool accepted);

Expand Down Expand Up @@ -268,25 +268,25 @@ class WheelHandler : public QObject
explicit WheelHandler(QObject *parent = nullptr);
~WheelHandler() override;

QQuickItem *target() const;
[[nodiscard]] QQuickItem *target() const;
void setTarget(QQuickItem *target);

qreal verticalStepSize() const;
[[nodiscard]] qreal verticalStepSize() const;
void setVerticalStepSize(qreal stepSize);
void resetVerticalStepSize();

qreal horizontalStepSize() const;
[[nodiscard]] qreal horizontalStepSize() const;
void setHorizontalStepSize(qreal stepSize);
void resetHorizontalStepSize();

Qt::KeyboardModifiers pageScrollModifiers() const;
[[nodiscard]] Qt::KeyboardModifiers pageScrollModifiers() const;
void setPageScrollModifiers(Qt::KeyboardModifiers modifiers);
void resetPageScrollModifiers();

bool filterMouseEvents() const;
[[nodiscard]] bool filterMouseEvents() const;
void setFilterMouseEvents(bool enabled);

bool keyNavigationEnabled() const;
[[nodiscard]] bool keyNavigationEnabled() const;
void setKeyNavigationEnabled(bool enabled);

/**
Expand Down
6 changes: 4 additions & 2 deletions src/cmd/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,9 @@ CommandMode parseOptions(const QStringList &app_args, CmdOptions *options)

auto it = QStringListIterator{args};
// skip file name;
if (it.hasNext())
if (it.hasNext()) {
it.next();
}

while (it.hasNext()) {
const auto option = it.next();
Expand Down Expand Up @@ -547,8 +548,9 @@ int main(int argc, char **argv)
// http: //192.168.178.23 : 8080
// 0 1 2
host = pList.at(1);
if (host.startsWith("//"))
if (host.startsWith("//")) {
host.remove(0, 2);
}

port = pList.at(2).toInt(&ok);

Expand Down
9 changes: 6 additions & 3 deletions src/common/checksums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ QByteArray calcSha256(const QByteArray &data)

QByteArray makeChecksumHeader(const QByteArray &checksumType, const QByteArray &checksum)
{
if (checksumType.isEmpty() || checksum.isEmpty())
if (checksumType.isEmpty() || checksum.isEmpty()) {
return QByteArray();
}
QByteArray header = checksumType;
header.append(':');
header.append(checksum);
Expand Down Expand Up @@ -269,8 +270,9 @@ ComputeChecksum *ValidateChecksumHeader::prepareStart(const QByteArray &checksum

void ValidateChecksumHeader::start(const QString &filePath, const QByteArray &checksumHeader)
{
if (auto calculator = prepareStart(checksumHeader))
if (auto calculator = prepareStart(checksumHeader)) {
calculator->start(filePath);
}
}

QByteArray ValidateChecksumHeader::calculatedChecksumType() const
Expand Down Expand Up @@ -307,8 +309,9 @@ CSyncChecksumHook::CSyncChecksumHook() = default;
QByteArray CSyncChecksumHook::hook(const QByteArray &path, const QByteArray &otherChecksumHeader, void * /*this_obj*/)
{
QByteArray type = parseChecksumHeaderType(QByteArray(otherChecksumHeader));
if (type.isEmpty())
if (type.isEmpty()) {
return nullptr;
}

qCInfo(lcChecksums) << "Computing" << type << "checksum of" << path << "in the csync hook";
QByteArray checksum = ComputeChecksum::computeNowOnFile(QString::fromUtf8(path), type);
Expand Down
6 changes: 4 additions & 2 deletions src/common/ownsql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,9 @@ void SqlDatabase::close()
q->finish();
}
SQLITE_DO(sqlite3_close(_db));
if (_errId != SQLITE_OK)
if (_errId != SQLITE_OK) {
qCWarning(lcSql) << "Closing database failed" << _error;
}
_db = nullptr;
}
}
Expand Down Expand Up @@ -442,8 +443,9 @@ int SqlQuery::numRowsAffected()

void SqlQuery::finish()
{
if (!_stmt)
if (!_stmt) {
return;
}
SQLITE_DO(sqlite3_finalize(_stmt));
_stmt = nullptr;
if (_sqldb) {
Expand Down
15 changes: 10 additions & 5 deletions src/common/remotepermissions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,28 @@ template <typename Char>
void RemotePermissions::fromArray(const Char *p)
{
_value = notNullMask;
if (!p)
if (!p) {
return;
}
while (*p) {
if (auto res = std::strchr(letters, static_cast<char>(*p)))
if (auto res = std::strchr(letters, static_cast<char>(*p))) {
_value |= (1 << (res - letters));
}
++p;
}
}

QByteArray RemotePermissions::toDbValue() const
{
QByteArray result;
if (isNull())
if (isNull()) {
return result;
}
result.reserve(PermissionsCount);
for (uint i = 1; i <= PermissionsCount; ++i) {
if (_value & (1 << i))
if (_value & (1 << i)) {
result.append(letters[i]);
}
}
if (result.isEmpty()) {
// Make sure it is not empty so we can differentiate null and empty permissions
Expand All @@ -60,8 +64,9 @@ QString RemotePermissions::toString() const

RemotePermissions RemotePermissions::fromDbValue(const QByteArray &value)
{
if (value.isEmpty())
if (value.isEmpty()) {
return {};
}
RemotePermissions perm;
perm.fromArray(value.constData());
return perm;
Expand Down
Loading
Loading