1 /*
2 SPDX-FileCopyrightText: 2007, 2008 Matthew Woehlke <mw_triad@users.sourceforge.net>
3 SPDX-FileCopyrightText: 2003 Christoph Cullmann <cullmann@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8 #include "kateconfig.h"
9
10 #include "katedocument.h"
11 #include "kateglobal.h"
12 #include "katepartdebug.h"
13 #include "katerenderer.h"
14 #include "katesyntaxmanager.h"
15 #include "kateview.h"
16
17 #include <KCharsets>
18 #include <KConfigGroup>
19
20 #include <QGuiApplication>
21 #include <QSettings>
22 #include <QStringListModel>
23 #include <QTextCodec>
24
25 #include <Sonnet/GuessLanguage>
26 #include <Sonnet/Speller>
27
28 // BEGIN KateConfig
KateConfig(const KateConfig * parent)29 KateConfig::KateConfig(const KateConfig *parent)
30 : m_parent(parent)
31 , m_configKeys(m_parent ? nullptr : new QStringList())
32 , m_configKeyToEntry(m_parent ? nullptr : new QHash<QString, const ConfigEntry *>())
33 {
34 }
35
36 KateConfig::~KateConfig() = default;
37
addConfigEntry(ConfigEntry && entry)38 void KateConfig::addConfigEntry(ConfigEntry &&entry)
39 {
40 // shall only be called for toplevel config
41 Q_ASSERT(isGlobal());
42
43 // there shall be no gaps in the entries
44 // we might later want to use a vector
45 Q_ASSERT(m_configEntries.size() == static_cast<size_t>(entry.enumKey));
46
47 // add new element
48 m_configEntries.emplace(entry.enumKey, entry);
49 }
50
finalizeConfigEntries()51 void KateConfig::finalizeConfigEntries()
52 {
53 // shall only be called for toplevel config
54 Q_ASSERT(isGlobal());
55
56 // compute list of all config keys + register map from key => config entry
57 //
58 // we skip entries without a command name, these config entries are not exposed ATM
59 for (const auto &entry : m_configEntries) {
60 if (!entry.second.commandName.isEmpty()) {
61 Q_ASSERT_X(!m_configKeys->contains(entry.second.commandName),
62 "finalizeConfigEntries",
63 (QLatin1String("KEY NOT UNIQUE: ") + entry.second.commandName).toLocal8Bit().constData());
64 m_configKeys->append(entry.second.commandName);
65 m_configKeyToEntry->insert(entry.second.commandName, &entry.second);
66 }
67 }
68 }
69
readConfigEntries(const KConfigGroup & config)70 void KateConfig::readConfigEntries(const KConfigGroup &config)
71 {
72 configStart();
73
74 // read all config entries, even the ones ATM not set in this config object but known in the toplevel one
75 for (const auto &entry : fullConfigEntries()) {
76 setValue(entry.second.enumKey, config.readEntry(entry.second.configKey, entry.second.defaultValue));
77 }
78
79 configEnd();
80 }
81
writeConfigEntries(KConfigGroup & config) const82 void KateConfig::writeConfigEntries(KConfigGroup &config) const
83 {
84 // write all config entries, even the ones ATM not set in this config object but known in the toplevel one
85 for (const auto &entry : fullConfigEntries()) {
86 config.writeEntry(entry.second.configKey, value(entry.second.enumKey));
87 }
88 }
89
configStart()90 void KateConfig::configStart()
91 {
92 configSessionNumber++;
93
94 if (configSessionNumber > 1) {
95 return;
96 }
97
98 configIsRunning = true;
99 }
100
configEnd()101 void KateConfig::configEnd()
102 {
103 if (configSessionNumber == 0) {
104 return;
105 }
106
107 configSessionNumber--;
108
109 if (configSessionNumber > 0) {
110 return;
111 }
112
113 configIsRunning = false;
114
115 updateConfig();
116 }
117
value(const int key) const118 QVariant KateConfig::value(const int key) const
119 {
120 // first: local lookup
121 const auto it = m_configEntries.find(key);
122 if (it != m_configEntries.end()) {
123 return it->second.value;
124 }
125
126 // else: fallback to parent config, if any
127 if (m_parent) {
128 return m_parent->value(key);
129 }
130
131 // if we arrive here, the key was invalid! => programming error
132 // for release builds, we just return invalid variant
133 Q_ASSERT(false);
134 return QVariant();
135 }
136
setValue(const int key,const QVariant & value)137 bool KateConfig::setValue(const int key, const QVariant &value)
138 {
139 // check: is this key known at all?
140 const auto &knownEntries = fullConfigEntries();
141 const auto knownIt = knownEntries.find(key);
142 if (knownIt == knownEntries.end()) {
143 // if we arrive here, the key was invalid! => programming error
144 // for release builds, we just fail to set the value
145 Q_ASSERT(false);
146 return false;
147 }
148
149 // validator set? use it, if not accepting, abort setting
150 if (knownIt->second.validator && !knownIt->second.validator(value)) {
151 return false;
152 }
153
154 // check if value already there for this config
155 auto valueIt = m_configEntries.find(key);
156 if (valueIt != m_configEntries.end()) {
157 // skip any work if value is equal
158 if (valueIt->second.value == value) {
159 return true;
160 }
161
162 // else: alter value and be done
163 configStart();
164 valueIt->second.value = value;
165 configEnd();
166 return true;
167 }
168
169 // if not in this hash, we must copy the known entry and adjust the value
170 configStart();
171 auto res = m_configEntries.emplace(key, knownIt->second);
172 res.first->second.value = value;
173 configEnd();
174 return true;
175 }
176
value(const QString & key) const177 QVariant KateConfig::value(const QString &key) const
178 {
179 // check if we know this key, if not, return invalid variant
180 const auto &knownEntries = fullConfigKeyToEntry();
181 const auto it = knownEntries.find(key);
182 if (it == knownEntries.end()) {
183 return QVariant();
184 }
185
186 // key known, dispatch to normal value() function with enum
187 return value(it.value()->enumKey);
188 }
189
setValue(const QString & key,const QVariant & value)190 bool KateConfig::setValue(const QString &key, const QVariant &value)
191 {
192 // check if we know this key, if not, ignore the set
193 const auto &knownEntries = fullConfigKeyToEntry();
194 const auto it = knownEntries.find(key);
195 if (it == knownEntries.end()) {
196 return false;
197 }
198
199 // key known, dispatch to normal setValue() function with enum
200 return setValue(it.value()->enumKey, value);
201 }
202
203 // END
204
205 // BEGIN HelperFunctions
206 KateGlobalConfig *KateGlobalConfig::s_global = nullptr;
207 KateDocumentConfig *KateDocumentConfig::s_global = nullptr;
208 KateViewConfig *KateViewConfig::s_global = nullptr;
209 KateRendererConfig *KateRendererConfig::s_global = nullptr;
210
211 /**
212 * validate if an encoding is ok
213 * @param name encoding name
214 * @return encoding ok?
215 */
isEncodingOk(const QString & name)216 static bool isEncodingOk(const QString &name)
217 {
218 bool found = false;
219 auto codec = KCharsets::charsets()->codecForName(name, found);
220 return found && codec;
221 }
222
inBounds(const int min,const QVariant & value,const int max)223 static bool inBounds(const int min, const QVariant &value, const int max)
224 {
225 const int val = value.toInt();
226 return (val >= min) && (val <= max);
227 }
228
isPositive(const QVariant & value)229 static bool isPositive(const QVariant &value)
230 {
231 bool ok;
232 value.toUInt(&ok);
233 return ok;
234 }
235 // END
236
237 // BEGIN KateGlobalConfig
KateGlobalConfig()238 KateGlobalConfig::KateGlobalConfig()
239 {
240 // register this as our global instance
241 Q_ASSERT(isGlobal());
242 s_global = this;
243
244 // init all known config entries
245 addConfigEntry(ConfigEntry(EncodingProberType, "Encoding Prober Type", QString(), KEncodingProber::Universal));
246 addConfigEntry(ConfigEntry(FallbackEncoding, "Fallback Encoding", QString(), QStringLiteral("ISO 8859-15"), [](const QVariant &value) {
247 return isEncodingOk(value.toString());
248 }));
249
250 // finalize the entries, e.g. hashs them
251 finalizeConfigEntries();
252
253 // init with defaults from config or really hardcoded ones
254 KConfigGroup cg(KTextEditor::EditorPrivate::config(), "KTextEditor Editor");
255 readConfig(cg);
256 }
257
readConfig(const KConfigGroup & config)258 void KateGlobalConfig::readConfig(const KConfigGroup &config)
259 {
260 // start config update group
261 configStart();
262
263 // read generic entries
264 readConfigEntries(config);
265
266 // end config update group, might trigger updateConfig()
267 configEnd();
268 }
269
writeConfig(KConfigGroup & config)270 void KateGlobalConfig::writeConfig(KConfigGroup &config)
271 {
272 // write generic entries
273 writeConfigEntries(config);
274 }
275
updateConfig()276 void KateGlobalConfig::updateConfig()
277 {
278 // write config
279 KConfigGroup cg(KTextEditor::EditorPrivate::config(), "KTextEditor Editor");
280 writeConfig(cg);
281 KTextEditor::EditorPrivate::config()->sync();
282
283 // trigger emission of KTextEditor::Editor::configChanged
284 KTextEditor::EditorPrivate::self()->triggerConfigChanged();
285 }
286
fallbackCodec() const287 QTextCodec *KateGlobalConfig::fallbackCodec() const
288 {
289 // query stored encoding, always fallback to ISO 8859-15 if nothing valid set
290 const auto encoding = value(FallbackEncoding).toString();
291 if (encoding.isEmpty()) {
292 return QTextCodec::codecForName("ISO 8859-15");
293 }
294
295 // use configured encoding
296 return KCharsets::charsets()->codecForName(encoding);
297 }
298 // END
299
300 // BEGIN KateDocumentConfig
KateDocumentConfig()301 KateDocumentConfig::KateDocumentConfig()
302 {
303 // register this as our global instance
304 Q_ASSERT(isGlobal());
305 s_global = this;
306
307 // init all known config entries
308 addConfigEntry(ConfigEntry(TabWidth, "Tab Width", QStringLiteral("tab-width"), 4, [](const QVariant &value) {
309 return value.toInt() >= 1;
310 }));
311 addConfigEntry(ConfigEntry(IndentationWidth, "Indentation Width", QStringLiteral("indent-width"), 4, [](const QVariant &value) {
312 return value.toInt() >= 1;
313 }));
314 addConfigEntry(ConfigEntry(OnTheFlySpellCheck, "On-The-Fly Spellcheck", QStringLiteral("on-the-fly-spellcheck"), false));
315 addConfigEntry(ConfigEntry(IndentOnTextPaste, "Indent On Text Paste", QStringLiteral("indent-pasted-text"), false));
316 addConfigEntry(ConfigEntry(ReplaceTabsWithSpaces, "ReplaceTabsDyn", QStringLiteral("replace-tabs"), true));
317 addConfigEntry(ConfigEntry(BackupOnSaveLocal, "Backup Local", QStringLiteral("backup-on-save-local"), false));
318 addConfigEntry(ConfigEntry(BackupOnSaveRemote, "Backup Remote", QStringLiteral("backup-on-save-remote"), false));
319 addConfigEntry(ConfigEntry(BackupOnSavePrefix, "Backup Prefix", QStringLiteral("backup-on-save-prefix"), QString()));
320 addConfigEntry(ConfigEntry(BackupOnSaveSuffix, "Backup Suffix", QStringLiteral("backup-on-save-suffix"), QStringLiteral("~")));
321 addConfigEntry(ConfigEntry(IndentationMode, "Indentation Mode", QString(), QStringLiteral("normal")));
322 addConfigEntry(ConfigEntry(TabHandlingMode, "Tab Handling", QString(), KateDocumentConfig::tabSmart));
323 addConfigEntry(ConfigEntry(StaticWordWrap, "Word Wrap", QString(), false));
324 addConfigEntry(ConfigEntry(StaticWordWrapColumn, "Word Wrap Column", QString(), 80, [](const QVariant &value) {
325 return value.toInt() >= 1;
326 }));
327 addConfigEntry(ConfigEntry(PageUpDownMovesCursor, "PageUp/PageDown Moves Cursor", QString(), false));
328 addConfigEntry(ConfigEntry(SmartHome, "Smart Home", QString(), true));
329 addConfigEntry(ConfigEntry(ShowTabs, "Show Tabs", QString(), true));
330 addConfigEntry(ConfigEntry(IndentOnTab, "Indent On Tab", QString(), true));
331 addConfigEntry(ConfigEntry(KeepExtraSpaces, "Keep Extra Spaces", QString(), false));
332 addConfigEntry(ConfigEntry(BackspaceIndents, "Indent On Backspace", QString(), true));
333 addConfigEntry(ConfigEntry(ShowSpacesMode, "Show Spaces", QString(), KateDocumentConfig::None));
334 addConfigEntry(ConfigEntry(TrailingMarkerSize, "Trailing Marker Size", QString(), 1));
335 addConfigEntry(ConfigEntry(RemoveSpacesMode, "Remove Spaces", QString(), 1 /* on modified lines per default */, [](const QVariant &value) {
336 return inBounds(0, value, 2);
337 }));
338 addConfigEntry(ConfigEntry(NewlineAtEOF, "Newline at End of File", QString(), true));
339 addConfigEntry(ConfigEntry(OverwriteMode, "Overwrite Mode", QString(), false));
340 addConfigEntry(ConfigEntry(Encoding, "Encoding", QString(), QStringLiteral("UTF-8"), [](const QVariant &value) {
341 return isEncodingOk(value.toString());
342 }));
343 addConfigEntry(ConfigEntry(EndOfLine, "End of Line", QString(), 0));
344 addConfigEntry(ConfigEntry(AllowEndOfLineDetection, "Allow End of Line Detection", QString(), true));
345 addConfigEntry(ConfigEntry(ByteOrderMark, "BOM", QString(), false));
346 addConfigEntry(ConfigEntry(SwapFile, "Swap File Mode", QString(), KateDocumentConfig::EnableSwapFile));
347 addConfigEntry(ConfigEntry(SwapFileDirectory, "Swap Directory", QString(), QString()));
348 addConfigEntry(ConfigEntry(SwapFileSyncInterval, "Swap Sync Interval", QString(), 15));
349 addConfigEntry(ConfigEntry(LineLengthLimit, "Line Length Limit", QString(), 10000));
350 addConfigEntry(ConfigEntry(CamelCursor, "Camel Cursor", QString(), true));
351
352 // finalize the entries, e.g. hashs them
353 finalizeConfigEntries();
354
355 // init with defaults from config or really hardcoded ones
356 KConfigGroup cg(KTextEditor::EditorPrivate::config(), "KTextEditor Document");
357 readConfig(cg);
358 }
359
KateDocumentConfig(KTextEditor::DocumentPrivate * doc)360 KateDocumentConfig::KateDocumentConfig(KTextEditor::DocumentPrivate *doc)
361 : KateConfig(s_global)
362 , m_doc(doc)
363 {
364 // per document config doesn't read stuff per default
365 }
366
readConfig(const KConfigGroup & config)367 void KateDocumentConfig::readConfig(const KConfigGroup &config)
368 {
369 // start config update group
370 configStart();
371
372 // read generic entries
373 readConfigEntries(config);
374
375 // fixup sonnet config, see KateSpellCheckConfigTab::apply(), too
376 // WARNING: this is slightly hackish, but it's currently the only way to
377 // do it, see also the KTextEdit class
378 if (isGlobal()) {
379 const QSettings settings(QStringLiteral("KDE"), QStringLiteral("Sonnet"));
380 const bool onTheFlyChecking = settings.value(QStringLiteral("checkerEnabledByDefault"), false).toBool();
381 setOnTheFlySpellCheck(onTheFlyChecking);
382
383 // ensure we load the default dictionary speller + trigrams early
384 // this avoids hangs for auto-spellchecking on first edits
385 // do this if we have on the fly spellchecking on only
386 if (onTheFlyChecking) {
387 Sonnet::Speller speller;
388 speller.setLanguage(Sonnet::Speller().defaultLanguage());
389 Sonnet::GuessLanguage languageGuesser;
390 languageGuesser.identify(QStringLiteral("dummy to trigger identify"));
391 }
392 }
393
394 // backwards compatibility mappings
395 // convert stuff, old entries deleted in writeConfig
396 if (const int backupFlags = config.readEntry("Backup Flags", 0)) {
397 setBackupOnSaveLocal(backupFlags & 0x1);
398 setBackupOnSaveRemote(backupFlags & 0x2);
399 }
400
401 // end config update group, might trigger updateConfig()
402 configEnd();
403 }
404
writeConfig(KConfigGroup & config)405 void KateDocumentConfig::writeConfig(KConfigGroup &config)
406 {
407 // write generic entries
408 writeConfigEntries(config);
409
410 // backwards compatibility mappings
411 // here we remove old entries we converted on readConfig
412 config.deleteEntry("Backup Flags");
413 }
414
updateConfig()415 void KateDocumentConfig::updateConfig()
416 {
417 if (m_doc) {
418 m_doc->updateConfig();
419 return;
420 }
421
422 if (isGlobal()) {
423 for (int z = 0; z < KTextEditor::EditorPrivate::self()->kateDocuments().size(); ++z) {
424 (KTextEditor::EditorPrivate::self()->kateDocuments())[z]->updateConfig();
425 }
426
427 // write config
428 KConfigGroup cg(KTextEditor::EditorPrivate::config(), "KTextEditor Document");
429 writeConfig(cg);
430 KTextEditor::EditorPrivate::config()->sync();
431
432 // trigger emission of KTextEditor::Editor::configChanged
433 KTextEditor::EditorPrivate::self()->triggerConfigChanged();
434 }
435 }
436
codec() const437 QTextCodec *KateDocumentConfig::codec() const
438 {
439 // query stored encoding, always fallback to UTF-8 if nothing valid set
440 const auto encoding = value(Encoding).toString();
441 if (encoding.isEmpty()) {
442 return QTextCodec::codecForName("UTF-8");
443 }
444
445 // use configured encoding
446 return KCharsets::charsets()->codecForName(encoding);
447 }
448
eolString()449 QString KateDocumentConfig::eolString()
450 {
451 switch (eol()) {
452 case KateDocumentConfig::eolDos:
453 return QStringLiteral("\r\n");
454
455 case KateDocumentConfig::eolMac:
456 return QStringLiteral("\r");
457
458 default:
459 return QStringLiteral("\n");
460 }
461 }
462 // END
463
464 // BEGIN KateViewConfig
KateViewConfig()465 KateViewConfig::KateViewConfig()
466 {
467 s_global = this;
468
469 // Init all known config entries
470 // NOTE: Ensure to keep the same order as listed in enum ConfigEntryTypes or it will later assert!
471 // addConfigEntry(ConfigEntry(<EnumKey>, <ConfigKey>, <CommandName>, <DefaultValue>, [<ValidatorFunction>]))
472 addConfigEntry(ConfigEntry(AllowMarkMenu, "Allow Mark Menu", QStringLiteral("allow-mark-menu"), true));
473 addConfigEntry(ConfigEntry(AutoBrackets, "Auto Brackets", QStringLiteral("auto-brackets"), false));
474 addConfigEntry(ConfigEntry(AutoCenterLines, "Auto Center Lines", QStringLiteral("auto-center-lines"), 0));
475 addConfigEntry(ConfigEntry(AutomaticCompletionInvocation, "Auto Completion", QString(), true));
476 addConfigEntry(ConfigEntry(AutomaticCompletionPreselectFirst, "Auto Completion Preselect First Entry", QString(), true));
477 addConfigEntry(ConfigEntry(BackspaceRemoveComposedCharacters, "Backspace Remove Composed Characters", QString(), false));
478 addConfigEntry(ConfigEntry(BookmarkSorting, "Bookmark Menu Sorting", QString(), 0));
479 addConfigEntry(ConfigEntry(CharsToEncloseSelection, "Chars To Enclose Selection", QStringLiteral("enclose-selection"), QStringLiteral("<>(){}[]'\"")));
480 addConfigEntry(ConfigEntry(DefaultMarkType,
481 "Default Mark Type",
482 QStringLiteral("default-mark-type"),
483 KTextEditor::MarkInterface::markType01,
484 [](const QVariant &value) {
485 return isPositive(value);
486 }));
487 addConfigEntry(ConfigEntry(DynWordWrapAlignIndent, "Dynamic Word Wrap Align Indent", QString(), 80, [](const QVariant &value) {
488 return inBounds(0, value, 100);
489 }));
490 addConfigEntry(ConfigEntry(DynWordWrapIndicators, "Dynamic Word Wrap Indicators", QString(), 1, [](const QVariant &value) {
491 return inBounds(1, value, 3);
492 }));
493 addConfigEntry(ConfigEntry(DynWrapAnywhere, "Dynamic Wrap not at word boundaries", QStringLiteral("dynamic-word-wrap-anywhere"), false));
494 addConfigEntry(ConfigEntry(DynWrapAtStaticMarker, "Dynamic Word Wrap At Static Marker", QString(), false));
495 addConfigEntry(ConfigEntry(DynamicWordWrap, "Dynamic Word Wrap", QStringLiteral("dynamic-word-wrap"), true));
496 addConfigEntry(ConfigEntry(FoldFirstLine, "Fold First Line", QString(), false));
497 addConfigEntry(ConfigEntry(InputMode, "Input Mode", QString(), 0, [](const QVariant &value) {
498 return isPositive(value);
499 }));
500 addConfigEntry(ConfigEntry(KeywordCompletion, "Keyword Completion", QStringLiteral("keyword-completion"), true));
501 addConfigEntry(ConfigEntry(MaxHistorySize, "Maximum Search History Size", QString(), 100, [](const QVariant &value) {
502 return inBounds(0, value, 999);
503 }));
504 addConfigEntry(ConfigEntry(MousePasteAtCursorPosition, "Mouse Paste At Cursor Position", QString(), false));
505 addConfigEntry(ConfigEntry(PersistentSelection, "Persistent Selection", QStringLiteral("persistent-selectionq"), false));
506 addConfigEntry(ConfigEntry(ScrollBarMiniMapWidth, "Scroll Bar Mini Map Width", QString(), 60, [](const QVariant &value) {
507 return inBounds(0, value, 999);
508 }));
509 addConfigEntry(ConfigEntry(ScrollPastEnd, "Scroll Past End", QString(), false));
510 addConfigEntry(ConfigEntry(SearchFlags, "Search/Replace Flags", QString(), IncFromCursor | PowerMatchCase | PowerModePlainText));
511 addConfigEntry(ConfigEntry(ShowBracketMatchPreview, "Bracket Match Preview", QStringLiteral("bracket-match-preview"), false));
512 addConfigEntry(ConfigEntry(ShowFoldingBar, "Folding Bar", QStringLiteral("folding-bar"), true));
513 addConfigEntry(ConfigEntry(ShowFoldingPreview, "Folding Preview", QStringLiteral("folding-preview"), true));
514 addConfigEntry(ConfigEntry(ShowIconBar, "Icon Bar", QStringLiteral("icon-bar"), false));
515 addConfigEntry(ConfigEntry(ShowLineCount, "Show Line Count", QString(), false));
516 addConfigEntry(ConfigEntry(ShowLineModification, "Line Modification", QStringLiteral("modification-markers"), true));
517 addConfigEntry(ConfigEntry(ShowLineNumbers, "Line Numbers", QStringLiteral("line-numbers"), true));
518 addConfigEntry(ConfigEntry(ShowScrollBarMarks, "Scroll Bar Marks", QString(), false));
519 addConfigEntry(ConfigEntry(ShowScrollBarMiniMap, "Scroll Bar MiniMap", QStringLiteral("scrollbar-minimap"), true));
520 addConfigEntry(ConfigEntry(ShowScrollBarMiniMapAll, "Scroll Bar Mini Map All", QString(), true));
521 addConfigEntry(ConfigEntry(ShowScrollBarPreview, "Scroll Bar Preview", QStringLiteral("scrollbar-preview"), true));
522 addConfigEntry(ConfigEntry(ShowScrollbars, "Show Scrollbars", QString(), AlwaysOn, [](const QVariant &value) {
523 return inBounds(0, value, 2);
524 }));
525 addConfigEntry(ConfigEntry(ShowWordCount, "Show Word Count", QString(), false));
526 addConfigEntry(ConfigEntry(TextDragAndDrop, "Text Drag And Drop", QString(), true));
527 addConfigEntry(ConfigEntry(SmartCopyCut, "Smart Copy Cut", QString(), true));
528 addConfigEntry(ConfigEntry(UserSetsOfCharsToEncloseSelection, "User Sets Of Chars To Enclose Selection", QString(), QStringList()));
529 addConfigEntry(ConfigEntry(ViInputModeStealKeys, "Vi Input Mode Steal Keys", QString(), false));
530 addConfigEntry(ConfigEntry(ViRelativeLineNumbers, "Vi Relative Line Numbers", QString(), false));
531 addConfigEntry(ConfigEntry(WordCompletion, "Word Completion", QString(), true));
532 addConfigEntry(ConfigEntry(WordCompletionMinimalWordLength, "Word Completion Minimal Word Length", QString(), 3, [](const QVariant &value) {
533 return inBounds(0, value, 99);
534 }));
535 addConfigEntry(ConfigEntry(WordCompletionRemoveTail, "Word Completion Remove Tail", QString(), true));
536
537 // Never forget to finalize or the <CommandName> becomes not available
538 finalizeConfigEntries();
539
540 // init with defaults from config or really hardcoded ones
541 KConfigGroup config(KTextEditor::EditorPrivate::config(), "KTextEditor View");
542 readConfig(config);
543 }
544
KateViewConfig(KTextEditor::ViewPrivate * view)545 KateViewConfig::KateViewConfig(KTextEditor::ViewPrivate *view)
546 : KateConfig(s_global)
547 , m_view(view)
548 {
549 }
550
551 KateViewConfig::~KateViewConfig() = default;
552
readConfig(const KConfigGroup & config)553 void KateViewConfig::readConfig(const KConfigGroup &config)
554 {
555 configStart();
556
557 // read generic entries
558 readConfigEntries(config);
559
560 configEnd();
561 }
562
writeConfig(KConfigGroup & config)563 void KateViewConfig::writeConfig(KConfigGroup &config)
564 {
565 // write generic entries
566 writeConfigEntries(config);
567 }
568
updateConfig()569 void KateViewConfig::updateConfig()
570 {
571 if (m_view) {
572 m_view->updateConfig();
573 return;
574 }
575
576 if (isGlobal()) {
577 const auto allViews = KTextEditor::EditorPrivate::self()->views();
578 for (KTextEditor::ViewPrivate *view : allViews) {
579 view->updateConfig();
580 }
581
582 // write config
583 KConfigGroup cg(KTextEditor::EditorPrivate::config(), "KTextEditor View");
584 writeConfig(cg);
585 KTextEditor::EditorPrivate::config()->sync();
586
587 // trigger emission of KTextEditor::Editor::configChanged
588 KTextEditor::EditorPrivate::self()->triggerConfigChanged();
589 }
590 }
591 // END
592
593 // BEGIN KateRendererConfig
KateRendererConfig()594 KateRendererConfig::KateRendererConfig()
595 : m_lineMarkerColor(KTextEditor::MarkInterface::reservedMarkersCount())
596 , m_schemaSet(false)
597 , m_fontSet(false)
598 , m_wordWrapMarkerSet(false)
599 , m_showIndentationLinesSet(false)
600 , m_showWholeBracketExpressionSet(false)
601 , m_backgroundColorSet(false)
602 , m_selectionColorSet(false)
603 , m_highlightedLineColorSet(false)
604 , m_highlightedBracketColorSet(false)
605 , m_wordWrapMarkerColorSet(false)
606 , m_tabMarkerColorSet(false)
607 , m_indentationLineColorSet(false)
608 , m_iconBarColorSet(false)
609 , m_foldingColorSet(false)
610 , m_lineNumberColorSet(false)
611 , m_currentLineNumberColorSet(false)
612 , m_separatorColorSet(false)
613 , m_spellingMistakeLineColorSet(false)
614 , m_templateColorsSet(false)
615 , m_modifiedLineColorSet(false)
616 , m_savedLineColorSet(false)
617 , m_searchHighlightColorSet(false)
618 , m_replaceHighlightColorSet(false)
619 , m_lineMarkerColorSet(m_lineMarkerColor.size())
620
621 {
622 // init bitarray
623 m_lineMarkerColorSet.fill(true);
624
625 s_global = this;
626
627 // Init all known config entries
628 addConfigEntry(ConfigEntry(AutoColorThemeSelection, "Auto Color Theme Selection", QString(), true));
629
630 // Never forget to finalize or the <CommandName> becomes not available
631 finalizeConfigEntries();
632
633 // init with defaults from config or really hardcoded ones
634 KConfigGroup config(KTextEditor::EditorPrivate::config(), "KTextEditor Renderer");
635 readConfig(config);
636 }
637
KateRendererConfig(KateRenderer * renderer)638 KateRendererConfig::KateRendererConfig(KateRenderer *renderer)
639 : KateConfig(s_global)
640 , m_lineMarkerColor(KTextEditor::MarkInterface::reservedMarkersCount())
641 , m_schemaSet(false)
642 , m_fontSet(false)
643 , m_wordWrapMarkerSet(false)
644 , m_showIndentationLinesSet(false)
645 , m_showWholeBracketExpressionSet(false)
646 , m_backgroundColorSet(false)
647 , m_selectionColorSet(false)
648 , m_highlightedLineColorSet(false)
649 , m_highlightedBracketColorSet(false)
650 , m_wordWrapMarkerColorSet(false)
651 , m_tabMarkerColorSet(false)
652 , m_indentationLineColorSet(false)
653 , m_iconBarColorSet(false)
654 , m_foldingColorSet(false)
655 , m_lineNumberColorSet(false)
656 , m_currentLineNumberColorSet(false)
657 , m_separatorColorSet(false)
658 , m_spellingMistakeLineColorSet(false)
659 , m_templateColorsSet(false)
660 , m_modifiedLineColorSet(false)
661 , m_savedLineColorSet(false)
662 , m_searchHighlightColorSet(false)
663 , m_replaceHighlightColorSet(false)
664 , m_lineMarkerColorSet(m_lineMarkerColor.size())
665 , m_renderer(renderer)
666 {
667 // init bitarray
668 m_lineMarkerColorSet.fill(false);
669 }
670
671 KateRendererConfig::~KateRendererConfig() = default;
672
673 namespace
674 {
675 const char KEY_FONT[] = "Font";
676 const char KEY_COLOR_THEME[] = "Color Theme";
677 const char KEY_WORD_WRAP_MARKER[] = "Word Wrap Marker";
678 const char KEY_SHOW_INDENTATION_LINES[] = "Show Indentation Lines";
679 const char KEY_SHOW_WHOLE_BRACKET_EXPRESSION[] = "Show Whole Bracket Expression";
680 const char KEY_ANIMATE_BRACKET_MATCHING[] = "Animate Bracket Matching";
681 }
682
readConfig(const KConfigGroup & config)683 void KateRendererConfig::readConfig(const KConfigGroup &config)
684 {
685 configStart();
686
687 // read generic entries
688 readConfigEntries(config);
689
690 // read font, but drop all styles, else we have no bold/italic/... variants
691 setFontWithDroppedStyleName(config.readEntry(KEY_FONT, QFontDatabase::systemFont(QFontDatabase::FixedFont)));
692
693 // setSchema will default to right theme
694 setSchema(config.readEntry(KEY_COLOR_THEME, QString()));
695
696 setWordWrapMarker(config.readEntry(KEY_WORD_WRAP_MARKER, false));
697
698 setShowIndentationLines(config.readEntry(KEY_SHOW_INDENTATION_LINES, false));
699
700 setShowWholeBracketExpression(config.readEntry(KEY_SHOW_WHOLE_BRACKET_EXPRESSION, false));
701
702 setAnimateBracketMatching(config.readEntry(KEY_ANIMATE_BRACKET_MATCHING, false));
703
704 configEnd();
705 }
706
writeConfig(KConfigGroup & config)707 void KateRendererConfig::writeConfig(KConfigGroup &config)
708 {
709 // write generic entries
710 writeConfigEntries(config);
711
712 config.writeEntry(KEY_FONT, baseFont());
713
714 config.writeEntry(KEY_COLOR_THEME, schema());
715
716 config.writeEntry(KEY_WORD_WRAP_MARKER, wordWrapMarker());
717
718 config.writeEntry(KEY_SHOW_INDENTATION_LINES, showIndentationLines());
719
720 config.writeEntry(KEY_SHOW_WHOLE_BRACKET_EXPRESSION, showWholeBracketExpression());
721
722 config.writeEntry(KEY_ANIMATE_BRACKET_MATCHING, animateBracketMatching());
723 }
724
updateConfig()725 void KateRendererConfig::updateConfig()
726 {
727 if (m_renderer) {
728 m_renderer->updateConfig();
729 return;
730 }
731
732 if (isGlobal()) {
733 for (int z = 0; z < KTextEditor::EditorPrivate::self()->views().size(); ++z) {
734 (KTextEditor::EditorPrivate::self()->views())[z]->renderer()->updateConfig();
735 }
736
737 // write config
738 KConfigGroup cg(KTextEditor::EditorPrivate::config(), "KTextEditor Renderer");
739 writeConfig(cg);
740 KTextEditor::EditorPrivate::config()->sync();
741
742 // trigger emission of KTextEditor::Editor::configChanged
743 KTextEditor::EditorPrivate::self()->triggerConfigChanged();
744 }
745 }
746
schema() const747 const QString &KateRendererConfig::schema() const
748 {
749 if (m_schemaSet || isGlobal()) {
750 return m_schema;
751 }
752
753 return s_global->schema();
754 }
755
setSchema(QString schema)756 void KateRendererConfig::setSchema(QString schema)
757 {
758 // check if we have some matching theme, else fallback to best theme for current palette
759 // same behavior as for the "Automatic Color Theme Selection"
760 if (!KateHlManager::self()->repository().theme(schema).isValid()) {
761 schema = KateHlManager::self()->repository().themeForPalette(qGuiApp->palette()).name();
762 }
763
764 if (m_schemaSet && m_schema == schema) {
765 return;
766 }
767
768 configStart();
769 m_schemaSet = true;
770 m_schema = schema;
771 setSchemaInternal(m_schema);
772 configEnd();
773 }
774
reloadSchema()775 void KateRendererConfig::reloadSchema()
776 {
777 if (isGlobal()) {
778 setSchemaInternal(m_schema);
779 const auto allViews = KTextEditor::EditorPrivate::self()->views();
780 for (KTextEditor::ViewPrivate *view : allViews) {
781 view->renderer()->config()->reloadSchema();
782 }
783 }
784
785 else if (m_renderer && m_schemaSet) {
786 setSchemaInternal(m_schema);
787 }
788
789 // trigger renderer/view update
790 if (m_renderer) {
791 m_renderer->updateConfig();
792 }
793 }
794
setSchemaInternal(const QString & schema)795 void KateRendererConfig::setSchemaInternal(const QString &schema)
796 {
797 // we always set the theme if we arrive here!
798 m_schemaSet = true;
799
800 // for the global config, we honor the auto selection based on the palette
801 // do the same if the set theme really doesn't exist, we need a valid theme or the rendering will be broken in bad ways!
802 if ((isGlobal() && value(AutoColorThemeSelection).toBool()) || !KateHlManager::self()->repository().theme(schema).isValid()) {
803 // always choose some theme matching the current application palette
804 // we will arrive here after palette changed signals, too!
805 m_schema = KateHlManager::self()->repository().themeForPalette(qGuiApp->palette()).name();
806 } else {
807 // take user given theme 1:1
808 m_schema = schema;
809 }
810
811 const auto theme = KateHlManager::self()->repository().theme(m_schema);
812
813 m_backgroundColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::BackgroundColor));
814 m_backgroundColorSet = true;
815
816 m_selectionColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::TextSelection));
817 m_selectionColorSet = true;
818
819 m_highlightedLineColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::CurrentLine));
820 m_highlightedLineColorSet = true;
821
822 m_highlightedBracketColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::BracketMatching));
823 m_highlightedBracketColorSet = true;
824
825 m_wordWrapMarkerColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::WordWrapMarker));
826 m_wordWrapMarkerColorSet = true;
827
828 m_tabMarkerColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::TabMarker));
829 m_tabMarkerColorSet = true;
830
831 m_indentationLineColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::IndentationLine));
832 m_indentationLineColorSet = true;
833
834 m_iconBarColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::IconBorder));
835 m_iconBarColorSet = true;
836
837 m_foldingColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::CodeFolding));
838 m_foldingColorSet = true;
839
840 m_lineNumberColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::LineNumbers));
841 m_lineNumberColorSet = true;
842
843 m_currentLineNumberColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::CurrentLineNumber));
844 m_currentLineNumberColorSet = true;
845
846 m_separatorColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::Separator));
847 m_separatorColorSet = true;
848
849 m_spellingMistakeLineColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::SpellChecking));
850 m_spellingMistakeLineColorSet = true;
851
852 m_modifiedLineColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::ModifiedLines));
853 m_modifiedLineColorSet = true;
854
855 m_savedLineColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::SavedLines));
856 m_savedLineColorSet = true;
857
858 m_searchHighlightColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::SearchHighlight));
859 m_searchHighlightColorSet = true;
860
861 m_replaceHighlightColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::ReplaceHighlight));
862 m_replaceHighlightColorSet = true;
863
864 for (int i = 0; i <= KSyntaxHighlighting::Theme::MarkError - KSyntaxHighlighting::Theme::MarkBookmark; i++) {
865 QColor col =
866 QColor::fromRgba(theme.editorColor(static_cast<KSyntaxHighlighting::Theme::EditorColorRole>(i + KSyntaxHighlighting::Theme::MarkBookmark)));
867 m_lineMarkerColorSet[i] = true;
868 m_lineMarkerColor[i] = col;
869 }
870
871 m_templateBackgroundColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::TemplateBackground));
872
873 m_templateFocusedEditablePlaceholderColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::TemplateFocusedPlaceholder));
874
875 m_templateEditablePlaceholderColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::TemplatePlaceholder));
876
877 m_templateNotEditablePlaceholderColor = QColor::fromRgba(theme.editorColor(KSyntaxHighlighting::Theme::TemplateReadOnlyPlaceholder));
878
879 m_templateColorsSet = true;
880 }
881
baseFont() const882 const QFont &KateRendererConfig::baseFont() const
883 {
884 if (m_fontSet || isGlobal()) {
885 return m_font;
886 }
887
888 return s_global->baseFont();
889 }
890
setFont(const QFont & font)891 void KateRendererConfig::setFont(const QFont &font)
892 {
893 if (m_fontSet && m_font == font) {
894 return;
895 }
896
897 configStart();
898 setFontWithDroppedStyleName(font);
899 configEnd();
900 }
901
setFontWithDroppedStyleName(const QFont & font)902 void KateRendererConfig::setFontWithDroppedStyleName(const QFont &font)
903 {
904 // Drop styleName, otherwise stuff like bold/italic/... won't work as style!
905 m_font = font;
906 m_font.setStyleName(QString());
907 m_fontSet = true;
908 }
909
wordWrapMarker() const910 bool KateRendererConfig::wordWrapMarker() const
911 {
912 if (m_wordWrapMarkerSet || isGlobal()) {
913 return m_wordWrapMarker;
914 }
915
916 return s_global->wordWrapMarker();
917 }
918
setWordWrapMarker(bool on)919 void KateRendererConfig::setWordWrapMarker(bool on)
920 {
921 if (m_wordWrapMarkerSet && m_wordWrapMarker == on) {
922 return;
923 }
924
925 configStart();
926
927 m_wordWrapMarkerSet = true;
928 m_wordWrapMarker = on;
929
930 configEnd();
931 }
932
backgroundColor() const933 const QColor &KateRendererConfig::backgroundColor() const
934 {
935 if (m_backgroundColorSet || isGlobal()) {
936 return m_backgroundColor;
937 }
938
939 return s_global->backgroundColor();
940 }
941
setBackgroundColor(const QColor & col)942 void KateRendererConfig::setBackgroundColor(const QColor &col)
943 {
944 if (m_backgroundColorSet && m_backgroundColor == col) {
945 return;
946 }
947
948 configStart();
949
950 m_backgroundColorSet = true;
951 m_backgroundColor = col;
952
953 configEnd();
954 }
955
selectionColor() const956 const QColor &KateRendererConfig::selectionColor() const
957 {
958 if (m_selectionColorSet || isGlobal()) {
959 return m_selectionColor;
960 }
961
962 return s_global->selectionColor();
963 }
964
setSelectionColor(const QColor & col)965 void KateRendererConfig::setSelectionColor(const QColor &col)
966 {
967 if (m_selectionColorSet && m_selectionColor == col) {
968 return;
969 }
970
971 configStart();
972
973 m_selectionColorSet = true;
974 m_selectionColor = col;
975
976 configEnd();
977 }
978
highlightedLineColor() const979 const QColor &KateRendererConfig::highlightedLineColor() const
980 {
981 if (m_highlightedLineColorSet || isGlobal()) {
982 return m_highlightedLineColor;
983 }
984
985 return s_global->highlightedLineColor();
986 }
987
setHighlightedLineColor(const QColor & col)988 void KateRendererConfig::setHighlightedLineColor(const QColor &col)
989 {
990 if (m_highlightedLineColorSet && m_highlightedLineColor == col) {
991 return;
992 }
993
994 configStart();
995
996 m_highlightedLineColorSet = true;
997 m_highlightedLineColor = col;
998
999 configEnd();
1000 }
1001
lineMarkerColor(KTextEditor::MarkInterface::MarkTypes type) const1002 const QColor &KateRendererConfig::lineMarkerColor(KTextEditor::MarkInterface::MarkTypes type) const
1003 {
1004 int index = 0;
1005 if (type > 0) {
1006 while ((type >> index++) ^ 1) { }
1007 }
1008 index -= 1;
1009
1010 if (index < 0 || index >= KTextEditor::MarkInterface::reservedMarkersCount()) {
1011 static QColor dummy;
1012 return dummy;
1013 }
1014
1015 if (m_lineMarkerColorSet[index] || isGlobal()) {
1016 return m_lineMarkerColor[index];
1017 }
1018
1019 return s_global->lineMarkerColor(type);
1020 }
1021
highlightedBracketColor() const1022 const QColor &KateRendererConfig::highlightedBracketColor() const
1023 {
1024 if (m_highlightedBracketColorSet || isGlobal()) {
1025 return m_highlightedBracketColor;
1026 }
1027
1028 return s_global->highlightedBracketColor();
1029 }
1030
setHighlightedBracketColor(const QColor & col)1031 void KateRendererConfig::setHighlightedBracketColor(const QColor &col)
1032 {
1033 if (m_highlightedBracketColorSet && m_highlightedBracketColor == col) {
1034 return;
1035 }
1036
1037 configStart();
1038
1039 m_highlightedBracketColorSet = true;
1040 m_highlightedBracketColor = col;
1041
1042 configEnd();
1043 }
1044
wordWrapMarkerColor() const1045 const QColor &KateRendererConfig::wordWrapMarkerColor() const
1046 {
1047 if (m_wordWrapMarkerColorSet || isGlobal()) {
1048 return m_wordWrapMarkerColor;
1049 }
1050
1051 return s_global->wordWrapMarkerColor();
1052 }
1053
setWordWrapMarkerColor(const QColor & col)1054 void KateRendererConfig::setWordWrapMarkerColor(const QColor &col)
1055 {
1056 if (m_wordWrapMarkerColorSet && m_wordWrapMarkerColor == col) {
1057 return;
1058 }
1059
1060 configStart();
1061
1062 m_wordWrapMarkerColorSet = true;
1063 m_wordWrapMarkerColor = col;
1064
1065 configEnd();
1066 }
1067
tabMarkerColor() const1068 const QColor &KateRendererConfig::tabMarkerColor() const
1069 {
1070 if (m_tabMarkerColorSet || isGlobal()) {
1071 return m_tabMarkerColor;
1072 }
1073
1074 return s_global->tabMarkerColor();
1075 }
1076
setTabMarkerColor(const QColor & col)1077 void KateRendererConfig::setTabMarkerColor(const QColor &col)
1078 {
1079 if (m_tabMarkerColorSet && m_tabMarkerColor == col) {
1080 return;
1081 }
1082
1083 configStart();
1084
1085 m_tabMarkerColorSet = true;
1086 m_tabMarkerColor = col;
1087
1088 configEnd();
1089 }
1090
indentationLineColor() const1091 const QColor &KateRendererConfig::indentationLineColor() const
1092 {
1093 if (m_indentationLineColorSet || isGlobal()) {
1094 return m_indentationLineColor;
1095 }
1096
1097 return s_global->indentationLineColor();
1098 }
1099
setIndentationLineColor(const QColor & col)1100 void KateRendererConfig::setIndentationLineColor(const QColor &col)
1101 {
1102 if (m_indentationLineColorSet && m_indentationLineColor == col) {
1103 return;
1104 }
1105
1106 configStart();
1107
1108 m_indentationLineColorSet = true;
1109 m_indentationLineColor = col;
1110
1111 configEnd();
1112 }
1113
iconBarColor() const1114 const QColor &KateRendererConfig::iconBarColor() const
1115 {
1116 if (m_iconBarColorSet || isGlobal()) {
1117 return m_iconBarColor;
1118 }
1119
1120 return s_global->iconBarColor();
1121 }
1122
setIconBarColor(const QColor & col)1123 void KateRendererConfig::setIconBarColor(const QColor &col)
1124 {
1125 if (m_iconBarColorSet && m_iconBarColor == col) {
1126 return;
1127 }
1128
1129 configStart();
1130
1131 m_iconBarColorSet = true;
1132 m_iconBarColor = col;
1133
1134 configEnd();
1135 }
1136
foldingColor() const1137 const QColor &KateRendererConfig::foldingColor() const
1138 {
1139 if (m_foldingColorSet || isGlobal()) {
1140 return m_foldingColor;
1141 }
1142
1143 return s_global->foldingColor();
1144 }
1145
setFoldingColor(const QColor & col)1146 void KateRendererConfig::setFoldingColor(const QColor &col)
1147 {
1148 if (m_foldingColorSet && m_foldingColor == col) {
1149 return;
1150 }
1151
1152 configStart();
1153
1154 m_foldingColorSet = true;
1155 m_foldingColor = col;
1156
1157 configEnd();
1158 }
1159
templateBackgroundColor() const1160 const QColor &KateRendererConfig::templateBackgroundColor() const
1161 {
1162 if (m_templateColorsSet || isGlobal()) {
1163 return m_templateBackgroundColor;
1164 }
1165
1166 return s_global->templateBackgroundColor();
1167 }
1168
templateEditablePlaceholderColor() const1169 const QColor &KateRendererConfig::templateEditablePlaceholderColor() const
1170 {
1171 if (m_templateColorsSet || isGlobal()) {
1172 return m_templateEditablePlaceholderColor;
1173 }
1174
1175 return s_global->templateEditablePlaceholderColor();
1176 }
1177
templateFocusedEditablePlaceholderColor() const1178 const QColor &KateRendererConfig::templateFocusedEditablePlaceholderColor() const
1179 {
1180 if (m_templateColorsSet || isGlobal()) {
1181 return m_templateFocusedEditablePlaceholderColor;
1182 }
1183
1184 return s_global->templateFocusedEditablePlaceholderColor();
1185 }
1186
templateNotEditablePlaceholderColor() const1187 const QColor &KateRendererConfig::templateNotEditablePlaceholderColor() const
1188 {
1189 if (m_templateColorsSet || isGlobal()) {
1190 return m_templateNotEditablePlaceholderColor;
1191 }
1192
1193 return s_global->templateNotEditablePlaceholderColor();
1194 }
1195
lineNumberColor() const1196 const QColor &KateRendererConfig::lineNumberColor() const
1197 {
1198 if (m_lineNumberColorSet || isGlobal()) {
1199 return m_lineNumberColor;
1200 }
1201
1202 return s_global->lineNumberColor();
1203 }
1204
setLineNumberColor(const QColor & col)1205 void KateRendererConfig::setLineNumberColor(const QColor &col)
1206 {
1207 if (m_lineNumberColorSet && m_lineNumberColor == col) {
1208 return;
1209 }
1210
1211 configStart();
1212
1213 m_lineNumberColorSet = true;
1214 m_lineNumberColor = col;
1215
1216 configEnd();
1217 }
1218
currentLineNumberColor() const1219 const QColor &KateRendererConfig::currentLineNumberColor() const
1220 {
1221 if (m_currentLineNumberColorSet || isGlobal()) {
1222 return m_currentLineNumberColor;
1223 }
1224
1225 return s_global->currentLineNumberColor();
1226 }
1227
setCurrentLineNumberColor(const QColor & col)1228 void KateRendererConfig::setCurrentLineNumberColor(const QColor &col)
1229 {
1230 if (m_currentLineNumberColorSet && m_currentLineNumberColor == col) {
1231 return;
1232 }
1233
1234 configStart();
1235
1236 m_currentLineNumberColorSet = true;
1237 m_currentLineNumberColor = col;
1238
1239 configEnd();
1240 }
1241
separatorColor() const1242 const QColor &KateRendererConfig::separatorColor() const
1243 {
1244 if (m_separatorColorSet || isGlobal()) {
1245 return m_separatorColor;
1246 }
1247
1248 return s_global->separatorColor();
1249 }
1250
setSeparatorColor(const QColor & col)1251 void KateRendererConfig::setSeparatorColor(const QColor &col)
1252 {
1253 if (m_separatorColorSet && m_separatorColor == col) {
1254 return;
1255 }
1256
1257 configStart();
1258
1259 m_separatorColorSet = true;
1260 m_separatorColor = col;
1261
1262 configEnd();
1263 }
1264
spellingMistakeLineColor() const1265 const QColor &KateRendererConfig::spellingMistakeLineColor() const
1266 {
1267 if (m_spellingMistakeLineColorSet || isGlobal()) {
1268 return m_spellingMistakeLineColor;
1269 }
1270
1271 return s_global->spellingMistakeLineColor();
1272 }
1273
setSpellingMistakeLineColor(const QColor & col)1274 void KateRendererConfig::setSpellingMistakeLineColor(const QColor &col)
1275 {
1276 if (m_spellingMistakeLineColorSet && m_spellingMistakeLineColor == col) {
1277 return;
1278 }
1279
1280 configStart();
1281
1282 m_spellingMistakeLineColorSet = true;
1283 m_spellingMistakeLineColor = col;
1284
1285 configEnd();
1286 }
1287
modifiedLineColor() const1288 const QColor &KateRendererConfig::modifiedLineColor() const
1289 {
1290 if (m_modifiedLineColorSet || isGlobal()) {
1291 return m_modifiedLineColor;
1292 }
1293
1294 return s_global->modifiedLineColor();
1295 }
1296
setModifiedLineColor(const QColor & col)1297 void KateRendererConfig::setModifiedLineColor(const QColor &col)
1298 {
1299 if (m_modifiedLineColorSet && m_modifiedLineColor == col) {
1300 return;
1301 }
1302
1303 configStart();
1304
1305 m_modifiedLineColorSet = true;
1306 m_modifiedLineColor = col;
1307
1308 configEnd();
1309 }
1310
savedLineColor() const1311 const QColor &KateRendererConfig::savedLineColor() const
1312 {
1313 if (m_savedLineColorSet || isGlobal()) {
1314 return m_savedLineColor;
1315 }
1316
1317 return s_global->savedLineColor();
1318 }
1319
setSavedLineColor(const QColor & col)1320 void KateRendererConfig::setSavedLineColor(const QColor &col)
1321 {
1322 if (m_savedLineColorSet && m_savedLineColor == col) {
1323 return;
1324 }
1325
1326 configStart();
1327
1328 m_savedLineColorSet = true;
1329 m_savedLineColor = col;
1330
1331 configEnd();
1332 }
1333
searchHighlightColor() const1334 const QColor &KateRendererConfig::searchHighlightColor() const
1335 {
1336 if (m_searchHighlightColorSet || isGlobal()) {
1337 return m_searchHighlightColor;
1338 }
1339
1340 return s_global->searchHighlightColor();
1341 }
1342
setSearchHighlightColor(const QColor & col)1343 void KateRendererConfig::setSearchHighlightColor(const QColor &col)
1344 {
1345 if (m_searchHighlightColorSet && m_searchHighlightColor == col) {
1346 return;
1347 }
1348
1349 configStart();
1350
1351 m_searchHighlightColorSet = true;
1352 m_searchHighlightColor = col;
1353
1354 configEnd();
1355 }
1356
replaceHighlightColor() const1357 const QColor &KateRendererConfig::replaceHighlightColor() const
1358 {
1359 if (m_replaceHighlightColorSet || isGlobal()) {
1360 return m_replaceHighlightColor;
1361 }
1362
1363 return s_global->replaceHighlightColor();
1364 }
1365
setReplaceHighlightColor(const QColor & col)1366 void KateRendererConfig::setReplaceHighlightColor(const QColor &col)
1367 {
1368 if (m_replaceHighlightColorSet && m_replaceHighlightColor == col) {
1369 return;
1370 }
1371
1372 configStart();
1373
1374 m_replaceHighlightColorSet = true;
1375 m_replaceHighlightColor = col;
1376
1377 configEnd();
1378 }
1379
showIndentationLines() const1380 bool KateRendererConfig::showIndentationLines() const
1381 {
1382 if (m_showIndentationLinesSet || isGlobal()) {
1383 return m_showIndentationLines;
1384 }
1385
1386 return s_global->showIndentationLines();
1387 }
1388
setShowIndentationLines(bool on)1389 void KateRendererConfig::setShowIndentationLines(bool on)
1390 {
1391 if (m_showIndentationLinesSet && m_showIndentationLines == on) {
1392 return;
1393 }
1394
1395 configStart();
1396
1397 m_showIndentationLinesSet = true;
1398 m_showIndentationLines = on;
1399
1400 configEnd();
1401 }
1402
showWholeBracketExpression() const1403 bool KateRendererConfig::showWholeBracketExpression() const
1404 {
1405 if (m_showWholeBracketExpressionSet || isGlobal()) {
1406 return m_showWholeBracketExpression;
1407 }
1408
1409 return s_global->showWholeBracketExpression();
1410 }
1411
setShowWholeBracketExpression(bool on)1412 void KateRendererConfig::setShowWholeBracketExpression(bool on)
1413 {
1414 if (m_showWholeBracketExpressionSet && m_showWholeBracketExpression == on) {
1415 return;
1416 }
1417
1418 configStart();
1419
1420 m_showWholeBracketExpressionSet = true;
1421 m_showWholeBracketExpression = on;
1422
1423 configEnd();
1424 }
1425
animateBracketMatching() const1426 bool KateRendererConfig::animateBracketMatching() const
1427 {
1428 return s_global->m_animateBracketMatching;
1429 }
1430
setAnimateBracketMatching(bool on)1431 void KateRendererConfig::setAnimateBracketMatching(bool on)
1432 {
1433 if (!isGlobal()) {
1434 s_global->setAnimateBracketMatching(on);
1435 } else if (on != m_animateBracketMatching) {
1436 configStart();
1437 m_animateBracketMatching = on;
1438 configEnd();
1439 }
1440 }
1441
1442 // END
1443