presentation/ComposeHighlighter.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "ComposeHighlighter.h" | ||
| 2 | |||
| 3 | #include "data/ComposeDocumentFormat.h" | ||
| 4 | |||
| 5 | #include <QElapsedTimer> | ||
| 6 | #include <QRegularExpression> | ||
| 7 | #include <QTextBlock> | ||
| 8 | #include <QTextBoundaryFinder> | ||
| 9 | #include <QTextCursor> | ||
| 10 | #include <QTextDocument> | ||
| 11 | #include <QTextTable> | ||
| 12 | #include <cmath> | ||
| 13 | |||
| 14 | using namespace ComposeDocumentFormat; | ||
| 15 | |||
| 16 | namespace { | ||
| 17 | |||
| 18 | 64 | qreal relativeLuminance(const QColor &color) { | |
| 19 | 192 | const auto channel = [](qreal value) { | |
| 20 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 192 times.
|
192 | return value <= 0.03928 ? value / 12.92 : std::pow((value + 0.055) / 1.055, 2.4); |
| 21 | }; | ||
| 22 | 64 | const QColor rgb = color.toRgb(); | |
| 23 | 64 | return 0.2126 * channel(rgb.redF()) + 0.7152 * channel(rgb.greenF()) + 0.0722 * channel(rgb.blueF()); | |
| 24 | } | ||
| 25 | |||
| 26 | } // namespace | ||
| 27 | |||
| 28 |
1/1✓ Branch 7 → 8 taken 197 times.
|
197 | ComposeHighlighter::ComposeHighlighter(QTextDocument *document) : QSyntaxHighlighter(document) {} |
| 29 | |||
| 30 | 160 | void ComposeHighlighter::setPalette(const Palette &palette) { | |
| 31 | 160 | m_palette = palette; | |
| 32 | 160 | rehighlightAll(); | |
| 33 | 160 | } | |
| 34 | |||
| 35 | 160 | void ComposeHighlighter::setBaseFontPointSize(qreal points) { | |
| 36 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 160 times.
|
160 | if (qFuzzyCompare(m_basePoints, points)) return; |
| 37 | 160 | m_basePoints = points; | |
| 38 | 160 | rehighlightAll(); | |
| 39 | } | ||
| 40 | |||
| 41 | 226 | void ComposeHighlighter::setSpellCheck(SpellCheck check, const QString &language) { | |
| 42 | 226 | m_spellCheck = std::move(check); | |
| 43 | 226 | m_language = language; | |
| 44 | 226 | m_misspellings.clear(); | |
| 45 | 226 | rehighlightAll(); | |
| 46 | 226 | } | |
| 47 | |||
| 48 | 547 | void ComposeHighlighter::rehighlightAll() { | |
| 49 | 547 | QTextDocument *doc = document(); | |
| 50 |
5/6✓ Branch 3 → 4 taken 547 times.
✗ Branch 3 → 6 not taken.
✓ Branch 5 → 6 taken 546 times.
✓ Branch 5 → 7 taken 1 time.
✓ Branch 8 → 9 taken 546 times.
✓ Branch 8 → 14 taken 1 time.
|
547 | if (!doc || doc->characterCount() <= GraduallyFromCharacters) { |
| 51 |
1/1✓ Branch 9 → 10 taken 546 times.
|
546 | m_next = QTextCursor(); |
| 52 | 546 | rehighlight(); | |
| 53 | 546 | return; | |
| 54 | } | ||
| 55 | 1 | const bool running = !m_next.isNull(); | |
| 56 |
1/1✓ Branch 15 → 16 taken 1 time.
|
1 | m_next = QTextCursor(doc); // (again) from the first block |
| 57 |
1/2✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 20 not taken.
|
1 | if (!running) rehighlightSlice(); |
| 58 | } | ||
| 59 | |||
| 60 | 176 | void ComposeHighlighter::rehighlightSlice() { | |
| 61 |
6/9✓ Branch 2 → 3 taken 176 times.
✓ Branch 3 → 4 taken 176 times.
✗ Branch 3 → 7 not taken.
✓ Branch 4 → 5 taken 176 times.
✓ Branch 5 → 6 taken 176 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 176 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 14 taken 176 times.
|
176 | if (m_next.isNull() || m_next.document() != document()) { |
| 62 | ✗ | m_next = QTextCursor(); | |
| 63 | 1 | return; | |
| 64 | } | ||
| 65 | 176 | QElapsedTimer slice; | |
| 66 | 176 | slice.start(); | |
| 67 |
1/1✓ Branch 15 → 16 taken 176 times.
|
176 | QTextBlock block = m_next.block(); |
| 68 |
7/7✓ Branch 21 → 22 taken 4176 times.
✓ Branch 22 → 23 taken 4175 times.
✓ Branch 22 → 26 taken 1 time.
✓ Branch 24 → 25 taken 4000 times.
✓ Branch 24 → 26 taken 175 times.
✓ Branch 27 → 17 taken 4000 times.
✓ Branch 27 → 28 taken 176 times.
|
4176 | while (block.isValid() && slice.elapsed() < SliceBudgetMs) { |
| 69 |
1/1✓ Branch 17 → 18 taken 4000 times.
|
4000 | rehighlightBlock(block); |
| 70 |
1/1✓ Branch 18 → 19 taken 4000 times.
|
4000 | block = block.next(); |
| 71 | } | ||
| 72 |
3/3✓ Branch 28 → 29 taken 176 times.
✓ Branch 29 → 30 taken 1 time.
✓ Branch 29 → 34 taken 175 times.
|
176 | if (!block.isValid()) { |
| 73 |
1/1✓ Branch 30 → 31 taken 1 time.
|
1 | m_next = QTextCursor(); |
| 74 | 1 | return; | |
| 75 | } | ||
| 76 |
2/2✓ Branch 34 → 35 taken 175 times.
✓ Branch 35 → 36 taken 175 times.
|
175 | m_next.setPosition(block.position()); |
| 77 |
1/1✓ Branch 36 → 37 taken 175 times.
|
175 | QTimer::singleShot(0, this, &ComposeHighlighter::rehighlightSlice); |
| 78 | } | ||
| 79 | |||
| 80 | 439 | void ComposeHighlighter::setCaret(int position, bool typing) { | |
| 81 | 439 | const bool wasTyping = m_typing; | |
| 82 | 439 | m_caret = position; | |
| 83 | 439 | m_typing = typing; | |
| 84 |
4/11✓ Branch 2 → 3 taken 331 times.
✓ Branch 2 → 7 taken 108 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 7 taken 331 times.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 13 taken 439 times.
✗ Branch 9 → 10 not taken.
✗ Branch 10 → 11 not taken.
✗ Branch 11 → 12 not taken.
|
439 | if (wasTyping && !typing && document()) rehighlightBlock(document()->findBlock(position)); |
| 85 | 439 | } | |
| 86 | |||
| 87 | 28 | void ComposeHighlighter::typingPaused() { | |
| 88 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 28 times.
|
28 | if (!m_typing) return; |
| 89 | 28 | m_typing = false; | |
| 90 |
6/9✓ Branch 5 → 6 taken 28 times.
✗ Branch 5 → 8 not taken.
✓ Branch 6 → 7 taken 28 times.
✗ Branch 6 → 8 not taken.
✓ Branch 9 → 10 taken 28 times.
✗ Branch 9 → 14 not taken.
✓ Branch 10 → 11 taken 28 times.
✓ Branch 11 → 12 taken 28 times.
✓ Branch 12 → 13 taken 28 times.
|
28 | if (document() && m_caret >= 0) rehighlightBlock(document()->findBlock(m_caret)); |
| 91 | } | ||
| 92 | |||
| 93 | 31 | qreal ComposeHighlighter::contrast(const QColor &a, const QColor &b) { | |
| 94 | 31 | const qreal la = relativeLuminance(a), lb = relativeLuminance(b); | |
| 95 | 31 | return (qMax(la, lb) + 0.05) / (qMin(la, lb) + 0.05); | |
| 96 | } | ||
| 97 | |||
| 98 | 3 | QColor ComposeHighlighter::readableOn(const QColor &color, const QColor &surface, qreal ratio) { | |
| 99 |
7/9✓ Branch 3 → 4 taken 3 times.
✗ Branch 3 → 8 not taken.
✓ Branch 5 → 6 taken 3 times.
✗ Branch 5 → 8 not taken.
✓ Branch 6 → 7 taken 3 times.
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 2 times.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 2 times.
|
3 | if (!color.isValid() || !surface.isValid() || contrast(color, surface) >= ratio) return color; |
| 100 | 2 | const bool darkSurface = relativeLuminance(surface) < 0.5; | |
| 101 | 2 | QColor hsl = color.toHsl(); | |
| 102 | // Shift lightness away from the surface in small steps. | ||
| 103 |
1/2✓ Branch 30 → 15 taken 26 times.
✗ Branch 30 → 31 not taken.
|
26 | for (int step = 0; step < 40; ++step) { |
| 104 |
1/2✓ Branch 16 → 17 taken 26 times.
✗ Branch 16 → 18 not taken.
|
26 | const qreal lightness = qBound(0.0, hsl.lightnessF() + (darkSurface ? 0.025 : -0.025), 1.0); |
| 105 |
2/3✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 26 times.
✓ Branch 25 → 26 taken 26 times.
|
26 | hsl.setHslF(hsl.hslHueF() < 0 ? 0 : hsl.hslHueF(), hsl.hslSaturationF(), lightness); |
| 106 |
3/3✓ Branch 26 → 27 taken 26 times.
✓ Branch 27 → 28 taken 2 times.
✓ Branch 27 → 29 taken 24 times.
|
26 | if (contrast(hsl, surface) >= ratio) break; |
| 107 | } | ||
| 108 | 2 | return hsl.toRgb(); | |
| 109 | } | ||
| 110 | |||
| 111 | 9935 | QList<ComposeHighlighter::Word> ComposeHighlighter::checkableWords(const QString &text) { | |
| 112 | 9935 | QList<Word> words; | |
| 113 | // URLs and mail addresses are whole tokens between spaces. | ||
| 114 | 9935 | QList<QPair<int, int>> skipped; | |
| 115 |
4/7✓ Branch 2 → 3 taken 12 times.
✓ Branch 2 → 15 taken 9923 times.
✓ Branch 4 → 5 taken 12 times.
✗ Branch 4 → 15 not taken.
✓ Branch 9 → 10 taken 12 times.
✗ Branch 102 → 103 not taken.
✗ Branch 102 → 104 not taken.
|
9947 | static const QRegularExpression token(QStringLiteral("\\S+")); |
| 116 |
4/4✓ Branch 16 → 17 taken 9935 times.
✓ Branch 46 → 47 taken 61941 times.
✓ Branch 47 → 18 taken 52006 times.
✓ Branch 47 → 48 taken 9935 times.
|
61941 | for (auto it = token.globalMatch(text); it.hasNext();) { |
| 117 |
1/1✓ Branch 18 → 19 taken 52006 times.
|
52006 | const auto match = it.next(); |
| 118 |
1/1✓ Branch 19 → 20 taken 52006 times.
|
52006 | const QString value = match.captured(); |
| 119 |
8/8✓ Branch 21 → 22 taken 52006 times.
✓ Branch 22 → 23 taken 52005 times.
✓ Branch 22 → 35 taken 1 time.
✓ Branch 24 → 25 taken 52005 times.
✓ Branch 25 → 26 taken 52004 times.
✓ Branch 25 → 35 taken 1 time.
✓ Branch 29 → 30 taken 108 times.
✓ Branch 29 → 36 taken 51896 times.
|
104118 | if (value.contains(QLatin1String("://")) || value.startsWith(QLatin1String("www."), Qt::CaseInsensitive) || |
| 120 |
4/4✓ Branch 34 → 35 taken 107 times.
✓ Branch 34 → 36 taken 1 time.
✓ Branch 37 → 38 taken 109 times.
✓ Branch 37 → 43 taken 51897 times.
|
104118 | (value.indexOf(QLatin1Char('@')) > 0 && value.indexOf(QLatin1Char('@')) < value.size() - 1)) |
| 121 |
3/3✓ Branch 38 → 39 taken 109 times.
✓ Branch 39 → 40 taken 109 times.
✓ Branch 41 → 42 taken 109 times.
|
109 | skipped.append({int(match.capturedStart()), int(match.capturedEnd())}); |
| 122 | 61941 | } | |
| 123 |
1/1✓ Branch 49 → 50 taken 9935 times.
|
9935 | QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text); |
| 124 | 9935 | int start = 0; | |
| 125 | while (true) { | ||
| 126 |
1/1✓ Branch 51 → 52 taken 106249 times.
|
106249 | const int end = int(finder.toNextBoundary()); |
| 127 |
2/2✓ Branch 52 → 53 taken 9935 times.
✓ Branch 52 → 54 taken 96314 times.
|
106249 | if (end < 0) break; |
| 128 |
3/3✓ Branch 54 → 55 taken 96314 times.
✓ Branch 57 → 58 taken 52107 times.
✓ Branch 57 → 90 taken 44207 times.
|
96314 | if (finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem) { |
| 129 |
1/1✓ Branch 58 → 59 taken 52107 times.
|
52107 | const QString word = text.mid(start, end - start); |
| 130 | 52107 | bool letters = false, digits = false, lower = false; | |
| 131 |
2/2✓ Branch 65 → 61 taken 261802 times.
✓ Branch 65 → 66 taken 52107 times.
|
313909 | for (const QChar c : word) { |
| 132 | 261802 | letters |= c.isLetter(); | |
| 133 | 261802 | digits |= c.isDigit(); | |
| 134 | 261802 | lower |= c.isLower(); | |
| 135 | } | ||
| 136 | 52107 | bool inSkipped = false; | |
| 137 |
6/6✓ Branch 70 → 71 taken 961 times.
✓ Branch 70 → 73 taken 572 times.
✓ Branch 71 → 72 taken 240 times.
✓ Branch 71 → 73 taken 721 times.
✓ Branch 76 → 69 taken 1533 times.
✓ Branch 76 → 77 taken 52107 times.
|
53640 | for (const auto &range : std::as_const(skipped)) inSkipped |= start >= range.first && end <= range.second; |
| 138 | // All-caps words (abbreviations) and words with digits are left alone. | ||
| 139 |
13/13✓ Branch 77 → 78 taken 43911 times.
✓ Branch 77 → 84 taken 8196 times.
✓ Branch 78 → 79 taken 43909 times.
✓ Branch 78 → 84 taken 2 times.
✓ Branch 79 → 80 taken 43818 times.
✓ Branch 79 → 84 taken 91 times.
✓ Branch 81 → 82 taken 43568 times.
✓ Branch 81 → 84 taken 250 times.
✓ Branch 82 → 83 taken 43330 times.
✓ Branch 82 → 84 taken 238 times.
✓ Branch 85 → 86 taken 43330 times.
✓ Branch 85 → 88 taken 8777 times.
✓ Branch 86 → 87 taken 43330 times.
|
52107 | if (letters && !digits && lower && word.size() > 1 && !inSkipped) words.append({start, end - start}); |
| 140 | 52107 | } | |
| 141 | 96314 | start = end; | |
| 142 | 96314 | } | |
| 143 | 9935 | return words; | |
| 144 | 9935 | } | |
| 145 | |||
| 146 | 119 | QList<ComposeHighlighter::Word> ComposeHighlighter::misspellings(const QTextBlock &block) const { | |
| 147 |
1/1✓ Branch 2 → 3 taken 119 times.
|
119 | return m_misspellings.value(block.blockNumber()); |
| 148 | } | ||
| 149 | |||
| 150 | 13793 | void ComposeHighlighter::highlightBlock(const QString &text) { | |
| 151 | 13793 | highlightStructure(text); | |
| 152 | 13793 | highlightSpelling(text); | |
| 153 | 13793 | } | |
| 154 | |||
| 155 | 13793 | void ComposeHighlighter::highlightStructure(const QString &text) { | |
| 156 |
1/1✓ Branch 2 → 3 taken 13793 times.
|
13793 | const QTextBlock block = currentBlock(); |
| 157 | 13793 | const int length = int(text.size()); | |
| 158 |
2/2✓ Branch 4 → 5 taken 13793 times.
✓ Branch 5 → 6 taken 13793 times.
|
13793 | const int heading = block.blockFormat().headingLevel(); |
| 159 |
9/12✓ Branch 7 → 8 taken 1124 times.
✓ Branch 7 → 9 taken 12669 times.
✓ Branch 9 → 10 taken 12669 times.
✓ Branch 10 → 11 taken 12669 times.
✗ Branch 10 → 15 not taken.
✓ Branch 11 → 12 taken 12669 times.
✓ Branch 12 → 13 taken 12669 times.
✓ Branch 13 → 14 taken 12669 times.
✓ Branch 17 → 18 taken 12669 times.
✓ Branch 17 → 19 taken 1124 times.
✗ Branch 168 → 169 not taken.
✗ Branch 168 → 170 not taken.
|
13793 | const qreal base = m_basePoints > 0 ? m_basePoints : (document() ? document()->defaultFont().pointSizeF() : 10); |
| 160 |
2/2✓ Branch 19 → 20 taken 30 times.
✓ Branch 19 → 32 taken 13763 times.
|
13793 | if (heading > 0) { |
| 161 |
1/1✓ Branch 20 → 21 taken 30 times.
|
30 | QTextCharFormat format; |
| 162 |
1/1✓ Branch 21 → 22 taken 30 times.
|
30 | format.setFontWeight(QFont::Bold); |
| 163 |
5/5✓ Branch 22 → 23 taken 4 times.
✓ Branch 22 → 27 taken 26 times.
✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 25 taken 3 times.
✓ Branch 28 → 29 taken 30 times.
|
30 | format.setFontPointSize(base * (heading == 1 ? 1.6 : heading == 2 ? 1.3 : 1.1)); |
| 164 |
1/1✓ Branch 29 → 30 taken 30 times.
|
30 | setFormat(0, length, format); |
| 165 | 30 | } | |
| 166 |
3/3✓ Branch 32 → 33 taken 13793 times.
✓ Branch 33 → 34 taken 3 times.
✓ Branch 33 → 55 taken 13790 times.
|
13793 | if (isCodeBlock(block)) { |
| 167 |
1/1✓ Branch 34 → 35 taken 3 times.
|
3 | QTextCharFormat format; |
| 168 |
3/5✓ Branch 39 → 40 taken 3 times.
✓ Branch 42 → 43 taken 3 times.
✓ Branch 42 → 44 taken 3 times.
✗ Branch 178 → 179 not taken.
✗ Branch 178 → 180 not taken.
|
6 | format.setFontFamilies({QStringLiteral("monospace")}); |
| 169 |
1/1✓ Branch 45 → 46 taken 3 times.
|
3 | format.setFontFixedPitch(true); |
| 170 |
1/4✗ Branch 47 → 48 not taken.
✓ Branch 47 → 52 taken 3 times.
✗ Branch 48 → 49 not taken.
✗ Branch 49 → 50 not taken.
|
3 | if (m_palette.codeBackground.isValid()) format.setBackground(m_palette.codeBackground); |
| 171 |
1/1✓ Branch 52 → 53 taken 3 times.
|
3 | setFormat(0, length, format); |
| 172 | 3 | return; | |
| 173 | 3 | } | |
| 174 |
8/8✓ Branch 55 → 56 taken 13790 times.
✓ Branch 56 → 57 taken 13784 times.
✓ Branch 56 → 59 taken 6 times.
✓ Branch 57 → 58 taken 13784 times.
✓ Branch 58 → 59 taken 3 times.
✓ Branch 58 → 60 taken 13781 times.
✓ Branch 61 → 62 taken 9 times.
✓ Branch 61 → 72 taken 13781 times.
|
13790 | if (quoteLevel(block) > 0 || region(block) == QuoteRegion) { |
| 175 |
1/1✓ Branch 62 → 63 taken 9 times.
|
9 | QTextCharFormat format; |
| 176 |
1/4✗ Branch 64 → 65 not taken.
✓ Branch 64 → 69 taken 9 times.
✗ Branch 65 → 66 not taken.
✗ Branch 66 → 67 not taken.
|
9 | if (m_palette.secondary.isValid()) format.setForeground(m_palette.secondary); |
| 177 |
1/1✓ Branch 69 → 70 taken 9 times.
|
9 | setFormat(0, length, format); |
| 178 | 9 | } | |
| 179 |
4/4✓ Branch 72 → 73 taken 13790 times.
✓ Branch 73 → 74 taken 13790 times.
✓ Branch 75 → 76 taken 185 times.
✓ Branch 75 → 96 taken 13605 times.
|
13790 | if (QTextTable *table = QTextCursor(block).currentTable()) { |
| 180 |
2/2✓ Branch 76 → 77 taken 185 times.
✓ Branch 77 → 78 taken 185 times.
|
185 | const QTextTableCell cell = table->cellAt(block.position()); |
| 181 |
7/13✓ Branch 79 → 80 taken 185 times.
✗ Branch 79 → 85 not taken.
✓ Branch 80 → 81 taken 185 times.
✓ Branch 81 → 82 taken 185 times.
✓ Branch 82 → 83 taken 185 times.
✗ Branch 83 → 84 not taken.
✓ Branch 83 → 85 taken 185 times.
✓ Branch 86 → 87 taken 185 times.
✗ Branch 86 → 88 not taken.
✗ Branch 88 → 89 not taken.
✓ Branch 88 → 94 taken 185 times.
✗ Branch 206 → 207 not taken.
✗ Branch 206 → 208 not taken.
|
185 | if (cell.isValid() && cell.row() < table->format().headerRowCount()) { |
| 182 | ✗ | QTextCharFormat format; | |
| 183 | ✗ | format.setFontWeight(QFont::Bold); | |
| 184 | ✗ | setFormat(0, length, format); | |
| 185 | ✗ | } | |
| 186 | 185 | } | |
| 187 |
4/4✓ Branch 96 → 97 taken 13790 times.
✓ Branch 160 → 161 taken 18344 times.
✓ Branch 162 → 98 taken 18344 times.
✓ Branch 162 → 163 taken 13790 times.
|
32134 | for (auto it = block.begin(); !it.atEnd(); ++it) { |
| 188 |
1/1✓ Branch 98 → 99 taken 18344 times.
|
18344 | const QTextFragment fragment = it.fragment(); |
| 189 |
1/2✗ Branch 100 → 101 not taken.
✓ Branch 100 → 102 taken 18344 times.
|
18344 | if (!fragment.isValid()) continue; |
| 190 |
1/1✓ Branch 102 → 103 taken 18344 times.
|
18344 | const QTextCharFormat source = fragment.charFormat(); |
| 191 |
2/2✓ Branch 103 → 104 taken 18344 times.
✓ Branch 104 → 105 taken 18344 times.
|
18344 | const int start = fragment.position() - block.position(); |
| 192 |
3/3✓ Branch 105 → 106 taken 18344 times.
✓ Branch 106 → 107 taken 2 times.
✓ Branch 106 → 129 taken 18342 times.
|
18344 | if (isInlineCode(source)) { |
| 193 |
1/1✓ Branch 107 → 108 taken 2 times.
|
2 | QTextCharFormat format = this->format(start); |
| 194 |
3/5✓ Branch 112 → 113 taken 2 times.
✓ Branch 115 → 116 taken 2 times.
✓ Branch 115 → 117 taken 2 times.
✗ Branch 219 → 220 not taken.
✗ Branch 219 → 221 not taken.
|
4 | format.setFontFamilies({QStringLiteral("monospace")}); |
| 195 |
1/1✓ Branch 118 → 119 taken 2 times.
|
2 | format.setFontFixedPitch(true); |
| 196 |
1/4✗ Branch 120 → 121 not taken.
✓ Branch 120 → 125 taken 2 times.
✗ Branch 121 → 122 not taken.
✗ Branch 122 → 123 not taken.
|
2 | if (m_palette.codeBackground.isValid()) format.setBackground(m_palette.codeBackground); |
| 197 |
2/2✓ Branch 125 → 126 taken 2 times.
✓ Branch 126 → 127 taken 2 times.
|
2 | setFormat(start, fragment.length(), format); |
| 198 | 2 | } | |
| 199 |
10/12✓ Branch 129 → 130 taken 48 times.
✓ Branch 129 → 137 taken 18296 times.
✓ Branch 130 → 131 taken 48 times.
✓ Branch 131 → 132 taken 1 time.
✓ Branch 131 → 137 taken 47 times.
✓ Branch 132 → 133 taken 1 time.
✓ Branch 133 → 134 taken 1 time.
✗ Branch 133 → 137 not taken.
✓ Branch 135 → 136 taken 1 time.
✗ Branch 135 → 137 not taken.
✓ Branch 138 → 139 taken 1 time.
✓ Branch 138 → 157 taken 18343 times.
|
18345 | if (m_palette.dark && source.hasProperty(QTextFormat::ForegroundBrush) && !source.isAnchor() && |
| 200 | 1 | m_palette.surface.isValid()) { | |
| 201 |
2/2✓ Branch 139 → 140 taken 1 time.
✓ Branch 141 → 142 taken 1 time.
|
1 | const QColor shown = readableOn(source.foreground().color(), m_palette.surface); |
| 202 |
2/3✓ Branch 143 → 144 taken 1 time.
✓ Branch 147 → 148 taken 1 time.
✗ Branch 147 → 156 not taken.
|
1 | if (shown != source.foreground().color()) { |
| 203 |
1/1✓ Branch 148 → 149 taken 1 time.
|
1 | QTextCharFormat format = this->format(start); |
| 204 |
2/2✓ Branch 149 → 150 taken 1 time.
✓ Branch 150 → 151 taken 1 time.
|
1 | format.setForeground(shown); |
| 205 |
2/2✓ Branch 152 → 153 taken 1 time.
✓ Branch 153 → 154 taken 1 time.
|
1 | setFormat(start, fragment.length(), format); |
| 206 | 1 | } | |
| 207 | } | ||
| 208 | 18344 | } | |
| 209 | 10 | } | |
| 210 | |||
| 211 | 13793 | void ComposeHighlighter::highlightSpelling(const QString &text) { | |
| 212 |
1/1✓ Branch 2 → 3 taken 13793 times.
|
13793 | const QTextBlock block = currentBlock(); |
| 213 | 13793 | QList<Word> found; | |
| 214 |
6/6✓ Branch 5 → 6 taken 10017 times.
✓ Branch 6 → 7 taken 10016 times.
✓ Branch 6 → 13 taken 1 time.
✓ Branch 7 → 8 taken 10016 times.
✓ Branch 8 → 9 taken 10015 times.
✓ Branch 8 → 13 taken 1 time.
|
23810 | const bool skipBlock = !m_spellCheck || isCodeBlock(block) || quoteLevel(block) > 0 || |
| 215 |
7/8✓ Branch 4 → 5 taken 10017 times.
✓ Branch 4 → 13 taken 3776 times.
✓ Branch 9 → 10 taken 10015 times.
✓ Branch 10 → 11 taken 10015 times.
✗ Branch 10 → 13 not taken.
✓ Branch 11 → 12 taken 10015 times.
✓ Branch 12 → 13 taken 83 times.
✓ Branch 12 → 14 taken 9932 times.
|
23810 | region(block) == QuoteRegion || region(block) == SignatureRegion; |
| 216 |
2/2✓ Branch 15 → 16 taken 9932 times.
✓ Branch 15 → 93 taken 3861 times.
|
13793 | if (!skipBlock) { |
| 217 |
2/2✓ Branch 16 → 17 taken 9932 times.
✓ Branch 17 → 18 taken 9932 times.
|
19864 | const QString language = block.blockFormat().stringProperty(LanguageProperty).isEmpty() |
| 218 |
2/8✓ Branch 19 → 20 taken 9932 times.
✗ Branch 19 → 21 not taken.
✗ Branch 21 → 22 not taken.
✗ Branch 22 → 23 not taken.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 9932 times.
✗ Branch 103 → 104 not taken.
✗ Branch 103 → 105 not taken.
|
9932 | ? m_language : block.blockFormat().stringProperty(LanguageProperty); |
| 219 |
1/1✓ Branch 27 → 28 taken 9932 times.
|
9932 | const int caretInBlock = m_caret - block.position(); |
| 220 | // Inline code and links are not checked: their ranges in one pass over | ||
| 221 | // the block's fragments (a cursor per word cost more than the check). | ||
| 222 | 9932 | QList<std::pair<int, int>> skipped; | |
| 223 |
4/4✓ Branch 28 → 29 taken 9932 times.
✓ Branch 54 → 55 taken 8875 times.
✓ Branch 56 → 30 taken 8875 times.
✓ Branch 56 → 57 taken 9932 times.
|
18807 | for (auto it = block.begin(); !it.atEnd(); ++it) { |
| 224 |
1/1✓ Branch 30 → 31 taken 8875 times.
|
8875 | const QTextFragment fragment = it.fragment(); |
| 225 |
12/20✓ Branch 32 → 33 taken 8875 times.
✗ Branch 32 → 40 not taken.
✓ Branch 33 → 34 taken 8875 times.
✓ Branch 34 → 35 taken 8875 times.
✓ Branch 35 → 36 taken 8875 times.
✗ Branch 35 → 39 not taken.
✓ Branch 36 → 37 taken 8875 times.
✓ Branch 37 → 38 taken 8875 times.
✓ Branch 38 → 39 taken 3 times.
✓ Branch 38 → 40 taken 8872 times.
✓ Branch 41 → 42 taken 8875 times.
✗ Branch 41 → 43 not taken.
✓ Branch 43 → 44 taken 8875 times.
✗ Branch 43 → 45 not taken.
✓ Branch 45 → 46 taken 3 times.
✓ Branch 45 → 54 taken 8872 times.
✗ Branch 113 → 114 not taken.
✗ Branch 113 → 115 not taken.
✗ Branch 117 → 118 not taken.
✗ Branch 117 → 119 not taken.
|
8875 | if (fragment.isValid() && (isInlineCode(fragment.charFormat()) || fragment.charFormat().isAnchor())) |
| 226 |
6/6✓ Branch 46 → 47 taken 3 times.
✓ Branch 47 → 48 taken 3 times.
✓ Branch 48 → 49 taken 3 times.
✓ Branch 49 → 50 taken 3 times.
✓ Branch 50 → 51 taken 3 times.
✓ Branch 52 → 53 taken 3 times.
|
3 | skipped.append({fragment.position() - block.position(), fragment.position() - block.position() + fragment.length()}); |
| 227 | } | ||
| 228 | 43052 | const auto inSkipped = [&skipped](int offset) { | |
| 229 |
4/4✓ Branch 2 → 3 taken 43052 times.
✓ Branch 3 → 4 taken 43052 times.
✓ Branch 13 → 5 taken 5 times.
✓ Branch 13 → 14 taken 43050 times.
|
43055 | for (const auto &[from, to] : skipped) |
| 230 |
3/4✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 11 taken 3 times.
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 11 not taken.
|
5 | if (offset >= from && offset < to) return true; |
| 231 | 43050 | return false; | |
| 232 | 9932 | }; | |
| 233 |
5/5✓ Branch 57 → 58 taken 9932 times.
✓ Branch 58 → 59 taken 9932 times.
✓ Branch 59 → 60 taken 9932 times.
✓ Branch 88 → 61 taken 43323 times.
✓ Branch 88 → 89 taken 9932 times.
|
53255 | for (const Word &word : checkableWords(text)) { |
| 234 | // The word being typed is not judged before the pause. | ||
| 235 |
6/6✓ Branch 62 → 63 taken 2120 times.
✓ Branch 62 → 66 taken 41203 times.
✓ Branch 63 → 64 taken 2080 times.
✓ Branch 63 → 66 taken 40 times.
✓ Branch 64 → 65 taken 271 times.
✓ Branch 64 → 66 taken 1809 times.
|
77948 | if (m_typing && caretInBlock >= word.start && caretInBlock <= word.start + word.length) continue; |
| 236 | // As the cursor read it: the format of the word's first character. | ||
| 237 |
3/3✓ Branch 66 → 67 taken 43052 times.
✓ Branch 67 → 68 taken 2 times.
✓ Branch 67 → 69 taken 43050 times.
|
43052 | if (inSkipped(word.start)) continue; |
| 238 |
4/4✓ Branch 69 → 70 taken 43050 times.
✓ Branch 70 → 71 taken 43050 times.
✓ Branch 72 → 73 taken 34623 times.
✓ Branch 72 → 74 taken 8427 times.
|
43050 | if (!m_spellCheck(text.mid(word.start, word.length), language)) continue; |
| 239 |
1/1✓ Branch 74 → 75 taken 8427 times.
|
8427 | found.append(word); |
| 240 |
1/1✓ Branch 75 → 76 taken 8427 times.
|
8427 | QTextCharFormat format = this->format(word.start); |
| 241 |
1/1✓ Branch 76 → 77 taken 8427 times.
|
8427 | format.setUnderlineStyle(QTextCharFormat::WaveUnderline); |
| 242 |
3/3✓ Branch 78 → 79 taken 391 times.
✓ Branch 78 → 80 taken 8036 times.
✓ Branch 81 → 82 taken 8427 times.
|
8427 | format.setUnderlineColor(m_palette.spellError.isValid() ? m_palette.spellError : QColor(Qt::red)); |
| 243 |
1/1✓ Branch 82 → 83 taken 8427 times.
|
8427 | setFormat(word.start, word.length, format); |
| 244 | 18359 | } | |
| 245 | 9932 | } | |
| 246 |
4/4✓ Branch 94 → 95 taken 5606 times.
✓ Branch 94 → 98 taken 8187 times.
✓ Branch 95 → 96 taken 5606 times.
✓ Branch 96 → 97 taken 5606 times.
|
13793 | if (found.isEmpty()) m_misspellings.remove(block.blockNumber()); |
| 247 |
2/2✓ Branch 98 → 99 taken 8187 times.
✓ Branch 99 → 100 taken 8187 times.
|
8187 | else m_misspellings.insert(block.blockNumber(), found); |
| 248 | 13793 | } | |
| 249 |