File indexing completed on 2023-09-24 04:14:58

0001 /*
0002     SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <aseigo@kde.org>
0003     SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef PLASMA_THEME_H
0009 #define PLASMA_THEME_H
0010 
0011 #include <QFont>
0012 #include <QGuiApplication>
0013 #include <QObject>
0014 
0015 #include <plasma/plasma_export.h>
0016 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 94)
0017 #include <KPluginInfo>
0018 #endif
0019 #include <KSharedConfig>
0020 
0021 class KPluginMetaData;
0022 
0023 namespace Plasma
0024 {
0025 class ThemePrivate;
0026 class SvgPrivate;
0027 
0028 /**
0029  * @class Theme plasma/theme.h <Plasma/Theme>
0030  *
0031  * @short Interface to the Plasma theme
0032  *
0033  *
0034  * Plasma::Theme provides access to a common and standardized set of graphic
0035  * elements stored in SVG format. This allows artists to create single packages
0036  * of SVGs that will affect the look and feel of all workspace components.
0037  *
0038  * Plasma::Svg uses Plasma::Theme internally to locate and load the appropriate
0039  * SVG data. Alternatively, Plasma::Theme can be used directly to retrieve
0040  * file system paths to SVGs by name.
0041  */
0042 class PLASMA_EXPORT Theme : public QObject
0043 {
0044     Q_OBJECT
0045 
0046     Q_PROPERTY(QString themeName READ themeName NOTIFY themeChanged)
0047     Q_PROPERTY(bool useGlobalSettings READ useGlobalSettings NOTIFY themeChanged)
0048     Q_PROPERTY(QString wallpaperPath READ wallpaperPath NOTIFY themeChanged)
0049 
0050     // fonts
0051     Q_PROPERTY(QFont defaultFont READ defaultFont NOTIFY defaultFontChanged)
0052     Q_PROPERTY(QFont smallestFont READ smallestFont NOTIFY smallestFontChanged)
0053 
0054     // stylesheet
0055     Q_PROPERTY(QString styleSheet READ styleSheet NOTIFY themeChanged)
0056 
0057     Q_PROPERTY(QPalette palette READ palette NOTIFY themeChanged)
0058 
0059 public:
0060     enum ColorRole {
0061         TextColor = 0, /**<  the text color to be used by items resting on the background */
0062         BackgroundColor = 1, /**< the default background color */
0063         HighlightColor = 2, /**<  the text highlight color to be used by items resting
0064                                    on the background */
0065         HoverColor = 3, /**< color for hover effect on view */
0066         FocusColor = 4, /**< color for focus effect on view */
0067         LinkColor = 5, /**< color for clickable links */
0068         VisitedLinkColor = 6, /**< color visited clickable links */
0069         HighlightedTextColor = 7, /**< color contrasting with HighlightColor, to be used for instance with */
0070         PositiveTextColor = 8, /**< color of foreground objects with a "positive message" connotation (usually green) */
0071         NeutralTextColor = 9, /**< color of foreground objects with a "neutral message" connotation (usually yellow) */
0072         NegativeTextColor = 10, /**< color of foreground objects with a "negative message" connotation (usually red) */
0073         DisabledTextColor = 11, /**< color of disabled text @since 5.64 */
0074     };
0075 
0076     enum ColorGroup {
0077         NormalColorGroup = 0,
0078         ButtonColorGroup = 1,
0079         ViewColorGroup = 2,
0080         ComplementaryColorGroup = 3,
0081         HeaderColorGroup,
0082         ToolTipColorGroup,
0083     };
0084     Q_ENUM(ColorGroup)
0085 
0086     /**
0087      * Default constructor. It will be the global theme configured in plasmarc
0088      * @param parent the parent object
0089      */
0090     explicit Theme(QObject *parent = nullptr);
0091 
0092     /**
0093      * Construct a theme. It will be a custom theme instance of themeName.
0094      * @param themeName the name of the theme to create
0095      * @param parent the parent object
0096      * @since 4.3
0097      */
0098     explicit Theme(const QString &themeName, QObject *parent = nullptr);
0099 
0100     ~Theme() override;
0101 
0102     /**
0103      * Sets the current theme being used.
0104      */
0105     void setThemeName(const QString &themeName);
0106 
0107     /**
0108      * @return the name of the theme.
0109      */
0110     QString themeName() const;
0111 
0112     /**
0113      * Retrieve the path for an SVG image in the current theme.
0114      *
0115      * @param name the name of the file in the theme directory (without the
0116      *           ".svg" part or a leading slash)
0117      * @return the full path to the requested file for the current theme
0118      */
0119     QString imagePath(const QString &name) const;
0120 
0121     /**
0122      * Retrieves the default wallpaper associated with this theme.
0123      *
0124      * @param size the target height and width of the wallpaper; if an invalid size
0125      *           is passed in, then a default size will be provided instead.
0126      * @return the full path to the wallpaper image
0127      */
0128     QString wallpaperPath(const QSize &size = QSize()) const;
0129 
0130     Q_INVOKABLE QString wallpaperPathForSize(int width = -1, int height = -1) const;
0131 
0132     /**
0133      * Checks if this theme has an image named in a certain way
0134      *
0135      * @param name the name of the file in the theme directory (without the
0136      *           ".svg" part or a leading slash)
0137      * @return true if the image exists for this theme
0138      */
0139     bool currentThemeHasImage(const QString &name) const;
0140 
0141     /**
0142      * Returns the color scheme configurationthat goes along this theme.
0143      * This can be used with KStatefulBrush and KColorScheme to determine
0144      * the proper colours to use along with the visual elements in this theme.
0145      */
0146     KSharedConfigPtr colorScheme() const;
0147 
0148     /**
0149      * Returns the text color to be used by items resting on the background
0150      *
0151      * @param role which role (usage pattern) to get the color for
0152      * @param group which group we want a color of
0153      */
0154     QColor color(ColorRole role, ColorGroup group = NormalColorGroup) const;
0155 
0156     /**
0157      * Tells the theme whether to follow the global settings or use application
0158      * specific settings
0159      *
0160      * @param useGlobal pass in true to follow the global settings
0161      */
0162     void setUseGlobalSettings(bool useGlobal);
0163 
0164     /**
0165      * @return true if the global settings are followed, false if application
0166      * specific settings are used.
0167      */
0168     bool useGlobalSettings() const;
0169 
0170     /**
0171      * Provides a Plasma::Theme-themed stylesheet for hybrid (web / native Plasma) widgets.
0172      *
0173      * You can use this method to retrieve a basic default stylesheet, or to theme your
0174      * custom stylesheet you use for example in Plasma::WebView. The QString you can pass
0175      * into this method does not have to be a valid stylesheet, in fact you can use this
0176      * method to replace color placeholders with the theme's color in any QString.
0177      *
0178      * In order to use this method with a custom stylesheet, just put for example %textcolor
0179      * in your QString and it will be replaced with the theme's text (or foreground) color.
0180      *
0181      * Just like in many other methods for retrieving theme information, do not forget to
0182      * update your stylesheet upon the themeChanged() signal.
0183      *
0184      * The following tags will be replaced by corresponding colors from Plasma::Theme:
0185      *
0186      * %textcolor
0187      * %backgroundcolor
0188      * %buttonbackgroundcolor
0189      *
0190      * %link
0191      * %activatedlink
0192      * %hoveredlink
0193      * %visitedlink
0194      *
0195      * %fontfamily
0196      * %fontsize
0197      * %smallfontsize
0198      *
0199      * @param css a stylesheet to theme, leave empty for a default stylesheet containing
0200      * theming for some commonly used elements, body text and links, for example.
0201      *
0202      * @return a piece of CSS that sets the most commonly used style elements to a theme
0203      * matching Plasma::Theme.
0204      *
0205      * @since 4.5
0206      */
0207     QString styleSheet(const QString &css = QString()) const;
0208 
0209     /**
0210      * Returns a QPalette with the colors set as defined by the theme.
0211      * @since 5.68
0212      */
0213     QPalette palette() const;
0214 
0215     /**
0216      * This is an overloaded member provided to check with file timestamp
0217      * where cache is still valid.
0218      *
0219      * @param key the name to use in the cache for this image
0220      * @param pix the pixmap object to populate with the resulting data if found
0221      * @param lastModified if non-zero, the time stamp is also checked on the file,
0222      *                     and must be newer than the timestamp to be loaded
0223      *
0224      * @note Since KF 5.75, a lastModified value of 0 is deprecated. If used, it
0225      *       will now always return false. Use a proper file timestamp instead
0226      *       so modification can be properly tracked.
0227      *
0228      * @return true when pixmap was found and loaded from cache, false otherwise
0229      * @since 4.3
0230      **/
0231     bool findInCache(const QString &key, QPixmap &pix, unsigned int lastModified = 0);
0232 
0233     /**
0234      * Insert specified pixmap into the cache.
0235      * If the cache already contains pixmap with the specified key then it is
0236      * overwritten.
0237      *
0238      * @param key the name to use in the cache for this pixmap
0239      * @param pix the pixmap data to store in the cache
0240      **/
0241     void insertIntoCache(const QString &key, const QPixmap &pix);
0242 
0243     /**
0244      * Insert specified pixmap into the cache.
0245      * If the cache already contains pixmap with the specified key then it is
0246      * overwritten.
0247      * The actual insert is delayed for optimization reasons and the id
0248      * parameter is used to discard repeated inserts in the delay time, useful
0249      * when for instance the graphics to insert comes from a quickly resizing
0250      * object: the frames between the start and destination sizes aren't
0251      * useful in the cache and just cause overhead.
0252      *
0253      * @param key the name to use in the cache for this pixmap
0254      * @param pix the pixmap data to store in the cache
0255      * @param id a name that identifies the caller class of this function in an unique fashion.
0256      *           This is needed to limit disk writes of the cache.
0257      *           If an image with the same id changes quickly,
0258      *           only the last size where insertIntoCache was called is actually stored on disk
0259      * @since 4.3
0260      **/
0261     void insertIntoCache(const QString &key, const QPixmap &pix, const QString &id);
0262 
0263     /**
0264      * Sets the maximum size of the cache (in kilobytes). If cache gets bigger
0265      * the limit then some entries are removed
0266      * Setting cache limit to 0 disables automatic cache size limiting.
0267      *
0268      * Note that the cleanup might not be done immediately, so the cache might
0269      *  temporarily (for a few seconds) grow bigger than the limit.
0270      **/
0271     void setCacheLimit(int kbytes);
0272 
0273 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 78)
0274     /**
0275      * Tries to load the rect of a sub element from a disk cache
0276      *
0277      * @param image path of the image we want to check
0278      * @param element sub element we want to retrieve
0279      * @param rect output parameter of the element rect found in cache
0280      *           if not found or if we are sure it doesn't exist it will be QRect()
0281      * @return true if the element was found in cache or if we are sure the element doesn't exist
0282      **/
0283     PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
0284     bool findInRectsCache(const QString &image, const QString &element, QRectF &rect) const;
0285 
0286     /**
0287      * Returns a list of all keys of cached rects for the given image.
0288      *
0289      * @param image path of the image for which the keys should be returned
0290      *
0291      * @return a QStringList whose elements are the entry keys in the rects cache
0292      *
0293      * @since 4.6
0294      */
0295     PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
0296     QStringList listCachedRectKeys(const QString &image) const;
0297 
0298     /**
0299      * Inserts a rectangle of a sub element of an image into a disk cache
0300      *
0301      * @param image path of the image we want to insert information
0302      * @param element sub element we want insert the rect
0303      * @param rect element rectangle
0304      **/
0305     PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
0306     void insertIntoRectsCache(const QString &image, const QString &element, const QRectF &rect);
0307 
0308     /**
0309      * Discards all the information about a given image from the rectangle disk cache
0310      *
0311      * @param image the path to the image the cache is associated with
0312      **/
0313     PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
0314     void invalidateRectsCache(const QString &image);
0315 
0316     /**
0317      * Frees up memory used by cached information for a given image without removing
0318      * the permanent record of it on disk.
0319      * @see invalidateRectsCache
0320      *
0321      * @param image the path to the image the cache is associated with
0322      */
0323     PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
0324     void releaseRectsCache(const QString &image);
0325 #endif
0326 
0327 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 67)
0328     /**
0329      * @return plugin info for this theme, with information such as
0330      * name, description, author, website etc
0331      * @since 5.0
0332      *
0333      * @deprecated since 5.67, use KPluginMetaData
0334      */
0335     PLASMA_DEPRECATED_VERSION(5, 67, "Use KPluginMetaData metadata()")
0336     KPluginInfo pluginInfo() const;
0337 #endif
0338 
0339     /**
0340      * @return plugin metadata for this theme, with information such as
0341      * name, description, author, website etc
0342      * @since 5.95
0343      */
0344     KPluginMetaData metadata() const;
0345 
0346     /**
0347      * @return The default application font
0348      * @since 5.0
0349      */
0350     QFont defaultFont() const;
0351 
0352     /**
0353      * @return The smallest readable font
0354      * @since 5.0
0355      */
0356     QFont smallestFont() const;
0357 
0358     /** This method allows Plasma to enable and disable the background
0359      * contrast effect for a given theme, improving readability. The
0360      * value is read from the "enabled" key in the "ContrastEffect"
0361      * group in the Theme's metadata file.
0362      * The configuration in the metadata.desktop file of the theme
0363      * could look like this (for a lighter background):
0364      * \code
0365      * [ContrastEffect]
0366      * enabled=true
0367      * contrast=0.45
0368      * intensity=0.45
0369      * saturation=1.7
0370      * \endcode
0371      * @return Whether or not to enable the contrasteffect
0372      * @since 5.0
0373      */
0374     bool backgroundContrastEnabled() const;
0375 
0376     /** This method allows Plasma to enable and disable the adaptive
0377      * transparency option of the panel, which allows user to decide
0378      * whether the panel should be always transparent, always opaque
0379      * or only opaque when a window is maximized.
0380      * The configuration in the metadata.desktop file of the theme
0381      * could look like this (for a lighter background):
0382      * \code
0383      * [AdaptiveTransparency]
0384      * enabled=true
0385      * \endcode
0386      * @return Whether or not to enable the adaptive transparency
0387      * @since 5.20
0388      */
0389     bool adaptiveTransparencyEnabled() const;
0390 
0391     /** This method allows Plasma to set a background contrast effect
0392      * for a given theme, improving readability. The value is read
0393      * from the "contrast" key in the "ContrastEffect" group in the
0394      * Theme's metadata file.
0395      * @return The contrast provided to the contrasteffect
0396      * @since 5.0
0397      * @see backgroundContrastEnabled
0398      */
0399     qreal backgroundContrast() const;
0400 
0401     /** This method allows Plasma to set a background contrast effect
0402      * for a given theme, improving readability. The value is read
0403      * from the "intensity" key in the "ContrastEffect" group in the
0404      * Theme's metadata file.
0405      * @return The intensity provided to the contrasteffect
0406      * @since 5.0
0407      * @see backgroundContrastEnabled
0408      */
0409     qreal backgroundIntensity() const;
0410 
0411     /** This method allows Plasma to set a background contrast effect
0412      * for a given theme, improving readability. The value is read
0413      * from the "saturation" key in the "ContrastEffect" group in the
0414      * Theme's metadata file.
0415      * @return The saturation provided to the contrasteffect
0416      * @since 5.0
0417      * @see backgroundContrastEnabled
0418      */
0419     qreal backgroundSaturation() const;
0420 
0421     /** This method allows Plasma to enable and disable the blurring
0422      * of what is behind the background for a given theme. The
0423      * value is read from the "enabled" key in the "BlurBehindEffect"
0424      * group in the Theme's metadata file. Default is @c true.
0425      *
0426      * The configuration in the metadata.desktop file of the theme
0427      * could look like this:
0428      * \code
0429      * [BlurBehindEffect]
0430      * enabled=false
0431      * \endcode
0432      * @return Whether or not to enable blurring of what is behind
0433      * @since 5.57
0434      */
0435     bool blurBehindEnabled() const;
0436 
0437     /**
0438      * Returns the size of the letter "M" as rendered on the screen with the given font.
0439      * This values gives you a base size that:
0440      * * scales dependent on the DPI of the screen
0441      * * Scales with the default font as set by the user
0442      * You can use it like this in QML Items:
0443      * \code
0444      * Item {
0445      *     width: PlasmaCore.Theme.mSize(PlasmaCore.Theme.defaultFont).height
0446      *     height: width
0447      * }
0448      * \endcode
0449      * This allows you to dynamically scale elements of your user interface with different font settings and
0450      * different physical outputs (with different DPI).
0451      * @param font The font to use for the metrics.
0452      * @return The size of the letter "M" as rendered on the screen with the given font.
0453      * @since 5.0
0454      */
0455     Q_INVOKABLE QSizeF mSize(const QFont &font = QGuiApplication::font()) const;
0456 
0457     QString backgroundPath(const QString &image) const;
0458 
0459     static QPalette globalPalette();
0460 
0461 Q_SIGNALS:
0462     /**
0463      * Emitted when the user changes the theme. Stylesheet usage, colors, etc. should
0464      * be updated at this point. However, SVGs should *not* be repainted in response
0465      * to this signal; connect to Svg::repaintNeeded() instead for that, as Svg objects
0466      * need repainting not only when themeChanged() is emitted; moreover Svg objects
0467      * connect to and respond appropriately to themeChanged() internally, emitting
0468      * Svg::repaintNeeded() at an appropriate time.
0469      */
0470     void themeChanged();
0471 
0472     /** Notifier for change of defaultFont property */
0473     void defaultFontChanged();
0474     /** Notifier for change of smallestFont property */
0475     void smallestFontChanged();
0476 
0477 private:
0478     friend class SvgPrivate;
0479     friend class FrameSvg;
0480     friend class FrameSvgPrivate;
0481     friend class ThemePrivate;
0482     ThemePrivate *d;
0483 };
0484 
0485 } // Plasma namespace
0486 
0487 #endif // multiple inclusion guard