summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/format.sh2
-rwxr-xr-xscripts/includemocs.py197
-rw-r--r--src/AliasEditModel.cpp2
-rw-r--r--src/AvatarProvider.cpp2
-rw-r--r--src/BlurhashProvider.cpp2
-rw-r--r--src/ChatPage.cpp2
-rw-r--r--src/Clipboard.cpp2
-rw-r--r--src/ColorImageProvider.h2
-rw-r--r--src/CombinedImagePackModel.cpp2
-rw-r--r--src/CompletionProxyModel.cpp2
-rw-r--r--src/FallbackAuth.cpp2
-rw-r--r--src/GridImagePackModel.cpp2
-rw-r--r--src/ImagePackListModel.cpp2
-rw-r--r--src/InviteesModel.cpp2
-rw-r--r--src/InviteesModel.h5
-rw-r--r--src/JdenticonProvider.cpp2
-rw-r--r--src/LoginPage.cpp2
-rw-r--r--src/MainWindow.cpp2
-rw-r--r--src/MemberList.cpp2
-rw-r--r--src/MxcImageProvider.cpp2
-rw-r--r--src/PowerlevelsEditModels.cpp2
-rw-r--r--src/ReCaptcha.cpp2
-rw-r--r--src/ReadReceiptsModel.cpp2
-rw-r--r--src/ReadReceiptsModel.h5
-rw-r--r--src/RegisterPage.cpp2
-rw-r--r--src/RoomDirectoryModel.cpp2
-rw-r--r--src/SSOHandler.cpp2
-rw-r--r--src/SSOHandler.h2
-rw-r--r--src/SingleImagePackModel.cpp2
-rw-r--r--src/TrayIcon.cpp2
-rw-r--r--src/UserDirectoryModel.cpp2
-rw-r--r--src/UserSettingsPage.cpp2
-rw-r--r--src/dbus/NhekoDBusApi.cpp2
-rw-r--r--src/dbus/NhekoDBusApi.h5
-rw-r--r--src/dbus/NhekoDBusBackend.cpp2
-rw-r--r--src/dbus/NhekoDBusBackend.h5
-rw-r--r--src/dock/Dock.cpp2
-rw-r--r--src/emoji/Provider.cpp2
-rw-r--r--src/encryption/DeviceVerificationFlow.cpp2
-rw-r--r--src/encryption/Olm.cpp2
-rw-r--r--src/encryption/SelfVerificationStatus.cpp2
-rw-r--r--src/encryption/VerificationManager.cpp2
-rw-r--r--src/notifications/Manager.cpp2
-rw-r--r--src/timeline/CommunitiesModel.cpp2
-rw-r--r--src/timeline/DelegateChooser.cpp2
-rw-r--r--src/timeline/EventDelegateChooser.cpp2
-rw-r--r--src/timeline/EventStore.cpp2
-rw-r--r--src/timeline/InputBar.cpp2
-rw-r--r--src/timeline/Permissions.cpp2
-rw-r--r--src/timeline/PresenceEmitter.cpp2
-rw-r--r--src/timeline/Reaction.cpp2
-rw-r--r--src/timeline/RoomlistModel.cpp2
-rw-r--r--src/timeline/TimelineFilter.cpp2
-rw-r--r--src/timeline/TimelineModel.cpp2
-rw-r--r--src/timeline/TimelineViewManager.cpp3
-rw-r--r--src/ui/EventExpiry.cpp2
-rw-r--r--src/ui/HiddenEvents.cpp2
-rw-r--r--src/ui/MxcAnimatedImage.cpp2
-rw-r--r--src/ui/MxcMediaProxy.cpp2
-rw-r--r--src/ui/NhekoCursorShape.cpp2
-rw-r--r--src/ui/NhekoDropArea.cpp2
-rw-r--r--src/ui/NhekoDropArea.h2
-rw-r--r--src/ui/NhekoGlobalObject.cpp2
-rw-r--r--src/ui/RoomSettings.cpp2
-rw-r--r--src/ui/RoomSummary.cpp2
-rw-r--r--src/ui/Theme.cpp2
-rw-r--r--src/ui/UIA.cpp2
-rw-r--r--src/ui/UserProfile.cpp2
-rw-r--r--src/voip/CallDevices.cpp2
-rw-r--r--src/voip/CallManager.cpp2
-rw-r--r--src/voip/ScreenCastPortal.cpp2
-rw-r--r--src/voip/WebRTCSession.cpp2
72 files changed, 335 insertions, 17 deletions
diff --git a/.ci/format.sh b/.ci/format.sh
index 20c1d126..04274fa9 100755
--- a/.ci/format.sh
+++ b/.ci/format.sh
@@ -17,6 +17,8 @@ done;
 
 git diff --exit-code
 
+./scripts/includemocs.py --insert-at-end -n src
+
 if command -v /usr/lib64/qt6/bin/qmllint &> /dev/null; then
     /usr/lib64/qt6/bin/qmllint $QML_FILES
 elif command -v /usr/lib/qt6/bin/qmllint &> /dev/null; then
