1 /*
2     SPDX-FileCopyrightText: 2006-2007 Fredrik Höglund <fredrik@kde.org>
3 
4     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
5 */
6 
7 #pragma once
8 
9 #include <QHash>
10 #include <QPixmap>
11 
12 /**
13  * This is the abstract base class for all cursor themes stored in a
14  * CursorThemeModel and previewed in a PreviewWidget.
15  *
16  * All cursor themes have a title, a description, an icon, and an internal
17  * name, all of which, except for the internal name, CursorThemeModel
18  * supplies to item views.
19  *
20  * A cursor theme may also have a path to the directory where the theme
21  * is located in the filesystem. If isWritable() returns true, This directory
22  * may be deleted in order to remove the theme at the users request.
23  *
24  * Subclasses must reimplement loadImage() and loadCursor(), which are
25  * called by PreviewWidget to load cursors and cursor images. Subclasses may
26  * optionally reimplement loadPixmap(), which in the default implementation
27  * calls loadImage(), and converts the returned image to a pixmap.
28  * Subclasses may also reimplement the protected function createIcon(),
29  * which creates the icon pixmap that's supplied to item views. The default
30  * implementation calls loadImage() to load the sample cursor, and creates
31  * the icon from that.
32  */
33 class CursorTheme
34 {
35 public:
36     enum ItemDataRole {
37         // Note: use   printf "0x%08X\n" $(($RANDOM*$RANDOM))
38         // to define additional roles.
39         DisplayDetailRole = 0x24A3DAF8,
40         IsWritableRole,
41         PendingDeletionRole,
42     };
43 
CursorTheme()44     CursorTheme()
45     {
46     }
47     CursorTheme(const QString &title, const QString &description = QString());
~CursorTheme()48     virtual ~CursorTheme()
49     {
50     }
51 
title()52     const QString title() const
53     {
54         return m_title;
55     }
description()56     const QString description() const
57     {
58         return m_description;
59     }
sample()60     const QString sample() const
61     {
62         return m_sample;
63     }
name()64     const QString name() const
65     {
66         return m_name;
67     }
path()68     const QString path() const
69     {
70         return m_path;
71     }
72     /** @returns A list of the available sizes in this cursor theme,
73         @warning This list may be empty if the engine doesn't support
74         the recognition of the size. */
availableSizes()75     const QList<int> availableSizes() const
76     {
77         return m_availableSizes;
78     }
isWritable()79     bool isWritable() const
80     {
81         return m_writable;
82     }
isHidden()83     bool isHidden() const
84     {
85         return m_hidden;
86     }
87     QPixmap icon() const;
88 
89     /// Hash value for the internal name
hash()90     uint hash() const
91     {
92         return m_hash;
93     }
94 
95     /// Loads the cursor image @p name, with the nominal size @p size.
96     /// The image should be autocropped to the smallest possible size.
97     /// If the theme doesn't have the cursor @p name, it should return a null image.
98     virtual QImage loadImage(const QString &name, int size = 0) const = 0;
99 
100     /// Convenience function. Default implementation calls
101     /// QPixmap::fromImage(loadImage());
102     virtual QPixmap loadPixmap(const QString &name, int size = 0) const;
103 
104     /// Loads the cursor @p name, with the nominal size @p size.
105     /// If the theme doesn't have the cursor @p name, it should return
106     /// the default cursor from the active theme instead.
107     virtual qulonglong loadCursor(const QString &name, int size = 0) const = 0;
108 
109     virtual int defaultCursorSize() const = 0;
110 
111     /** Creates the icon returned by @ref icon(). Don't use this function
112         directly but use @ref icon() instead, because @ref icon() caches
113         the icon.
114         @returns A pixmap with a cursor (usually left_ptr) that can
115         be used as icon for this theme. The size is adopted to
116         standard icon sizes.*/
117     virtual QPixmap createIcon() const;
118     /** @returns A pixmap with a cursor (usually left_ptr) that can
119         be used as icon for this theme. */
120     virtual QPixmap createIcon(int size) const;
121 
122     static bool haveXfixes();
123 
124 protected:
setTitle(const QString & title)125     void setTitle(const QString &title)
126     {
127         m_title = title;
128     }
setDescription(const QString & desc)129     void setDescription(const QString &desc)
130     {
131         m_description = desc;
132     }
setSample(const QString & sample)133     void setSample(const QString &sample)
134     {
135         m_sample = sample;
136     }
137     inline void setName(const QString &name);
setPath(const QString & path)138     void setPath(const QString &path)
139     {
140         m_path = path;
141     }
setAvailableSizes(const QList<int> & availableSizes)142     void setAvailableSizes(const QList<int> &availableSizes)
143     {
144         m_availableSizes = availableSizes;
145     }
setIcon(const QPixmap & icon)146     void setIcon(const QPixmap &icon)
147     {
148         m_icon = icon;
149     }
setIsWritable(bool val)150     void setIsWritable(bool val)
151     {
152         m_writable = val;
153     }
setIsHidden(bool val)154     void setIsHidden(bool val)
155     {
156         m_hidden = val;
157     }
158 
159     /// Convenience function for cropping an image.
160     QImage autoCropImage(const QImage &image) const;
161 
162     // Convenience function that uses Xfixes to tag a cursor with a name
163     void setCursorName(qulonglong cursor, const QString &name) const;
164 
165     QString m_title;
166     QString m_description;
167     QString m_path;
168     QList<int> m_availableSizes;
169     QString m_sample;
170     mutable QPixmap m_icon;
171     bool m_writable : 1;
172     bool m_hidden : 1;
173 
174 private:
175     QString m_name;
176     uint m_hash;
177 
178     friend class CursorThemeModel;
179 };
180 
setName(const QString & name)181 void CursorTheme::setName(const QString &name)
182 {
183     m_name = name;
184     m_hash = qHash(name);
185 }
186