File indexing completed on 2024-05-12 16:16:00
0001 /* 0002 SPDX-FileCopyrightText: 2022-2023 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "grammarresultutil.h" 0008 #include "textgrammarcheck_debug.h" 0009 0010 #include <KLocalizedString> 0011 #include <QTextBlock> 0012 #include <QTextDocument> 0013 using namespace TextGrammarCheck; 0014 0015 void GrammarResultUtil::applyGrammarResult(const QVector<TextGrammarCheck::GrammarError> &infos, QTextDocument *document, const QColor &negativeTextColor) 0016 { 0017 for (const TextGrammarCheck::GrammarError &info : infos) { 0018 int blockNumberId = info.blockId(); 0019 int startSelectionIndex = info.start(); 0020 // Block id based on 1 not 0 as QTextDocument (perhaps remove -1 when loading ?) 0021 if (blockNumberId == -1) { // Languagetool adapt grammar error We need to generate info. By default languagetool uses 1 paragraph info. 0022 const QTextBlock firstBlock = document->findBlockByNumber(0); 0023 if (firstBlock.isValid()) { 0024 QTextCursor cur(document); 0025 0026 cur.setPosition(info.start()); 0027 blockNumberId = cur.blockNumber(); 0028 for (int i = 0; i < blockNumberId; ++i) { 0029 const QTextBlock block = document->findBlockByNumber(i); 0030 if (block.isValid()) { 0031 if (block.text() != QLatin1Char('\n')) { 0032 startSelectionIndex -= block.length(); 0033 } 0034 } 0035 } 0036 } 0037 } else { 0038 blockNumberId = info.blockId() - 1; 0039 } 0040 QTextBlock block = document->findBlockByNumber(blockNumberId); 0041 if (block.isValid()) { 0042 QTextCursor cur(block); 0043 QTextCharFormat format; 0044 // Verify color 0045 format.setBackground(info.color().isValid() ? info.color() : negativeTextColor); 0046 QString toolTip = info.error(); 0047 // TODO generate new tooltip! 0048 if (!info.url().isEmpty()) { 0049 toolTip += QLatin1Char('\n') + i18n("See on: %1", info.url()); 0050 } 0051 format.setToolTip(toolTip); 0052 TextGrammarCheck::GrammarAction act; 0053 act.setLength(info.length()); 0054 act.setStart(startSelectionIndex); 0055 act.setSuggestions(info.suggestions()); 0056 act.setBlockId(blockNumberId + 1); 0057 if (!info.url().isEmpty()) { 0058 act.setInfoUrls({info.url()}); 0059 } 0060 format.setProperty(ReplaceFormatInfo, QVariant::fromValue(act)); 0061 const int position = cur.position() + startSelectionIndex; 0062 cur.setPosition(position); 0063 cur.setPosition(position + info.length(), QTextCursor::KeepAnchor); 0064 cur.mergeCharFormat(format); 0065 } else { 0066 qCWarning(TEXTGRAMMARCHECK_LOG) << "Unable to find block Id" << (info.blockId() - 1); 0067 } 0068 } 0069 } 0070 0071 void GrammarResultUtil::replaceWord(const TextGrammarCheck::GrammarAction &act, const QString &replacementWord, QTextDocument *document) 0072 { 0073 QTextBlock block = document->findBlockByNumber(act.blockId() - 1); 0074 if (block.isValid()) { 0075 QTextCursor cur(block); 0076 const int initialCurrentPosition = cur.position(); 0077 qCDebug(TEXTGRAMMARCHECK_LOG) << " cur.position()" << cur.position(); 0078 const int position = cur.position() + act.start(); 0079 cur.setPosition(position); 0080 cur.setPosition(position + act.length(), QTextCursor::KeepAnchor); 0081 QTextCharFormat format; 0082 cur.insertText(replacementWord, format); 0083 const int diff = replacementWord.length() - act.length(); 0084 qCDebug(TEXTGRAMMARCHECK_LOG) << " diff " << diff; 0085 if (diff != 0) { 0086 const int blockLength = block.length(); 0087 qCDebug(TEXTGRAMMARCHECK_LOG) << "current blockLength " << blockLength << " position " << position << ""; 0088 for (int i = position + replacementWord.length() + 1; i < blockLength + initialCurrentPosition; ++i) { 0089 cur.setPosition(i); 0090 qCDebug(TEXTGRAMMARCHECK_LOG) << " Position " << i; 0091 QTextCharFormat currentCharFormat = cur.charFormat(); 0092 if (currentCharFormat.hasProperty(GrammarResultUtil::TextInfo::ReplaceFormatInfo)) { 0093 auto act = cur.charFormat().property(GrammarResultUtil::TextInfo::ReplaceFormatInfo).value<TextGrammarCheck::GrammarAction>(); 0094 qCDebug(TEXTGRAMMARCHECK_LOG) << "BEFORE Update GrammarResultUtil::TextInfo::ReplaceFormatInfo " << act; 0095 act.setStart(act.start() + diff); 0096 qCDebug(TEXTGRAMMARCHECK_LOG) << "AFTER Update GrammarResultUtil::TextInfo::ReplaceFormatInfo " << act.start(); 0097 currentCharFormat.setProperty(GrammarResultUtil::TextInfo::ReplaceFormatInfo, QVariant::fromValue(act)); 0098 0099 const int newPosition = i - 1; 0100 qCDebug(TEXTGRAMMARCHECK_LOG) << " newPosition " << newPosition; 0101 qCDebug(TEXTGRAMMARCHECK_LOG) << "BEFORE Update GrammarResultUtil::TextInfo::ReplaceFormatInfo newPosition " << newPosition; 0102 cur.setPosition(newPosition); 0103 cur.setPosition(newPosition + act.length(), QTextCursor::KeepAnchor); 0104 qCDebug(TEXTGRAMMARCHECK_LOG) << "AFTER Update GrammarResultUtil::TextInfo::ReplaceFormatInfo newPosition " << newPosition + act.length(); 0105 cur.setCharFormat(currentCharFormat); 0106 0107 i += act.length(); 0108 } 0109 } 0110 } 0111 } 0112 }