diff --git a/scripts/includemocs.py b/scripts/includemocs.py
new file mode 100755
index 00000000..1f48122a
--- /dev/null
+++ b/scripts/includemocs.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python3
+
+#
+# This file is part of KDToolBox.
+#
+# SPDX-FileCopyrightText: 2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
+# Author: Jesper K. Pedersen <jesper.pedersen@kdab.com>
+#
+# SPDX-License-Identifier: MIT
+#
+
+'''
+Script to add inclusion of mocs to files recursively.
+'''
+
+# pylint: disable=redefined-outer-name
+
+import os
+import re
+import argparse
+import sys
+
+dirty = False
+
+
+def stripInitialSlash(path):
+    if path and path.startswith("/"):
+        path = path[1:]
+    return path
+
+# Returns true if the path is to be excluded from the search
+
+
+def shouldExclude(root, path):
+    # pylint: disable=used-before-assignment
+    if not args.excludes:
+        return False  # No excludes provided
+
+    assert root.startswith(args.root)
+    root = stripInitialSlash(root[len(args.root):])
+
+    if args.headerPrefix:
+        assert root.startswith(args.headerPrefix)
+        root = stripInitialSlash(root[len(args.headerPrefix):])
+
+    return (path in args.excludes) or (root + "/" + path in args.excludes)
+
+
+regexp = re.compile("\\s*(Q_OBJECT|Q_GADGET|Q_NAMESPACE)\\s*")
+# Returns true if the header file provides contains a Q_OBJECT, Q_GADGET or Q_NAMESPACE macro
+
+
+def hasMacro(fileName):
+    with open(fileName, "r", encoding="ISO-8859-1") as fileHandle:
+        for line in fileHandle:
+            if regexp.match(line):
+                return True
+        return False
+
+# returns the matching .cpp file for the given .h file
+
+
+def matchingCPPFile(root, fileName):
+    assert root.startswith(args.root)
+    root = stripInitialSlash(root[len(args.root):])
+
+    if args.headerPrefix:
+        assert root.startswith(args.headerPrefix)
+        root = stripInitialSlash(root[len(args.headerPrefix):])
+
+    if args.sourcePrefix:
+        root = args.sourcePrefix + "/" + root
+
+    return args.root + "/"  \
+        + root + ("/" if root != "" else "") \
+        + fileNameWithoutExtension(fileName) + ".cpp"
+
+
+def fileNameWithoutExtension(fileName):
+    return os.path.splitext(os.path.basename(fileName))[0]
+
+# returns true if the specifies .cpp file already has the proper include
+
+
+def cppHasMOCInclude(fileName):
+    includeStatement = '#include "moc_%s.cpp"' % fileNameWithoutExtension(fileName)
+    with open(fileName, encoding="utf8") as fileHandle:
+        return includeStatement in fileHandle.read()
+
+
+def getMocInsertionLocation(filename, content):
+    headerIncludeRegex = re.compile(r'#include "%s\.h".*\n' % fileNameWithoutExtension(filename), re.M)
+    match = headerIncludeRegex.search(content)
+    if match:
+        return match.end()
+    return 0
+
+
+def trimExistingMocInclude(content, cppFileName):
+    mocStrRegex = re.compile(r'#include "moc_%s\.cpp"\n' % fileNameWithoutExtension(cppFileName))
+    match = mocStrRegex.search(content)
+    if match:
+        return content[:match.start()] + content[match.end():]
+    return content
+
+
+def processFile(root, fileName):
+    # pylint: disable=global-statement
+    global dirty
+    macroFound = hasMacro(root+"/"+fileName)
+    logVerbose("Inspecting %s %s" %
+               (root+"/"+fileName, "[Has Q_OBJECT / Q_GADGET / Q_NAMESPACE]" if macroFound else ""))
+
+    if macroFound:
+        cppFileName = matchingCPPFile(root, fileName)
+        logVerbose("  -> %s" % cppFileName)
+
+        if not os.path.exists(cppFileName):
+            log("file %s didn't exist (which might not be an error)" % cppFileName)
+            return
+
+        if args.replaceExisting or not cppHasMOCInclude(cppFileName):
+            dirty = True
+            if args.dryRun:
+                log("Missing moc include file: %s" % cppFileName)
+            else:
+                log("Updating %s" % cppFileName)
+
+                with open(cppFileName, "r", encoding="utf8") as f:
+                    content = f.read()
+
+                if args.replaceExisting:
+                    content = trimExistingMocInclude(content, cppFileName)
+
+                loc = getMocInsertionLocation(cppFileName, content)
+                if args.insertAtEnd:
+                    with open(cppFileName, "a", encoding="utf8") as f:
+                        f.write('\n#include "moc_%s.cpp"\n' % fileNameWithoutExtension(cppFileName))
+                else:
+                    with open(cppFileName, "w", encoding="utf8") as f:
+                        f.write(content[:loc] + ('#include "moc_%s.cpp"\n' %
+                                fileNameWithoutExtension(cppFileName)) + content[loc:])
+
+
+def log(content):
+    if not args.quiet:
+        print(content)
+
+
+def logVerbose(content):
+    if args.verbose:
+        print(content)
+
+
+################################ MAIN #################################
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description="""Script to add inclusion of mocs to files recursively.
+        The source files either need to be in the same directories as the header files or in parallel directories,
+        where the root of the headers are specified using --header-prefix and the root of the sources are specified using --source-prefix.
+        If either header-prefix or source-prefix is the current directory, then they may be omitted.""")
+    parser.add_argument("--dry-run", "-n", dest="dryRun", action='store_true', help="only report files to be updated")
+    parser.add_argument("--quiet", "-q", dest="quiet", action='store_true', help="suppress output")
+    parser.add_argument("--verbose", "-v", dest="verbose", action='store_true')
+    parser.add_argument("--header-prefix", metavar="directory", dest="headerPrefix",
+                        help="This directory will be replaced with source-prefix when "
+                             "searching for matching source files")
+    parser.add_argument("--source-prefix", metavar="directory", dest="sourcePrefix", help="see --header-prefix")
+    parser.add_argument("--excludes", metavar="directory", dest="excludes", nargs="*",
+                        help="directories to be excluded, might either be in the form of a directory name, "
+                        "e.g. 3rdparty or a partial directory prefix from the root, e.g 3rdparty/parser")
+    parser.add_argument("--insert-at-end", dest="insertAtEnd", action='store_true',
+                        help="insert the moc include at the end of the file instead of the beginning")
+    parser.add_argument("--replace-existing", dest="replaceExisting", action='store_true',
+                        help="delete and readd existing MOC include statements")
+    parser.add_argument(dest="root", default=".", metavar="directory",
+                        nargs="?", help="root directory for the operation")
+
+    args = parser.parse_args()
+
+    root = args.root
+    if args.headerPrefix:
+        root += "/" + args.headerPrefix
+
+    path = os.walk(root)
+    for root, directories, files in path:
+        # Filter out directories specified in --exclude
+        directories[:] = [d for d in directories if not shouldExclude(root, d)]
+
+        for file in files:
+            if file.endswith(".h") or file.endswith(".hpp"):
+                processFile(root, file)
+
+    if not dirty:
+        log("No changes needed")
+
+    sys.exit(-1 if dirty else 0)
+
diff --git a/src/AliasEditModel.cpp b/src/AliasEditModel.cpp
index cc6ea137..61808d98 100644
--- a/src/AliasEditModel.cpp
+++ b/src/AliasEditModel.cpp
@@ -333,3 +333,5 @@ AliasEditingModel::commit()
           }
       });
 }
