diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-06-19 01:38:40 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2023-06-19 01:38:40 +0200 |
commit | ce1a64bc19ffc21e115bdf2587bb053d7a417f3e (patch) | |
tree | a195d127228218772a535448de642f0bb7b6d053 /src | |
parent | Remove explicit link styling (diff) | |
download | nheko-ce1a64bc19ffc21e115bdf2587bb053d7a417f3e.tar.xz |
Move to automatic type registration
Diffstat (limited to 'src')
44 files changed, 391 insertions, 300 deletions
diff --git a/src/AliasEditModel.h b/src/AliasEditModel.h index 2263659b..04de5016 100644 --- a/src/AliasEditModel.h +++ b/src/AliasEditModel.h @@ -5,6 +5,7 @@ #pragma once #include <QAbstractListModel> +#include <QQmlEngine> #include <QVector> #include <mtx/events/canonical_alias.hpp> @@ -29,6 +30,9 @@ signals: class AliasEditingModel final : public QAbstractListModel { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("Please use editAliases to create the models") + Q_PROPERTY(bool canAdvertize READ canAdvertize CONSTANT) public: diff --git a/src/CacheCryptoStructs.h b/src/CacheCryptoStructs.h index 96fc35ec..2a5b895f 100644 --- a/src/CacheCryptoStructs.h +++ b/src/CacheCryptoStructs.h @@ -5,6 +5,7 @@ #pragma once #include <QObject> +#include <QQmlEngine> #include <map> #include <mutex> @@ -16,6 +17,8 @@ namespace crypto { Q_NAMESPACE +QML_NAMED_ELEMENT(Crypto) + //! How much a participant is trusted. enum Trust { diff --git a/src/Clipboard.h b/src/Clipboard.h index bad9fd10..8bf89c22 100644 --- a/src/Clipboard.h +++ b/src/Clipboard.h @@ -5,11 +5,15 @@ #pragma once #include <QObject> +#include <QQmlEngine> #include <QString> class Clipboard final : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) public: diff --git a/src/LoginPage.h b/src/LoginPage.h index f20ba0c6..e3d0d2e0 100644 --- a/src/LoginPage.h +++ b/src/LoginPage.h @@ -5,13 +5,10 @@ #pragma once #include <QObject> +#include <QQmlEngine> #include <QVariantList> -namespace mtx { -namespace responses { -struct Login; -} -} +#include <mtx/responses/login.hpp> struct SSOProvider { @@ -33,6 +30,7 @@ public: class LoginPage : public QObject { Q_OBJECT + QML_ELEMENT Q_PROPERTY(QString mxid READ mxid WRITE setMxid NOTIFY matrixIdChanged) Q_PROPERTY(QString homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged) diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 51b23e0f..d06171de 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -25,21 +25,15 @@ #include "InviteesModel.h" #include "JdenticonProvider.h" #include "Logging.h" -#include "LoginPage.h" #include "MainWindow.h" #include "MatrixClient.h" #include "MemberList.h" #include "MxcImageProvider.h" #include "PowerlevelsEditModels.h" -#include "ReadReceiptsModel.h" -#include "RegisterPage.h" -#include "RoomDirectoryModel.h" -#include "RoomsModel.h" #include "SingleImagePackModel.h" #include "TrayIcon.h" #include "UserDirectoryModel.h" #include "UserSettingsPage.h" -#include "UsersModel.h" #include "Utils.h" #include "dock/Dock.h" #include "emoji/Provider.h" @@ -48,12 +42,6 @@ #include "timeline/DelegateChooser.h" #include "timeline/TimelineFilter.h" #include "timeline/TimelineViewManager.h" -#include "ui/HiddenEvents.h" -#include "ui/MxcAnimatedImage.h" -#include "ui/MxcMediaProxy.h" -#include "ui/NhekoCursorShape.h" -#include "ui/NhekoDropArea.h" -#include "ui/NhekoEventObserver.h" #include "ui/NhekoGlobalObject.h" #include "ui/RoomSummary.h" #include "ui/UIA.h" @@ -83,7 +71,7 @@ MainWindow::MainWindow(QWindow *parent) registerQmlTypes(); setColor(Theme::paletteFromTheme(userSettings_->theme()).window().color()); - setSource(QUrl(QStringLiteral("qrc:///qml/Root.qml"))); + setSource(QUrl(QStringLiteral("qrc:///resources/qml/Root.qml"))); trayIcon_ = new TrayIcon(QStringLiteral(":/logos/nheko.svg"), this); @@ -132,156 +120,57 @@ MainWindow::MainWindow(QWindow *parent) void MainWindow::registerQmlTypes() { - qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject, - "im.nheko", - 1, - 0, - "MtxEvent", - QStringLiteral("Can't instantiate enum!")); - qmlRegisterUncreatableMetaObject( - olm::staticMetaObject, "im.nheko", 1, 0, "Olm", QStringLiteral("Can't instantiate enum!")); - qmlRegisterUncreatableMetaObject(crypto::staticMetaObject, - "im.nheko", - 1, - 0, - "Crypto", - QStringLiteral("Can't instantiate enum!")); - qmlRegisterUncreatableMetaObject(verification::staticMetaObject, - "im.nheko", - 1, - 0, - "VerificationStatus", - QStringLiteral("Can't instantiate enum!")); - - qmlRegisterType<DelegateChoice>("im.nheko", 1, 0, "DelegateChoice"); - qmlRegisterType<DelegateChooser>("im.nheko", 1, 0, "DelegateChooser"); - qmlRegisterType<NhekoDropArea>("im.nheko", 1, 0, "NhekoDropArea"); - qmlRegisterType<NhekoCursorShape>("im.nheko", 1, 0, "CursorShape"); - qmlRegisterType<NhekoEventObserver>("im.nheko", 1, 0, "EventObserver"); - qmlRegisterType<MxcAnimatedImage>("im.nheko", 1, 0, "MxcAnimatedImage"); - qmlRegisterType<MxcMediaProxy>("im.nheko", 1, 0, "MxcMedia"); - qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel"); - qmlRegisterType<UserDirectoryModel>("im.nheko", 1, 0, "UserDirectoryModel"); - qmlRegisterType<LoginPage>("im.nheko", 1, 0, "Login"); - qmlRegisterType<RegisterPage>("im.nheko", 1, 0, "Registration"); - qmlRegisterType<HiddenEvents>("im.nheko", 1, 0, "HiddenEvents"); - qmlRegisterType<TimelineFilter>("im.nheko", 1, 0, "TimelineFilter"); - qmlRegisterUncreatableType<RoomSummary>( - "im.nheko", - 1, - 0, - "RoomSummary", - QStringLiteral("Please use joinRoom to create a room summary.")); - qmlRegisterUncreatableType<AliasEditingModel>( - "im.nheko", - 1, - 0, - "AliasEditingModel", - QStringLiteral("Please use editAliases to create the models")); - - qmlRegisterUncreatableType<PowerlevelEditingModels>( - "im.nheko", - 1, - 0, - "PowerlevelEditingModels", - QStringLiteral("Please use editPowerlevels to create the models")); - qmlRegisterUncreatableType<DeviceVerificationFlow>( - "im.nheko", - 1, - 0, - "DeviceVerificationFlow", - QStringLiteral("Can't create verification flow from QML!")); - qmlRegisterUncreatableType<UserProfile>( - "im.nheko", - 1, - 0, - "UserProfileModel", - QStringLiteral("UserProfile needs to be instantiated on the C++ side")); - qmlRegisterUncreatableType<MemberList>( - "im.nheko", - 1, - 0, - "MemberList", - QStringLiteral("MemberList needs to be instantiated on the C++ side")); - qmlRegisterUncreatableType<RoomSettings>( - "im.nheko", - 1, - 0, - "RoomSettingsModel", - QStringLiteral("Room Settings needs to be instantiated on the C++ side")); - qmlRegisterUncreatableType<TimelineModel>( - "im.nheko", 1, 0, "Room", QStringLiteral("Room needs to be instantiated on the C++ side")); - qmlRegisterUncreatableType<ImagePackListModel>( - "im.nheko", - 1, - 0, - "ImagePackListModel", - QStringLiteral("ImagePackListModel needs to be instantiated on the C++ side")); - qmlRegisterUncreatableType<SingleImagePackModel>( - "im.nheko", - 1, - 0, - "SingleImagePackModel", - QStringLiteral("SingleImagePackModel needs to be instantiated on the C++ side")); - qmlRegisterUncreatableType<InviteesModel>( - "im.nheko", - 1, - 0, - "InviteesModel", - QStringLiteral("InviteesModel needs to be instantiated on the C++ side")); - qmlRegisterUncreatableType<ReadReceiptsProxy>( - "im.nheko", - 1, - 0, - "ReadReceiptsProxy", - QStringLiteral("ReadReceiptsProxy needs to be instantiated on the C++ side")); - - qmlRegisterSingletonType<Clipboard>( - "im.nheko", 1, 0, "Clipboard", [](QQmlEngine *, QJSEngine *) -> QObject * { - return new Clipboard(); - }); - qmlRegisterSingletonType<Nheko>( - "im.nheko", 1, 0, "Nheko", [](QQmlEngine *, QJSEngine *) -> QObject * { - return new Nheko(); - }); - qmlRegisterSingletonType<UserSettingsModel>( - "im.nheko", 1, 0, "UserSettingsModel", [](QQmlEngine *, QJSEngine *) -> QObject * { - return new UserSettingsModel(); - }); - - qmlRegisterSingletonInstance("im.nheko", 1, 0, "Settings", userSettings_.data()); - - qmlRegisterUncreatableType<FilteredCommunitiesModel>( - "im.nheko", - 1, - 0, - "FilteredCommunitiesModel", - QStringLiteral("Use Communities.filtered() to create a FilteredCommunitiesModel")); - - qmlRegisterUncreatableType<MediaUpload>( - "im.nheko", 1, 0, "MediaUpload", QStringLiteral("MediaUploads can not be created in Qml")); - qmlRegisterUncreatableMetaObject(emoji::staticMetaObject, - "im.nheko.EmojiModel", - 1, - 0, - "EmojiCategory", - QStringLiteral("Error: Only enums")); - - qmlRegisterType<RoomDirectoryModel>("im.nheko", 1, 0, "RoomDirectoryModel"); - - qmlRegisterSingletonType<SelfVerificationStatus>( - "im.nheko", 1, 0, "SelfVerificationStatus", [](QQmlEngine *, QJSEngine *) -> QObject * { - auto ptr = new SelfVerificationStatus(); - QObject::connect(ChatPage::instance(), - &ChatPage::initializeEmptyViews, - ptr, - &SelfVerificationStatus::invalidate); - return ptr; - }); - qmlRegisterSingletonInstance("im.nheko", 1, 0, "MainWindow", this); - qmlRegisterSingletonInstance("im.nheko", 1, 0, "UIA", UIA::instance()); - qmlRegisterSingletonInstance( - "im.nheko", 1, 0, "CallManager", ChatPage::instance()->callManager()); + // qmlRegisterUncreatableType<DeviceVerificationFlow>( + // "im.nheko", + // 1, + // 0, + // "DeviceVerificationFlow", + // QStringLiteral("Can't create verification flow from QML!")); + // qmlRegisterUncreatableType<UserProfile>( + // "im.nheko", + // 1, + // 0, + // "UserProfileModel", + // QStringLiteral("UserProfile needs to be instantiated on the C++ side")); + // qmlRegisterUncreatableType<MemberList>( + // "im.nheko", + // 1, + // 0, + // "MemberList", + // QStringLiteral("MemberList needs to be instantiated on the C++ side")); + // qmlRegisterUncreatableType<RoomSettings>( + // "im.nheko", + // 1, + // 0, + // "RoomSettingsModel", + // QStringLiteral("Room Settings needs to be instantiated on the C++ side")); + // qmlRegisterUncreatableType<TimelineModel>( + // "im.nheko", 1, 0, "Room", QStringLiteral("Room needs to be instantiated on the C++ side")); + // qmlRegisterUncreatableType<ImagePackListModel>( + // "im.nheko", + // 1, + // 0, + // "ImagePackListModel", + // QStringLiteral("ImagePackListModel needs to be instantiated on the C++ side")); + // qmlRegisterUncreatableType<SingleImagePackModel>( + // "im.nheko", + // 1, + // 0, + // "SingleImagePackModel", + // QStringLiteral("SingleImagePackModel needs to be instantiated on the C++ side")); + // qmlRegisterUncreatableType<InviteesModel>( + // "im.nheko", + // 1, + // 0, + // "InviteesModel", + // QStringLiteral("InviteesModel needs to be instantiated on the C++ side")); + + // qmlRegisterUncreatableMetaObject(emoji::staticMetaObject, + // "im.nheko.EmojiModel", + // 1, + // 0, + // "EmojiCategory", + // QStringLiteral("Error: Only enums")); imgProvider = new MxcImageProvider(); engine()->addImageProvider(QStringLiteral("MxcImage"), imgProvider); diff --git a/src/MainWindow.h b/src/MainWindow.h index 0a5f9433..20e81efc 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -50,14 +50,35 @@ public: bool eventFilter(QObject *obj, QEvent *event) override; }; -class MainWindow final : public QQuickView +class MainWindow : public QQuickView { Q_OBJECT + QML_ELEMENT + QML_SINGLETON public: - explicit MainWindow(QWindow *parent = nullptr); + explicit MainWindow(QWindow *parent); static MainWindow *instance() { return instance_; } + static MainWindow *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance_); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance_->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership); + return instance_; + } + void saveCurrentWindowSize(); void openJoinRoomDialog(std::function<void(const QString &room_id)> callback); diff --git a/src/PowerlevelsEditModels.h b/src/PowerlevelsEditModels.h index fe9735d3..c9d262d8 100644 --- a/src/PowerlevelsEditModels.h +++ b/src/PowerlevelsEditModels.h @@ -5,6 +5,7 @@ #pragma once #include <QAbstractListModel> +#include <QQmlEngine> #include <QSortFilterProxyModel> #include <mtx/events/power_levels.hpp> @@ -196,6 +197,9 @@ class PowerlevelEditingModels final : public QObject { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("Please use editPowerlevels to create the models") + Q_PROPERTY(PowerlevelsUserListModel *users READ users CONSTANT) Q_PROPERTY(PowerlevelsTypeListModel *types READ types CONSTANT) Q_PROPERTY(PowerlevelsSpacesListModel *spaces READ spaces CONSTANT) diff --git a/src/ReadReceiptsModel.h b/src/ReadReceiptsModel.h index b870061a..56f67509 100644 --- a/src/ReadReceiptsModel.h +++ b/src/ReadReceiptsModel.h @@ -8,6 +8,7 @@ #include <QAbstractListModel> #include <QDateTime> #include <QObject> +#include <QQmlEngine> #include <QSortFilterProxyModel> #include <QString> @@ -54,6 +55,9 @@ class ReadReceiptsProxy final : public QSortFilterProxyModel { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("") + Q_PROPERTY(QString eventId READ eventId CONSTANT) Q_PROPERTY(QString roomId READ roomId CONSTANT) diff --git a/src/RegisterPage.h b/src/RegisterPage.h index 7c58b40c..dcf61489 100644 --- a/src/RegisterPage.h +++ b/src/RegisterPage.h @@ -5,6 +5,7 @@ #pragma once #include <QObject> +#include <QQmlEngine> #include <QString> #include <mtx/user_interactive.hpp> @@ -13,6 +14,7 @@ class RegisterPage : public QObject { Q_OBJECT + QML_ELEMENT Q_PROPERTY(QString error READ error NOTIFY errorChanged) Q_PROPERTY(QString hsError READ hsError NOTIFY hsErrorChanged) diff --git a/src/RoomDirectoryModel.h b/src/RoomDirectoryModel.h index 8a367e2e..a5103112 100644 --- a/src/RoomDirectoryModel.h +++ b/src/RoomDirectoryModel.h @@ -5,6 +5,7 @@ #pragma once #include <QAbstractListModel> +#include <QQmlEngine> #include <QString> #include <string> #include <vector> @@ -32,6 +33,7 @@ signals: class RoomDirectoryModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT Q_PROPERTY(bool loadingMoreRooms READ loadingMoreRooms NOTIFY loadingMoreRoomsChanged) Q_PROPERTY( diff --git a/src/UserDirectoryModel.h b/src/UserDirectoryModel.h index f0416ecf..ffa9ae93 100644 --- a/src/UserDirectoryModel.h +++ b/src/UserDirectoryModel.h @@ -5,6 +5,7 @@ #pragma once #include <QAbstractListModel> +#include <QQmlEngine> #include <QString> #include <string> #include <vector> @@ -26,6 +27,7 @@ signals: class UserDirectoryModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT Q_PROPERTY(bool searchingUsers READ searchingUsers NOTIFY searchingUsersChanged) diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 657a362d..301a1b67 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -6,6 +6,7 @@ #include <QAbstractListModel> #include <QProcessEnvironment> +#include <QQmlEngine> #include <QSettings> #include <QSharedPointer> @@ -23,6 +24,8 @@ class QVBoxLayout; class UserSettings final : public QObject { Q_OBJECT + QML_NAMED_ELEMENT(Settings) + QML_SINGLETON Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(bool messageHoverHighlight READ messageHoverHighlight WRITE setMessageHoverHighlight @@ -131,6 +134,24 @@ class UserSettings final : public QObject public: static QSharedPointer<UserSettings> instance(); static void initialize(std::optional<QString> profile); + static UserSettings *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance()); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance()->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance().get(), QJSEngine::CppOwnership); + return instance().get(); + } QSettings *qsettings() { return &settings; } @@ -431,9 +452,10 @@ private: static QSharedPointer<UserSettings> instance_; }; -class UserSettingsModel final : public QAbstractListModel +class UserSettingsModel : public QAbstractListModel { Q_OBJECT + QML_ELEMENT enum Indices { diff --git a/src/encryption/Olm.h b/src/encryption/Olm.h index f0e51070..726b9590 100644 --- a/src/encryption/Olm.h +++ b/src/encryption/Olm.h @@ -9,10 +9,13 @@ #include <mtx/events/encrypted.hpp> #include <mtxclient/crypto/client.hpp> +#include <QQmlEngine> + #include <CacheCryptoStructs.h> namespace olm { Q_NAMESPACE +QML_NAMED_ELEMENT(Olm) enum DecryptionErrorCode { diff --git a/src/encryption/SelfVerificationStatus.cpp b/src/encryption/SelfVerificationStatus.cpp index 6fa737d4..d9d3d787 100644 --- a/src/encryption/SelfVerificationStatus.cpp +++ b/src/encryption/SelfVerificationStatus.cpp @@ -29,6 +29,11 @@ SelfVerificationStatus::SelfVerificationStatus(QObject *o) Qt::UniqueConnection); cache::client()->markUserKeysOutOfDate({http::client()->user_id().to_string()}); }); + + connect(ChatPage::instance(), + &ChatPage::initializeEmptyViews, + this, + &SelfVerificationStatus::invalidate); } void diff --git a/src/encryption/SelfVerificationStatus.h b/src/encryption/SelfVerificationStatus.h index ea790c8b..c65fffd0 100644 --- a/src/encryption/SelfVerificationStatus.h +++ b/src/encryption/SelfVerificationStatus.h @@ -5,11 +5,15 @@ #pragma once #include <QObject> +#include <QQmlEngine> class SelfVerificationStatus final : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON + Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(bool hasSSSS READ hasSSSS NOTIFY hasSSSSChanged) diff --git a/src/encryption/VerificationManager.cpp b/src/encryption/VerificationManager.cpp index 802a8177..d1248755 100644 --- a/src/encryption/VerificationManager.cpp +++ b/src/encryption/VerificationManager.cpp @@ -15,6 +15,7 @@ VerificationManager::VerificationManager(TimelineViewManager *o) : QObject(o) , rooms_(o->rooms()) { + instance_ = this; } static bool diff --git a/src/encryption/VerificationManager.h b/src/encryption/VerificationManager.h index 7b32bc98..cdc8af30 100644 --- a/src/encryption/VerificationManager.h +++ b/src/encryption/VerificationManager.h @@ -6,6 +6,7 @@ #include <QHash> #include <QObject> +#include <QQmlEngine> #include <QSharedPointer> #include <mtx/events.hpp> @@ -21,8 +22,30 @@ class VerificationManager final : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON + public: - VerificationManager(TimelineViewManager *o = nullptr); + VerificationManager(TimelineViewManager *o); + + static VerificationManager *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance_); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance_->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership); + return instance_; + } Q_INVOKABLE void removeVerificationFlow(DeviceVerificationFlow *flow); void verifyUser(QString userid); @@ -45,4 +68,6 @@ private: QHash<QString, QSharedPointer<DeviceVerificationFlow>> dvList; bool isInitialSync_ = false; RoomlistModel *rooms_; + + inline static VerificationManager *instance_ = nullptr; }; diff --git a/src/main.cpp b/src/main.cpp index da67ca43..07397d62 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -346,7 +346,7 @@ main(int argc, char *argv[]) QStringLiteral(":/translations"))) app.installTranslator(&appTranslator); - MainWindow w; + MainWindow w(nullptr); // QQuickView w; // Move the MainWindow to the center diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index b04fd7a9..3c09d747 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -22,6 +22,7 @@ CommunitiesModel::CommunitiesModel(QObject *parent) , hiddenTagIds_{UserSettings::instance()->hiddenTags()} , mutedTagIds_{UserSettings::instance()->mutedTags()} { + instance_ = this; } QHash<int, QByteArray> diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index a90fa6a2..d0841f4b 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -6,6 +6,7 @@ #include <QAbstractListModel> #include <QHash> +#include <QQmlEngine> #include <QSortFilterProxyModel> #include <QString> #include <QStringList> @@ -21,6 +22,8 @@ class CommunitiesModel; class FilteredCommunitiesModel final : public QSortFilterProxyModel { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("Use Communities.filtered() to create a FilteredCommunitiesModel") public: explicit FilteredCommunitiesModel(CommunitiesModel *model, QObject *parent = nullptr); @@ -73,6 +76,9 @@ public: class CommunitiesModel final : public QAbstractListModel { Q_OBJECT + QML_NAMED_ELEMENT(Communities) + QML_SINGLETON + Q_PROPERTY(QString currentTagId READ currentTagId WRITE setCurrentTagId NOTIFY currentTagIdChanged RESET resetCurrentTagId) Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged) @@ -149,6 +155,26 @@ public: }; CommunitiesModel(QObject *parent = nullptr); + + static CommunitiesModel *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance_); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance_->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership); + return instance_; + } + QHash<int, QByteArray> roleNames() const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override { @@ -221,4 +247,6 @@ private: mtx::responses::UnreadNotifications dmUnreads{}; friend class FilteredCommunitiesModel; + + inline static CommunitiesModel *instance_ = nullptr; }; diff --git a/src/timeline/DelegateChooser.h b/src/timeline/DelegateChooser.h index c27f2c43..ac227382 100644 --- a/src/timeline/DelegateChooser.h +++ b/src/timeline/DelegateChooser.h @@ -19,6 +19,7 @@ class QQmlAdaptorModel; class DelegateChoice : public QObject { Q_OBJECT + QML_ELEMENT Q_CLASSINFO("DefaultProperty", "delegate") public: @@ -45,6 +46,7 @@ private: class DelegateChooser : public QQuickItem { Q_OBJECT + QML_ELEMENT Q_CLASSINFO("DefaultProperty", "choices") public: diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h index f03e6019..3cd65524 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h @@ -7,11 +7,13 @@ #include <QIODevice> #include <QImage> #include <QObject> +#include <QQmlEngine> #include <QSize> #include <QStringList> #include <QTimer> #include <QUrl> #include <QVariantList> + #include <deque> #include <memory> @@ -43,6 +45,10 @@ enum class MarkdownOverride class MediaUpload final : public QObject { Q_OBJECT + + QML_ELEMENT + QML_UNCREATABLE("") + Q_PROPERTY(int mediaType READ type NOTIFY mediaTypeChanged) // https://stackoverflow.com/questions/33422265/pass-qimage-to-qml/68554646#68554646 Q_PROPERTY(QUrl thumbnail READ thumbnailDataUrl NOTIFY thumbnailChanged) diff --git a/src/timeline/PresenceEmitter.h b/src/timeline/PresenceEmitter.h index e89fb316..09ad1301 100644 --- a/src/timeline/PresenceEmitter.h +++ b/src/timeline/PresenceEmitter.h @@ -5,6 +5,7 @@ #pragma once #include <QObject> +#include <QQmlEngine> #include <vector> @@ -15,10 +16,33 @@ class PresenceEmitter final : public QObject { Q_OBJECT + QML_NAMED_ELEMENT(Presence) + QML_SINGLETON + public: PresenceEmitter(QObject *p = nullptr) : QObject(p) { + instance_ = this; + } + + static PresenceEmitter *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance_); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance_->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership); + return instance_; } void sync(const std::vector<mtx::events::Event<mtx::events::presence::Presence>> &presences); @@ -28,4 +52,7 @@ public: signals: void presenceChanged(QString userid); + +private: + inline static PresenceEmitter *instance_ = nullptr; }; diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index ec41cc12..8d8d2977 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -909,6 +909,8 @@ FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *pare : QSortFilterProxyModel(parent) , roomlistmodel(model) { + instance_ = this; + this->sortByImportance = UserSettings::instance()->sortByImportance(); this->sortByAlphabet = UserSettings::instance()->sortByAlphabet(); setSourceModel(model); diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index c06ab67d..34bf3f9a 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -167,12 +167,36 @@ private: class FilteredRoomlistModel final : public QSortFilterProxyModel { Q_OBJECT + + QML_NAMED_ELEMENT(Rooms) + QML_SINGLETON + Q_PROPERTY( TimelineModel *currentRoom READ currentRoom NOTIFY currentRoomChanged RESET resetCurrentRoom) Q_PROPERTY(RoomPreview currentRoomPreview READ currentRoomPreview NOTIFY currentRoomChanged RESET resetCurrentRoom) public: FilteredRoomlistModel(RoomlistModel *model, QObject *parent = nullptr); + + static FilteredRoomlistModel *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance_); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance_->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership); + return instance_; + } + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; bool filterAcceptsRow(int sourceRow, const QModelIndex &) const override; @@ -249,4 +273,6 @@ private: FilterBy filterType = FilterBy::Nothing; QStringList hiddenTags, hiddenSpaces; bool hideDMs = false; + + inline static FilteredRoomlistModel *instance_ = nullptr; }; diff --git a/src/timeline/TimelineFilter.h b/src/timeline/TimelineFilter.h index 1c92c89a..658a8c57 100644 --- a/src/timeline/TimelineFilter.h +++ b/src/timeline/TimelineFilter.h @@ -4,6 +4,7 @@ #pragma once +#include <QQmlEngine> #include <QSortFilterProxyModel> #include <QString> @@ -14,6 +15,7 @@ class TimelineFilter : public QSortFilterProxyModel { Q_OBJECT + QML_ELEMENT Q_PROPERTY(QString filterByThread READ filterByThread WRITE setThreadId NOTIFY threadIdChanged) Q_PROPERTY(QString filterByContent READ filterByContent WRITE setContentFilter NOTIFY diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index a232b4ee..fd1a4396 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -11,6 +11,7 @@ #include <QTimer> #include <QVariant> +#include <mtx/responses/common.hpp> #include <mtxclient/http/errors.hpp> #include "CacheCryptoStructs.h" @@ -36,6 +37,7 @@ struct RelatedInfo; namespace qml_mtx_events { Q_NAMESPACE +QML_NAMED_ELEMENT(MtxEvent) enum EventType { @@ -193,6 +195,9 @@ class TimelineViewManager; class TimelineModel final : public QAbstractListModel { Q_OBJECT + QML_NAMED_ELEMENT(Room) + QML_UNCREATABLE("") + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) Q_PROPERTY(std::vector<QString> typingUsers READ typingUsers WRITE updateTypingUsers NOTIFY typingUsersChanged) diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index a3b91ce7..2f6553e5 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -96,29 +96,21 @@ TimelineViewManager::userColor(QString id, QColor background) TimelineViewManager::TimelineViewManager(CallManager *, ChatPage *parent) : QObject(parent) , rooms_(new RoomlistModel(this)) + , frooms_(new FilteredRoomlistModel(this->rooms_)) , communities_(new CommunitiesModel(this)) , verificationManager_(new VerificationManager(this)) , presenceEmitter(new PresenceEmitter(this)) { - static auto self = this; - qmlRegisterSingletonInstance("im.nheko", 1, 0, "TimelineManager", self); - qmlRegisterSingletonType<RoomlistModel>( - "im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * { - auto ptr = new FilteredRoomlistModel(self->rooms_); - - connect(self->communities_, - &CommunitiesModel::currentTagIdChanged, - ptr, - &FilteredRoomlistModel::updateFilterTag); - connect(self->communities_, - &CommunitiesModel::hiddenTagsChanged, - ptr, - &FilteredRoomlistModel::updateHiddenTagsAndSpaces); - return ptr; - }); - qmlRegisterSingletonInstance("im.nheko", 1, 0, "Communities", self->communities_); - qmlRegisterSingletonInstance("im.nheko", 1, 0, "VerificationManager", verificationManager_); - qmlRegisterSingletonInstance("im.nheko", 1, 0, "Presence", presenceEmitter); + instance_ = this; + + connect(this->communities_, + &CommunitiesModel::currentTagIdChanged, + frooms_, + &FilteredRoomlistModel::updateFilterTag); + connect(this->communities_, + &CommunitiesModel::hiddenTagsChanged, + frooms_, + &FilteredRoomlistModel::updateHiddenTagsAndSpaces); updateColorPalette(); diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h index 303e2af2..a4bc6c41 100644 --- a/src/timeline/TimelineViewManager.h +++ b/src/timeline/TimelineViewManager.h @@ -34,6 +34,9 @@ class TimelineViewManager final : public QObject { Q_OBJECT + QML_NAMED_ELEMENT(TimelineManager) + QML_SINGLETON + Q_PROPERTY( bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged) Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged) @@ -41,6 +44,25 @@ class TimelineViewManager final : public QObject public: TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr); + static TimelineViewManager *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance_); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance_->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance_, QJSEngine::CppOwnership); + return instance_; + } + void sync(const mtx::responses::Sync &sync_); VerificationManager *verificationManager() { return verificationManager_; } @@ -123,6 +145,7 @@ private: bool isConnected_ = true; RoomlistModel *rooms_ = nullptr; + FilteredRoomlistModel *frooms_ = nullptr; CommunitiesModel *communities_ = nullptr; // don't move this above the rooms_ @@ -130,4 +153,6 @@ private: PresenceEmitter *presenceEmitter = nullptr; QHash<QPair<QString, quint64>, QColor> userColors; + + inline static TimelineViewManager *instance_ = nullptr; }; diff --git a/src/ui/HiddenEvents.h b/src/ui/HiddenEvents.h index bb68e0fa..4f0d23b4 100644 --- a/src/ui/HiddenEvents.h +++ b/src/ui/HiddenEvents.h @@ -5,6 +5,7 @@ #pragma once #include <QObject> +#include <QQmlEngine> #include <QString> #include <QVariantList> @@ -13,6 +14,7 @@ class HiddenEvents : public QObject { Q_OBJECT + QML_ELEMENT Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged REQUIRED) Q_PROPERTY(QVariantList hiddenEvents READ hiddenEvents NOTIFY hiddenEventsChanged) public: diff --git a/src/ui/MxcAnimatedImage.h b/src/ui/MxcAnimatedImage.h index bc53e711..c9f89764 100644 --- a/src/ui/MxcAnimatedImage.h +++ b/src/ui/MxcAnimatedImage.h @@ -15,6 +15,7 @@ class MxcAnimatedImage : public QQuickItem { Q_OBJECT + QML_ELEMENT Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) Q_PROPERTY(bool animatable READ animatable NOTIFY animatableChanged) diff --git a/src/ui/MxcMediaProxy.h b/src/ui/MxcMediaProxy.h index 5c2eac33..d245dcae 100644 --- a/src/ui/MxcMediaProxy.h +++ b/src/ui/MxcMediaProxy.h @@ -8,6 +8,7 @@ #include <QMediaPlayer> #include <QObject> #include <QPointer> +#include <QQuickItem> #include <QString> #include <QUrl> #include <QVideoSink> @@ -21,6 +22,8 @@ class TimelineModel; class MxcMediaProxy : public QMediaPlayer { Q_OBJECT + QML_NAMED_ELEMENT(MxcMedia) + Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) diff --git a/src/ui/NhekoCursorShape.h b/src/ui/NhekoCursorShape.h index 84d56fad..123852f9 100644 --- a/src/ui/NhekoCursorShape.h +++ b/src/ui/NhekoCursorShape.h @@ -12,7 +12,7 @@ class NhekoCursorShape : public QQuickItem { Q_OBJECT - + QML_ELEMENT Q_PROPERTY( Qt::CursorShape cursorShape READ cursorShape WRITE setCursorShape NOTIFY cursorShapeChanged) diff --git a/src/ui/NhekoDropArea.h b/src/ui/NhekoDropArea.h index 91116844..46a02da5 100644 --- a/src/ui/NhekoDropArea.h +++ b/src/ui/NhekoDropArea.h @@ -7,6 +7,7 @@ class NhekoDropArea : public QQuickItem { Q_OBJECT + QML_ELEMENT Q_PROPERTY(QString roomid READ roomid WRITE setRoomid NOTIFY roomidChanged) public: NhekoDropArea(QQuickItem *parent = nullptr); diff --git a/src/ui/NhekoEventObserver.cpp b/src/ui/NhekoEventObserver.cpp deleted file mode 100644 index 713a0733..00000000 --- a/src/ui/NhekoEventObserver.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "NhekoEventObserver.h" - -#include <QMouseEvent> - -#include "Logging.h" - -NhekoEventObserver::NhekoEventObserver(QQuickItem *parent) - : QQuickItem(parent) -{ - setFiltersChildMouseEvents(true); -} - -bool -NhekoEventObserver::childMouseEventFilter(QQuickItem * /*item*/, QEvent *event) -{ - // nhlog::ui()->debug("Touched {}", item->metaObject()->className()); - - auto setTouched = [this](bool touched) { - if (touched != this->wasTouched_) { - this->wasTouched_ = touched; - emit wasTouchedChanged(); - } - }; - - // see - // https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quicktemplates2/qquickscrollview.cpp?id=7f29e89c26ae2babc358b1c4e6f965af6ec759f4#n471 - switch (event->type()) { - case QEvent::TouchBegin: - case QEvent::TouchEnd: - setTouched(true); - break; - - case QEvent::MouseButtonPress: - if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) { - setTouched(false); - } - break; - - case QEvent::MouseMove: - case QEvent::MouseButtonRelease: - if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) - setTouched(false); - break; - - case QEvent::HoverEnter: - case QEvent::HoverMove: - case QEvent::Wheel: - setTouched(false); - break; - - default: - break; - } - - return false; -} diff --git a/src/ui/NhekoEventObserver.h b/src/ui/NhekoEventObserver.h deleted file mode 100644 index 63739d4a..00000000 --- a/src/ui/NhekoEventObserver.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Nheko Contributors -// -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <QQuickItem> - -class NhekoEventObserver : public QQuickItem -{ - Q_OBJECT - - Q_PROPERTY(bool wasTouched READ wasTouched NOTIFY wasTouchedChanged) - -public: - explicit NhekoEventObserver(QQuickItem *parent = 0); - - bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; - -private: - bool wasTouched() { return wasTouched_; } - - bool wasTouched_ = false; - -signals: - void wasTouchedChanged(); -}; diff --git a/src/ui/NhekoGlobalObject.h b/src/ui/NhekoGlobalObject.h index b7a7a637..91210c54 100644 --- a/src/ui/NhekoGlobalObject.h +++ b/src/ui/NhekoGlobalObject.h @@ -7,6 +7,7 @@ #include <QFontDatabase> #include <QObject> #include <QPalette> +#include <QQmlEngine> #include <QWindow> #include "AliasEditModel.h" @@ -19,6 +20,9 @@ class Nheko final : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON + Q_PROPERTY(QPalette colors READ colors NOTIFY colorsChanged) Q_PROPERTY(QPalette inactiveColors READ inactiveColors NOTIFY colorsChanged) Q_PROPERTY(Theme theme READ theme NOTIFY colorsChanged) diff --git a/src/ui/RoomSummary.h b/src/ui/RoomSummary.h index c02ea5d5..8225f0ae 100644 --- a/src/ui/RoomSummary.h +++ b/src/ui/RoomSummary.h @@ -7,6 +7,7 @@ #include <optional> #include <QObject> +#include <QQmlEngine> #include <mtx/responses/public_rooms.hpp> @@ -25,6 +26,9 @@ class RoomSummary final : public QObject { Q_OBJECT + QML_ELEMENT + QML_UNCREATABLE("Please use joinRoom to create a room summary.") + Q_PROPERTY(QString reason READ reason WRITE setReason NOTIFY reasonChanged) Q_PROPERTY(QString roomid READ roomid NOTIFY loaded) diff --git a/src/ui/UIA.h b/src/ui/UIA.h index 7d23d88e..414cb804 100644 --- a/src/ui/UIA.h +++ b/src/ui/UIA.h @@ -5,6 +5,7 @@ #pragma once #include <QObject> +#include <QQmlEngine> #include <mtxclient/http/client.hpp> @@ -12,10 +13,31 @@ class UIA final : public QObject { Q_OBJECT + QML_ELEMENT + QML_SINGLETON + Q_PROPERTY(QString title READ title NOTIFY titleChanged) public: static UIA *instance(); + static UIA *create(QQmlEngine *qmlEngine, QJSEngine *) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(instance()); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance()->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance(), QJSEngine::CppOwnership); + return instance(); + } UIA(QObject *parent = nullptr) : QObject(parent) diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h index a880f320..d8e06aa1 100644 --- a/src/ui/UserProfile.h +++ b/src/ui/UserProfile.h @@ -6,6 +6,7 @@ #include <QAbstractListModel> #include <QObject> +#include <QQmlEngine> #include <QString> #include <QVector> #include <mtx/responses.hpp> @@ -16,6 +17,7 @@ namespace verification { Q_NAMESPACE +QML_NAMED_ELEMENT(VerificationStatus) enum Status { diff --git a/src/voip/CallManager.cpp b/src/voip/CallManager.cpp index feb06835..5479ba31 100644 --- a/src/voip/CallManager.cpp +++ b/src/voip/CallManager.cpp @@ -54,6 +54,27 @@ std::vector<std::string> getTurnURIs(const mtx::responses::TurnServer &turnServer); } +CallManager * +CallManager::create(QQmlEngine *qmlEngine, QJSEngine *) +{ + // The instance has to exist before it is used. We cannot replace it. + auto instance = ChatPage::instance()->callManager(); + Q_ASSERT(instance); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(qmlEngine->thread() == instance->thread()); + + // There can only be one engine accessing the singleton. + static QJSEngine *s_engine = nullptr; + if (s_engine) + Q_ASSERT(qmlEngine == s_engine); + else + s_engine = qmlEngine; + + QJSEngine::setObjectOwnership(instance, QJSEngine::CppOwnership); + return instance; +} + CallManager::CallManager(QObject *parent) : QObject(parent) , session_(WebRTCSession::instance()) diff --git a/src/voip/CallManager.h b/src/voip/CallManager.h index bbc7a903..e84b79c9 100644 --- a/src/voip/CallManager.h +++ b/src/voip/CallManager.h @@ -9,6 +9,7 @@ #include <QMediaPlayer> #include <QObject> +#include <QQmlEngine> #include <QString> #include <QStringList> #include <QTimer> @@ -29,6 +30,10 @@ class QUrl; class CallManager final : public QObject { Q_OBJECT + + QML_ELEMENT + QML_SINGLETON + Q_PROPERTY(bool haveCallInvite READ haveCallInvite NOTIFY newInviteState) Q_PROPERTY(bool isOnCall READ isOnCall NOTIFY newCallState) Q_PROPERTY(bool isOnCallOnOtherDevice READ isOnCallOnOtherDevice NOTIFY newCallDeviceState) @@ -49,6 +54,8 @@ class CallManager final : public QObject public: CallManager(QObject *); + static CallManager *create(QQmlEngine *qmlEngine, QJSEngine *); + bool haveCallInvite() const { return haveCallInvite_; } bool isOnCall() const { return (session_.state() != webrtc::State::DISCONNECTED); } bool isOnCallOnOtherDevice() const { return (isOnCallOnOtherDevice_ != ""); } diff --git a/src/voip/WebRTCSession.cpp b/src/voip/WebRTCSession.cpp index c40b39a4..ff459bf9 100644 --- a/src/voip/WebRTCSession.cpp +++ b/src/voip/WebRTCSession.cpp @@ -48,26 +48,26 @@ using webrtc::State; WebRTCSession::WebRTCSession() : devices_(CallDevices::instance()) { - qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, - "im.nheko", - 1, - 0, - "CallType", - QStringLiteral("Can't instantiate enum")); - - qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, - "im.nheko", - 1, - 0, - "ScreenShareType", - QStringLiteral("Can't instantiate enum")); - - qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, - "im.nheko", - 1, - 0, - "WebRTCState", - QStringLiteral("Can't instantiate enum")); + // qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, + // "im.nheko", + // 1, + // 0, + // "CallType", + // QStringLiteral("Can't instantiate enum")); + + // qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, + // "im.nheko", + // 1, + // 0, + // "ScreenShareType", + // QStringLiteral("Can't instantiate enum")); + + // qmlRegisterUncreatableMetaObject(webrtc::staticMetaObject, + // "im.nheko", + // 1, + // 0, + // "WebRTCState", + // QStringLiteral("Can't instantiate enum")); connect(this, &WebRTCSession::stateChanged, this, &WebRTCSession::setState); init(); diff --git a/src/voip/WebRTCSession.h b/src/voip/WebRTCSession.h index 82753372..3357bff7 100644 --- a/src/voip/WebRTCSession.h +++ b/src/voip/WebRTCSession.h @@ -8,6 +8,7 @@ #include <vector> #include <QObject> +#include <QQmlEngine> #include "mtx/events/voip.hpp" @@ -17,6 +18,7 @@ class QQuickItem; namespace webrtc { Q_NAMESPACE +QML_NAMED_ELEMENT(Voip) enum class CallType { |