1 /*
2     SPDX-FileCopyrightText: 2003 Christoph Cullmann <cullmann@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef KATE_CONFIG_H
8 #define KATE_CONFIG_H
9 
10 #include <ktexteditor_export.h>
11 
12 #include <ktexteditor/markinterface.h>
13 #include <ktexteditor/view.h>
14 
15 #include <KEncodingProber>
16 
17 #include <functional>
18 #include <map>
19 #include <memory>
20 
21 #include <QBitRef>
22 #include <QColor>
23 #include <QObject>
24 #include <QVector>
25 
26 class KConfigGroup;
27 namespace KTextEditor
28 {
29 class ViewPrivate;
30 }
31 namespace KTextEditor
32 {
33 class DocumentPrivate;
34 }
35 class KateRenderer;
36 
37 namespace KTextEditor
38 {
39 class EditorPrivate;
40 }
41 
42 class KConfig;
43 
44 class QTextCodec;
45 
46 /**
47  * Base Class for the Kate Config Classes
48  * Current childs are KateDocumentConfig/KateDocumentConfig/KateDocumentConfig
49  */
50 class KTEXTEDITOR_EXPORT KateConfig
51 {
52 public:
53     /**
54      * Start some config changes.
55      * This method is needed to init some kind of transaction for config changes,
56      * update will only be done once, at configEnd() call.
57      */
58     void configStart();
59 
60     /**
61      * End a config change transaction, update the concerned
62      * KateDocumentConfig/KateDocumentConfig/KateDocumentConfig
63      */
64     void configEnd();
65 
66     /**
67      * Is this a global config object?
68      * @return true when this is a global config object
69      */
isGlobal()70     bool isGlobal() const
71     {
72         return !m_parent;
73     }
74 
75     /**
76      * All known config keys.
77      * This will use the knowledge about all registered keys of the global object.
78      * @return all known config keys
79      */
configKeys()80     QStringList configKeys() const
81     {
82         return m_parent ? m_parent->configKeys() : *m_configKeys.get();
83     }
84 
85     /**
86      * Get a config value.
87      * @param key config key, aka enum from KateConfig* classes
88      * @return value for the wanted key, will assert if key is not valid
89      */
90     QVariant value(const int key) const;
91 
92     /**
93      * Set a config value.
94      * Will assert if key is invalid.
95      * Might not alter the value if given value fails validation.
96      * @param key config key, aka enum from KateConfig* classes
97      * @param value value to set
98      * @return true on success
99      */
100     bool setValue(const int key, const QVariant &value);
101 
102     /**
103      * Get a config value for the string key.
104      * @param key config key, aka commandName from KateConfig* classes
105      * @return value for the wanted key, will return invalid variant if key is not known
106      */
107     QVariant value(const QString &key) const;
108 
109     /**
110      * Set a config value.
111      * Will do nothing if key is not known or the given value fails validation.
112      * @param key config key, aka commandName from KateConfig* classes
113      * @param value value to set
114      * @return true on success
115      */
116     bool setValue(const QString &key, const QVariant &value);
117 
118 protected:
119     /**
120      * Construct a KateConfig.
121      * @param parent parent config object, if any
122      */
123     KateConfig(const KateConfig *parent = nullptr);
124 
125     /**
126      * Virtual Destructor
127      */
128     virtual ~KateConfig();
129 
130     /**
131      * One config entry.
132      */
133     class ConfigEntry
134     {
135     public:
136         /**
137          * Construct one config entry.
138          * @param enumId value of the enum for this config entry
139          * @param configId value of the key for the KConfig file for this config entry
140          * @param command command name
141          * @param defaultVal default value
142          * @param valid validator function, default none
143          */
144         ConfigEntry(int enumId, const char *configId, QString command, QVariant defaultVal, std::function<bool(const QVariant &)> valid = nullptr)
enumKey(enumId)145             : enumKey(enumId)
146             , configKey(configId)
147             , commandName(command)
148             , defaultValue(defaultVal)
149             , value(defaultVal)
150             , validator(valid)
151         {
152         }
153 
154         /**
155          * Enum key for this config entry, shall be unique
156          */
157         const int enumKey;
158 
159         /**
160          * KConfig entry key for this config entry, shall be unique in its group
161          * e.g. "Tab Width"
162          */
163         const char *const configKey;
164 
165         /**
166          * Command name as used in e.g. ConfigInterface or modeline/command line
167          * e.g. tab-width
168          */
169         const QString commandName;
170 
171         /**
172          * Default value if nothing special was configured
173          */
174         const QVariant defaultValue;
175 
176         /**
177          * The concrete value, per default == defaultValue
178          */
179         QVariant value;
180 
181         /**
182          * An optional validator function, only when these returns true
183          * we accept a given new value.
184          * Is no validator set, we accept any value.
185          */
186         std::function<bool(const QVariant &)> validator;
187     };
188 
189     /**
190      * Read all config entries from given config group.
191      * @param config config group to read from
192      */
193     void readConfigEntries(const KConfigGroup &config);
194 
195     /**
196      * Write all config entries to given config group.
197      * @param config config group to write to
198      */
199     void writeConfigEntries(KConfigGroup &config) const;
200 
201     /**
202      * Register a new config entry.
203      * Used by the sub classes to register all there known ones.
204      * @param entry new entry to add
205      */
206     void addConfigEntry(ConfigEntry &&entry);
207 
208     /**
209      * Finalize the config entries.
210      * Called by the sub classes after all entries are registered
211      */
212     void finalizeConfigEntries();
213 
214     /**
215      * do the real update
216      */
217     virtual void updateConfig() = 0;
218 
219 private:
220     /**
221      * Get full map of config entries, aka the m_configEntries of the top config object
222      * @return full map with all config entries
223      */
fullConfigEntries()224     const std::map<int, ConfigEntry> &fullConfigEntries() const
225     {
226         return m_parent ? m_parent->fullConfigEntries() : m_configEntries;
227     }
228     /**
229      * Get hash of config entries, aka the m_configKeyToEntry of the top config object
230      * @return full hash with all config entries
231      */
fullConfigKeyToEntry()232     const QHash<QString, const ConfigEntry *> &fullConfigKeyToEntry() const
233     {
234         return m_parent ? m_parent->fullConfigKeyToEntry() : *m_configKeyToEntry.get();
235     }
236 
237 private:
238     /**
239      * parent config object, if any
240      */
241     const KateConfig *const m_parent = nullptr;
242 
243     /**
244      * recursion depth
245      */
246     uint configSessionNumber = 0;
247 
248     /**
249      * is a config session running
250      */
251     bool configIsRunning = false;
252 
253     /**
254      * two cases:
255      *   - we have m_parent == nullptr => this contains all known config entries
256      *   - we have m_parent != nullptr => this contains all set config entries for this level of configuration
257      *
258      * uses a map ATM for deterministic iteration e.g. for read/writeConfig
259      */
260     std::map<int, ConfigEntry> m_configEntries;
261 
262     /**
263      * All known config keys, filled only for the object with m_parent == nullptr
264      */
265     std::unique_ptr<QStringList> m_configKeys;
266 
267     /**
268      * Hash of config keys => config entry, filled only for the object with m_parent == nullptr
269      */
270     std::unique_ptr<QHash<QString, const ConfigEntry *>> m_configKeyToEntry;
271 };
272 
273 class KTEXTEDITOR_EXPORT KateGlobalConfig : public KateConfig
274 {
275 private:
276     friend class KTextEditor::EditorPrivate;
277 
278     /**
279      * only used in KTextEditor::EditorPrivate for the static global fallback !!!
280      */
281     KateGlobalConfig();
282 
283 public:
global()284     static KateGlobalConfig *global()
285     {
286         return s_global;
287     }
288 
289     /**
290      * Known config entries
291      */
292     enum ConfigEntryTypes {
293         /**
294          * Encoding prober
295          */
296         EncodingProberType,
297 
298         /**
299          * Fallback encoding
300          */
301         FallbackEncoding
302     };
303 
304 public:
305     /**
306      * Read config from object
307      */
308     void readConfig(const KConfigGroup &config);
309 
310     /**
311      * Write config to object
312      */
313     void writeConfig(KConfigGroup &config);
314 
315 protected:
316     void updateConfig() override;
317 
318 public:
proberType()319     KEncodingProber::ProberType proberType() const
320     {
321         return KEncodingProber::ProberType(value(EncodingProberType).toInt());
322     }
323 
setProberType(KEncodingProber::ProberType type)324     bool setProberType(KEncodingProber::ProberType type)
325     {
326         return setValue(EncodingProberType, type);
327     }
328 
329     /**
330      * Fallback codec.
331      * Based on fallback encoding.
332      * @return fallback codec
333      */
334     QTextCodec *fallbackCodec() const;
335 
fallbackEncoding()336     QString fallbackEncoding() const
337     {
338         return value(FallbackEncoding).toString();
339     }
340 
setFallbackEncoding(const QString & encoding)341     bool setFallbackEncoding(const QString &encoding)
342     {
343         return setValue(FallbackEncoding, encoding);
344     }
345 
346 private:
347     static KateGlobalConfig *s_global;
348 };
349 
350 class KTEXTEDITOR_EXPORT KateDocumentConfig : public KateConfig
351 {
352 private:
353     friend class KTextEditor::EditorPrivate;
354 
355     KateDocumentConfig();
356 
357 public:
358     /**
359      * Construct a DocumentConfig
360      */
361     explicit KateDocumentConfig(KTextEditor::DocumentPrivate *doc);
362 
global()363     inline static KateDocumentConfig *global()
364     {
365         return s_global;
366     }
367 
368     /**
369      * Known config entries
370      */
371     enum ConfigEntryTypes {
372         /**
373          * Tabulator width
374          */
375         TabWidth,
376 
377         /**
378          * Indentation width
379          */
380         IndentationWidth,
381 
382         /**
383          * On-the-fly spellcheck enabled?
384          */
385         OnTheFlySpellCheck,
386 
387         /**
388          * Indent pasted text?
389          */
390         IndentOnTextPaste,
391 
392         /**
393          * Replace tabs with spaces?
394          */
395         ReplaceTabsWithSpaces,
396 
397         /**
398          * Backup files for local files?
399          */
400         BackupOnSaveLocal,
401 
402         /**
403          * Backup files for remote files?
404          */
405         BackupOnSaveRemote,
406 
407         /**
408          * Prefix for backup files
409          */
410         BackupOnSavePrefix,
411 
412         /**
413          * Suffix for backup files
414          */
415         BackupOnSaveSuffix,
416 
417         /**
418          * Indentation mode, like "normal"
419          */
420         IndentationMode,
421 
422         /**
423          * Tab handling, like indent, insert tab, smart
424          */
425         TabHandlingMode,
426 
427         /**
428          * Static word wrap?
429          */
430         StaticWordWrap,
431 
432         /**
433          * Static word wrap column
434          */
435         StaticWordWrapColumn,
436 
437         /**
438          * PageUp/Down moves cursor?
439          */
440         PageUpDownMovesCursor,
441 
442         /**
443          * Smart Home key?
444          */
445         SmartHome,
446 
447         /**
448          * Show Tabs?
449          */
450         ShowTabs,
451 
452         /**
453          * Indent on tab?
454          */
455         IndentOnTab,
456 
457         /**
458          * Keep extra space?
459          */
460         KeepExtraSpaces,
461 
462         /**
463          * Backspace key indents?
464          */
465         BackspaceIndents,
466 
467         /**
468          * Show spaces mode like none, all, ...
469          */
470         ShowSpacesMode,
471 
472         /**
473          * Trailing Marker Size
474          */
475         TrailingMarkerSize,
476 
477         /**
478          * Remove spaces mode
479          */
480         RemoveSpacesMode,
481 
482         /**
483          * Ensure newline at end of file
484          */
485         NewlineAtEOF,
486 
487         /**
488          * Overwrite mode?
489          */
490         OverwriteMode,
491 
492         /**
493          * Encoding
494          */
495         Encoding,
496 
497         /**
498          * End of line mode: dos, mac, unix
499          */
500         EndOfLine,
501 
502         /**
503          * Allow EOL detection
504          */
505         AllowEndOfLineDetection,
506 
507         /**
508          * Use Byte Order Mark
509          */
510         ByteOrderMark,
511 
512         /**
513          * Swap file mode
514          */
515         SwapFile,
516 
517         /**
518          * Swap file directory
519          */
520         SwapFileDirectory,
521 
522         /**
523          * Swap file sync interval
524          */
525         SwapFileSyncInterval,
526 
527         /**
528          * Line length limit
529          */
530         LineLengthLimit,
531 
532         /**
533          * Camel Cursor Movement?
534          */
535         CamelCursor
536     };
537 
538 public:
539     /**
540      * Read config from object
541      */
542     void readConfig(const KConfigGroup &config);
543 
544     /**
545      * Write config to object
546      */
547     void writeConfig(KConfigGroup &config);
548 
549 protected:
550     void updateConfig() override;
551 
552 public:
tabWidth()553     int tabWidth() const
554     {
555         return value(TabWidth).toInt();
556     }
557 
setTabWidth(int tabWidth)558     void setTabWidth(int tabWidth)
559     {
560         setValue(TabWidth, QVariant(tabWidth));
561     }
562 
indentationWidth()563     int indentationWidth() const
564     {
565         return value(IndentationWidth).toInt();
566     }
567 
setIndentationWidth(int indentationWidth)568     void setIndentationWidth(int indentationWidth)
569     {
570         setValue(IndentationWidth, QVariant(indentationWidth));
571     }
572 
onTheFlySpellCheck()573     bool onTheFlySpellCheck() const
574     {
575         return value(OnTheFlySpellCheck).toBool();
576     }
577 
setOnTheFlySpellCheck(bool on)578     void setOnTheFlySpellCheck(bool on)
579     {
580         setValue(OnTheFlySpellCheck, QVariant(on));
581     }
582 
indentPastedText()583     bool indentPastedText() const
584     {
585         return value(IndentOnTextPaste).toBool();
586     }
587 
setIndentPastedText(bool on)588     void setIndentPastedText(bool on)
589     {
590         setValue(IndentOnTextPaste, QVariant(on));
591     }
592 
replaceTabsDyn()593     bool replaceTabsDyn() const
594     {
595         return value(ReplaceTabsWithSpaces).toBool();
596     }
597 
setReplaceTabsDyn(bool on)598     void setReplaceTabsDyn(bool on)
599     {
600         setValue(ReplaceTabsWithSpaces, QVariant(on));
601     }
602 
backupOnSaveLocal()603     bool backupOnSaveLocal() const
604     {
605         return value(BackupOnSaveLocal).toBool();
606     }
607 
setBackupOnSaveLocal(bool on)608     void setBackupOnSaveLocal(bool on)
609     {
610         setValue(BackupOnSaveLocal, QVariant(on));
611     }
612 
backupOnSaveRemote()613     bool backupOnSaveRemote() const
614     {
615         return value(BackupOnSaveRemote).toBool();
616     }
617 
setBackupOnSaveRemote(bool on)618     void setBackupOnSaveRemote(bool on)
619     {
620         setValue(BackupOnSaveRemote, QVariant(on));
621     }
622 
backupPrefix()623     QString backupPrefix() const
624     {
625         return value(BackupOnSavePrefix).toString();
626     }
627 
setBackupPrefix(const QString & prefix)628     void setBackupPrefix(const QString &prefix)
629     {
630         setValue(BackupOnSavePrefix, QVariant(prefix));
631     }
632 
backupSuffix()633     QString backupSuffix() const
634     {
635         return value(BackupOnSaveSuffix).toString();
636     }
637 
setBackupSuffix(const QString & suffix)638     void setBackupSuffix(const QString &suffix)
639     {
640         setValue(BackupOnSaveSuffix, QVariant(suffix));
641     }
642 
indentationMode()643     QString indentationMode() const
644     {
645         return value(IndentationMode).toString();
646     }
647 
setIndentationMode(const QString & identationMode)648     void setIndentationMode(const QString &identationMode)
649     {
650         setValue(IndentationMode, identationMode);
651     }
652 
653     enum TabHandling {
654         tabInsertsTab = 0,
655         tabIndents = 1,
656         tabSmart = 2 //!< indents in leading space, otherwise inserts tab
657     };
658 
659     enum WhitespaceRendering { None, Trailing, All };
660 
tabHandling()661     int tabHandling() const
662     {
663         return value(TabHandlingMode).toInt();
664     }
665 
setTabHandling(int tabHandling)666     void setTabHandling(int tabHandling)
667     {
668         setValue(TabHandlingMode, tabHandling);
669     }
670 
wordWrap()671     bool wordWrap() const
672     {
673         return value(StaticWordWrap).toBool();
674     }
675 
setWordWrap(bool on)676     void setWordWrap(bool on)
677     {
678         setValue(StaticWordWrap, on);
679     }
680 
wordWrapAt()681     int wordWrapAt() const
682     {
683         return value(StaticWordWrapColumn).toInt();
684     }
685 
setWordWrapAt(int col)686     void setWordWrapAt(int col)
687     {
688         setValue(StaticWordWrapColumn, col);
689     }
690 
pageUpDownMovesCursor()691     bool pageUpDownMovesCursor() const
692     {
693         return value(PageUpDownMovesCursor).toBool();
694     }
695 
setPageUpDownMovesCursor(bool on)696     void setPageUpDownMovesCursor(bool on)
697     {
698         setValue(PageUpDownMovesCursor, on);
699     }
700 
setKeepExtraSpaces(bool on)701     void setKeepExtraSpaces(bool on)
702     {
703         setValue(KeepExtraSpaces, on);
704     }
705 
keepExtraSpaces()706     bool keepExtraSpaces() const
707     {
708         return value(KeepExtraSpaces).toBool();
709     }
710 
setBackspaceIndents(bool on)711     void setBackspaceIndents(bool on)
712     {
713         setValue(BackspaceIndents, on);
714     }
715 
backspaceIndents()716     bool backspaceIndents() const
717     {
718         return value(BackspaceIndents).toBool();
719     }
720 
setSmartHome(bool on)721     void setSmartHome(bool on)
722     {
723         setValue(SmartHome, on);
724     }
725 
smartHome()726     bool smartHome() const
727     {
728         return value(SmartHome).toBool();
729     }
730 
setShowTabs(bool on)731     void setShowTabs(bool on)
732     {
733         setValue(ShowTabs, on);
734     }
735 
showTabs()736     bool showTabs() const
737     {
738         return value(ShowTabs).toBool();
739     }
740 
setShowSpaces(WhitespaceRendering mode)741     void setShowSpaces(WhitespaceRendering mode)
742     {
743         setValue(ShowSpacesMode, mode);
744     }
745 
showSpaces()746     WhitespaceRendering showSpaces() const
747     {
748         return WhitespaceRendering(value(ShowSpacesMode).toInt());
749     }
750 
setMarkerSize(int markerSize)751     void setMarkerSize(int markerSize)
752     {
753         setValue(TrailingMarkerSize, markerSize);
754     }
755 
markerSize()756     int markerSize() const
757     {
758         return value(TrailingMarkerSize).toInt();
759     }
760 
761     /**
762      * Remove trailing spaces on save.
763      * triState = 0: never remove trailing spaces
764      * triState = 1: remove trailing spaces of modified lines (line modification system)
765      * triState = 2: remove trailing spaces in entire document
766      */
setRemoveSpaces(int triState)767     void setRemoveSpaces(int triState)
768     {
769         setValue(RemoveSpacesMode, triState);
770     }
771 
removeSpaces()772     int removeSpaces() const
773     {
774         return value(RemoveSpacesMode).toInt();
775     }
776 
setNewLineAtEof(bool on)777     void setNewLineAtEof(bool on)
778     {
779         setValue(NewlineAtEOF, on);
780     }
781 
newLineAtEof()782     bool newLineAtEof() const
783     {
784         return value(NewlineAtEOF).toBool();
785     }
786 
setOvr(bool on)787     void setOvr(bool on)
788     {
789         setValue(OverwriteMode, on);
790     }
791 
ovr()792     bool ovr() const
793     {
794         return value(OverwriteMode).toBool();
795     }
796 
setTabIndents(bool on)797     void setTabIndents(bool on)
798     {
799         setValue(IndentOnTab, on);
800     }
801 
tabIndentsEnabled()802     bool tabIndentsEnabled() const
803     {
804         return value(IndentOnTab).toBool();
805     }
806 
807     /**
808      * Get current text codec.
809      * Based on current set encoding
810      * @return current text codec.
811      */
812     QTextCodec *codec() const;
813 
encoding()814     QString encoding() const
815     {
816         return value(Encoding).toString();
817     }
818 
setEncoding(const QString & encoding)819     bool setEncoding(const QString &encoding)
820     {
821         return setValue(Encoding, encoding);
822     }
823 
824     enum Eol { eolUnix = 0, eolDos = 1, eolMac = 2 };
825 
eol()826     int eol() const
827     {
828         return value(EndOfLine).toInt();
829     }
830 
831     /**
832      * Get current end of line string.
833      * Based on current set eol mode.
834      * @return current end of line string
835      */
836     QString eolString();
837 
setEol(int mode)838     void setEol(int mode)
839     {
840         setValue(EndOfLine, mode);
841     }
842 
bom()843     bool bom() const
844     {
845         return value(ByteOrderMark).toBool();
846     }
847 
setBom(bool bom)848     void setBom(bool bom)
849     {
850         setValue(ByteOrderMark, bom);
851     }
852 
allowEolDetection()853     bool allowEolDetection() const
854     {
855         return value(AllowEndOfLineDetection).toBool();
856     }
857 
setAllowEolDetection(bool on)858     void setAllowEolDetection(bool on)
859     {
860         setValue(AllowEndOfLineDetection, on);
861     }
862 
swapDirectory()863     QString swapDirectory() const
864     {
865         return value(SwapFileDirectory).toString();
866     }
867 
setSwapDirectory(const QString & directory)868     void setSwapDirectory(const QString &directory)
869     {
870         setValue(SwapFileDirectory, directory);
871     }
872 
873     enum SwapFileMode { DisableSwapFile = 0, EnableSwapFile, SwapFilePresetDirectory };
874 
swapFileMode()875     SwapFileMode swapFileMode() const
876     {
877         return SwapFileMode(value(SwapFile).toInt());
878     }
879 
setSwapFileMode(int mode)880     void setSwapFileMode(int mode)
881     {
882         setValue(SwapFile, mode);
883     }
884 
swapSyncInterval()885     int swapSyncInterval() const
886     {
887         return value(SwapFileSyncInterval).toInt();
888     }
889 
setSwapSyncInterval(int interval)890     void setSwapSyncInterval(int interval)
891     {
892         setValue(SwapFileSyncInterval, interval);
893     }
894 
lineLengthLimit()895     int lineLengthLimit() const
896     {
897         return value(LineLengthLimit).toInt();
898     }
899 
setLineLengthLimit(int limit)900     void setLineLengthLimit(int limit)
901     {
902         setValue(LineLengthLimit, limit);
903     }
904 
setCamelCursor(bool on)905     void setCamelCursor(bool on)
906     {
907         setValue(CamelCursor, on);
908     }
909 
camelCursor()910     bool camelCursor() const
911     {
912         return value(CamelCursor).toBool();
913     }
914 
915 private:
916     static KateDocumentConfig *s_global;
917     KTextEditor::DocumentPrivate *m_doc = nullptr;
918 };
919 
920 class KTEXTEDITOR_EXPORT KateViewConfig : public KateConfig
921 {
922 private:
923     friend class KTextEditor::EditorPrivate;
924 
925     /**
926      * only used in KTextEditor::EditorPrivate for the static global fallback !!!
927      */
928     KateViewConfig();
929 
930 public:
931     /**
932      * Construct a ViewConfig
933      */
934     explicit KateViewConfig(KTextEditor::ViewPrivate *view);
935 
936     /**
937      * Cu ViewConfig
938      */
939     ~KateViewConfig() override;
940 
global()941     inline static KateViewConfig *global()
942     {
943         return s_global;
944     }
945 
946     /**
947      * All known config keys
948      * Keep them sorted alphabetic for our convenience
949      */
950     enum ConfigEntryTypes {
951         AllowMarkMenu,
952         AutoBrackets,
953         AutoCenterLines,
954         AutomaticCompletionInvocation,
955         AutomaticCompletionPreselectFirst,
956         BackspaceRemoveComposedCharacters,
957         BookmarkSorting,
958         CharsToEncloseSelection,
959         DefaultMarkType,
960         DynWordWrapAlignIndent,
961         DynWordWrapIndicators,
962         DynWrapAnywhere,
963         DynWrapAtStaticMarker,
964         DynamicWordWrap,
965         FoldFirstLine,
966         InputMode,
967         KeywordCompletion,
968         MaxHistorySize,
969         MousePasteAtCursorPosition,
970         PersistentSelection,
971         ScrollBarMiniMapWidth,
972         ScrollPastEnd,
973         SearchFlags,
974         ShowBracketMatchPreview,
975         ShowFoldingBar,
976         ShowFoldingPreview,
977         ShowIconBar,
978         ShowLineCount,
979         ShowLineModification,
980         ShowLineNumbers,
981         ShowScrollBarMarks,
982         ShowScrollBarMiniMap,
983         ShowScrollBarMiniMapAll,
984         ShowScrollBarPreview,
985         ShowScrollbars,
986         ShowWordCount,
987         TextDragAndDrop,
988         SmartCopyCut,
989         UserSetsOfCharsToEncloseSelection,
990         ViInputModeStealKeys,
991         ViRelativeLineNumbers,
992         WordCompletion,
993         WordCompletionMinimalWordLength,
994         WordCompletionRemoveTail,
995     };
996 
997 public:
998     /**
999      * Read config from object
1000      */
1001     void readConfig(const KConfigGroup &config);
1002 
1003     /**
1004      * Write config to object
1005      */
1006     void writeConfig(KConfigGroup &config);
1007 
1008 protected:
1009     void updateConfig() override;
1010 
1011 public:
dynWordWrap()1012     bool dynWordWrap() const
1013     {
1014         return value(DynamicWordWrap).toBool();
1015     }
setDynWordWrap(bool on)1016     void setDynWordWrap(bool on)
1017     {
1018         setValue(DynamicWordWrap, on);
1019     }
dynWrapAnywhere()1020     bool dynWrapAnywhere() const
1021     {
1022         return value(DynWrapAnywhere).toBool();
1023     }
1024 
dynWrapAtStaticMarker()1025     bool dynWrapAtStaticMarker() const
1026     {
1027         return value(DynWrapAtStaticMarker).toBool();
1028     }
1029 
dynWordWrapIndicators()1030     int dynWordWrapIndicators() const
1031     {
1032         return value(DynWordWrapIndicators).toInt();
1033     }
1034 
dynWordWrapAlignIndent()1035     int dynWordWrapAlignIndent() const
1036     {
1037         return value(DynWordWrapAlignIndent).toInt();
1038     }
1039 
lineNumbers()1040     bool lineNumbers() const
1041     {
1042         return value(ShowLineNumbers).toBool();
1043     }
1044 
scrollBarMarks()1045     bool scrollBarMarks() const
1046     {
1047         return value(ShowScrollBarMarks).toBool();
1048     }
1049 
scrollBarPreview()1050     bool scrollBarPreview() const
1051     {
1052         return value(ShowScrollBarPreview).toBool();
1053     }
1054 
scrollBarMiniMap()1055     bool scrollBarMiniMap() const
1056     {
1057         return value(ShowScrollBarMiniMap).toBool();
1058     }
1059 
scrollBarMiniMapAll()1060     bool scrollBarMiniMapAll() const
1061     {
1062         return value(ShowScrollBarMiniMapAll).toBool();
1063     }
1064 
scrollBarMiniMapWidth()1065     int scrollBarMiniMapWidth() const
1066     {
1067         return value(ScrollBarMiniMapWidth).toInt();
1068     }
1069 
1070     /* Whether to show scrollbars */
1071     enum ScrollbarMode { AlwaysOn = 0, ShowWhenNeeded, AlwaysOff };
1072 
showScrollbars()1073     int showScrollbars() const
1074     {
1075         return value(ShowScrollbars).toInt();
1076     }
1077 
iconBar()1078     bool iconBar() const
1079     {
1080         return value(ShowIconBar).toBool();
1081     }
1082 
foldingBar()1083     bool foldingBar() const
1084     {
1085         return value(ShowFoldingBar).toBool();
1086     }
1087 
foldingPreview()1088     bool foldingPreview() const
1089     {
1090         return value(ShowFoldingPreview).toBool();
1091     }
1092 
lineModification()1093     bool lineModification() const
1094     {
1095         return value(ShowLineModification).toBool();
1096     }
1097 
bookmarkSort()1098     int bookmarkSort() const
1099     {
1100         return value(BookmarkSorting).toInt();
1101     }
1102 
autoCenterLines()1103     int autoCenterLines() const
1104     {
1105         return value(AutoCenterLines).toInt();
1106     }
1107 
1108     enum SearchFlags {
1109         IncMatchCase = 1 << 0,
1110         IncHighlightAll = 1 << 1,
1111         IncFromCursor = 1 << 2,
1112         PowerMatchCase = 1 << 3,
1113         PowerHighlightAll = 1 << 4,
1114         PowerFromCursor = 1 << 5,
1115         // PowerSelectionOnly = 1 << 6, Better not save to file // Sebastian
1116         PowerModePlainText = 1 << 7,
1117         PowerModeWholeWords = 1 << 8,
1118         PowerModeEscapeSequences = 1 << 9,
1119         PowerModeRegularExpression = 1 << 10,
1120         PowerUsePlaceholders = 1 << 11
1121     };
1122 
searchFlags()1123     uint searchFlags() const
1124     {
1125         return value(SearchFlags).toUInt();
1126     }
setSearchFlags(uint flags)1127     void setSearchFlags(uint flags)
1128     {
1129         setValue(SearchFlags, flags);
1130     }
1131 
maxHistorySize()1132     int maxHistorySize() const
1133     {
1134         return value(MaxHistorySize).toInt();
1135     }
1136 
defaultMarkType()1137     uint defaultMarkType() const
1138     {
1139         return value(DefaultMarkType).toUInt();
1140     }
1141 
allowMarkMenu()1142     bool allowMarkMenu() const
1143     {
1144         return value(AllowMarkMenu).toBool();
1145     }
1146 
persistentSelection()1147     bool persistentSelection() const
1148     {
1149         return value(PersistentSelection).toBool();
1150     }
1151 
inputMode()1152     KTextEditor::View::InputMode inputMode() const
1153     {
1154         return static_cast<KTextEditor::View::InputMode>(value(InputMode).toUInt());
1155     }
1156 
viInputModeStealKeys()1157     bool viInputModeStealKeys() const
1158     {
1159         return value(ViInputModeStealKeys).toBool();
1160     }
1161 
viRelativeLineNumbers()1162     bool viRelativeLineNumbers() const
1163     {
1164         return value(ViRelativeLineNumbers).toBool();
1165     }
1166 
1167     // Do we still need the enum and related functions below?
1168     enum TextToSearch { Nowhere = 0, SelectionOnly = 1, SelectionWord = 2, WordOnly = 3, WordSelection = 4 };
1169 
automaticCompletionInvocation()1170     bool automaticCompletionInvocation() const
1171     {
1172         return value(AutomaticCompletionInvocation).toBool();
1173     }
1174 
automaticCompletionPreselectFirst()1175     bool automaticCompletionPreselectFirst() const
1176     {
1177         return value(AutomaticCompletionPreselectFirst).toBool();
1178     }
1179 
wordCompletion()1180     bool wordCompletion() const
1181     {
1182         return value(WordCompletion).toBool();
1183     }
1184 
keywordCompletion()1185     bool keywordCompletion() const
1186     {
1187         return value(KeywordCompletion).toBool();
1188     }
1189 
wordCompletionMinimalWordLength()1190     int wordCompletionMinimalWordLength() const
1191     {
1192         return value(WordCompletionMinimalWordLength).toInt();
1193     }
1194 
wordCompletionRemoveTail()1195     bool wordCompletionRemoveTail() const
1196     {
1197         return value(WordCompletionRemoveTail).toBool();
1198     }
1199 
textDragAndDrop()1200     bool textDragAndDrop() const
1201     {
1202         return value(TextDragAndDrop).toBool();
1203     }
1204 
smartCopyCut()1205     bool smartCopyCut() const
1206     {
1207         return value(SmartCopyCut).toBool();
1208     }
1209 
mousePasteAtCursorPosition()1210     bool mousePasteAtCursorPosition() const
1211     {
1212         return value(MousePasteAtCursorPosition).toBool();
1213     }
1214 
scrollPastEnd()1215     bool scrollPastEnd() const
1216     {
1217         return value(ScrollPastEnd).toBool();
1218     }
1219 
foldFirstLine()1220     bool foldFirstLine() const
1221     {
1222         return value(FoldFirstLine).toBool();
1223     }
1224 
showWordCount()1225     bool showWordCount() const
1226     {
1227         return value(ShowWordCount).toBool();
1228     }
setShowWordCount(bool on)1229     void setShowWordCount(bool on)
1230     {
1231         setValue(ShowWordCount, on);
1232     }
1233 
showLineCount()1234     bool showLineCount() const
1235     {
1236         return value(ShowLineCount).toBool();
1237     }
1238 
setShowLineCount(bool on)1239     void setShowLineCount(bool on)
1240     {
1241         setValue(ShowLineCount, on);
1242     }
1243 
autoBrackets()1244     bool autoBrackets() const
1245     {
1246         return value(AutoBrackets).toBool();
1247     }
1248 
encloseSelectionInChars()1249     bool encloseSelectionInChars() const
1250     {
1251         return !value(CharsToEncloseSelection).toString().isEmpty();
1252     }
1253 
charsToEncloseSelection()1254     QString charsToEncloseSelection() const
1255     {
1256         return value(CharsToEncloseSelection).toString();
1257     }
1258 
backspaceRemoveComposed()1259     bool backspaceRemoveComposed() const
1260     {
1261         return value(BackspaceRemoveComposedCharacters).toBool();
1262     }
1263 
1264 private:
1265     static KateViewConfig *s_global;
1266     KTextEditor::ViewPrivate *m_view = nullptr;
1267 };
1268 
1269 class KTEXTEDITOR_EXPORT KateRendererConfig : public KateConfig
1270 {
1271 private:
1272     friend class KTextEditor::EditorPrivate;
1273 
1274     /**
1275      * only used in KTextEditor::EditorPrivate for the static global fallback !!!
1276      */
1277     KateRendererConfig();
1278 
1279 public:
1280     /**
1281      * Construct a RendererConfig
1282      */
1283     explicit KateRendererConfig(KateRenderer *renderer);
1284 
1285     /**
1286      * Cu RendererConfig
1287      */
1288     ~KateRendererConfig() override;
1289 
global()1290     inline static KateRendererConfig *global()
1291     {
1292         return s_global;
1293     }
1294 
1295     /**
1296      * All known config keys
1297      * Keep them sorted alphabetic for our convenience
1298      */
1299     enum ConfigEntryTypes {
1300         /**
1301          * auto-select the color theme based on application palette
1302          */
1303         AutoColorThemeSelection
1304     };
1305 
1306 public:
1307     /**
1308      * Read config from object
1309      */
1310     void readConfig(const KConfigGroup &config);
1311 
1312     /**
1313      * Write config to object
1314      */
1315     void writeConfig(KConfigGroup &config);
1316 
1317 protected:
1318     void updateConfig() override;
1319 
1320 public:
1321     const QString &schema() const;
1322     void setSchema(QString schema);
1323 
1324     /**
1325      * Reload the schema from the schema manager.
1326      * For the global instance, have all other instances reload.
1327      * Used by the schema config page to apply changes.
1328      */
1329     void reloadSchema();
1330 
1331     /**
1332      * Base font to use for the views and co.
1333      * Will be adjusted there to avoid rendering artifacts for HiDPI stuff.
1334      * @return base font to use
1335      */
1336     const QFont &baseFont() const;
1337 
1338     void setFont(const QFont &font);
1339 
1340     bool wordWrapMarker() const;
1341     void setWordWrapMarker(bool on);
1342 
1343     const QColor &backgroundColor() const;
1344     void setBackgroundColor(const QColor &col);
1345 
1346     const QColor &selectionColor() const;
1347     void setSelectionColor(const QColor &col);
1348 
1349     const QColor &highlightedLineColor() const;
1350     void setHighlightedLineColor(const QColor &col);
1351 
1352     const QColor &lineMarkerColor(KTextEditor::MarkInterface::MarkTypes type = KTextEditor::MarkInterface::markType01) const; // markType01 == Bookmark
1353 
1354     const QColor &highlightedBracketColor() const;
1355     void setHighlightedBracketColor(const QColor &col);
1356 
1357     const QColor &wordWrapMarkerColor() const;
1358     void setWordWrapMarkerColor(const QColor &col);
1359 
1360     const QColor &tabMarkerColor() const;
1361     void setTabMarkerColor(const QColor &col);
1362 
1363     const QColor &indentationLineColor() const;
1364     void setIndentationLineColor(const QColor &col);
1365 
1366     const QColor &iconBarColor() const;
1367     void setIconBarColor(const QColor &col);
1368 
1369     const QColor &foldingColor() const;
1370     void setFoldingColor(const QColor &col);
1371 
1372     // the line number color is used for the line numbers on the left bar
1373     const QColor &lineNumberColor() const;
1374     void setLineNumberColor(const QColor &col);
1375     const QColor &currentLineNumberColor() const;
1376     void setCurrentLineNumberColor(const QColor &col);
1377 
1378     // the color of the separator between line numbers and icon bar
1379     const QColor &separatorColor() const;
1380     void setSeparatorColor(const QColor &col);
1381 
1382     const QColor &spellingMistakeLineColor() const;
1383     void setSpellingMistakeLineColor(const QColor &col);
1384 
1385     bool showIndentationLines() const;
1386     void setShowIndentationLines(bool on);
1387 
1388     bool showWholeBracketExpression() const;
1389     void setShowWholeBracketExpression(bool on);
1390 
1391     bool animateBracketMatching() const;
1392     void setAnimateBracketMatching(bool on);
1393 
1394     const QColor &templateBackgroundColor() const;
1395     const QColor &templateEditablePlaceholderColor() const;
1396     const QColor &templateFocusedEditablePlaceholderColor() const;
1397     const QColor &templateNotEditablePlaceholderColor() const;
1398 
1399     const QColor &modifiedLineColor() const;
1400     void setModifiedLineColor(const QColor &col);
1401 
1402     const QColor &savedLineColor() const;
1403     void setSavedLineColor(const QColor &col);
1404 
1405     const QColor &searchHighlightColor() const;
1406     void setSearchHighlightColor(const QColor &col);
1407 
1408     const QColor &replaceHighlightColor() const;
1409     void setReplaceHighlightColor(const QColor &col);
1410 
1411 private:
1412     /**
1413      * Read the schema properties from the config file.
1414      */
1415     void setSchemaInternal(const QString &schema);
1416 
1417     /**
1418      * Set the font but drop style name before that.
1419      * Otherwise e.g. styles like bold/italic/... will not work
1420      */
1421     void setFontWithDroppedStyleName(const QFont &font);
1422 
1423     QString m_schema;
1424     QFont m_font;
1425     QColor m_backgroundColor;
1426     QColor m_selectionColor;
1427     QColor m_highlightedLineColor;
1428     QColor m_highlightedBracketColor;
1429     QColor m_wordWrapMarkerColor;
1430     QColor m_tabMarkerColor;
1431     QColor m_indentationLineColor;
1432     QColor m_iconBarColor;
1433     QColor m_foldingColor;
1434     QColor m_lineNumberColor;
1435     QColor m_currentLineNumberColor;
1436     QColor m_separatorColor;
1437     QColor m_spellingMistakeLineColor;
1438     QVector<QColor> m_lineMarkerColor;
1439 
1440     QColor m_templateBackgroundColor;
1441     QColor m_templateEditablePlaceholderColor;
1442     QColor m_templateFocusedEditablePlaceholderColor;
1443     QColor m_templateNotEditablePlaceholderColor;
1444 
1445     QColor m_modifiedLineColor;
1446     QColor m_savedLineColor;
1447     QColor m_searchHighlightColor;
1448     QColor m_replaceHighlightColor;
1449 
1450     bool m_wordWrapMarker = false;
1451     bool m_showIndentationLines = false;
1452     bool m_showWholeBracketExpression = false;
1453     bool m_animateBracketMatching = false;
1454 
1455     bool m_schemaSet : 1;
1456     bool m_fontSet : 1;
1457     bool m_wordWrapMarkerSet : 1;
1458     bool m_showIndentationLinesSet : 1;
1459     bool m_showWholeBracketExpressionSet : 1;
1460     bool m_backgroundColorSet : 1;
1461     bool m_selectionColorSet : 1;
1462     bool m_highlightedLineColorSet : 1;
1463     bool m_highlightedBracketColorSet : 1;
1464     bool m_wordWrapMarkerColorSet : 1;
1465     bool m_tabMarkerColorSet : 1;
1466     bool m_indentationLineColorSet : 1;
1467     bool m_iconBarColorSet : 1;
1468     bool m_foldingColorSet : 1;
1469     bool m_lineNumberColorSet : 1;
1470     bool m_currentLineNumberColorSet : 1;
1471     bool m_separatorColorSet : 1;
1472     bool m_spellingMistakeLineColorSet : 1;
1473     bool m_templateColorsSet : 1;
1474     bool m_modifiedLineColorSet : 1;
1475     bool m_savedLineColorSet : 1;
1476     bool m_searchHighlightColorSet : 1;
1477     bool m_replaceHighlightColorSet : 1;
1478     QBitArray m_lineMarkerColorSet;
1479 
1480 private:
1481     static KateRendererConfig *s_global;
1482     KateRenderer *m_renderer = nullptr;
1483 };
1484 
1485 #endif
1486