+
+#include "moc_AliasEditModel.cpp"
diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp
index 0e4195db..4608aca4 100644
--- a/src/AvatarProvider.cpp
+++ b/src/AvatarProvider.cpp
@@ -69,3 +69,5 @@ resolve(const QString &room_id,
     resolve(std::move(avatarUrl), size, receiver, callback);
 }
 }
+
+#include "moc_AvatarProvider.cpp"
diff --git a/src/BlurhashProvider.cpp b/src/BlurhashProvider.cpp
index 1fdc9319..7a56cfa7 100644
--- a/src/BlurhashProvider.cpp
+++ b/src/BlurhashProvider.cpp
@@ -45,3 +45,5 @@ BlurhashRunnable::run()
 
     emit done(image.convertToFormat(QImage::Format_RGB32));
 }
+
+#include "moc_BlurhashProvider.cpp"
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index a43a190c..956888d0 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -1773,3 +1773,5 @@ ChatPage::removeAllNotifications()
     notificationsManager->closeAllNotifications();
 #endif
 }
+
+#include "moc_ChatPage.cpp"
diff --git a/src/Clipboard.cpp b/src/Clipboard.cpp
index d8f5f1d0..cb02f5fa 100644
--- a/src/Clipboard.cpp
+++ b/src/Clipboard.cpp
@@ -24,3 +24,5 @@ Clipboard::text() const
 {
     return QGuiApplication::clipboard()->text();
 }
+
+#include "moc_Clipboard.cpp"
diff --git a/src/ColorImageProvider.h b/src/ColorImageProvider.h
index 254cdff9..fd7e4822 100644
--- a/src/ColorImageProvider.h
+++ b/src/ColorImageProvider.h
@@ -2,6 +2,8 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
+#pragma once
+
 #include <QQuickImageProvider>
 
 class ColorImageProvider final : public QQuickImageProvider
diff --git a/src/CombinedImagePackModel.cpp b/src/CombinedImagePackModel.cpp
index c4a09847..f98537ea 100644
--- a/src/CombinedImagePackModel.cpp
+++ b/src/CombinedImagePackModel.cpp
@@ -103,3 +103,5 @@ CombinedImagePackModel::data(const QModelIndex &index, int role) const
     }
     return {};
 }
+
+#include "moc_CombinedImagePackModel.cpp"
diff --git a/src/CompletionProxyModel.cpp b/src/CompletionProxyModel.cpp
index bce873e7..895cabbb 100644
--- a/src/CompletionProxyModel.cpp
+++ b/src/CompletionProxyModel.cpp
@@ -169,3 +169,5 @@ CompletionProxyModel::setSearchString(const QString &s)
 {
     emit newSearchString(s);
 }
+
+#include "moc_CompletionProxyModel.cpp"
diff --git a/src/FallbackAuth.cpp b/src/FallbackAuth.cpp
index 5b668310..dc16b7cb 100644
--- a/src/FallbackAuth.cpp
+++ b/src/FallbackAuth.cpp
@@ -27,3 +27,5 @@ FallbackAuth::openFallbackAuth()
 
     QDesktopServices::openUrl(url);
 }
+
+#include "moc_FallbackAuth.cpp"
diff --git a/src/GridImagePackModel.cpp b/src/GridImagePackModel.cpp
index 4dbe6af3..9d8ac41f 100644
--- a/src/GridImagePackModel.cpp
+++ b/src/GridImagePackModel.cpp
@@ -400,3 +400,5 @@ GridImagePackModel::setSearchString(QString key)
     endResetModel();
     emit newSearchString();
 }
