KTextAddons

grammarresultutil.cpp
1/*
2 SPDX-FileCopyrightText: 2022-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "grammarresultutil.h"
8#include "textgrammarcheck_debug.h"
9
10#include <KLocalizedString>
11#include <QTextBlock>
12#include <QTextDocument>
13using namespace TextGrammarCheck;
14
15void GrammarResultUtil::applyGrammarResult(const QVector<TextGrammarCheck::GrammarError> &infos, QTextDocument *document, const QColor &negativeTextColor)
16{
17 for (const TextGrammarCheck::GrammarError &info : infos) {
18 int blockNumberId = info.blockId();
19 int startSelectionIndex = info.start();
20 // Block id based on 1 not 0 as QTextDocument (perhaps remove -1 when loading ?)
21 if (blockNumberId == -1) { // Languagetool adapt grammar error We need to generate info. By default languagetool uses 1 paragraph info.
22 const QTextBlock firstBlock = document->findBlockByNumber(0);
23 if (firstBlock.isValid()) {
24 QTextCursor cur(document);
25
26 cur.setPosition(info.start());
27 blockNumberId = cur.blockNumber();
28 for (int i = 0; i < blockNumberId; ++i) {
29 const QTextBlock block = document->findBlockByNumber(i);
30 if (block.isValid()) {
31 if (block.text() != QLatin1Char('\n')) {
32 startSelectionIndex -= block.length();
33 }
34 }
35 }
36 }
37 } else {
38 blockNumberId = info.blockId() - 1;
39 }
40 QTextBlock block = document->findBlockByNumber(blockNumberId);
41 if (block.isValid()) {
42 QTextCursor cur(block);
43 QTextCharFormat format;
44 // Verify color
45 format.setBackground(info.color().isValid() ? info.color() : negativeTextColor);
46 QString toolTip = info.error();
47 // TODO generate new tooltip!
48 if (!info.url().isEmpty()) {
49 toolTip += QLatin1Char('\n') + i18n("See on: %1", info.url());
50 }
51 format.setToolTip(toolTip);
52 TextGrammarCheck::GrammarAction act;
53 act.setLength(info.length());
54 act.setStart(startSelectionIndex);
55 act.setSuggestions(info.suggestions());
56 act.setBlockId(blockNumberId + 1);
57 if (!info.url().isEmpty()) {
58 act.setInfoUrls({info.url()});
59 }
60 format.setProperty(ReplaceFormatInfo, QVariant::fromValue(act));
61 const int position = cur.position() + startSelectionIndex;
62 cur.setPosition(position);
63 cur.setPosition(position + info.length(), QTextCursor::KeepAnchor);
64 cur.mergeCharFormat(format);
65 } else {
66 qCWarning(TEXTGRAMMARCHECK_LOG) << "Unable to find block Id" << (info.blockId() - 1);
67 }
68 }
69}
70
71void GrammarResultUtil::replaceWord(const TextGrammarCheck::GrammarAction &act, const QString &replacementWord, QTextDocument *document)
72{
73 QTextBlock block = document->findBlockByNumber(act.blockId() - 1);
74 if (block.isValid()) {
75 QTextCursor cur(block);
76 const int initialCurrentPosition = cur.position();
77 qCDebug(TEXTGRAMMARCHECK_LOG) << " cur.position()" << cur.position();
78 const int position = cur.position() + act.start();
79 cur.setPosition(position);
80 cur.setPosition(position + act.length(), QTextCursor::KeepAnchor);
81 QTextCharFormat format;
82 cur.insertText(replacementWord, format);
83 const int diff = replacementWord.length() - act.length();
84 qCDebug(TEXTGRAMMARCHECK_LOG) << " diff " << diff;
85 if (diff != 0) {
86 const int blockLength = block.length();
87 qCDebug(TEXTGRAMMARCHECK_LOG) << "current blockLength " << blockLength << " position " << position << "";
88 for (int i = position + replacementWord.length() + 1; i < blockLength + initialCurrentPosition; ++i) {
89 cur.setPosition(i);
90 qCDebug(TEXTGRAMMARCHECK_LOG) << " Position " << i;
91 QTextCharFormat currentCharFormat = cur.charFormat();
92 if (currentCharFormat.hasProperty(GrammarResultUtil::TextInfo::ReplaceFormatInfo)) {
93 auto act = cur.charFormat().property(GrammarResultUtil::TextInfo::ReplaceFormatInfo).value<TextGrammarCheck::GrammarAction>();
94 qCDebug(TEXTGRAMMARCHECK_LOG) << "BEFORE Update GrammarResultUtil::TextInfo::ReplaceFormatInfo " << act;
95 act.setStart(act.start() + diff);
96 qCDebug(TEXTGRAMMARCHECK_LOG) << "AFTER Update GrammarResultUtil::TextInfo::ReplaceFormatInfo " << act.start();
97 currentCharFormat.setProperty(GrammarResultUtil::TextInfo::ReplaceFormatInfo, QVariant::fromValue(act));
98
99 const int newPosition = i - 1;
100 qCDebug(TEXTGRAMMARCHECK_LOG) << " newPosition " << newPosition;
101 qCDebug(TEXTGRAMMARCHECK_LOG) << "BEFORE Update GrammarResultUtil::TextInfo::ReplaceFormatInfo newPosition " << newPosition;
102 cur.setPosition(newPosition);
103 cur.setPosition(newPosition + act.length(), QTextCursor::KeepAnchor);
104 qCDebug(TEXTGRAMMARCHECK_LOG) << "AFTER Update GrammarResultUtil::TextInfo::ReplaceFormatInfo newPosition " << newPosition + act.length();
105 cur.setCharFormat(currentCharFormat);
106
107 i += act.length();
108 }
109 }
110 }
111 }
112}
QString i18n(const char *text, const TYPE &arg...)
qsizetype length() const const
bool isValid() const const
int length() const const
QString text() const const
void setToolTip(const QString &text)
QTextBlock findBlockByNumber(int blockNumber) const const
bool hasProperty(int propertyId) const const
void setBackground(const QBrush &brush)
void setProperty(int propertyId, const QList< QTextLength > &value)
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:51:28 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.