1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org> |
4 | SPDX-FileCopyrightText: 2005-2008 David Faure <faure@kde.org> |
5 | SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org> |
6 | |
7 | SPDX-License-Identifier: LGPL-2.0-only |
8 | */ |
9 | |
10 | #ifndef KSYCOCA_H |
11 | #define KSYCOCA_H |
12 | |
13 | #include <kservice_export.h> |
14 | #include <ksycocatype.h> |
15 | |
16 | #include <QObject> |
17 | #include <QStringList> |
18 | |
19 | class QDataStream; |
20 | class KSycocaFactory; |
21 | class KSycocaFactoryList; |
22 | class KSycocaPrivate; |
23 | |
24 | /*! |
25 | * \macro KBUILDSYCOCA_EXENAME |
26 | * \relates KSycoca |
27 | * |
28 | * Executable name of the kbuildsycoca program |
29 | */ |
30 | #define KBUILDSYCOCA_EXENAME "kbuildsycoca6" |
31 | |
32 | /*! |
33 | * \class KSycoca |
34 | * \inmodule KService |
35 | * |
36 | * \brief Read-only SYstem COnfiguration CAche. |
37 | */ |
38 | class KSERVICE_EXPORT KSycoca : public QObject |
39 | { |
40 | Q_OBJECT |
41 | // Q_CLASSINFO("D-Bus Interface", "org.kde.KSycoca") |
42 | |
43 | protected: |
44 | /*! |
45 | * \internal |
46 | * Building database |
47 | */ |
48 | explicit KSycoca(bool /* buildDatabase */); |
49 | |
50 | public: |
51 | KSycoca(); |
52 | |
53 | /*! |
54 | * Get or create the only instance of KSycoca (read-only) |
55 | */ |
56 | static KSycoca *self(); |
57 | |
58 | ~KSycoca() override; |
59 | |
60 | /*! |
61 | * Returns the compiled-in version, i.e. the one used when writing a new ksycoca |
62 | */ |
63 | static int version(); |
64 | |
65 | /*! |
66 | * Returns \c true if the ksycoca database is available |
67 | * |
68 | * This is usually the case, except if KDE isn't installed yet, |
69 | * or before kded is started. |
70 | */ |
71 | static bool isAvailable(); |
72 | |
73 | /*! |
74 | * \internal - called by factories in read-only mode |
75 | * This is how factories get a stream to an entry |
76 | */ |
77 | QDataStream *findEntry(int offset, KSycocaType &type); // KF6: make it private |
78 | /*! |
79 | * \internal - called by factories in read-only mode |
80 | * Returns stream(), but positioned for reading this factory, 0 on error. |
81 | */ |
82 | QDataStream *findFactory(KSycocaFactoryId id); // KF6: make it private |
83 | |
84 | /*! |
85 | * \internal - returns absolute file path of the database |
86 | * |
87 | * For the global database type, the database is searched under |
88 | * the 'share/ksycoca' install path. |
89 | * Otherwise, the value from the environment variable KDESYCOCA |
90 | * is returned if set. If not set the path is built based on |
91 | * QStandardPaths cache save location, typically ~/.cache on Unix. |
92 | * |
93 | * Since 5.15, the filename includes language and a sha1 of the directories |
94 | * in GenericDataLocation, i.e. the directories with the desktop files. |
95 | * This allows to have one database per setup, when using different install prefixes |
96 | * or when switching languages. |
97 | */ |
98 | static QString absoluteFilePath(); |
99 | |
100 | /*! |
101 | * \internal - returns all directories with information |
102 | * stored inside sycoca. |
103 | */ |
104 | QStringList allResourceDirs(); // KF6: make it private |
105 | |
106 | /*! |
107 | * \internal - add a factory |
108 | */ |
109 | void addFactory(KSycocaFactory *); // KF6: make it private |
110 | |
111 | /*! |
112 | * \internal |
113 | * @return true if building (i.e. if a KBuildSycoca); |
114 | */ |
115 | virtual bool isBuilding(); |
116 | |
117 | /*! |
118 | * Disables automatic rebuilding of the cache on service file changes. |
119 | * |
120 | * Be extremely careful when using this. Only threads that definitely have no use for |
121 | * automatic reloading should use this. Specifically shared runner threads (as seen in |
122 | * the threadweaver framework) can avoid claiming persistent resources this way |
123 | * (e.g. inotify instances on Linux). |
124 | */ |
125 | static void disableAutoRebuild(); |
126 | |
127 | /*! |
128 | * A read error occurs. |
129 | * \internal |
130 | */ |
131 | static void flagError(); |
132 | |
133 | /*! |
134 | * Ensures the ksycoca database is up to date. |
135 | * |
136 | * If the database was modified by another process, close it, so the next use reopens it. |
137 | * If the desktop files have been modified more recently than the database, update it. |
138 | * |
139 | * Update the sycoca file from the files on disk (e.g. desktop files or mimeapps.list). |
140 | * You don't normally have to call this because the next use of KSycoca |
141 | * (e.g. via KMimeTypeTrader, KService etc.) will notice that the sycoca |
142 | * database is out of date, by looking a directory modification times. |
143 | * In addition, in a full KDE session, kded monitors directories to detect changes. |
144 | * |
145 | * This is however useful for GUIs that allow to create a new desktop file |
146 | * and then want to ensure it is available immediately in KSycoca. |
147 | * This is also useful after modifying a mimeapps.list file. |
148 | * |
149 | * KBuildSycocaProgressDialog can also be used instead of this method, in GUI apps. |
150 | * |
151 | * \since 5.15 |
152 | */ |
153 | void ensureCacheValid(); // Warning for kservice code: this can delete all the factories. |
154 | |
155 | /*! |
156 | * Sets up a minimal applications.menu file in the appropriate location. |
157 | * |
158 | * This is useful when writing unit tests that interact with KService. |
159 | * |
160 | * You should call QStandardPaths::setTestModeEnabled(true) before calling this. |
161 | * |
162 | * \since 6.0 |
163 | */ |
164 | static void (); |
165 | |
166 | /*! |
167 | * Connect to this to get notified when the database changes. |
168 | * |
169 | * Example: after creating a .desktop file in KOpenWithDialog, it |
170 | * must wait until kbuildsycoca6 finishes until the KService::Ptr is available. |
171 | * Other examples: anything that displays a list of apps or plugins to the user |
172 | * and which is always visible (otherwise querying sycoca before showing |
173 | * could be enough). |
174 | */ |
175 | Q_SIGNAL void databaseChanged(); |
176 | |
177 | protected: |
178 | // \internal used by kbuildsycoca |
179 | KSycocaFactoryList *factories(); |
180 | |
181 | // \internal used by factories and kbuildsycoca |
182 | QDataStream *&stream(); |
183 | friend class KSycocaFactory; |
184 | friend class KSycocaDict; |
185 | |
186 | void connectNotify(const QMetaMethod &signal) override; |
187 | |
188 | private: |
189 | /*! |
190 | * Clear all caches related to ksycoca contents. |
191 | * \internal only used by kded and kbuildsycoca. |
192 | */ |
193 | static void clearCaches(); |
194 | |
195 | KSERVICE_NO_EXPORT bool needsRebuild(); |
196 | |
197 | friend class KBuildSycoca; |
198 | friend class Kded; |
199 | friend class KSycocaPrivate; |
200 | friend class KSycocaXdgDirsTest; |
201 | |
202 | Q_DISABLE_COPY(KSycoca) |
203 | KSycocaPrivate *const d; |
204 | }; |
205 | |
206 | #endif |
207 | |