+
+#include "moc_GridImagePackModel.cpp"
diff --git a/src/ImagePackListModel.cpp b/src/ImagePackListModel.cpp
index 94b319f2..6245acbe 100644
--- a/src/ImagePackListModel.cpp
+++ b/src/ImagePackListModel.cpp
@@ -97,3 +97,5 @@ ImagePackListModel::containsAccountPack() const
             return true;
     return false;
 }
+
+#include "moc_ImagePackListModel.cpp"
diff --git a/src/InviteesModel.cpp b/src/InviteesModel.cpp
index ecb9e66c..7385c118 100644
--- a/src/InviteesModel.cpp
+++ b/src/InviteesModel.cpp
@@ -110,3 +110,5 @@ Invitee::Invitee(QString mxid, QString displayName, QString avatarUrl, QObject *
         emit userInfoLoaded();
     }
 }
+
+#include "moc_InviteesModel.cpp"
diff --git a/src/InviteesModel.h b/src/InviteesModel.h
index b9b4b862..36d04c0f 100644
--- a/src/InviteesModel.h
+++ b/src/InviteesModel.h
@@ -2,8 +2,7 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-#ifndef INVITEESMODEL_H
-#define INVITEESMODEL_H
+#pragma once
 
 #include <QAbstractListModel>
 #include <QQmlEngine>
@@ -73,5 +72,3 @@ private:
     QVector<Invitee *> invitees_;
     TimelineModel *room_;
 };
-
-#endif // INVITEESMODEL_H
diff --git a/src/JdenticonProvider.cpp b/src/JdenticonProvider.cpp
index f34275c9..46d898ef 100644
--- a/src/JdenticonProvider.cpp
+++ b/src/JdenticonProvider.cpp
@@ -120,3 +120,5 @@ JdenticonProvider::isAvailable()
 {
     return Jdenticon::getJdenticonInterface() != nullptr;
 }
+
+#include "moc_JdenticonProvider.cpp"
diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp
index fd35240b..ea295136 100644
--- a/src/LoginPage.cpp
+++ b/src/LoginPage.cpp
@@ -352,3 +352,5 @@ LoginPage::onLoginButtonClicked(LoginMethod loginMethod,
     loggingIn_ = true;
     emit loggingInChanged();
 }
+
+#include "moc_LoginPage.cpp"
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 9b2626cf..9f719227 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -322,3 +322,5 @@ MainWindow::focusedRoom() const
 
     return nullptr;
 }
+
+#include "moc_MainWindow.cpp"
diff --git a/src/MemberList.cpp b/src/MemberList.cpp
index a5e6565e..56f2b5b7 100644
--- a/src/MemberList.cpp
+++ b/src/MemberList.cpp
@@ -169,3 +169,5 @@ MemberList::filterAcceptsRow(int source_row, const QModelIndex &) const
            m_model.m_memberList[source_row].first.display_name.contains(filterString,
                                                                         Qt::CaseInsensitive);
 }
+
+#include "moc_MemberList.cpp"
diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp
index 05c2bbe7..de8027c3 100644
--- a/src/MxcImageProvider.cpp
+++ b/src/MxcImageProvider.cpp
@@ -370,3 +370,5 @@ MxcImageProvider::download(const QString &id,
         }
     }
 }
+
+#include "moc_MxcImageProvider.cpp"
diff --git a/src/PowerlevelsEditModels.cpp b/src/PowerlevelsEditModels.cpp
index 01337f11..7c0bca43 100644
--- a/src/PowerlevelsEditModels.cpp
+++ b/src/PowerlevelsEditModels.cpp
@@ -827,3 +827,5 @@ PowerlevelsSpacesListModel::roleNames() const
       {ApplyPermissions, "applyPermissions"},
     };
 }
+
+#include "moc_PowerlevelsEditModels.cpp"
diff --git a/src/ReCaptcha.cpp b/src/ReCaptcha.cpp
index ab9db8cc..a1d0c56f 100644
--- a/src/ReCaptcha.cpp
+++ b/src/ReCaptcha.cpp
@@ -27,3 +27,5 @@ ReCaptcha::openReCaptcha()
 
     QDesktopServices::openUrl(url);
 }
+
+#include "moc_ReCaptcha.cpp"
diff --git a/src/ReadReceiptsModel.cpp b/src/ReadReceiptsModel.cpp
index dfaab567..156d3824 100644
--- a/src/ReadReceiptsModel.cpp
+++ b/src/ReadReceiptsModel.cpp
@@ -129,3 +129,5 @@ ReadReceiptsProxy::ReadReceiptsProxy(QString event_id, QString room_id, QObject
     sort(0, Qt::DescendingOrder);
     setDynamicSortFilter(true);
 }
+
+#include "moc_ReadReceiptsModel.cpp"
diff --git a/src/ReadReceiptsModel.h b/src/ReadReceiptsModel.h
index 56f67509..ad404bf1 100644
--- a/src/ReadReceiptsModel.h
+++ b/src/ReadReceiptsModel.h
@@ -2,8 +2,7 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-#ifndef READRECEIPTSMODEL_H
-#define READRECEIPTSMODEL_H
+#pragma once
 
 #include <QAbstractListModel>
 #include <QDateTime>
