11#include "katethemeconfig.h"
13#include "katecolortreewidget.h"
14#include "kateconfig.h"
15#include "katedocument.h"
16#include "kateglobal.h"
17#include "katehighlight.h"
18#include "katestyletreewidget.h"
19#include "katesyntaxmanager.h"
22#include <KLocalizedString>
24#include <KMessageWidget>
29#include <QInputDialog>
46 case KSyntaxHighlighting::Theme::TextStyle::Normal:
47 return i18nc(
"@item:intable Text context",
"Normal");
48 case KSyntaxHighlighting::Theme::TextStyle::Keyword:
49 return i18nc(
"@item:intable Text context",
"Keyword");
50 case KSyntaxHighlighting::Theme::TextStyle::Function:
51 return i18nc(
"@item:intable Text context",
"Function");
52 case KSyntaxHighlighting::Theme::TextStyle::Variable:
53 return i18nc(
"@item:intable Text context",
"Variable");
54 case KSyntaxHighlighting::Theme::TextStyle::ControlFlow:
55 return i18nc(
"@item:intable Text context",
"Control Flow");
56 case KSyntaxHighlighting::Theme::TextStyle::Operator:
57 return i18nc(
"@item:intable Text context",
"Operator");
58 case KSyntaxHighlighting::Theme::TextStyle::BuiltIn:
59 return i18nc(
"@item:intable Text context",
"Built-in");
60 case KSyntaxHighlighting::Theme::TextStyle::Extension:
61 return i18nc(
"@item:intable Text context",
"Extension");
62 case KSyntaxHighlighting::Theme::TextStyle::Preprocessor:
63 return i18nc(
"@item:intable Text context",
"Preprocessor");
64 case KSyntaxHighlighting::Theme::TextStyle::Attribute:
65 return i18nc(
"@item:intable Text context",
"Attribute");
67 case KSyntaxHighlighting::Theme::TextStyle::Char:
68 return i18nc(
"@item:intable Text context",
"Character");
69 case KSyntaxHighlighting::Theme::TextStyle::SpecialChar:
70 return i18nc(
"@item:intable Text context",
"Special Character");
71 case KSyntaxHighlighting::Theme::TextStyle::String:
72 return i18nc(
"@item:intable Text context",
"String");
73 case KSyntaxHighlighting::Theme::TextStyle::VerbatimString:
74 return i18nc(
"@item:intable Text context",
"Verbatim String");
75 case KSyntaxHighlighting::Theme::TextStyle::SpecialString:
76 return i18nc(
"@item:intable Text context",
"Special String");
77 case KSyntaxHighlighting::Theme::TextStyle::Import:
78 return i18nc(
"@item:intable Text context",
"Imports, Modules, Includes");
80 case KSyntaxHighlighting::Theme::TextStyle::DataType:
81 return i18nc(
"@item:intable Text context",
"Data Type");
82 case KSyntaxHighlighting::Theme::TextStyle::DecVal:
83 return i18nc(
"@item:intable Text context",
"Decimal/Value");
84 case KSyntaxHighlighting::Theme::TextStyle::BaseN:
85 return i18nc(
"@item:intable Text context",
"Base-N Integer");
86 case KSyntaxHighlighting::Theme::TextStyle::Float:
87 return i18nc(
"@item:intable Text context",
"Floating Point");
88 case KSyntaxHighlighting::Theme::TextStyle::Constant:
89 return i18nc(
"@item:intable Text context",
"Constant");
91 case KSyntaxHighlighting::Theme::TextStyle::Comment:
92 return i18nc(
"@item:intable Text context",
"Comment");
93 case KSyntaxHighlighting::Theme::TextStyle::Documentation:
94 return i18nc(
"@item:intable Text context",
"Documentation");
95 case KSyntaxHighlighting::Theme::TextStyle::Annotation:
96 return i18nc(
"@item:intable Text context",
"Annotation");
97 case KSyntaxHighlighting::Theme::TextStyle::CommentVar:
98 return i18nc(
"@item:intable Text context",
"Comment Variable");
99 case KSyntaxHighlighting::Theme::TextStyle::RegionMarker:
101 return i18nc(
"@item:intable Text context",
"Region Marker");
102 case KSyntaxHighlighting::Theme::TextStyle::Information:
103 return i18nc(
"@item:intable Text context",
"Information");
104 case KSyntaxHighlighting::Theme::TextStyle::Warning:
105 return i18nc(
"@item:intable Text context",
"Warning");
106 case KSyntaxHighlighting::Theme::TextStyle::Alert:
107 return i18nc(
"@item:intable Text context",
"Alert");
109 case KSyntaxHighlighting::Theme::TextStyle::Others:
110 return i18nc(
"@item:intable Text context",
"Others");
111 case KSyntaxHighlighting::Theme::TextStyle::Error:
113 return i18nc(
"@item:intable Text context",
"Error");
130 const QByteArray jsonData = loadFile.readAll();
148 QFile saveFile(themeFileName);
157KateThemeConfigColorTab::KateThemeConfigColorTab()
159 QGridLayout *l =
new QGridLayout(
this);
161 ui =
new KateColorTreeWidget(
this);
162 QPushButton *btnUseColorScheme =
new QPushButton(
i18n(
"Use Default Colors"),
this);
171 connect(ui, &KateColorTreeWidget::changed,
this, &KateThemeConfigColorTab::changed);
182 ci.category =
i18n(
"Editor Background Colors");
184 ci.name =
i18n(
"Text Area");
185 ci.key = QStringLiteral(
"Color Background");
186 ci.whatsThis =
i18n(
"<p>Sets the background color of the editing area.</p>");
191 ci.name =
i18n(
"Selected Text");
192 ci.key = QStringLiteral(
"Color Selection");
194 "<p>Sets the background color of the selection.</p><p>To set the text color for selected text, use the "<b>Configure Highlighting</b>" "
200 ci.name =
i18n(
"Current Line");
201 ci.key = QStringLiteral(
"Color Highlighted Line");
202 ci.whatsThis =
i18n(
"<p>Sets the background color of the currently active line, which means the line where your cursor is positioned.</p>");
207 ci.name =
i18n(
"Search Highlight");
208 ci.key = QStringLiteral(
"Color Search Highlight");
209 ci.whatsThis =
i18n(
"<p>Sets the background color of search results.</p>");
214 ci.name =
i18n(
"Replace Highlight");
215 ci.key = QStringLiteral(
"Color Replace Highlight");
216 ci.whatsThis =
i18n(
"<p>Sets the background color of replaced text.</p>");
223 ci.category =
i18n(
"Icon Border");
226 ci.name =
i18n(
"Background Area");
227 ci.key = QStringLiteral(
"Color Icon Bar");
228 ci.whatsThis =
i18n(
"<p>Sets the background color of the icon border.</p>");
233 ci.name =
i18n(
"Line Numbers");
234 ci.key = QStringLiteral(
"Color Line Number");
235 ci.whatsThis =
i18n(
"<p>This color will be used to draw the line numbers (if enabled).</p>");
240 ci.name =
i18n(
"Current Line Number");
241 ci.key = QStringLiteral(
"Color Current Line Number");
242 ci.whatsThis =
i18n(
"<p>This color will be used to draw the number of the current line (if enabled).</p>");
247 ci.name =
i18n(
"Separator");
248 ci.key = QStringLiteral(
"Color Separator");
249 ci.whatsThis =
i18n(
"<p>This color will be used to draw the line between line numbers and the icon borders, if both are enabled.</p>");
254 ci.name =
i18n(
"Word Wrap Marker");
255 ci.key = QStringLiteral(
"Color Word Wrap Marker");
257 "<p>Sets the color of Word Wrap-related markers:</p><dl><dt>Static Word Wrap</dt><dd>A vertical line which shows the column where text is going to be "
258 "wrapped</dd><dt>Dynamic Word Wrap</dt><dd>An arrow shown to the left of "
259 "visually-wrapped lines</dd></dl>");
264 ci.name =
i18n(
"Code Folding");
265 ci.key = QStringLiteral(
"Color Code Folding");
266 ci.whatsThis =
i18n(
"<p>Sets the color of the code folding bar.</p>");
271 ci.name =
i18n(
"Modified Lines");
272 ci.key = QStringLiteral(
"Color Modified Lines");
273 ci.whatsThis =
i18n(
"<p>Sets the color of the line modification marker for modified lines.</p>");
278 ci.name =
i18n(
"Saved Lines");
279 ci.key = QStringLiteral(
"Color Saved Lines");
280 ci.whatsThis =
i18n(
"<p>Sets the color of the line modification marker for saved lines.</p>");
287 ci.category =
i18n(
"Text Decorations");
290 ci.name =
i18n(
"Spelling Mistake Line");
291 ci.key = QStringLiteral(
"Color Spelling Mistake Line");
292 ci.whatsThis =
i18n(
"<p>Sets the color of the line that is used to indicate spelling mistakes.</p>");
297 ci.name =
i18n(
"Tab and Space Markers");
298 ci.key = QStringLiteral(
"Color Tab Marker");
299 ci.whatsThis =
i18n(
"<p>Sets the color of the tabulator marks.</p>");
304 ci.name =
i18n(
"Indentation Line");
305 ci.key = QStringLiteral(
"Color Indentation Line");
306 ci.whatsThis =
i18n(
"<p>Sets the color of the vertical indentation lines.</p>");
311 ci.name =
i18n(
"Bracket Highlight");
312 ci.key = QStringLiteral(
"Color Highlighted Bracket");
314 "<p>Sets the bracket matching color. This means, if you place the cursor e.g. at a <b>(</b>, the matching <b>)</b> will be highlighted with this "
322 ci.category =
i18n(
"Marker Colors");
325 i18n(
"Active Breakpoint"),
326 i18n(
"Reached Breakpoint"),
327 i18n(
"Disabled Breakpoint"),
332 ci.whatsThis =
i18n(
"<p>Sets the background color of mark type.</p><p><b>Note</b>: The marker color is displayed lightly because of transparency.</p>");
336 ci.name = markerNames[i];
344 ci.category =
i18n(
"Text Templates & Snippets");
349 ci.name =
i18n(
"Background");
350 ci.key = QStringLiteral(
"Color Template Background");
355 ci.name =
i18n(
"Editable Placeholder");
356 ci.key = QStringLiteral(
"Color Template Editable Placeholder");
361 ci.name =
i18n(
"Focused Editable Placeholder");
362 ci.key = QStringLiteral(
"Color Template Focused Editable Placeholder");
367 ci.name =
i18n(
"Not Editable Placeholder");
368 ci.key = QStringLiteral(
"Color Template Not Editable Placeholder");
378void KateThemeConfigColorTab::schemaChanged(
const QString &newSchema)
381 const auto theme = KateHlManager::self()->repository().
theme(newSchema);
385 if (!m_currentSchema.isEmpty()) {
386 auto it = m_schemas.find(m_currentSchema);
387 if (it != m_schemas.end()) {
388 m_schemas.erase(m_currentSchema);
392 m_schemas[m_currentSchema] = ui->colorItems();
395 if (newSchema == m_currentSchema) {
400 m_currentSchema = newSchema;
403 if (m_schemas.find(newSchema) == m_schemas.end()) {
404 QList<KateColorItem> items = colorItemList(theme);
405 for (
auto &item : items) {
408 m_schemas[newSchema] = std::move(items);
415 ui->addColorItems(m_schemas[m_currentSchema]);
429void KateThemeConfigColorTab::apply()
431 schemaChanged(m_currentSchema);
434 static const auto idx = KSyntaxHighlighting::Theme::staticMetaObject.indexOfEnumerator(
"EditorColorRole");
436 const auto metaEnum = KSyntaxHighlighting::Theme::staticMetaObject.enumerator(idx);
439 for (
auto it = m_schemas.cbegin(); it != m_schemas.cend(); ++it) {
441 const auto theme = KateHlManager::self()->repository().
theme(it->first);
447 QJsonObject newThemeObject = jsonForTheme(theme);
451 const auto &colorItems = it->second;
452 for (
const KateColorItem &item : colorItems) {
453 QColor c = item.useDefault ? item.defaultColor : item.color;
454 colors[QLatin1String(metaEnum.key(item.role))] = hexName(c);
456 newThemeObject[QLatin1String(
"editor-colors")] = colors;
459 writeJson(newThemeObject, theme.
filePath());
466void KateThemeConfigColorTab::reload()
472 const auto backupName = m_currentSchema;
473 m_currentSchema.clear();
474 schemaChanged(backupName);
477QColor KateThemeConfigColorTab::backgroundColor()
const
479 return ui->findColor(QStringLiteral(
"Color Background"));
482QColor KateThemeConfigColorTab::selectionColor()
const
484 return ui->findColor(QStringLiteral(
"Color Selection"));
489KateThemeConfigDefaultStylesTab::KateThemeConfigDefaultStylesTab(KateThemeConfigColorTab *colorTab)
491 m_colorTab = colorTab;
494 QGridLayout *grid =
new QGridLayout(
this);
496 m_defaultStyles =
new KateStyleTreeWidget(
this);
497 connect(m_defaultStyles, &KateStyleTreeWidget::changed,
this, &KateThemeConfigDefaultStylesTab::changed);
500 m_defaultStyles->setWhatsThis(
501 i18n(
"<p>This list displays the default styles for the current color theme and "
502 "offers the means to edit them. The style name reflects the current "
503 "style settings.</p>"
504 "<p>To edit the colors, click the colored squares, or select the color "
505 "to edit from the popup menu.</p><p>You can unset the Background and Selected "
506 "Background colors from the popup menu when appropriate.</p>"));
509KateAttributeList *KateThemeConfigDefaultStylesTab::attributeList(
const QString &schema)
511 auto it = m_defaultStyleLists.find(schema);
512 if (it == m_defaultStyleLists.end()) {
515 KateAttributeList
list;
517 const KSyntaxHighlighting::Theme currentTheme = KateHlManager::self()->repository().
theme(schema);
518 for (
int z = 0; z < numStyles; z++) {
533 i->clearBackground();
539 i->clearProperty(SelectedBackground);
548 it = m_defaultStyleLists.emplace(schema, list).first;
551 return &(it->second);
554void KateThemeConfigDefaultStylesTab::schemaChanged(
const QString &schema)
557 const auto theme = KateHlManager::self()->repository().
theme(schema);
560 m_currentSchema = schema;
562 m_defaultStyles->
clear();
564 KateAttributeList *l = attributeList(schema);
565 updateColorPalette(l->
at(0)->foreground().color());
568 QTreeWidgetItem *
parent =
new QTreeWidgetItem(m_defaultStyles, QStringList() <<
i18nc(
"@item:intable",
"Normal Text & Source Code"));
569 parent->setFirstColumnSpanned(
true);
570 for (
int i = (
int)KSyntaxHighlighting::Theme::TextStyle::Normal; i <= (int)KSyntaxHighlighting::Theme::TextStyle::Attribute; ++i) {
575 parent =
new QTreeWidgetItem(m_defaultStyles, QStringList() <<
i18nc(
"@item:intable",
"Numbers, Types & Constants"));
576 parent->setFirstColumnSpanned(
true);
577 for (
int i = (
int)KSyntaxHighlighting::Theme::TextStyle::DataType; i <= (int)KSyntaxHighlighting::Theme::TextStyle::Constant; ++i) {
582 parent =
new QTreeWidgetItem(m_defaultStyles, QStringList() <<
i18nc(
"@item:intable",
"Strings & Characters"));
583 parent->setFirstColumnSpanned(
true);
584 for (
int i = (
int)KSyntaxHighlighting::Theme::TextStyle::Char; i <= (int)KSyntaxHighlighting::Theme::TextStyle::Import; ++i) {
589 parent =
new QTreeWidgetItem(m_defaultStyles, QStringList() <<
i18nc(
"@item:intable",
"Comments & Documentation"));
590 parent->setFirstColumnSpanned(
true);
591 for (
int i = (
int)KSyntaxHighlighting::Theme::TextStyle::Comment; i <= (int)KSyntaxHighlighting::Theme::TextStyle::Alert; ++i) {
596 parent =
new QTreeWidgetItem(m_defaultStyles, QStringList() <<
i18nc(
"@item:intable",
"Miscellaneous"));
597 parent->setFirstColumnSpanned(
true);
598 for (
int i = (
int)KSyntaxHighlighting::Theme::TextStyle::Others; i <= (int)KSyntaxHighlighting::Theme::TextStyle::Error; ++i) {
602 m_defaultStyles->expandAll();
605void KateThemeConfigDefaultStylesTab::updateColorPalette(
const QColor &textColor)
607 QPalette p(m_defaultStyles->palette());
611 m_defaultStyles->setPalette(p);
614void KateThemeConfigDefaultStylesTab::reload()
616 m_defaultStyles->clear();
617 m_defaultStyleLists.clear();
619 schemaChanged(m_currentSchema);
622void KateThemeConfigDefaultStylesTab::apply()
625 static const auto idx = KSyntaxHighlighting::Theme::staticMetaObject.indexOfEnumerator(
"TextStyle");
627 const auto metaEnum = KSyntaxHighlighting::Theme::staticMetaObject.enumerator(idx);
630 for (
const auto &kv : m_defaultStyleLists) {
632 const auto theme = KateHlManager::self()->repository().
theme(kv.first);
638 QJsonObject newThemeObject = jsonForTheme(theme);
643 for (
int z = 0; z < numStyles; z++) {
647 style[QLatin1String(
"text-color")] = hexName(p->foreground().color());
650 style[QLatin1String(
"background-color")] = hexName(p->background().color());
652 if (p->hasProperty(SelectedForeground)) {
653 style[QLatin1String(
"selected-text-color")] = hexName(p->selectedForeground().color());
655 if (p->hasProperty(SelectedBackground)) {
656 style[QLatin1String(
"selected-background-color")] = hexName(p->selectedBackground().color());
659 style[QLatin1String(
"bold")] =
true;
662 style[QLatin1String(
"italic")] =
true;
665 style[QLatin1String(
"underline")] =
true;
668 style[QLatin1String(
"strike-through")] =
true;
670 styles[QLatin1String(metaEnum.key((z)))] =
style;
672 newThemeObject[QLatin1String(
"text-styles")] = styles;
675 writeJson(newThemeObject, theme.
filePath());
679void KateThemeConfigDefaultStylesTab::showEvent(
QShowEvent *event)
681 if (!
event->spontaneous() && !m_currentSchema.isEmpty()) {
682 KateAttributeList *l = attributeList(m_currentSchema);
683 Q_ASSERT(l !=
nullptr);
684 updateColorPalette(l->
at(0)->foreground().color());
692KateThemeConfigHighlightTab::KateThemeConfigHighlightTab(KateThemeConfigDefaultStylesTab *page, KateThemeConfigColorTab *colorTab)
695 m_colorTab = colorTab;
699 QVBoxLayout *
layout =
new QVBoxLayout(
this);
701 QHBoxLayout *headerLayout =
new QHBoxLayout;
702 layout->addLayout(headerLayout);
704 QLabel *lHl =
new QLabel(
i18n(
"H&ighlight:"),
this);
707 hlCombo =
new QComboBox(
this);
708 hlCombo->setEditable(
false);
716 const auto modeList = KateHlManager::self()->modeList();
717 for (
const auto &hl : modeList) {
718 const auto section = hl.translatedSection();
719 if (!section.isEmpty()) {
720 hlCombo->addItem(section + QLatin1Char(
'/') + hl.translatedName());
722 hlCombo->addItem(hl.translatedName());
725 hlCombo->setCurrentIndex(0);
728 m_styles =
new KateStyleTreeWidget(
this,
true);
729 connect(m_styles, &KateStyleTreeWidget::changed,
this, &KateThemeConfigHighlightTab::changed);
730 layout->addWidget(m_styles, 999);
734 KTextEditor::ViewPrivate *kv =
737 const QString hlName = kv->doc()->highlight()->name();
738 hl = KateHlManager::self()->nameFind(hlName);
742 hlCombo->setCurrentIndex(hl);
745 m_styles->setWhatsThis(
746 i18n(
"<p>This list displays the contexts of the current syntax highlight mode and "
747 "offers the means to edit them. The context name reflects the current "
748 "style settings.</p><p>To edit using the keyboard, press "
749 "<strong><SPACE></strong> and choose a property from the popup menu.</p>"
750 "<p>To edit the colors, click the colored squares, or select the color "
751 "to edit from the popup menu.</p><p>You can unset the Background and Selected "
752 "Background colors from the context menu when appropriate.</p>"));
755void KateThemeConfigHighlightTab::hlChanged(
int z)
758 schemaChanged(m_schema);
765static KateAttributeList defaultsForHighlighting(
const std::vector<KSyntaxHighlighting::Format> &formats,
const KateAttributeList &defaultStyleAttributes)
769 for (
const auto &format : formats) {
776 if (format.hasTextColorOverride()) {
777 newAttribute->setForeground(format.textColor(invalidTheme));
779 if (format.hasBackgroundColorOverride()) {
780 newAttribute->setBackground(format.backgroundColor(invalidTheme));
782 if (format.hasSelectedTextColorOverride()) {
783 newAttribute->setSelectedForeground(format.selectedTextColor(invalidTheme));
785 if (format.hasSelectedBackgroundColorOverride()) {
786 newAttribute->setSelectedBackground(format.selectedBackgroundColor(invalidTheme));
788 if (format.hasBoldOverride()) {
789 newAttribute->setFontBold(format.isBold(invalidTheme));
791 if (format.hasItalicOverride()) {
792 newAttribute->setFontItalic(format.isItalic(invalidTheme));
794 if (format.hasUnderlineOverride()) {
795 newAttribute->setFontUnderline(format.isUnderline(invalidTheme));
797 if (format.hasStrikeThroughOverride()) {
798 newAttribute->setFontStrikeOut(format.isStrikeThrough(invalidTheme));
802 newAttribute->setSkipSpellChecking(format.spellCheck());
808void KateThemeConfigHighlightTab::schemaChanged(
const QString &schema)
811 const auto theme = KateHlManager::self()->repository().
theme(schema);
815 const auto isNoneSchema = m_hl == 0;
822 auto it = m_hlDict.find(m_schema);
823 if (it == m_hlDict.end()) {
824 it = m_hlDict.insert(schema, QHash<
int, QList<KTextEditor::Attribute::Ptr>>());
828 KateAttributeList *l = m_defaults->attributeList(schema);
829 updateColorPalette(l->
at(0)->foreground().color());
832 auto attributes = KateHlManager::self()->getHl(m_hl)->attributesForDefinition(m_schema);
833 auto formats = KateHlManager::self()->getHl(m_hl)->formats();
834 auto defaults = defaultsForHighlighting(formats, *l);
836 for (
int i = 0; i < attributes.size(); ++i) {
839 int c = attributes[i]->
name().
indexOf(QLatin1Char(
':'));
844 QString highlighting = attributes[i]->name().left(c);
845 QString
name = attributes[i]->name().
mid(c + 1);
846 auto &uniqueAttribute = m_uniqueAttributes[m_schema][highlighting][
name].
first;
847 auto &uniqueAttributeDefault = m_uniqueAttributes[m_schema][highlighting][
name].second;
849 if (uniqueAttribute.data()) {
850 attributes[i] = uniqueAttribute;
852 uniqueAttribute = attributes[i];
855 if (uniqueAttributeDefault.data()) {
856 defaults[i] = uniqueAttributeDefault;
858 uniqueAttributeDefault =
defaults[i];
862 auto &subMap = it.value();
863 auto it1 = subMap.find(m_hl);
864 if (it1 == subMap.end()) {
865 it1 = subMap.insert(m_hl, attributes);
868 QHash<QString, QTreeWidgetItem *> prefixes;
869 const auto &attribs = it1.value();
870 auto vec_it = attribs.cbegin();
872 while (vec_it != attribs.end()) {
878 int c = itemData->name().indexOf(QLatin1Char(
':'));
880 QString prefix = itemData->name().left(c);
881 QString
name = itemData->name().mid(c + 1);
883 QTreeWidgetItem *
parent = prefixes[prefix];
885 parent =
new QTreeWidgetItem(m_styles, QStringList() << prefix);
886 m_styles->expandItem(
parent);
891 m_styles->addItem(itemData->name(),
defaults.at(i), itemData);
897 m_styles->resizeColumns();
900void KateThemeConfigHighlightTab::updateColorPalette(
const QColor &textColor)
902 QPalette p(m_styles->palette());
906 m_styles->setPalette(p);
909void KateThemeConfigHighlightTab::reload()
914 m_uniqueAttributes.clear();
916 hlChanged(hlCombo->currentIndex());
919void KateThemeConfigHighlightTab::apply()
922 for (
const auto &themeIt : m_uniqueAttributes) {
924 const auto theme = KateHlManager::self()->repository().
theme(themeIt.first);
930 QJsonObject newThemeObject = jsonForTheme(theme);
933 QJsonObject overrides = newThemeObject[QLatin1String(
"custom-styles")].toObject();
934 for (
const auto &highlightingIt : themeIt.second) {
936 const QString definitionName = highlightingIt.first;
937 QJsonObject styles = overrides[definitionName].toObject();
938 for (
const auto &attributeIt : highlightingIt.second) {
943 if (p->foreground().color() != pDefault->foreground().color()) {
944 style[QLatin1String(
"text-color")] = hexName(p->foreground().color());
946 if (p->background().color() != pDefault->background().color()) {
947 style[QLatin1String(
"background-color")] = hexName(p->background().color());
949 if (p->selectedForeground().color() != pDefault->selectedForeground().color()) {
950 style[QLatin1String(
"selected-text-color")] = hexName(p->selectedForeground().color());
952 if (p->selectedBackground().color() != pDefault->selectedBackground().color()) {
953 style[QLatin1String(
"selected-background-color")] = hexName(p->selectedBackground().color());
955 if (p->fontBold() != pDefault->fontBold()) {
956 style[QLatin1String(
"bold")] = p->fontBold();
958 if (p->fontItalic() != pDefault->fontItalic()) {
959 style[QLatin1String(
"italic")] = p->fontItalic();
961 if (p->fontUnderline() != pDefault->fontUnderline()) {
962 style[QLatin1String(
"underline")] = p->fontUnderline();
964 if (p->fontStrikeOut() != pDefault->fontStrikeOut()) {
965 style[QLatin1String(
"strike-through")] = p->fontStrikeOut();
969 if (!
style.isEmpty()) {
970 styles[attributeIt.first] =
style;
972 styles.
remove(attributeIt.first);
978 overrides[definitionName] = styles;
980 overrides.
remove(definitionName);
985 newThemeObject[QLatin1String(
"custom-styles")] = overrides;
988 writeJson(newThemeObject, theme.
filePath());
994 auto it = m_hlDict.find(schema);
995 if (it != m_hlDict.end()) {
996 return it.value().keys();
1001void KateThemeConfigHighlightTab::showEvent(
QShowEvent *event)
1003 if (!
event->spontaneous()) {
1004 KateAttributeList *l = m_defaults->attributeList(m_schema);
1005 Q_ASSERT(l !=
nullptr);
1006 updateColorPalette(l->
at(0)->foreground().color());
1014KateThemeConfigPage::KateThemeConfigPage(
QWidget *parent)
1015 : KateConfigPage(parent)
1024 auto *themeEditor =
new QWidget(
this);
1025 auto *themeChooser =
new QWidget(
this);
1026 tabWidget->
addTab(themeChooser,
i18n(
"Default Theme"));
1027 tabWidget->
addTab(themeEditor,
i18n(
"Theme Editor"));
1028 layoutThemeChooserTab(themeChooser);
1029 layoutThemeEditorTab(themeEditor);
1034void KateThemeConfigPage::layoutThemeChooserTab(
QWidget *tab)
1036 QVBoxLayout *
layout =
new QVBoxLayout(tab);
1037 layout->setContentsMargins({});
1039 auto *comboLayout =
new QHBoxLayout;
1041 auto lHl =
new QLabel(
i18n(
"Select theme:"),
this);
1042 comboLayout->addWidget(lHl);
1044 defaultSchemaCombo =
new QComboBox(
this);
1045 comboLayout->addWidget(defaultSchemaCombo);
1046 defaultSchemaCombo->setEditable(
false);
1049 comboLayout->addStretch();
1051 layout->addLayout(comboLayout);
1053 m_doc =
new KTextEditor::DocumentPrivate;
1054 m_doc->setParent(
this);
1056 const auto code = R
"sample(
1071int main(uint64_t magicArgument)
1073 if (magicArgument > 1) {
1074 const std::string string = "source file: \"" __FILE__ "\"";
1075 const QString qString(QStringLiteral("test"));
1079 /* BUG: bogus integer constant inside next line */
1080 const double g = 1.1e12 * 0b01'01'01'01 - 43a + 0x11234 * 0234ULL - 'c' * 42;
1085 m_doc->setHighlightingMode(QStringLiteral(
"C++"));
1086 m_themePreview =
new KTextEditor::ViewPrivate(m_doc,
this);
1088 layout->addWidget(m_themePreview);
1091 const QString schema = defaultSchemaCombo->itemData(idx).toString();
1092 m_themePreview->rendererConfig()->setSchema(schema);
1094 m_themePreview->rendererConfig()->setValue(KateRendererConfig::AutoColorThemeSelection,
true);
1096 m_themePreview->rendererConfig()->setValue(KateRendererConfig::AutoColorThemeSelection,
false);
1101void KateThemeConfigPage::layoutThemeEditorTab(
QWidget *tab)
1103 QVBoxLayout *
layout =
new QVBoxLayout(tab);
1104 layout->setContentsMargins(0, 0, 0, 0);
1107 QHBoxLayout *headerLayout =
new QHBoxLayout;
1108 layout->addLayout(headerLayout);
1110 QLabel *lHl =
new QLabel(
i18n(
"&Theme:"),
this);
1113 schemaCombo =
new QComboBox(
this);
1114 schemaCombo->setEditable(
false);
1119 auto *copyButton =
new QPushButton(
i18nc(
"@action:button",
"&Copy…"),
this);
1123 btndel =
new QPushButton(
i18n(
"&Delete"),
this);
1127 auto *btnexport =
new QPushButton(
i18nc(
"@action:button",
"Export…"),
this);
1131 auto *btnimport =
new QPushButton(
i18nc(
"@action:button",
"Import…"),
this);
1138 m_readOnlyThemeLabel =
new KMessageWidget(
i18n(
"Bundled read-only theme. To modify the theme, please copy it."),
this);
1139 m_readOnlyThemeLabel->setCloseButtonVisible(
false);
1141 m_readOnlyThemeLabel->hide();
1142 layout->addWidget(m_readOnlyThemeLabel);
1145 QTabWidget *tabWidget =
new QTabWidget(
this);
1146 layout->addWidget(tabWidget);
1148 m_colorTab =
new KateThemeConfigColorTab();
1149 tabWidget->
addTab(m_colorTab,
i18n(
"Colors"));
1150 connect(m_colorTab, &KateThemeConfigColorTab::changed,
this, &KateThemeConfigPage::slotChanged);
1152 m_defaultStylesTab =
new KateThemeConfigDefaultStylesTab(m_colorTab);
1153 tabWidget->
addTab(m_defaultStylesTab,
i18n(
"Default Text Styles"));
1154 connect(m_defaultStylesTab, &KateThemeConfigDefaultStylesTab::changed,
this, &KateThemeConfigPage::slotChanged);
1156 m_highlightTab =
new KateThemeConfigHighlightTab(m_defaultStylesTab, m_colorTab);
1157 tabWidget->
addTab(m_highlightTab,
i18n(
"Highlighting Text Styles"));
1158 connect(m_highlightTab, &KateThemeConfigHighlightTab::changed,
this, &KateThemeConfigPage::slotChanged);
1160 QHBoxLayout *footLayout =
new QHBoxLayout;
1161 layout->addLayout(footLayout);
1164void KateThemeConfigPage::exportFullSchema()
1167 const QString currentSchemaName = m_currentSchema;
1169 i18n(
"Exporting color theme: %1", currentSchemaName),
1170 currentSchemaName + QLatin1String(
".theme"),
1171 QStringLiteral(
"%1 (*.theme)").arg(
i18n(
"Color theme")));
1177 const QString currentThemeName = schemaCombo->itemData(schemaCombo->currentIndex()).toString();
1178 const auto currentTheme = KateHlManager::self()->repository().
theme(currentThemeName);
1189void KateThemeConfigPage::importFullSchema()
1191 const QString srcName =
1201 const QString themesFullFileName = themesPath + QStringLiteral(
"/") + QFileInfo(srcName).fileName();
1206 i18n(
"Importing will overwrite the existing theme file \"%1\". This can not be undone.", themesFullFileName),
1207 i18n(
"Possible Data Loss"),
1208 KGuiItem(
i18n(
"Import Nevertheless")),
1216 QDir().mkpath(themesPath);
1225 KateHlManager::self()->reload();
1226 for (
int i = 0; i < KateHlManager::self()->modeList().size(); ++i) {
1227 KateHlManager::self()->getHl(i)->clearAttributeArrays();
1232 refillCombos(schemaCombo->itemData(schemaCombo->currentIndex()).toString(), defaultSchemaCombo->itemData(defaultSchemaCombo->currentIndex()).toString());
1235void KateThemeConfigPage::apply()
1238 const QString schemaName = schemaCombo->itemData(schemaCombo->currentIndex()).toString();
1241 m_colorTab->apply();
1242 m_defaultStylesTab->apply();
1243 m_highlightTab->apply();
1246 KateHlManager::self()->reload();
1247 for (
int i = 0; i < KateHlManager::self()->modeList().size(); ++i) {
1248 KateHlManager::self()->getHl(i)->clearAttributeArrays();
1252 const auto defaultTheme = defaultSchemaCombo->itemData(defaultSchemaCombo->currentIndex()).toString();
1253 if (defaultTheme.isEmpty()) {
1254 KateRendererConfig::global()->
setValue(KateRendererConfig::AutoColorThemeSelection,
true);
1256 KateRendererConfig::global()->
setValue(KateRendererConfig::AutoColorThemeSelection,
false);
1257 KateRendererConfig::global()->setSchema(defaultTheme);
1259 KateRendererConfig::global()->reloadSchema();
1263 refillCombos(schemaCombo->itemData(schemaCombo->currentIndex()).toString(), defaultSchemaCombo->itemData(defaultSchemaCombo->currentIndex()).toString());
1264 schemaChanged(schemaName);
1268 m_colorTab->reload();
1269 m_defaultStylesTab->reload();
1270 m_highlightTab->reload();
1273void KateThemeConfigPage::reload()
1276 refillCombos(KateRendererConfig::global()->schema(), KateRendererConfig::global()->schema());
1279 schemaChanged(schemaCombo->itemData(schemaCombo->currentIndex()).toString());
1283 m_colorTab->reload();
1284 m_defaultStylesTab->reload();
1285 m_highlightTab->reload();
1288void KateThemeConfigPage::refillCombos(
const QString &schemaName,
const QString &defaultSchemaName)
1290 schemaCombo->blockSignals(
true);
1291 defaultSchemaCombo->blockSignals(
true);
1294 schemaCombo->clear();
1295 defaultSchemaCombo->clear();
1296 defaultSchemaCombo->addItem(
i18n(
"Follow System Color Scheme"), QString());
1297 defaultSchemaCombo->insertSeparator(1);
1298 const auto themes = KateHlManager::self()->sortedThemes();
1299 for (
const auto &theme : themes) {
1305 int schemaIndex = schemaCombo->findData(schemaName);
1306 if (schemaIndex == -1) {
1307 schemaIndex = schemaCombo->findData(
1312 int defaultSchemaIndex = 0;
1313 if (!KateRendererConfig::global()->value(KateRendererConfig::AutoColorThemeSelection).toBool()) {
1314 defaultSchemaIndex = defaultSchemaCombo->findData(defaultSchemaName);
1315 if (defaultSchemaIndex == -1) {
1316 defaultSchemaIndex = 0;
1320 Q_ASSERT(schemaIndex != -1);
1321 Q_ASSERT(defaultSchemaIndex != -1);
1323 defaultSchemaCombo->setCurrentIndex(defaultSchemaIndex);
1324 schemaCombo->setCurrentIndex(schemaIndex);
1326 schemaCombo->blockSignals(
false);
1327 defaultSchemaCombo->blockSignals(
false);
1329 m_themePreview->rendererConfig()->setSchema(defaultSchemaName);
1332void KateThemeConfigPage::reset()
1335 KateHlManager::self()->reload();
1336 for (
int i = 0; i < KateHlManager::self()->modeList().size(); ++i) {
1337 KateHlManager::self()->getHl(i)->clearAttributeArrays();
1344void KateThemeConfigPage::defaults()
1349void KateThemeConfigPage::deleteSchema()
1351 const int comboIndex = schemaCombo->currentIndex();
1352 const QString schemaNameToDelete = schemaCombo->itemData(comboIndex).toString();
1355 const auto theme = KateHlManager::self()->repository().
theme(schemaNameToDelete);
1362 i18n(
"Do you really want to delete the theme \"%1\"? This can not be undone.", schemaNameToDelete),
1363 i18n(
"Possible Data Loss"),
1364 KGuiItem(
i18n(
"Delete Nevertheless")),
1374 KateHlManager::self()->reload();
1377 schemaCombo->setCurrentIndex(schemaCombo->findData(
1379 if (defaultSchemaCombo->currentIndex() == defaultSchemaCombo->findData(schemaNameToDelete)) {
1380 defaultSchemaCombo->setCurrentIndex(0);
1384 schemaCombo->removeItem(comboIndex);
1385 defaultSchemaCombo->removeItem(comboIndex);
1388 m_colorTab->reload();
1391bool KateThemeConfigPage::copyTheme()
1394 const QString currentThemeName = schemaCombo->itemData(schemaCombo->currentIndex()).toString();
1395 const auto currentTheme = KateHlManager::self()->repository().
theme(currentThemeName);
1402 QString themeFileName;
1403 while (schemaName.
isEmpty()) {
1404 QInputDialog newNameDialog(
this);
1406 newNameDialog.setWindowTitle(
i18n(
"Copy theme"));
1407 newNameDialog.setLabelText(
i18n(
"Name for copy of color theme \"%1\":", currentThemeName));
1408 newNameDialog.setTextValue(currentThemeName);
1412 schemaName = newNameDialog.textValue();
1416 themeFileName = themesPath + QStringLiteral(
"/") + schemaName + QStringLiteral(
".theme");
1417 if (KateHlManager::self()->repository().theme(schemaName).
isValid() ||
QFile::exists(themeFileName)) {
1419 i18n(
"<p>The theme \"%1\" already exists.</p><p>Please choose a different theme name.</p>", schemaName),
1420 i18n(
"Copy Theme"));
1426 QJsonObject newThemeObject = jsonForTheme(currentTheme);
1427 QJsonObject metaData;
1428 metaData[QLatin1String(
"revision")] = 1;
1429 metaData[QLatin1String(
"name")] = schemaName;
1430 newThemeObject[QLatin1String(
"metadata")] = metaData;
1433 QDir().mkpath(themesPath);
1434 if (!writeJson(newThemeObject, themeFileName)) {
1439 KateHlManager::self()->reload();
1442 schemaCombo->addItem(schemaName, QVariant(schemaName));
1443 defaultSchemaCombo->addItem(schemaName, QVariant(schemaName));
1446 schemaCombo->setCurrentIndex(schemaCombo->count() - 1);
1450void KateThemeConfigPage::schemaChanged(
const QString &schema)
1453 const auto theme = KateHlManager::self()->repository().
theme(schema);
1455 m_readOnlyThemeLabel->setVisible(theme.
isReadOnly());
1458 m_colorTab->schemaChanged(schema);
1459 m_defaultStylesTab->schemaChanged(schema);
1460 m_highlightTab->schemaChanged(schema);
1463 m_currentSchema = schema;
1466void KateThemeConfigPage::comboBoxIndexChanged(
int currentIndex)
1468 schemaChanged(schemaCombo->itemData(currentIndex).toString());
1471QString KateThemeConfigPage::name()
const
1473 return i18n(
"Color Themes");
1476QString KateThemeConfigPage::fullName()
const
1478 return i18n(
"Color Themes");
1481QIcon KateThemeConfigPage::icon()
const
1488#include "moc_katethemeconfig.cpp"
Q_INVOKABLE KSyntaxHighlighting::Theme theme(const QString &themeName) const
bool isStrikeThrough(TextStyle style) const
QString translatedName() const
QRgb textColor(TextStyle style) const
bool isBold(TextStyle style) const
QRgb selectedTextColor(TextStyle style) const
QRgb selectedBackgroundColor(TextStyle style) const
bool isUnderline(TextStyle style) const
TemplateFocusedPlaceholder
TemplateReadOnlyPlaceholder
bool isItalic(TextStyle style) const
QRgb backgroundColor(TextStyle style) const
QRgb editorColor(EditorColorRole role) const
A class which provides customized text decorations.
QExplicitlySharedDataPointer< Attribute > Ptr
Shared data pointer for Attribute.
static KTextEditor::EditorPrivate * self()
Kate Part Internal stuff ;)
bool setValue(const int key, const QVariant &value)
Set a config value.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
bool isValid(QStringView ifopt)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QString name(StandardAction id)
const QList< QKeySequence > & reload()
The KTextEditor namespace contains all the public API that is required to use the KTextEditor compone...
void addStretch(int stretch)
QColor fromRgba(QRgb rgba)
QString name(NameFormat format) const const
void activated(int index)
void currentIndexChanged(int index)
bool copy(const QString &fileName, const QString &newName)
bool exists() const const
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
void setColumnStretch(int column, int stretch)
iterator insert(const Key &key, const T &value)
QIcon fromTheme(const QString &name)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonObject object() const const
bool isEmpty() const const
void remove(QLatin1StringView key)
void setBuddy(QWidget *buddy)
void setContentsMargins(const QMargins &margins)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
void reserve(qsizetype size)
bool blockSignals(bool block)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool event(QEvent *e)
QObject * parent() const const
T qobject_cast(QObject *object)
QString writableLocation(StandardLocation type)
QString first(qsizetype n) const const
QString fromUtf8(QByteArrayView str)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString mid(qsizetype position, qsizetype n) const const
QString number(double n, char format, int precision)