File indexing completed on 2024-09-15 04:28:35
0001 // SPDX-FileCopyrightText: 2022 Nicolas Fella <nicolas.fella@gmx.de> 0002 // SPDX-License-Identifier: GPL-2.0-or-later 0003 0004 #pragma once 0005 0006 #include <QDBusContext> 0007 #include <QObject> 0008 0009 #include <QDBusArgument> 0010 #include <QList> 0011 #include <QString> 0012 #include <QVariantMap> 0013 0014 #include "models/roomlistmodel.h" 0015 #include "models/sortfilterroomlistmodel.h" 0016 0017 /** 0018 * The type of match. Value is important here as it is used for sorting 0019 * 0020 * Copied from KRunner/QueryMatch 0021 * 0022 * @sa KRunner/QueryMatch 0023 */ 0024 enum MatchType { 0025 NoMatch = 0, /**< Null match */ 0026 CompletionMatch = 10, /**< Possible completion for the data of the query */ 0027 PossibleMatch = 30, /**< Something that may match the query */ 0028 InformationalMatch = 50, /**< A purely informational, non-runnable match, 0029 such as the answer to a question or calculation. 0030 The data of the match will be converted to a string 0031 and set in the search field */ 0032 HelperMatch = 70, /**< A match that represents an action not directly related 0033 to activating the given search term, such as a search 0034 in an external tool or a command learning trigger. Helper 0035 matches tend to be generic to the query and should not 0036 be autoactivated just because the user hits "Enter" 0037 while typing. They must be explicitly selected to 0038 be activated, but unlike InformationalMatch cause 0039 an action to be triggered. */ 0040 ExactMatch = 100, /**< An exact match to the query */ 0041 }; 0042 0043 struct RemoteMatch { 0044 // sssuda{sv} 0045 QString id; 0046 QString text; 0047 QString iconName; 0048 MatchType type = MatchType::NoMatch; 0049 qreal relevance = 0; 0050 QVariantMap properties; 0051 }; 0052 0053 typedef QList<RemoteMatch> RemoteMatches; 0054 0055 struct RemoteAction { 0056 QString id; 0057 QString text; 0058 QString iconName; 0059 }; 0060 0061 typedef QList<RemoteAction> RemoteActions; 0062 0063 struct RemoteImage { 0064 // iiibiiay (matching notification spec image-data attribute) 0065 int width; 0066 int height; 0067 qsizetype rowStride; 0068 bool hasAlpha; 0069 int bitsPerSample; 0070 int channels; 0071 QByteArray data; 0072 }; 0073 0074 inline QDBusArgument &operator<<(QDBusArgument &argument, const RemoteMatch &match) 0075 { 0076 argument.beginStructure(); 0077 argument << match.id; 0078 argument << match.text; 0079 argument << match.iconName; 0080 argument << match.type; 0081 argument << match.relevance; 0082 argument << match.properties; 0083 argument.endStructure(); 0084 return argument; 0085 } 0086 0087 inline const QDBusArgument &operator>>(const QDBusArgument &argument, RemoteMatch &match) 0088 { 0089 argument.beginStructure(); 0090 argument >> match.id; 0091 argument >> match.text; 0092 argument >> match.iconName; 0093 uint type; 0094 argument >> type; 0095 match.type = static_cast<MatchType>(type); 0096 argument >> match.relevance; 0097 argument >> match.properties; 0098 argument.endStructure(); 0099 0100 return argument; 0101 } 0102 0103 inline QDBusArgument &operator<<(QDBusArgument &argument, const RemoteAction &action) 0104 { 0105 argument.beginStructure(); 0106 argument << action.id; 0107 argument << action.text; 0108 argument << action.iconName; 0109 argument.endStructure(); 0110 return argument; 0111 } 0112 0113 inline const QDBusArgument &operator>>(const QDBusArgument &argument, RemoteAction &action) 0114 { 0115 argument.beginStructure(); 0116 argument >> action.id; 0117 argument >> action.text; 0118 argument >> action.iconName; 0119 argument.endStructure(); 0120 return argument; 0121 } 0122 0123 inline QDBusArgument &operator<<(QDBusArgument &argument, const RemoteImage &image) 0124 { 0125 argument.beginStructure(); 0126 argument << image.width; 0127 argument << image.height; 0128 argument << image.rowStride; 0129 argument << image.hasAlpha; 0130 argument << image.bitsPerSample; 0131 argument << image.channels; 0132 argument << image.data; 0133 argument.endStructure(); 0134 return argument; 0135 } 0136 0137 inline const QDBusArgument &operator>>(const QDBusArgument &argument, RemoteImage &image) 0138 { 0139 argument.beginStructure(); 0140 argument >> image.width; 0141 argument >> image.height; 0142 argument >> image.rowStride; 0143 argument >> image.hasAlpha; 0144 argument >> image.bitsPerSample; 0145 argument >> image.channels; 0146 argument >> image.data; 0147 argument.endStructure(); 0148 return argument; 0149 } 0150 0151 Q_DECLARE_METATYPE(RemoteMatch) 0152 Q_DECLARE_METATYPE(RemoteMatches) 0153 Q_DECLARE_METATYPE(RemoteAction) 0154 Q_DECLARE_METATYPE(RemoteActions) 0155 Q_DECLARE_METATYPE(RemoteImage) 0156 0157 /** 0158 * @class Runner 0159 * 0160 * A class to define the NeoChat KRunner plugin. 0161 * 0162 * @sa KRunner 0163 */ 0164 class Runner : public QObject, protected QDBusContext 0165 { 0166 Q_OBJECT 0167 Q_CLASSINFO("D-Bus Interface", "org.kde.krunner1") 0168 QML_ELEMENT 0169 QML_SINGLETON 0170 0171 Q_PROPERTY(RoomListModel *roomListModel READ roomListModel WRITE setRoomListModel NOTIFY roomListModelChanged) 0172 public: 0173 static Runner *create(QQmlEngine *engine, QJSEngine *) 0174 { 0175 static Runner instance; 0176 engine->setObjectOwnership(&instance, QQmlEngine::CppOwnership); 0177 return &instance; 0178 } 0179 0180 /** 0181 * @brief Return a list of KRunner actions. 0182 * 0183 * @note It's always empty; nothing is broken. 0184 */ 0185 Q_SCRIPTABLE RemoteActions Actions(); 0186 0187 /** 0188 * @brief Return a list of room matches for a search. 0189 */ 0190 Q_SCRIPTABLE RemoteMatches Match(const QString &searchTerm); 0191 0192 /** 0193 * @brief Handle action calls. 0194 */ 0195 Q_SCRIPTABLE void Run(const QString &id, const QString &actionId); 0196 0197 void setRoomListModel(RoomListModel *roomListModel); 0198 RoomListModel *roomListModel() const; 0199 0200 Q_SIGNALS: 0201 void roomListModelChanged(); 0202 0203 private: 0204 RemoteImage serializeImage(const QImage &image); 0205 0206 SortFilterRoomListModel m_model; 0207 RoomListModel m_sourceModel; 0208 Runner(); 0209 };