File indexing completed on 2024-10-06 03:41:00

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org>
0004     SPDX-FileCopyrightText: 2005-2008 David Faure <faure@kde.org>
0005     SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-only
0008 */
0009 
0010 #ifndef KSYCOCA_H
0011 #define KSYCOCA_H
0012 
0013 #include <kservice_export.h>
0014 #include <ksycocatype.h>
0015 
0016 #include <QObject>
0017 #include <QStringList>
0018 
0019 class QDataStream;
0020 class KSycocaFactory;
0021 class KSycocaFactoryList;
0022 class KSycocaPrivate;
0023 
0024 /**
0025  * Executable name of the kbuildsycoca program
0026  */
0027 #define KBUILDSYCOCA_EXENAME "kbuildsycoca6"
0028 
0029 /**
0030  * @internal
0031  * Read-only SYstem COnfiguration CAche
0032  */
0033 class KSERVICE_EXPORT KSycoca : public QObject
0034 {
0035     Q_OBJECT
0036     // Q_CLASSINFO("D-Bus Interface", "org.kde.KSycoca")
0037 
0038 protected:
0039     /**
0040      * @internal
0041      * Building database
0042      */
0043     explicit KSycoca(bool /* buildDatabase */);
0044 
0045 public:
0046     /**
0047      * Read-only database
0048      */
0049     KSycoca();
0050 
0051     /**
0052      * Get or create the only instance of KSycoca (read-only)
0053      */
0054     static KSycoca *self();
0055 
0056     ~KSycoca() override;
0057 
0058     /**
0059      * @return the compiled-in version, i.e. the one used when writing a new ksycoca
0060      */
0061     static int version();
0062 
0063     /**
0064      * @return true if the ksycoca database is available
0065      * This is usually the case, except if KDE isn't installed yet,
0066      * or before kded is started.
0067      */
0068     static bool isAvailable();
0069 
0070     /**
0071      * @internal - called by factories in read-only mode
0072      * This is how factories get a stream to an entry
0073      */
0074     QDataStream *findEntry(int offset, KSycocaType &type); // KF6: make it private
0075     /**
0076      * @internal - called by factories in read-only mode
0077      * Returns stream(), but positioned for reading this factory, 0 on error.
0078      */
0079     QDataStream *findFactory(KSycocaFactoryId id); // KF6: make it private
0080 
0081     /**
0082      * @internal - returns absolute file path of the database
0083      *
0084      * For the global database type, the database is searched under
0085      * the 'share/ksycoca' install path.
0086      * Otherwise, the value from the environment variable KDESYCOCA
0087      * is returned if set. If not set the path is built based on
0088      * QStandardPaths cache save location, typically ~/.cache on Unix.
0089      *
0090      * Since 5.15, the filename includes language and a sha1 of the directories
0091      * in GenericDataLocation, i.e. the directories with the desktop files.
0092      * This allows to have one database per setup, when using different install prefixes
0093      * or when switching languages.
0094      */
0095     static QString absoluteFilePath();
0096 
0097     /**
0098      * @internal - returns all directories with information
0099      * stored inside sycoca.
0100      */
0101     QStringList allResourceDirs(); // KF6: make it private
0102 
0103     /**
0104      * @internal - add a factory
0105      */
0106     void addFactory(KSycocaFactory *); // KF6: make it private
0107 
0108     /**
0109      * @internal
0110      * @return true if building (i.e. if a KBuildSycoca);
0111      */
0112     virtual bool isBuilding();
0113 
0114     /**
0115      * Disables automatic rebuilding of the cache on service file changes.
0116      * Be extremely careful when using this. Only threads that definitely have no use for
0117      * automatic reloading should use this. Specifically shared runner threads (as seen in
0118      * the threadweaver framework) can avoid claiming persistent resources this way
0119      * (e.g. inotify instances on Linux).
0120      */
0121     static void disableAutoRebuild();
0122 
0123     /**
0124      * A read error occurs.
0125      * @internal
0126      */
0127     static void flagError();
0128 
0129     /**
0130      * Ensures the ksycoca database is up to date.
0131      * If the database was modified by another process, close it, so the next use reopens it.
0132      * If the desktop files have been modified more recently than the database, update it.
0133      *
0134      * Update the sycoca file from the files on disk (e.g. desktop files or mimeapps.list).
0135      * You don't normally have to call this because the next use of KSycoca
0136      * (e.g. via KMimeTypeTrader, KService etc.) will notice that the sycoca
0137      * database is out of date, by looking a directory modification times.
0138      * In addition, in a full KDE session, kded monitors directories to detect changes.
0139      *
0140      * This is however useful for GUIs that allow to create a new desktop file
0141      * and then want to ensure it is available immediately in KSycoca.
0142      * This is also useful after modifying a mimeapps.list file.
0143      *
0144      * KBuildSycocaProgressDialog can also be used instead of this method, in GUI apps.
0145      *
0146      * @since 5.15
0147      */
0148     void ensureCacheValid(); // Warning for kservice code: this can delete all the factories.
0149 
0150     /**
0151      * Sets up a minimal applications.menu file in the appropriate location.
0152      * This is useful when writing unit tests that interact with KService.
0153      *
0154      * You should call QStandardPaths::setTestModeEnabled(true) before calling this.
0155      *
0156      * @since 6.0
0157      */
0158     static void setupTestMenu();
0159 
0160     /**
0161      * Connect to this to get notified when the database changes.
0162      *
0163      * Example: after creating a .desktop file in KOpenWithDialog, it
0164      * must wait until kbuildsycoca6 finishes until the KService::Ptr is available.
0165      * Other examples: anything that displays a list of apps or plugins to the user
0166      * and which is always visible (otherwise querying sycoca before showing
0167      * could be enough).
0168      */
0169     Q_SIGNAL void databaseChanged();
0170 
0171 protected:
0172     // @internal used by kbuildsycoca
0173     KSycocaFactoryList *factories();
0174 
0175     // @internal used by factories and kbuildsycoca
0176     QDataStream *&stream();
0177     friend class KSycocaFactory;
0178     friend class KSycocaDict;
0179 
0180     void connectNotify(const QMetaMethod &signal) override;
0181 
0182 private:
0183     /**
0184      * Clear all caches related to ksycoca contents.
0185      * @internal only used by kded and kbuildsycoca.
0186      */
0187     static void clearCaches();
0188 
0189     KSERVICE_NO_EXPORT bool needsRebuild();
0190 
0191     friend class KBuildSycoca;
0192     friend class Kded;
0193     friend class KSycocaPrivate;
0194     friend class KSycocaXdgDirsTest;
0195 
0196     Q_DISABLE_COPY(KSycoca)
0197     KSycocaPrivate *const d;
0198 };
0199 
0200 #endif