MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 1 / 0 / 1
Functions: 100.0% 1 / 0 / 1
Branches: -% 0 / 0 / 0

presentation/ComposeHighlighter.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QColor>
4 #include <QHash>
5 #include <QSet>
6 #include <QSyntaxHighlighter>
7 #include <QTextCursor>
8 #include <QTimer>
9 #include <functional>
10
11 // Sprint 108 (S108.3.7, S108.3.8, S108.4.3): the composer's display layer.
12 // A QSyntaxHighlighter adds formats only to what is shown — the document
13 // and therefore the sent message never change:
14 // - headings larger and bold, code (blocks and inline) in a monospace font
15 // on the code background, quotes in the secondary colour, table header
16 // cells bold (the document carries structure, not these looks);
17 // - in the dark theme, explicit text colours that would be unreadable on
18 // the editor's surface are shown lighter until they reach 4.5:1 (§4.14,
19 // the stored colour is kept);
20 // - misspellings with a wavy underline (D-12): only words outside quotes,
21 // the signature, code, URLs and addresses, not all-caps and without
22 // digits, never the word at the caret while typing.
23 // One highlighter per editor document; GUI thread.
24 class ComposeHighlighter final : public QSyntaxHighlighter {
25 Q_OBJECT
26 public:
27 struct Palette {
28 QColor text;
29 QColor secondary;
30 QColor surface;
31 QColor codeBackground;
32 QColor spellError;
33 bool dark = false;
34 };
35 // A word to check: offset and length in the block's text.
36 struct Word {
37 int start = 0;
38 int length = 0;
39 };
40 // Returns true when `word` is misspelled in `language`.
41 using SpellCheck = std::function<bool(const QString &word, const QString &language)>;
42
43 explicit ComposeHighlighter(QTextDocument *document);
44 void setPalette(const Palette &palette);
45 void setBaseFontPointSize(qreal points);
46 void setSpellCheck(SpellCheck check, const QString &language);
47 QString language() const { return m_language; }
48 // Everything again after a change of language, words, palette or size
49 // (G11): at once up to GraduallyFromCharacters, in slices of
50 // SliceBudgetMs per turn of the event loop for longer documents (a
51 // 1 MiB paste is checked without a stall). Blocks edited meanwhile are
52 // highlighted by the edit itself.
53 static constexpr int GraduallyFromCharacters = 32 * 1024;
54 static constexpr int SliceBudgetMs = 8;
55 void rehighlightAll();
56 31 bool rehighlighting() const { return !m_next.isNull(); }
57 // The caret's position while typing: the word under it is not marked
58 // until typingPaused() (D-12, 400 ms after the last keystroke).
59 void setCaret(int position, bool typing);
60 void typingPaused();
61 // Words of `text` that spell checking looks at (skip zones applied).
62 static QList<Word> checkableWords(const QString &text);
63 // Misspelled words of a block as found by the last highlight (tests,
64 // Shift+F7 and the context menu).
65 QList<Word> misspellings(const QTextBlock &block) const;
66 // A colour readable on `surface` with at least `ratio` contrast, shifted
67 // in lightness only (display adjustment of explicit colours).
68 static QColor readableOn(const QColor &color, const QColor &surface, qreal ratio = 4.5);
69 static qreal contrast(const QColor &a, const QColor &b);
70
71 protected:
72 void highlightBlock(const QString &text) override;
73
74 private:
75 Palette m_palette;
76 qreal m_basePoints = 0;
77 SpellCheck m_spellCheck;
78 QString m_language;
79 int m_caret = -1;
80 bool m_typing = false;
81 QHash<int, QList<Word>> m_misspellings; // block number → words
82 QTextCursor m_next; // the next block of a gradual rehighlight (null: none)
83 void rehighlightSlice();
84 void highlightStructure(const QString &text);
85 void highlightSpelling(const QString &text);
86 };
87