KSyntaxHighlighting

format.cpp
1 /*
2  SPDX-FileCopyrightText: 2016 Volker Krause <[email protected]>
3  SPDX-FileCopyrightText: 2020 Jonathan Poelen <[email protected]>
4 
5  SPDX-License-Identifier: MIT
6 */
7 
8 #include "format.h"
9 #include "definition.h"
10 #include "definitionref_p.h"
11 #include "format_p.h"
12 #include "textstyledata_p.h"
13 #include "themedata_p.h"
14 #include "xml_p.h"
15 
16 #include <QColor>
17 #include <QMetaEnum>
18 #include <QXmlStreamReader>
19 
20 using namespace KSyntaxHighlighting;
21 
22 static Theme::TextStyle stringToDefaultFormat(QStringView str)
23 {
24  if (!str.startsWith(QLatin1String("ds"))) {
25  return Theme::Normal;
26  }
27 
28  const auto metaEnum = QMetaEnum::fromType<Theme::TextStyle>();
29 
30  bool ok = false;
31  const auto value = metaEnum.keyToValue(str.mid(2).toLatin1().constData(), &ok);
32  if (!ok || value < 0) {
33  return Theme::Normal;
34  }
35  return static_cast<Theme::TextStyle>(value);
36 }
37 
38 FormatPrivate *FormatPrivate::detachAndGet(Format &format)
39 {
40  format.d.detach();
41  return format.d.data();
42 }
43 
44 TextStyleData FormatPrivate::styleOverride(const Theme &theme) const
45 {
46  return ThemeData::get(theme)->textStyleOverride(definitionName, name);
47 }
48 
49 QColor FormatPrivate::color(const Theme &theme, StyleColor styleColor, ThemeColor themeColor) const
50 {
51  const auto overrideStyle = styleOverride(theme);
52  if (overrideStyle.*styleColor) {
53  return QColor::fromRgb(overrideStyle.*styleColor);
54  }
55  // use QColor::fromRgba for QRgb => QColor conversion to avoid unset colors == black!
56  return QColor::fromRgba(style.*styleColor ? style.*styleColor : (theme.*themeColor)(defaultStyle));
57 }
58 
59 bool FormatPrivate::hasColor(const Theme &theme, StyleColor styleColor, ThemeColor themeColor) const
60 {
61  // use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
62  return color(theme, styleColor, themeColor) != QColor::fromRgba((theme.*themeColor)(Theme::Normal)) && (style.*styleColor || (theme.*themeColor)(defaultStyle) || styleOverride(theme).*styleColor);
63 }
64 
65 static QExplicitlySharedDataPointer<FormatPrivate> &sharedDefaultPrivate()
66 {
67  static QExplicitlySharedDataPointer<FormatPrivate> def(new FormatPrivate);
68  return def;
69 }
70 
72  : d(sharedDefaultPrivate())
73 {
74 }
75 
76 Format::Format(const Format &other)
77  : d(other.d)
78 {
79 }
80 
81 Format::~Format()
82 {
83 }
84 
85 Format &Format::operator=(const Format &other)
86 {
87  d = other.d;
88  return *this;
89 }
90 
91 bool Format::isValid() const
92 {
93  return !d->name.isEmpty();
94 }
95 
97 {
98  return d->name;
99 }
100 
101 quint16 Format::id() const
102 {
103  return d->id;
104 }
105 
107 {
108  return d->defaultStyle;
109 }
110 
111 bool Format::isDefaultTextStyle(const Theme &theme) const
112 {
113  // use QColor::fromRgba for background QRgb => QColor conversion to avoid unset colors == black!
114  return (!hasTextColor(theme)) && (!hasBackgroundColor(theme)) && (selectedTextColor(theme).rgba() == theme.selectedTextColor(Theme::Normal))
115  && (selectedBackgroundColor(theme).rgba() == (theme.selectedBackgroundColor(Theme::Normal))) && (isBold(theme) == theme.isBold(Theme::Normal))
116  && (isItalic(theme) == theme.isItalic(Theme::Normal)) && (isUnderline(theme) == theme.isUnderline(Theme::Normal))
117  && (isStrikeThrough(theme) == theme.isStrikeThrough(Theme::Normal));
118 }
119 
120 bool Format::hasTextColor(const Theme &theme) const
121 {
122  return d->hasColor(theme, &TextStyleData::textColor, &Theme::textColor);
123 }
124 
125 QColor Format::textColor(const Theme &theme) const
126 {
127  return d->color(theme, &TextStyleData::textColor, &Theme::textColor);
128 }
129 
131 {
132  return d->color(theme, &TextStyleData::selectedTextColor, &Theme::selectedTextColor);
133 }
134 
135 bool Format::hasBackgroundColor(const Theme &theme) const
136 {
137  return d->hasColor(theme, &TextStyleData::backgroundColor, &Theme::backgroundColor);
138 }
139 
141 {
142  return d->color(theme, &TextStyleData::backgroundColor, &Theme::backgroundColor);
143 }
144 
146 {
147  return d->color(theme, &TextStyleData::selectedBackgroundColor, &Theme::selectedBackgroundColor);
148 }
149 
150 bool Format::isBold(const Theme &theme) const
151 {
152  const auto overrideStyle = d->styleOverride(theme);
153  if (overrideStyle.hasBold) {
154  return overrideStyle.bold;
155  }
156  return d->style.hasBold ? d->style.bold : theme.isBold(d->defaultStyle);
157 }
158 
159 bool Format::isItalic(const Theme &theme) const
160 {
161  const auto overrideStyle = d->styleOverride(theme);
162  if (overrideStyle.hasItalic) {
163  return overrideStyle.italic;
164  }
165  return d->style.hasItalic ? d->style.italic : theme.isItalic(d->defaultStyle);
166 }
167 
168 bool Format::isUnderline(const Theme &theme) const
169 {
170  const auto overrideStyle = d->styleOverride(theme);
171  if (overrideStyle.hasUnderline) {
172  return overrideStyle.underline;
173  }
174  return d->style.hasUnderline ? d->style.underline : theme.isUnderline(d->defaultStyle);
175 }
176 
177 bool Format::isStrikeThrough(const Theme &theme) const
178 {
179  const auto overrideStyle = d->styleOverride(theme);
180  if (overrideStyle.hasStrikeThrough) {
181  return overrideStyle.strikeThrough;
182  }
183  return d->style.hasStrikeThrough ? d->style.strikeThrough : theme.isStrikeThrough(d->defaultStyle);
184 }
185 
186 bool Format::spellCheck() const
187 {
188  return d->spellCheck;
189 }
190 
192 {
193  return d->style.hasBold;
194 }
195 
197 {
198  return d->style.hasItalic;
199 }
200 
202 {
203  return d->style.hasUnderline;
204 }
205 
207 {
208  return d->style.hasStrikeThrough;
209 }
210 
212 {
213  return d->style.textColor;
214 }
215 
217 {
218  return d->style.backgroundColor;
219 }
220 
222 {
223  return d->style.selectedTextColor;
224 }
225 
227 {
228  return d->style.selectedBackgroundColor;
229 }
230 
231 void FormatPrivate::load(QXmlStreamReader &reader)
232 {
233  name = reader.attributes().value(QLatin1String("name")).toString();
234  defaultStyle = stringToDefaultFormat(reader.attributes().value(QLatin1String("defStyleNum")));
235 
236  QStringView attribute = reader.attributes().value(QLatin1String("color"));
237  if (!attribute.isEmpty()) {
238  style.textColor = QColor(attribute).rgba();
239  }
240 
241  attribute = reader.attributes().value(QLatin1String("selColor"));
242  if (!attribute.isEmpty()) {
243  style.selectedTextColor = QColor(attribute).rgba();
244  }
245 
246  attribute = reader.attributes().value(QLatin1String("backgroundColor"));
247  if (!attribute.isEmpty()) {
248  style.backgroundColor = QColor(attribute).rgba();
249  }
250 
251  attribute = reader.attributes().value(QLatin1String("selBackgroundColor"));
252  if (!attribute.isEmpty()) {
253  style.selectedBackgroundColor = QColor(attribute).rgba();
254  }
255 
256  attribute = reader.attributes().value(QLatin1String("italic"));
257  if (!attribute.isEmpty()) {
258  style.hasItalic = true;
259  style.italic = Xml::attrToBool(attribute);
260  }
261 
262  attribute = reader.attributes().value(QLatin1String("bold"));
263  if (!attribute.isEmpty()) {
264  style.hasBold = true;
265  style.bold = Xml::attrToBool(attribute);
266  }
267 
268  attribute = reader.attributes().value(QLatin1String("underline"));
269  if (!attribute.isEmpty()) {
270  style.hasUnderline = true;
271  style.underline = Xml::attrToBool(attribute);
272  }
273 
274  attribute = reader.attributes().value(QLatin1String("strikeOut"));
275  if (!attribute.isEmpty()) {
276  style.hasStrikeThrough = true;
277  style.strikeThrough = Xml::attrToBool(attribute);
278  }
279 
280  attribute = reader.attributes().value(QLatin1String("spellChecking"));
281  if (!attribute.isEmpty()) {
282  spellCheck = Xml::attrToBool(attribute);
283  }
284 }
bool isValid() const
Returns true if this is a valid format, ie.
Definition: format.cpp:91
QString name() const
The name of this format as used in the syntax definition file.
Definition: format.cpp:96
QByteArray toLatin1() const const
QColor selectedBackgroundColor(const Theme &theme) const
Returns the background color of selected text of the combination of this format and the given theme.
Definition: format.cpp:145
bool hasBackgroundColor(const Theme &theme) const
Returns true if the combination of this format and the theme theme change the background color compar...
Definition: format.cpp:135
QStringRef value(const QString &namespaceUri, const QString &name) const const
quint16 id() const
Returns a unique identifier of this format.
Definition: format.cpp:101
bool hasStrikeThroughOverride() const
Returns true if the syntax definition file specifies a value for the struck through text attribute.
Definition: format.cpp:206
bool hasUnderlineOverride() const
Returns true if the syntax definition file sets a value for the underlined text attribute and,...
Definition: format.cpp:201
QStringView mid(qsizetype start) const const
Describes the format to be used for a specific text fragment.
Definition: format.h:33
bool hasBoldOverride() const
Returns true if the syntax definition file sets a value for the bold text attribute and,...
Definition: format.cpp:191
TextStyle
Default styles that can be referenced from syntax definition XML files.
Definition: theme.h:80
QColor fromRgba(QRgb rgba)
QRgb backgroundColor(TextStyle style) const
Returns the background color to be used for style.
Definition: theme.cpp:72
bool isItalic(TextStyle style) const
Returns whether the given style should be shown in italic.
Definition: theme.cpp:87
Format()
Creates an empty/invalid format.
Definition: format.cpp:71
bool isStrikeThrough(TextStyle style) const
Returns whether the given style should be shown struck through.
Definition: theme.cpp:97
bool hasTextColor(const Theme &theme) const
Returns true if the combination of this format and the theme theme change the foreground color compar...
Definition: format.cpp:120
bool spellCheck() const
Returns whether characters with this format should be spell checked.
Definition: format.cpp:186
bool isItalic(const Theme &theme) const
Returns true if the combination of this format and the given theme results in italic text formatting.
Definition: format.cpp:159
QColor textColor(const Theme &theme) const
Returns the foreground color of the combination of this format and the given theme.
Definition: format.cpp:125
bool isBold(TextStyle style) const
Returns whether the given style should be shown in bold.
Definition: theme.cpp:82
QXmlStreamAttributes attributes() const const
QColor backgroundColor(const Theme &theme) const
Returns the background color of the combination of this format and the given theme.
Definition: format.cpp:140
QColor fromRgb(QRgb rgb)
QRgb selectedBackgroundColor(TextStyle style) const
Returns the background color to be used for selected text for style.
Definition: theme.cpp:77
bool hasBackgroundColorOverride() const
Returns true if the syntax definition file sets a value for the background color attribute and,...
Definition: format.cpp:216
QRgb selectedTextColor(TextStyle style) const
Returns the selected text color to be used for style.
Definition: theme.cpp:67
bool isUnderline(TextStyle style) const
Returns whether the given style should be shown underlined.
Definition: theme.cpp:92
bool isUnderline(const Theme &theme) const
Returns true if the combination of this format and the given theme results in underlined text.
Definition: format.cpp:168
bool isEmpty() const const
bool hasTextColorOverride() const
Returns true if the syntax definition file sets a value for the foreground text color attribute and,...
Definition: format.cpp:211
Theme::TextStyle textStyle() const
Returns the underlying TextStyle of this Format.
Definition: format.cpp:106
QString toString() const const
const char * constData() const const
@ Normal
Default text style for normal text and source code without special highlighting.
Definition: theme.h:83
bool isStrikeThrough(const Theme &theme) const
Returns true if the combination of this format and the given theme results in struck through text.
Definition: format.cpp:177
bool hasSelectedTextColorOverride() const
Returns true if the syntax definition file specifies a value for the selected text color attribute.
Definition: format.cpp:221
bool hasSelectedBackgroundColorOverride() const
Returns true if the syntax definition file specifies a value for the selected background color attrib...
Definition: format.cpp:226
bool isBold(const Theme &theme) const
Returns true if the combination of this format and the given theme results in bold text formatting.
Definition: format.cpp:150
QRgb textColor(TextStyle style) const
Returns the text color to be used for style.
Definition: theme.cpp:62
bool startsWith(QStringView str, Qt::CaseSensitivity cs) const const
QRgb rgba() const const
QColor selectedTextColor(const Theme &theme) const
Returns the foreground color for selected text of the combination of this format and the given theme.
Definition: format.cpp:130
bool hasItalicOverride() const
Returns true if the syntax definition file sets a value for the italic text attribute and,...
Definition: format.cpp:196
virtual QVariant get(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName)
Color theme definition used for highlighting.
Definition: theme.h:64
bool isDefaultTextStyle(const Theme &theme) const
Returns true if the combination of this format and the theme theme do not change the default text for...
Definition: format.cpp:111
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 21 2023 04:01:45 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.