The recommended code style is Qt one. See this document
for more details. To avoid manual labor there is automatic cmake target named
clangformat
(see below). Some additional detail see below.
-
Indent is only spaces. 4 spaces.
-
Any private variable should start with
m_
prefix (m_foo
). The only one exception isUi
object which should be named asui
. -
Avoid to create a large methods. Exception: if method contains lambda functions.
-
STL containers are not recommended, use Qt ones instead.
-
In other hand Qt specific variables types (
qint
,qfloat
, etc) are not recommended. -
Do not repeat yourself (DRY).
-
Headers declaration:
- Include only those headers which are strictly necessary inside headers. Use forward class declaration instead. Exception is base class header declaration.
- In a
*.cpp
file header declaration should have the following order separated by a new line in the alphabet order:- Class header.
- KDE specific headers.
- Qt specific headers.
- Third party headers.
- Project headers.
- Any header should have
#pragma once
.
-
If any
#if
directive is used condition should be mentioned in#endif
:#if (FOO) someCodeInside(); #endif /* FOO */
-
Q_PROPERTY
macro is allowed and recommended for QObject based classes. -
Qt macros (e.g.
signals
,slots
,Q_OBJECT
, etc) are allowed. In other handQ_FOREACH
(foreach
) is not allowed usefor (auto &foo : bar)
instead. -
Current project standard is C++23.
-
Do not use C-like code:
- C-like style iteration if possible. Use
for (auto &foo : bar)
andstd::for_each
instead if possible. It is also recommended to use iterators. - C-like casts, use
const_cast
,static_cast
,dymanic_Cast
instead. Using ofreinterpret_cast
is not recommended. It is highly recommended to usedynamic_cast
with the exception catching. It is also possible to useqvariant_cast
if required. - C-like
NULL
, usenullptr
instead. - C-like constant definition, use
static const vartype foo = bar
definition instead.
- C-like style iteration if possible. Use
-
Abstract classes (which have at least one pure virtual method) are allowed.
-
Templates are allowed and recommended. Templates usually should be described inside header not source code file.
-
Hardcode is not recommended. But it is possible to use cmake variables to configure some items during build time.
-
Build should not require any additional system variable declaration/changing.
-
Any line should not end with space.
-
Do not hesitate move public methods to private one if possible.
-
Do not hesitate use
const
modifier. In other handvolatile
modifier is not recommended. -
New lines rules:
- One line after license header.
- One line between header group declaration (see above).
- Two lines after header declaration and before declaration at the end of a file.
- One line after class and types forward declarations in headers.
- One line before each method modifiers (
public
,public slots
, etc). - Two lines between methods inside source code (
*.cpp
). - One line after
qCDebug()
information (see below). - One line inside a method to improve code reading.
-
Each destructor should be virtual.
-
Class constructor should have default arguments. Use
QObject *_parent
property for QObject based classes. -
QObject based classes constructors should have explicit modifier.
-
Create one file (source and header) per class.
-
else if
construction is allowed and recommended. -
'true ? foo : bar' construction is allowed and recommended for one-line assignment.
-
Any global pointer should be assigned to
nullptr
after deletion and before initialization. Exception: if object is deleted into class destructor. -
Do not use semicolon in qml files unless it is required.
-
Any method argument including class constructors should start with
_
.
Please do not hesitate to use comments inside source code (especially in non-obvious blocks). Comments also may use the following keywords:
- TODO - indicates that some new code should be implemented here later. Please note that usually these methods should be implemented before the next release.
- FIXME - some dirty hacks and/or methods which should be done better.
- HACK - hacks inside code which requires to avoid some restrictions and/or which adds additional non-obvious optimizations.
Do not use dots at the end of the comment line.
-
Officially the latest libraries versions should be used. In addition, it is possible to add workarounds for all versions (usually by using preprocessor directives); in this case patches should be placed to
packages
directory. -
Build should not contain any warning.
-
Try to minimize message in Release build with logging disabled. It is highly recommended to fix KDE/Qt specific warning if possible
-
Do not use dependency to KDE libraries if there are no any strictly necessary. Exceptions are KNotification and KI18n libraries.
-
It is highly recommended to use submodules for third party libraries if possible.
-
The main branch is master.
-
For experimental features development new branch
feature/foo
creation is allowed and recommended. -
Experimental features should be added inside
BUILD_FUTURE
definition:#ifdef BUILD_FUTURE someTestFunctionInside(); #endif /* BUILD_FUTURE */
-
Any project specific build variable should be mentioned inside
version.h
as well. -
Recommended compiler is
clang
.
The recommended HIG is KDE one. Avoid to paint interfaces inside plugin because QML and C++ parts may have different theming.
All files should be licensed under GPLv3, the owner of the license should be the project (i.e. awesome-widgets). See Tools section for more details.
For logging please use QLoggingCategory. Available categories should be declared in awdebug.*
files. The following log levels should be used:
- debug (
qCDebug()
) - method arguments information. Please note that it is recommended to logging all arguments in the one line. - info (
qCInfo()
) - additional information inside methods. - warning (
qCWarning()
) - not critical information, which may be caused by mistakes in configuration for example. - critical (
qCCritical()
) - a critical error. After this error program may be terminated.
The empty log string (e.g. qCDebug();
) is not allowed because the method names will be stripped by compiler with Release
build type. To log class constructor and destructor use __PRETTY_FUNCTION__
macro.
- Any changes should be tested by using
plasmawindowed
andplasmashell
applications. (It is also possible to useplasmaengineexplorer
andplasmoidviewer
in addition.) - Any test should be performed on real (not Virtual Machine) system.
- Test builds should be:
-DCMAKE_BUILD_TYPE=Debug
.-DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
.-DCMAKE_BUILD_TYPE=Release
.
- Additional test functions should be declated and used only inside
BUILD_TESTING
definition.
-
For QString concatenation use
QString::arg
method. -
Any source file should have license header:
/*************************************************************************** * This file is part of awesome-widgets * * * * awesome-widgets is free software: you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * * * awesome-widgets is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with awesome-widgets. If not, see http://www.gnu.org/licenses/ * ***************************************************************************/
-
Recommended class constructor for QObject based classes:
FooClass::FooClass(QObject *_parent, const QVariant _var) : QObject(_parent) , m_var(_var) { qCDebug(LOG_AW) << __PRETTY_FUNCTION__; // some code below if any }
-
Property usage:
Q_PROPERTY(bool prop READ prop WRITE setProp); public: bool prop() const { return m_prop; }; void setProp(const bool _prop) { // error checking if required m_prop = _prop } private: // declare with default value bool m_prop = false;
-
Use
cppcheck
to avoid common errors in the code. To start application just runmake cppcheck
. -
Use
clang-format
to apply valid code format. To start application just runmake clangformat
. -
use
-DCMAKE_CXX_COMPILER=clang++
in order to enable clang-tidy checks.