1 /*
2     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
3 
4     SPDX-License-Identifier: MIT
5 */
6 
7 #ifndef KSYNTAXHIGHLIGHTING_THEME_H
8 #define KSYNTAXHIGHLIGHTING_THEME_H
9 
10 #include "ksyntaxhighlighting_export.h"
11 
12 #include <QColor>
13 #include <QExplicitlySharedDataPointer>
14 #include <QTypeInfo>
15 #include <qobjectdefs.h>
16 
17 namespace KSyntaxHighlighting
18 {
19 class ThemeData;
20 class RepositoryPrivate;
21 
22 /**
23  * Color theme definition used for highlighting.
24  *
25  * @section theme_intro Introduction
26  *
27  * The Theme provides a full color theme for painting the highlighted text.
28  * One Theme is defined either as a *.theme file on disk, or as a file compiled
29  * into the SyntaxHighlighting library by using Qt's resource system. Each
30  * Theme has a unique name(), including a translatedName() if put into the UI.
31  * Themes shipped by default are typically read-only, see isReadOnly().
32  *
33  * A Theme defines two sets of colors:
34  * - Text colors, including foreground and background colors, colors for
35  *   selected text, and properties such as bold and italic. These colors are
36  *   used e.g. by the SyntaxHighlighter.
37  * - Editor colors, including a background color for the entire editor widget,
38  *   the line number color, code folding colors, etc.
39  *
40  * @section theme_text_colors Text Colors and the Class Format
41  *
42  * The text colors are used for syntax highlighting.
43  * // TODO: elaborate more and explain relation to Format class
44  *
45  * @section theme_editor_colors Editor Colors
46  *
47  * If you want to use the SyntaxHighlighting framework to write your own text
48  * editor, you also need to paint the background of the editing widget. In
49  * addition, the editor may support showing line numbers, a folding bar, a
50  * highlight for the current text line, and similar features. All these colors
51  * are defined in terms of the "editor colors" and accessible by calling
52  * editorColor() with the desired enum EditorColorRole.
53  *
54  * @section theme_access Accessing a Theme
55  *
56  * All available Theme%s are accessed through the Repository. These themes are
57  * typically valid themes. If you create a Theme on your own, isValid() will
58  * return @e false, and all colors provided by this Theme are in fact invalid
59  * and therefore unusable.
60  *
61  * @see Format
62  * @since 5.28
63  */
64 class KSYNTAXHIGHLIGHTING_EXPORT Theme
65 {
66     Q_GADGET
67     Q_PROPERTY(QString name READ name)
68     Q_PROPERTY(QString translatedName READ translatedName)
69 public:
70     // TODO KF6:
71     // - make TextStyle an enum class
72     // - move out of Theme into KSyntaxHighlighting
73     // - do the same for EditorColorRole
74 
75     /**
76      * Default styles that can be referenced from syntax definition XML files.
77      * Make sure to choose readable colors with good contrast especially in
78      * combination with the EditorColorRole%s.
79      */
80     enum TextStyle {
81         //! Default text style for normal text and source code without
82         //! special highlighting.
83         Normal = 0,
84         //! Text style for language keywords.
85         Keyword,
86         //! Text style for function definitions and function calls.
87         Function,
88         //! Text style for variables, if applicable. For instance, variables in
89         //! PHP typically start with a '$', so all identifiers following the
90         //! pattern $foo are highlighted as variable.
91         Variable,
92         //! Text style for control flow highlighting, such as @e if, @e then,
93         //! @e else, @e return, or @e continue.
94         ControlFlow,
95         //! Text style for operators such as +, -, *, / and :: etc.
96         Operator,
97         //! Text style for built-in language classes and functions.
98         BuiltIn,
99         //! Text style for well-known extensions, such as Qt or boost.
100         Extension,
101         //! Text style for preprocessor statements.
102         Preprocessor,
103         //! Text style for attributes of functions or objects, e.g. \@override
104         //! in Java, or __declspec(...) and __attribute__((...)) in C++.
105         Attribute,
106         //! Text style for single characters such as 'a'.
107         Char,
108         //! Text style for escaped characters in strings, such as "hello\n".
109         SpecialChar,
110         //! Text style for strings, for instance "hello world".
111         String,
112         //! Text style for verbatim strings such as HERE docs.
113         VerbatimString,
114         //! Text style for special strings such as regular expressions in
115         //! ECMAScript or the LaTeX math mode.
116         SpecialString,
117         //! Text style for includes, imports, modules, or LaTeX packages.
118         Import,
119         //! Text style for data types such as int, char, float etc.
120         DataType,
121         //! Text style for decimal values.
122         DecVal,
123         //! Text style for numbers with base other than 10.
124         BaseN,
125         //! Text style for floating point numbers.
126         Float,
127         //! Text style for language constants, e.g. True, False, None in Python
128         //! or nullptr in C/C++.
129         Constant,
130         //! Text style for normal comments.
131         Comment,
132         //! Text style for comments that reflect API documentation, such as
133         //! doxygen /** */ comments.
134         Documentation,
135         //! Text style for annotations in comments, such as \@param in Doxygen
136         //! or JavaDoc.
137         Annotation,
138         //! Text style that refers to variables in a comment, such as after
139         //! \@param \<identifier\> in Doxygen or JavaDoc.
140         CommentVar,
141         //! Text style for region markers, typically defined by BEGIN/END.
142         RegionMarker,
143         //! Text style for information, such as the keyword \@note in Doxygen.
144         Information,
145         //! Text style for warnings, such as the keyword \@warning in Doxygen.
146         Warning,
147         //! Text style for comment specials such as TODO and WARNING in
148         //! comments.
149         Alert,
150         //! Text style indicating wrong syntax.
151         Error,
152         //! Text style for attributes that do not match any of the other default
153         //! styles.
154         Others
155     };
156     Q_ENUM(TextStyle)
157 
158     /**
159      * Editor color roles, used to paint line numbers, editor background etc.
160      * The colors typically should have good contrast with the colors used
161      * in the TextStyle%s.
162      */
163     enum EditorColorRole {
164         //! Background color for the editing area.
165         BackgroundColor = 0,
166         //! Background color for selected text.
167         TextSelection,
168         //! Background color for the line of the current text cursor.
169         CurrentLine,
170         //! Background color for matching text while searching.
171         SearchHighlight,
172         //! Background color for replaced text for a search & replace action.
173         ReplaceHighlight,
174         //! Background color for matching bracket pairs (including quotes)
175         BracketMatching,
176         //! Foreground color for visualizing tabs and trailing spaces.
177         TabMarker,
178         //! Color used to underline spell check errors.
179         SpellChecking,
180         //! Color used to draw vertical indentation levels, typically a line.
181         IndentationLine,
182         //! Background color for the icon border.
183         IconBorder,
184         //! Background colors for code folding regions in the text area, as well
185         //! as code folding indicators in the code folding border.
186         CodeFolding,
187         //! Foreground color for drawing the line numbers. This should have a
188         //! good contrast with the IconBorder background color.
189         LineNumbers,
190         //! Foreground color for drawing the current line number. This should
191         //! have a good contrast with the IconBorder background color.
192         CurrentLineNumber,
193         //! Color used in the icon border to indicate dynamically wrapped lines.
194         //! This color should have a good contrast with the IconBorder
195         //! background color.
196         WordWrapMarker,
197         //! Color used to draw a vertical line for marking changed lines.
198         ModifiedLines,
199         //! Color used to draw a vertical line for marking saved lines.
200         SavedLines,
201         //! Line color used to draw separator lines, e.g. at column 80 in the
202         //! text editor area.
203         Separator,
204         //! Background color for bookmarks.
205         MarkBookmark,
206         //! Background color for active breakpoints.
207         MarkBreakpointActive,
208         //! Background color for a reached breakpoint.
209         MarkBreakpointReached,
210         //! Background color for inactive (disabled) breakpoints.
211         MarkBreakpointDisabled,
212         //! Background color for marking the current execution position.
213         MarkExecution,
214         //! Background color for general warning marks.
215         MarkWarning,
216         //! Background color for general error marks.
217         MarkError,
218         //! Background color for text templates (snippets).
219         TemplateBackground,
220         //! Background color for all editable placeholders in text templates.
221         TemplatePlaceholder,
222         //! Background color for the currently active placeholder in text
223         //! templates.
224         TemplateFocusedPlaceholder,
225         //! Background color for read-only placeholders in text templates.
226         TemplateReadOnlyPlaceholder
227     };
228     Q_ENUM(EditorColorRole)
229 
230     /**
231      * Default constructor, creating an invalid Theme, see isValid().
232      */
233     Theme();
234 
235     /**
236      * Copy constructor, sharing the Theme data with @p copy.
237      */
238     Theme(const Theme &copy);
239 
240     /**
241      * Destructor.
242      */
243     ~Theme();
244 
245     /**
246      * Assignment operator, sharing the Theme data with @p other.
247      */
248     Theme &operator=(const Theme &other);
249 
250     /**
251      * Returns @c true if this is a valid Theme.
252      * If the theme is invalid, none of the returned colors are well-defined.
253      */
254     bool isValid() const;
255 
256     /**
257      * Returns the unique name of this Theme.
258      * @see translatedName()
259      */
260     QString name() const;
261 
262     /**
263      * Returns the translated name of this Theme. The translated name can be
264      * used in the user interface.
265      */
266     QString translatedName() const;
267 
268     /**
269      * Returns @c true if this Theme is read-only.
270      *
271      * A Theme is read-only, if the filePath() points to a non-writable file.
272      * This is typically the case for Themes that are compiled into the executable
273      * as resource file, as well as for theme files that are installed in read-only
274      * system locations (e.g. /usr/share/).
275      */
276     bool isReadOnly() const;
277 
278     /**
279      * Returns the full path and file name to this Theme.
280      * Themes from the Qt resource return the Qt resource path.
281      * Themes from disk return the local path.
282      *
283      * If the theme is invalid (isValid()), an empty string is returned.
284      */
285     QString filePath() const;
286 
287     /**
288      * Returns the text color to be used for @p style.
289      * @c 0 is returned for styles that do not specify a text color,
290      * use the default text color in that case.
291      */
292     QRgb textColor(TextStyle style) const;
293 
294     /**
295      * Returns the selected text color to be used for @p style.
296      * @c 0 is returned for styles that do not specify a selected text color,
297      * use the default textColor() in that case.
298      */
299     QRgb selectedTextColor(TextStyle style) const;
300 
301     /**
302      * Returns the background color to be used for @p style.
303      * @c 0 is returned for styles that do not specify a background color,
304      * use the default background color in that case.
305      */
306     QRgb backgroundColor(TextStyle style) const;
307 
308     /**
309      * Returns the background color to be used for selected text for @p style.
310      * @c 0 is returned for styles that do not specify a background color,
311      * use the default backgroundColor() in that case.
312      */
313     QRgb selectedBackgroundColor(TextStyle style) const;
314 
315     /**
316      * Returns whether the given style should be shown in bold.
317      */
318     bool isBold(TextStyle style) const;
319 
320     /**
321      * Returns whether the given style should be shown in italic.
322      */
323     bool isItalic(TextStyle style) const;
324 
325     /**
326      * Returns whether the given style should be shown underlined.
327      */
328     bool isUnderline(TextStyle style) const;
329 
330     /**
331      * Returns whether the given style should be shown struck through.
332      */
333     bool isStrikeThrough(TextStyle style) const;
334 
335 public:
336     /**
337      * Returns the editor color for the requested @p role.
338      */
339     QRgb editorColor(EditorColorRole role) const;
340 
341 private:
342     /**
343      * Constructor taking a shared ThemeData instance.
344      */
345     explicit Theme(ThemeData *data);
346     friend class RepositoryPrivate;
347     friend class ThemeData;
348 
349 private:
350     /**
351      * Shared data holder.
352      */
353     QExplicitlySharedDataPointer<ThemeData> m_data;
354 };
355 
356 }
357 
358 QT_BEGIN_NAMESPACE
359 Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Theme, Q_MOVABLE_TYPE);
360 QT_END_NAMESPACE
361 
362 #endif // KSYNTAXHIGHLIGHTING_THEME_H
363