@@ -73,5 +72,3 @@ private:
 
     ReadReceiptsModel model_;
 };
-
-#endif // READRECEIPTSMODEL_H
diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp
index e1f86e53..824547bc 100644
--- a/src/RegisterPage.cpp
+++ b/src/RegisterPage.cpp
@@ -255,3 +255,5 @@ RegisterPage::startRegistration(const QString &username,
           devicename.isEmpty() ? LoginPage::initialDeviceName_() : devicename.toStdString());
     }
 }
+
+#include "moc_RegisterPage.cpp"
diff --git a/src/RoomDirectoryModel.cpp b/src/RoomDirectoryModel.cpp
index a100c040..9a71cbc3 100644
--- a/src/RoomDirectoryModel.cpp
+++ b/src/RoomDirectoryModel.cpp
@@ -228,3 +228,5 @@ RoomDirectoryModel::displayRooms(std::vector<mtx::responses::PublicRoomsChunk> f
 
     nhlog::ui()->debug("Finished loading rooms");
 }
+
+#include "moc_RoomDirectoryModel.cpp"
diff --git a/src/SSOHandler.cpp b/src/SSOHandler.cpp
index 93eb539c..7d844047 100644
--- a/src/SSOHandler.cpp
+++ b/src/SSOHandler.cpp
@@ -55,3 +55,5 @@ SSOHandler::url() const
 {
     return "http://localhost:" + std::to_string(port) + "/sso";
 }
+
+#include "moc_SSOHandler.cpp"
diff --git a/src/SSOHandler.h b/src/SSOHandler.h
index d7e3f380..c9708584 100644
--- a/src/SSOHandler.h
+++ b/src/SSOHandler.h
@@ -2,6 +2,8 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
+#pragma once
+
 #include "httplib.h"
 
 #include <QObject>
diff --git a/src/SingleImagePackModel.cpp b/src/SingleImagePackModel.cpp
index 95a863d3..0a0d9265 100644
--- a/src/SingleImagePackModel.cpp
+++ b/src/SingleImagePackModel.cpp
@@ -488,3 +488,5 @@ SingleImagePackModel::addImageCb(std::string uri, std::string filename, mtx::com
     if (this->pack.pack->avatar_url.empty())
         this->setAvatarUrl(QString::fromStdString(uri));
 }
+
+#include "moc_SingleImagePackModel.cpp"
diff --git a/src/TrayIcon.cpp b/src/TrayIcon.cpp
index 3b74544c..c89e69cc 100644
--- a/src/TrayIcon.cpp
+++ b/src/TrayIcon.cpp
@@ -123,3 +123,5 @@ TrayIcon::setUnreadCount(int count)
 {
     qGuiApp->setBadgeNumber(count);
 }
+
+#include "moc_TrayIcon.cpp"
diff --git a/src/UserDirectoryModel.cpp b/src/UserDirectoryModel.cpp
index 72a5a13e..00efb6f4 100644
--- a/src/UserDirectoryModel.cpp
+++ b/src/UserDirectoryModel.cpp
@@ -103,3 +103,5 @@ UserDirectoryModel::displaySearchResults(std::vector<mtx::responses::User> resul
     endInsertRows();
     canFetchMore_ = false;
 }
+
+#include "moc_UserDirectoryModel.cpp"
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index ed6175ae..c8ea6eb8 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -2332,3 +2332,5 @@ UserSettingsModel::UserSettingsModel(QObject *p)
         emit dataChanged(index(ExpireEvents), index(ExpireEvents), {Value});
     });
 }
+
+#include "moc_UserSettingsPage.cpp"
diff --git a/src/dbus/NhekoDBusApi.cpp b/src/dbus/NhekoDBusApi.cpp
index 6b481941..c2c62eb7 100644
--- a/src/dbus/NhekoDBusApi.cpp
+++ b/src/dbus/NhekoDBusApi.cpp
@@ -228,3 +228,5 @@ operator>>(const QDBusArgument &arg, QImage &image)
 
     return arg;
 }
+
+#include "moc_NhekoDBusApi.cpp"
diff --git a/src/dbus/NhekoDBusApi.h b/src/dbus/NhekoDBusApi.h
index ce265a17..6acb2b65 100644
--- a/src/dbus/NhekoDBusApi.h
+++ b/src/dbus/NhekoDBusApi.h
@@ -2,8 +2,7 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-#ifndef NHEKODBUSAPI_H
-#define NHEKODBUSAPI_H
+#pragma once
 
 #include <QDBusArgument>
 #include <QIcon>
@@ -99,5 +98,3 @@ const QDBusArgument &
 operator>>(const QDBusArgument &arg, QImage &);
 
 #define NHEKO_DBUS_SERVICE_NAME "im.nheko.Nheko"
-
-#endif // NHEKODBUSAPI_H
diff --git a/src/dbus/NhekoDBusBackend.cpp b/src/dbus/NhekoDBusBackend.cpp
index 5e0f8418..b397a670 100644
--- a/src/dbus/NhekoDBusBackend.cpp
+++ b/src/dbus/NhekoDBusBackend.cpp
@@ -117,3 +117,5 @@ NhekoDBusBackend::bringWindowToTop() const
     MainWindow::instance()->show();
     MainWindow::instance()->raise();
 }
