diff --git a/src/lib/themedata.cpp b/src/lib/themedata.cpp index a658b57..9abda83 100644 --- a/src/lib/themedata.cpp +++ b/src/lib/themedata.cpp @@ -1,252 +1,250 @@ /* Copyright (C) 2016 Volker Krause Copyright (C) 2016 Dominik Haumann This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "themedata_p.h" #include "ksyntaxhighlighting_logging.h" #include #include #include #include #include #include #include using namespace KSyntaxHighlighting; ThemeData* ThemeData::get(const Theme &theme) { return theme.m_data.data(); } ThemeData::ThemeData() : m_revision(0) { memset(m_editorColors, 0, sizeof(m_editorColors)); } /** * Convert QJsonValue @p val into a color, if possible. Valid colors are only * in hex format: #rrggbb. On error, returns 0x00000000. */ static inline QRgb readColor(const QJsonValue &val) { const QRgb unsetColor = 0; if (!val.isString()) { return unsetColor; } const QString str = val.toString(); if (str.isEmpty() || str[0] != QLatin1Char('#')) { return unsetColor; } const QColor color(str); return color.isValid() ? color.rgb() : unsetColor; } static inline TextStyleData readThemeData(const QJsonObject &obj) { TextStyleData td; td.textColor = readColor(obj.value(QLatin1String("text-color"))); td.backgroundColor = readColor(obj.value(QLatin1String("background-color"))); td.selectedTextColor = readColor(obj.value(QLatin1String("selected-text-color"))); td.selectedBackgroundColor = readColor(obj.value(QLatin1String("selected-background-color"))); auto val = obj.value(QLatin1String("bold")); if (val.isBool()) { td.bold = val.toBool(); td.hasBold = true; } val = obj.value(QLatin1String("italic")); if (val.isBool()) { td.italic = val.toBool(); td.hasItalic = true; } val = obj.value(QLatin1String("underline")); if (val.isBool()) { td.underline = val.toBool(); td.hasUnderline = true; } val = obj.value(QLatin1String("strike-through")); if (val.isBool()) { td.strikeThrough = val.toBool(); td.hasStrikeThrough = true; } return td; } bool ThemeData::load(const QString &filePath) { QFile loadFile(filePath); if (!loadFile.open(QIODevice::ReadOnly)) { return false; } const QByteArray jsonData = loadFile.readAll(); QJsonParseError parseError; QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseError); if (parseError.error != QJsonParseError::NoError) { qCWarning(Log) << "Failed to parse theme file" << filePath << ":" << parseError.errorString(); return false; } m_filePath = filePath; QJsonObject obj = jsonDoc.object(); // read metadata const QJsonObject metadata = obj.value(QLatin1String("metadata")).toObject(); m_name = metadata.value(QLatin1String("name")).toString(); m_revision = metadata.value(QLatin1String("revision")).toInt(); - m_author = metadata.value(QLatin1String("author")).toString(); - m_license = metadata.value(QLatin1String("license")).toString(); // read text styles static const auto idx = Theme::staticMetaObject.indexOfEnumerator("TextStyle"); Q_ASSERT(idx >= 0); const auto metaEnum = Theme::staticMetaObject.enumerator(idx); const QJsonObject textStyles = obj.value(QLatin1String("text-styles")).toObject(); for (int i = 0; i < metaEnum.keyCount(); ++i) { Q_ASSERT(i == metaEnum.value(i)); m_textStyles[i] = readThemeData(textStyles.value(QLatin1String(metaEnum.key(i))).toObject()); } // read editor area colors const QJsonObject editorColors = obj.value(QLatin1String("editor-colors")).toObject(); m_editorColors[Theme::BackgroundColor] = readColor(editorColors.value(QLatin1String("background-color"))); m_editorColors[Theme::TextSelection] = readColor(editorColors.value(QLatin1String("selection"))); m_editorColors[Theme::CurrentLine] = readColor(editorColors.value(QLatin1String("current-line"))); m_editorColors[Theme::SearchHighlight] = readColor(editorColors.value(QLatin1String("search-highlight"))); m_editorColors[Theme::ReplaceHighlight] = readColor(editorColors.value(QLatin1String("replace-highlight"))); m_editorColors[Theme::BracketMatching] = readColor(editorColors.value(QLatin1String("bracket-matching"))); m_editorColors[Theme::TabMarker] = readColor(editorColors.value(QLatin1String("tab-marker"))); m_editorColors[Theme::SpellChecking] = readColor(editorColors.value(QLatin1String("spell-checking"))); m_editorColors[Theme::IndentationLine] = readColor(editorColors.value(QLatin1String("indentation-line"))); m_editorColors[Theme::IconBorder] = readColor(editorColors.value(QLatin1String("icon-border"))); m_editorColors[Theme::CodeFolding] = readColor(editorColors.value(QLatin1String("code-folding"))); m_editorColors[Theme::LineNumbers] = readColor(editorColors.value(QLatin1String("line-numbers"))); m_editorColors[Theme::CurrentLineNumber] = readColor(editorColors.value(QLatin1String("current-line-number"))); m_editorColors[Theme::WordWrapMarker] = readColor(editorColors.value(QLatin1String("word-wrap-marker"))); m_editorColors[Theme::ModifiedLines] = readColor(editorColors.value(QLatin1String("modified-lines"))); m_editorColors[Theme::SavedLines] = readColor(editorColors.value(QLatin1String("saved-lines"))); m_editorColors[Theme::Separator] = readColor(editorColors.value(QLatin1String("separator"))); m_editorColors[Theme::MarkBookmark] = readColor(editorColors.value(QLatin1String("mark-bookmark"))); m_editorColors[Theme::MarkBreakpointActive] = readColor(editorColors.value(QLatin1String("mark-breakpoint-active"))); m_editorColors[Theme::MarkBreakpointReached] = readColor(editorColors.value(QLatin1String("mark-breakpoint-reached"))); m_editorColors[Theme::MarkBreakpointDisabled] = readColor(editorColors.value(QLatin1String("mark-breakpoint-disabled"))); m_editorColors[Theme::MarkExecution] = readColor(editorColors.value(QLatin1String("mark-execution"))); m_editorColors[Theme::MarkWarning] = readColor(editorColors.value(QLatin1String("mark-warning"))); m_editorColors[Theme::MarkError] = readColor(editorColors.value(QLatin1String("mark-error"))); m_editorColors[Theme::TemplateBackground] = readColor(editorColors.value(QLatin1String("template-background"))); m_editorColors[Theme::TemplatePlaceholder] = readColor(editorColors.value(QLatin1String("template-placeholder"))); m_editorColors[Theme::TemplateFocusedPlaceholder] = readColor(editorColors.value(QLatin1String("template-focused-placeholder"))); m_editorColors[Theme::TemplateReadOnlyPlaceholder] = readColor(editorColors.value(QLatin1String("template-read-only-placeholder"))); // read per-definition style overrides const auto customStyles = obj.value(QLatin1String("custom-styles")).toObject(); for (auto it = customStyles.begin(); it != customStyles.end(); ++it) { const auto obj = it.value().toObject(); QHash overrideStyle; for (auto it2 = obj.begin(); it2 != obj.end(); ++it2) overrideStyle.insert(it2.key(), readThemeData(it2.value().toObject())); m_textStyleOverrides.insert(it.key(), overrideStyle); } return true; } QString ThemeData::name() const { return m_name; } int ThemeData::revision() const { return m_revision; } bool ThemeData::isReadOnly() const { return !QFileInfo(m_filePath).isWritable(); } QString ThemeData::filePath() const { return m_filePath; } QRgb ThemeData::textColor(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].textColor; } QRgb ThemeData::selectedTextColor(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].selectedTextColor; } QRgb ThemeData::backgroundColor(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].backgroundColor; } QRgb ThemeData::selectedBackgroundColor(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].selectedBackgroundColor; } bool ThemeData::isBold(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].bold; } bool ThemeData::isItalic(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].italic; } bool ThemeData::isUnderline(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].underline; } bool ThemeData::isStrikeThrough(Theme::TextStyle style) const { Q_ASSERT(static_cast(style) >= 0 && static_cast(style) <= static_cast(Theme::Others)); return m_textStyles[style].strikeThrough; } QRgb ThemeData::editorColor(Theme::EditorColorRole role) const { Q_ASSERT(static_cast(role) >= 0 && static_cast(role) <= static_cast(Theme::TemplateReadOnlyPlaceholder)); return m_editorColors[role]; } TextStyleData ThemeData::textStyleOverride(const QString& definitionName, const QString& attributeName) const { return m_textStyleOverrides.value(definitionName).value(attributeName); } diff --git a/src/lib/themedata_p.h b/src/lib/themedata_p.h index 49eea13..b2f28a8 100644 --- a/src/lib/themedata_p.h +++ b/src/lib/themedata_p.h @@ -1,150 +1,148 @@ /* Copyright (C) 2016 Volker Krause Copyright (C) 2016 Dominik Haumann This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KSYNTAXHIGHLIGHTING_THEMEDATA_P_H #define KSYNTAXHIGHLIGHTING_THEMEDATA_P_H #include "theme.h" #include "textstyledata_p.h" #include #include namespace KSyntaxHighlighting { /** * Data container for a Theme. */ class ThemeData : public QSharedData { public: static ThemeData* get(const Theme &theme); /** * Default constructor, creating an uninitialized ThemeData instance. */ ThemeData(); /** * Load the Theme data from the file @p filePath. * Note, that @p filePath either is a local file, or a qt resource location. */ bool load(const QString &filePath); /** * Returns the unique name of this Theme. */ QString name() const; int revision() const; /** * Returns @c true if this Theme is read-only. * Typically, themes that are shipped by default are read-only. */ bool isReadOnly() const; /** * Returns the full path and filename to this Theme. * Themes from the Qt resource return the Qt resource path. * Themes from disk return the local path. * * If the theme is invalid (isValid()), an empty string is returned. */ QString filePath() const; /** * Returns the text color to be used for @p style. * @c 0 is returned for styles that do not specify a text color, * use the default text color in that case. */ QRgb textColor(Theme::TextStyle style) const; /** * Returns the text color for selected to be used for @p style. * @c 0 is returned for styles that do not specify a selected text color, * use the textColor() in that case. */ QRgb selectedTextColor(Theme::TextStyle style) const; /** * Returns the background color to be used for @p style. * @c 0 is returned for styles that do not specify a background color, * use the default background color in that case. */ QRgb backgroundColor(Theme::TextStyle style) const; /** * Returns the background color for selected text to be used for @p style. * @c 0 is returned for styles that do not specify a selected background * color, use the default backgroundColor() in that case. */ QRgb selectedBackgroundColor(Theme::TextStyle style) const; /** * Returns whether the given style should be shown in bold. */ bool isBold(Theme::TextStyle style) const; /** * Returns whether the given style should be shown in italic. */ bool isItalic(Theme::TextStyle style) const; /** * Returns whether the given style should be shown underlined. */ bool isUnderline(Theme::TextStyle style) const; /** * Returns whether the given style should be shown struck through. */ bool isStrikeThrough(Theme::TextStyle style) const; public: /** * Returns the editor color for the requested @p role. */ QRgb editorColor(Theme::EditorColorRole role) const; TextStyleData textStyleOverride(const QString &definitionName, const QString &attributeName) const; private: int m_revision; QString m_name; - QString m_author; - QString m_license; QString m_filePath; //! TextStyles TextStyleData m_textStyles[Theme::Others + 1]; //! style overrides for individual itemData entries // definition name -> attribute name -> style QHash > m_textStyleOverrides; //! Editor area colors QRgb m_editorColors[Theme::TemplateReadOnlyPlaceholder + 1]; }; } Q_DECLARE_TYPEINFO(KSyntaxHighlighting::TextStyleData, Q_MOVABLE_TYPE); #endif // KSYNTAXHIGHLIGHTING_THEMEDATA_P_H