File indexing completed on 2024-05-12 16:16:00
0001 /* 0002 SPDX-FileCopyrightText: 2019-2023 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "grammarresulttextedit.h" 0008 #include "grammarresultutil.h" 0009 #include "textgrammarcheck_debug.h" 0010 #include <KStatefulBrush> 0011 0012 #include <KLocalizedString> 0013 #include <KStandardAction> 0014 #include <QDesktopServices> 0015 0016 #include <KColorScheme> 0017 #include <QAction> 0018 #include <QApplication> 0019 #include <QContextMenuEvent> 0020 #include <QMenu> 0021 #include <QPainter> 0022 using namespace TextGrammarCheck; 0023 GrammarResultTextEdit::GrammarResultTextEdit(QWidget *parent) 0024 : QTextEdit(parent) 0025 { 0026 setReadOnly(true); 0027 setAcceptRichText(false); 0028 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0029 connect(qApp, &QApplication::paletteChanged, this, &GrammarResultTextEdit::generalPaletteChanged); 0030 #endif 0031 generalPaletteChanged(); 0032 } 0033 0034 GrammarResultTextEdit::~GrammarResultTextEdit() = default; 0035 0036 void GrammarResultTextEdit::paintEvent(QPaintEvent *event) 0037 { 0038 if (document()->isEmpty()) { 0039 const QString label = i18n("Any text to check."); 0040 0041 QPainter p(viewport()); 0042 0043 QFont font = p.font(); 0044 font.setItalic(true); 0045 p.setFont(font); 0046 0047 if (!mTextColor.isValid()) { 0048 generalPaletteChanged(); 0049 } 0050 p.setPen(mTextColor); 0051 0052 p.drawText(QRect(0, 0, width(), height()), Qt::AlignCenter, label); 0053 } else { 0054 QTextEdit::paintEvent(event); 0055 } 0056 } 0057 0058 bool GrammarResultTextEdit::event(QEvent *ev) 0059 { 0060 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0061 if (ev->type() == QEvent::ApplicationPaletteChange) { 0062 generalPaletteChanged(); 0063 } 0064 #endif 0065 return QTextEdit::event(ev); 0066 } 0067 0068 void GrammarResultTextEdit::generalPaletteChanged() 0069 { 0070 const QPalette palette = viewport()->palette(); 0071 QColor color = palette.text().color(); 0072 color.setAlpha(128); 0073 mTextColor = color; 0074 const KStatefulBrush bgBrush = KStatefulBrush(KColorScheme::View, KColorScheme::NegativeText); 0075 mNegativeTextColor = bgBrush.brush(palette).color(); 0076 } 0077 0078 void GrammarResultTextEdit::applyGrammarResult(const QVector<GrammarError> &infos) 0079 { 0080 GrammarResultUtil::applyGrammarResult(infos, document(), mNegativeTextColor); 0081 } 0082 0083 void GrammarResultTextEdit::contextMenuEvent(QContextMenuEvent *event) 0084 { 0085 QMenu *popup = createStandardContextMenu(); 0086 if (popup) { 0087 QTextCursor cursor = cursorForPosition(event->pos()); 0088 if (cursor.charFormat().hasProperty(GrammarResultUtil::TextInfo::ReplaceFormatInfo)) { 0089 const auto act = cursor.charFormat().property(GrammarResultUtil::TextInfo::ReplaceFormatInfo).value<TextGrammarCheck::GrammarAction>(); 0090 const QStringList sugg = act.suggestions(); 0091 if (!sugg.isEmpty()) { 0092 popup->addSeparator(); 0093 QMenu *popupReplacement = popup->addMenu(i18n("Replacement")); 0094 for (const QString &str : sugg) { 0095 QAction *actReplacement = popupReplacement->addAction(str); 0096 connect(actReplacement, &QAction::triggered, this, [this, act, str]() { 0097 slotReplaceWord(act, str); 0098 }); 0099 } 0100 const QStringList lst = act.infoUrls(); 0101 if (!lst.isEmpty()) { 0102 QMenu *popupUrlInfo = popup->addMenu(i18n("Online Grammar Information")); 0103 for (const QString &str : lst) { 0104 QAction *actUrlInfo = popupUrlInfo->addAction(str); 0105 connect(actUrlInfo, &QAction::triggered, this, [this, str]() { 0106 slotOpenGrammarUrlInfo(str); 0107 }); 0108 } 0109 } 0110 } else { 0111 qCDebug(TEXTGRAMMARCHECK_LOG) << " no suggestion " << act; 0112 } 0113 } 0114 popup->addSeparator(); 0115 QAction *checkAgainAct = popup->addAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("Check Again")); 0116 connect(checkAgainAct, &QAction::triggered, this, &GrammarResultTextEdit::checkAgain); 0117 popup->addSeparator(); 0118 QAction *configureAct = popup->addAction(QIcon::fromTheme(QStringLiteral("settings-configure")), i18n("Configure...")); 0119 connect(configureAct, &QAction::triggered, this, &GrammarResultTextEdit::configure); 0120 popup->addSeparator(); 0121 QAction *closeAct = KStandardAction::close(this, &GrammarResultTextEdit::closeChecker, this); 0122 closeAct->setShortcut({}); 0123 popup->addAction(closeAct); 0124 popup->exec(event->globalPos()); 0125 delete popup; 0126 } 0127 } 0128 0129 void GrammarResultTextEdit::slotOpenGrammarUrlInfo(const QString &url) 0130 { 0131 QDesktopServices::openUrl(QUrl(url)); 0132 } 0133 0134 void GrammarResultTextEdit::slotReplaceWord(const TextGrammarCheck::GrammarAction &act, const QString &replacementWord) 0135 { 0136 TextGrammarCheck::GrammarAction actWithReplacement = act; 0137 actWithReplacement.setReplacement(replacementWord); 0138 GrammarResultUtil::replaceWord(actWithReplacement, replacementWord, document()); 0139 Q_EMIT replaceText(actWithReplacement); 0140 } 0141 0142 #include "moc_grammarresulttextedit.cpp"