+
+#include "moc_NhekoDBusBackend.cpp"
diff --git a/src/dbus/NhekoDBusBackend.h b/src/dbus/NhekoDBusBackend.h
index e1b5fabb..79d396f8 100644
--- a/src/dbus/NhekoDBusBackend.h
+++ b/src/dbus/NhekoDBusBackend.h
@@ -2,8 +2,7 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
-#ifndef NHEKODBUSBACKEND_H
-#define NHEKODBUSBACKEND_H
+#pragma once
 
 #include <QDBusMessage>
 #include <QObject>
@@ -47,5 +46,3 @@ private:
 
     RoomlistModel *m_parent;
 };
-
-#endif // NHEKODBUSBACKEND_H
diff --git a/src/dock/Dock.cpp b/src/dock/Dock.cpp
index a4745e54..de15df3a 100644
--- a/src/dock/Dock.cpp
+++ b/src/dock/Dock.cpp
@@ -90,3 +90,5 @@ Dock::setUnreadCount(const int count)
     qGuiApp->setBadgeNumber(count);
 }
 #endif
+
+#include "moc_Dock.cpp"
diff --git a/src/emoji/Provider.cpp b/src/emoji/Provider.cpp
index c77a7835..9c1fb5a2 100644
--- a/src/emoji/Provider.cpp
+++ b/src/emoji/Provider.cpp
@@ -15287,3 +15287,5 @@ constexpr
             std::u16string_view(u"flag: Wales"),
             emoji::Emoji::Category::Flags},
 };
+
+#include "moc_Provider.cpp"
diff --git a/src/encryption/DeviceVerificationFlow.cpp b/src/encryption/DeviceVerificationFlow.cpp
index 3de14658..ac228669 100644
--- a/src/encryption/DeviceVerificationFlow.cpp
+++ b/src/encryption/DeviceVerificationFlow.cpp
@@ -987,3 +987,5 @@ DeviceVerificationFlow::send(T msg)
                         mtx::events::to_string(mtx::events::to_device_content_to_type<T>),
                         state().toStdString());
 }
+
+#include "moc_DeviceVerificationFlow.cpp"
diff --git a/src/encryption/Olm.cpp b/src/encryption/Olm.cpp
index f336c2ba..08c09df2 100644
--- a/src/encryption/Olm.cpp
+++ b/src/encryption/Olm.cpp
@@ -1770,3 +1770,5 @@ download_cross_signing_keys()
 }
 
 } // namespace olm
+
+#include "moc_Olm.cpp"
diff --git a/src/encryption/SelfVerificationStatus.cpp b/src/encryption/SelfVerificationStatus.cpp
index b5549ca1..b67bba71 100644
--- a/src/encryption/SelfVerificationStatus.cpp
+++ b/src/encryption/SelfVerificationStatus.cpp
@@ -355,3 +355,5 @@ SelfVerificationStatus::invalidate()
         return;
     }
 }
+
+#include "moc_SelfVerificationStatus.cpp"
diff --git a/src/encryption/VerificationManager.cpp b/src/encryption/VerificationManager.cpp
index d1248755..985bd619 100644
--- a/src/encryption/VerificationManager.cpp
+++ b/src/encryption/VerificationManager.cpp
@@ -169,3 +169,5 @@ VerificationManager::verifyOneOfDevices(QString userid, std::vector<QString> dev
     this->dvList[flow->transactionId()] = flow;
     emit newDeviceVerificationRequest(flow.data());
 }
+
+#include "moc_VerificationManager.cpp"
diff --git a/src/notifications/Manager.cpp b/src/notifications/Manager.cpp
index 5790d43e..895beaf7 100644
--- a/src/notifications/Manager.cpp
+++ b/src/notifications/Manager.cpp
@@ -53,3 +53,5 @@ NotificationsManager::removeNotifications(const QString &roomId_,
         }
     }
 }
+
+#include "moc_Manager.cpp"
diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp
index 3ba4e92b..3f28da11 100644
--- a/src/timeline/CommunitiesModel.cpp
+++ b/src/timeline/CommunitiesModel.cpp
@@ -936,3 +936,5 @@ CommunitiesModel::updateSpaceStatus(QString space,
         }
     }
 }
+
+#include "moc_CommunitiesModel.cpp"
diff --git a/src/timeline/DelegateChooser.cpp b/src/timeline/DelegateChooser.cpp
index b95116ec..98adbf39 100644
--- a/src/timeline/DelegateChooser.cpp
+++ b/src/timeline/DelegateChooser.cpp
@@ -138,3 +138,5 @@ DelegateChooser::DelegateIncubator::statusChanged(QQmlIncubator::Status status)
             nhlog::ui()->error("Error instantiating delegate: {}", e.toString().toStdString());
     }
 }
+
+#include "moc_DelegateChooser.cpp"
diff --git a/src/timeline/EventDelegateChooser.cpp b/src/timeline/EventDelegateChooser.cpp
index 5ce8d63e..2a3e2a71 100644
--- a/src/timeline/EventDelegateChooser.cpp
+++ b/src/timeline/EventDelegateChooser.cpp
@@ -369,3 +369,5 @@ EventDelegateChooserAttachedType::polishChooser()
         }
     }
 }
+
+#include "moc_EventDelegateChooser.cpp"
diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp
index de109b1a..68089ceb 100644
--- a/src/timeline/EventStore.cpp
+++ b/src/timeline/EventStore.cpp
@@ -941,3 +941,5 @@ EventStore::fetchMore()
           emit oldMessagesRetrieved(std::move(res));
       });
 }
+
+#include "moc_EventStore.cpp"
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index f8b57b81..afb4585a 100644
--- a/src/timeline/InputBar.cpp
+++ b/src/timeline/InputBar.cpp
@@ -1495,3 +1495,5 @@ InputBar::reaction(const QString &reactedEvent, const QString &reactionKey)
         room->redactEvent(selfReactedEvent);
     }
 }
+
+#include "moc_InputBar.cpp"
diff --git a/src/timeline/Permissions.cpp b/src/timeline/Permissions.cpp
index c68e8149..2ef6e5cd 100644
--- a/src/timeline/Permissions.cpp
+++ b/src/timeline/Permissions.cpp
@@ -91,3 +91,5 @@ Permissions::canPingRoom()
     return pl.user_level(http::client()->user_id().to_string()) >=
            pl.notification_level(mtx::events::state::notification_keys::room);
 }
+
+#include "moc_Permissions.cpp"
diff --git a/src/timeline/PresenceEmitter.cpp b/src/timeline/PresenceEmitter.cpp
index 9b498432..da03f9bf 100644
--- a/src/timeline/PresenceEmitter.cpp
+++ b/src/timeline/PresenceEmitter.cpp
@@ -75,3 +75,5 @@ PresenceEmitter::userStatus(QString id) const
     else
         return pullPresence(id)->status;
 }
+
+#include "moc_PresenceEmitter.cpp"
diff --git a/src/timeline/Reaction.cpp b/src/timeline/Reaction.cpp
index 64c868c6..5457072d 100644
--- a/src/timeline/Reaction.cpp
+++ b/src/timeline/Reaction.cpp
@@ -3,3 +3,5 @@
 // SPDX-License-Identifier: GPL-3.0-or-later
 
 #include "Reaction.h"
+
+#include "moc_Reaction.cpp"
diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp
index da639843..898e6e83 100644
--- a/src/timeline/RoomlistModel.cpp
+++ b/src/timeline/RoomlistModel.cpp
@@ -1288,3 +1288,5 @@ RoomPreview::inviterUserId() const
 
     return QString();
 }
+
+#include "moc_RoomlistModel.cpp"
diff --git a/src/timeline/TimelineFilter.cpp b/src/timeline/TimelineFilter.cpp
index a933a9e4..a92dfb13 100644
--- a/src/timeline/TimelineFilter.cpp
+++ b/src/timeline/TimelineFilter.cpp
@@ -252,3 +252,5 @@ TimelineFilter::filterAcceptsRow(int source_row, const QModelIndex &) const
         return true;
     }
 }
+
+#include "moc_TimelineFilter.cpp"
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index e7fb31f5..92a37aa1 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -3373,3 +3373,5 @@ TimelineModel::parentSpace()
 
     return parentSummary.get();
 }
+
+#include "moc_TimelineModel.cpp"
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index e2616c14..9ea8dc77 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -599,4 +599,5 @@ TimelineViewManager::processIgnoredUsers(const mtx::responses::AccountData &data
         emit this->ignoredUsersChanged(convertIgnoredToQt(ignoredEv));
         break;
     }
-}
\ No newline at end of file
+}
+#include "moc_TimelineViewManager.cpp"
diff --git a/src/ui/EventExpiry.cpp b/src/ui/EventExpiry.cpp
index afacd2cd..8065c397 100644
--- a/src/ui/EventExpiry.cpp
+++ b/src/ui/EventExpiry.cpp
@@ -123,3 +123,5 @@ EventExpiry::setExpireStateEvents(bool val)
     this->event.exclude_state_events = !val;
     emit expireEventsAfterCountChanged();
 }
+
+#include "moc_EventExpiry.cpp"
diff --git a/src/ui/HiddenEvents.cpp b/src/ui/HiddenEvents.cpp
index f92b992d..78bb72d6 100644
--- a/src/ui/HiddenEvents.cpp
+++ b/src/ui/HiddenEvents.cpp
@@ -104,3 +104,5 @@ HiddenEvents::save()
               }
           });
 }
+
+#include "moc_HiddenEvents.cpp"
diff --git a/src/ui/MxcAnimatedImage.cpp b/src/ui/MxcAnimatedImage.cpp
index f536b39f..e58f2e6e 100644
--- a/src/ui/MxcAnimatedImage.cpp
+++ b/src/ui/MxcAnimatedImage.cpp
@@ -208,3 +208,5 @@ MxcAnimatedImage::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeD
 
     return n;
 }
+
+#include "moc_MxcAnimatedImage.cpp"
diff --git a/src/ui/MxcMediaProxy.cpp b/src/ui/MxcMediaProxy.cpp
index 39fdb155..1b7a31be 100644
--- a/src/ui/MxcMediaProxy.cpp
+++ b/src/ui/MxcMediaProxy.cpp
@@ -172,3 +172,5 @@ MxcMediaProxy::startDownload(bool onlyCached)
                                  }
                              });
 }
+
+#include "moc_MxcMediaProxy.cpp"
diff --git a/src/ui/NhekoCursorShape.cpp b/src/ui/NhekoCursorShape.cpp
index 76a5e097..626470cd 100644
--- a/src/ui/NhekoCursorShape.cpp
+++ b/src/ui/NhekoCursorShape.cpp
@@ -28,3 +28,5 @@ NhekoCursorShape::setCursorShape(Qt::CursorShape cursorShape)
     setCursor(cursorShape);
     emit cursorShapeChanged();
 }
+
+#include "moc_NhekoCursorShape.cpp"
diff --git a/src/ui/NhekoDropArea.cpp b/src/ui/NhekoDropArea.cpp
index 571ccf69..6751a729 100644
--- a/src/ui/NhekoDropArea.cpp
+++ b/src/ui/NhekoDropArea.cpp
@@ -40,3 +40,5 @@ NhekoDropArea::dropEvent(QDropEvent *event)
         }
     }
 }
+
+#include "moc_NhekoDropArea.cpp"
diff --git a/src/ui/NhekoDropArea.h b/src/ui/NhekoDropArea.h
index 46a02da5..63a1be4c 100644
--- a/src/ui/NhekoDropArea.h
+++ b/src/ui/NhekoDropArea.h
@@ -2,6 +2,8 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
+#pragma once
+
 #include <QQuickItem>
 
 class NhekoDropArea : public QQuickItem
diff --git a/src/ui/NhekoGlobalObject.cpp b/src/ui/NhekoGlobalObject.cpp
index 54c4c1c9..591eed3c 100644
--- a/src/ui/NhekoGlobalObject.cpp
+++ b/src/ui/NhekoGlobalObject.cpp
@@ -212,3 +212,5 @@ Nheko::setWindowRole([[maybe_unused]] QWindow *win, [[maybe_unused]] QString new
                         role.data());
 #endif
 }
+
+#include "moc_NhekoGlobalObject.cpp"
diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp
index 073b27d0..b61cab26 100644
--- a/src/ui/RoomSettings.cpp
+++ b/src/ui/RoomSettings.cpp
@@ -811,3 +811,5 @@ RoomSettings::applyAllowedFromModel()
     this->allowedRoomsModified_ = true;
     emit allowedRoomsModifiedChanged();
 }
+
+#include "moc_RoomSettings.cpp"
diff --git a/src/ui/RoomSummary.cpp b/src/ui/RoomSummary.cpp
index a56c228a..edef8339 100644
--- a/src/ui/RoomSummary.cpp
+++ b/src/ui/RoomSummary.cpp
@@ -95,3 +95,5 @@ RoomSummary::promptJoin()
     else
         ChatPage::instance()->joinRoomVia(roomIdOrAlias, vias, true, reason_);
 }
+
+#include "moc_RoomSummary.cpp"
diff --git a/src/ui/Theme.cpp b/src/ui/Theme.cpp
index 159fc2ae..4d46db13 100644
--- a/src/ui/Theme.cpp
+++ b/src/ui/Theme.cpp
@@ -84,3 +84,5 @@ Theme::Theme(QStringView theme)
         error_             = QColor(0xdd, 0x3d, 0x3d);
     }
 }
+
+#include "moc_Theme.cpp"
diff --git a/src/ui/UIA.cpp b/src/ui/UIA.cpp
index 4c1d35b9..f212fc1d 100644
--- a/src/ui/UIA.cpp
+++ b/src/ui/UIA.cpp
@@ -285,3 +285,5 @@ UIA::submit3pidToken(const QString &token)
           this->submit_url.clear();
       });
 }
+
+#include "moc_UIA.cpp"
diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp
index c7254e23..6f5fbc61 100644
--- a/src/ui/UserProfile.cpp
+++ b/src/ui/UserProfile.cpp
@@ -627,3 +627,5 @@ UserProfile::openGlobalProfile()
 {
     emit manager->openGlobalUserProfile(userid_);
 }
+
+#include "moc_UserProfile.cpp"
diff --git a/src/voip/CallDevices.cpp b/src/voip/CallDevices.cpp
index c279248b..90eef113 100644
--- a/src/voip/CallDevices.cpp
+++ b/src/voip/CallDevices.cpp
@@ -393,3 +393,5 @@ CallDevices::frameRates(const std::string &, const std::string &) const
 }
 
 #endif
+
+#include "moc_CallDevices.cpp"
diff --git a/src/voip/CallManager.cpp b/src/voip/CallManager.cpp
index e5754417..ac3ec8ee 100644
--- a/src/voip/CallManager.cpp
+++ b/src/voip/CallManager.cpp
@@ -1172,3 +1172,5 @@ getTurnURIs(const mtx::responses::TurnServer &turnServer)
     return ret;
 }
 }
+
+#include "moc_CallManager.cpp"
diff --git a/src/voip/ScreenCastPortal.cpp b/src/voip/ScreenCastPortal.cpp
index 83f7595b..784e5aa3 100644
--- a/src/voip/ScreenCastPortal.cpp
+++ b/src/voip/ScreenCastPortal.cpp
@@ -511,3 +511,5 @@ ScreenCastPortal::openPipeWireRemote()
 }
 
 #endif
+
+#include "moc_ScreenCastPortal.cpp"
diff --git a/src/voip/WebRTCSession.cpp b/src/voip/WebRTCSession.cpp
index 332a27fd..049b3431 100644
--- a/src/voip/WebRTCSession.cpp
+++ b/src/voip/WebRTCSession.cpp
@@ -1305,3 +1305,5 @@ WebRTCSession::end()
 }
 
 #endif
+
+#include "moc_WebRTCSession.cpp"