File indexing completed on 2024-06-23 04:40:18
0001 /* 0002 SPDX-FileCopyrightText: 2020 Igor Poboiko <igor.poboiko@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "findutils.h" 0008 #include "textfindreplacewidget.h" 0009 #include <TextUtils/ConvertText> 0010 0011 #include <QDebug> 0012 #include <QPlainTextEdit> 0013 #include <QRegularExpression> 0014 #include <QTextCursor> 0015 #include <QTextEdit> 0016 0017 using namespace TextCustomEditor; 0018 QTextDocument::FindFlags FindUtils::convertTextEditFindFlags(TextEditFindBarBase::FindFlags textEditFlags) 0019 { 0020 QTextDocument::FindFlags flags; 0021 if (textEditFlags & TextEditFindBarBase::FindBackward) { 0022 flags |= QTextDocument::FindBackward; 0023 } 0024 if (textEditFlags & TextEditFindBarBase::FindCaseSensitively) { 0025 flags |= QTextDocument::FindCaseSensitively; 0026 } 0027 if (textEditFlags & TextEditFindBarBase::FindWholeWords) { 0028 flags |= QTextDocument::FindWholeWords; 0029 } 0030 return flags; 0031 } 0032 0033 int FindUtils::replaceAll(QTextEdit *view, const QString &str, const QString &replaceStr, TextEditFindBarBase::FindFlags searchOptions) 0034 { 0035 auto document = view->document(); 0036 int count = 0; 0037 // Ignoring FindBackward when replacing all 0038 const QTextDocument::FindFlags flags = FindUtils::convertTextEditFindFlags(searchOptions) & ~QTextDocument::FindBackward; 0039 if (searchOptions & TextEditFindBarBase::FindFlag::FindRespectDiacritics) { 0040 view->textCursor().beginEditBlock(); 0041 QTextCursor c(document); 0042 while (!c.isNull()) { 0043 c = document->find(str, c, flags); 0044 if (!c.isNull()) { 0045 c.insertText(replaceStr); 0046 count++; 0047 } else { 0048 break; 0049 } 0050 } 0051 view->textCursor().endEditBlock(); 0052 } else { 0053 const QString toPlainTextWithoutRespectDiacritics{TextUtils::ConvertText::normalize(view->toPlainText())}; 0054 const QString searchStrWithoutRespectDiacritics{TextUtils::ConvertText::normalize(str)}; 0055 0056 QTextDocument documentWithoutRespectDiacritics(toPlainTextWithoutRespectDiacritics); 0057 QTextCursor documentWithoutRespectDiacriticsTextCursor(&documentWithoutRespectDiacritics); 0058 documentWithoutRespectDiacriticsTextCursor.setPosition(0); 0059 0060 view->textCursor().beginEditBlock(); 0061 QTextCursor c(document); 0062 0063 while (!documentWithoutRespectDiacriticsTextCursor.isNull()) { 0064 documentWithoutRespectDiacriticsTextCursor = 0065 documentWithoutRespectDiacritics.find(searchStrWithoutRespectDiacritics, documentWithoutRespectDiacriticsTextCursor, flags); 0066 if (!documentWithoutRespectDiacriticsTextCursor.isNull()) { 0067 c.setPosition(documentWithoutRespectDiacriticsTextCursor.selectionStart()); 0068 c.setPosition(documentWithoutRespectDiacriticsTextCursor.selectionEnd(), QTextCursor::KeepAnchor); 0069 c.insertText(replaceStr); 0070 documentWithoutRespectDiacriticsTextCursor.insertText(replaceStr); 0071 count++; 0072 } else { 0073 break; 0074 } 0075 } 0076 view->textCursor().endEditBlock(); 0077 } 0078 return count; 0079 } 0080 0081 int FindUtils::replaceAll(QPlainTextEdit *view, const QString &str, const QString &replaceStr, TextEditFindBarBase::FindFlags searchOptions) 0082 { 0083 auto document = view->document(); 0084 int count = 0; 0085 // Ignoring FindBackward when replacing all 0086 const QTextDocument::FindFlags flags = FindUtils::convertTextEditFindFlags(searchOptions) & ~QTextDocument::FindBackward; 0087 if (searchOptions & TextEditFindBarBase::FindFlag::FindRespectDiacritics) { 0088 view->textCursor().beginEditBlock(); 0089 QTextCursor c(document); 0090 while (!c.isNull()) { 0091 c = document->find(str, c, flags); 0092 if (!c.isNull()) { 0093 c.insertText(replaceStr); 0094 count++; 0095 } else { 0096 break; 0097 } 0098 } 0099 view->textCursor().endEditBlock(); 0100 } else { 0101 const QString toPlainTextWithoutRespectDiacritics{TextUtils::ConvertText::normalize(view->toPlainText())}; 0102 const QString searchStrWithoutRespectDiacritics{TextUtils::ConvertText::normalize(str)}; 0103 0104 QTextDocument documentWithoutRespectDiacritics(toPlainTextWithoutRespectDiacritics); 0105 QTextCursor documentWithoutRespectDiacriticsTextCursor(&documentWithoutRespectDiacritics); 0106 documentWithoutRespectDiacriticsTextCursor.setPosition(0); 0107 0108 view->textCursor().beginEditBlock(); 0109 QTextCursor c(document); 0110 0111 while (!documentWithoutRespectDiacriticsTextCursor.isNull()) { 0112 documentWithoutRespectDiacriticsTextCursor = 0113 documentWithoutRespectDiacritics.find(searchStrWithoutRespectDiacritics, documentWithoutRespectDiacriticsTextCursor, flags); 0114 if (!documentWithoutRespectDiacriticsTextCursor.isNull()) { 0115 c.setPosition(documentWithoutRespectDiacriticsTextCursor.selectionStart()); 0116 c.setPosition(documentWithoutRespectDiacriticsTextCursor.selectionEnd(), QTextCursor::KeepAnchor); 0117 c.insertText(replaceStr); 0118 documentWithoutRespectDiacriticsTextCursor.insertText(replaceStr); 0119 count++; 0120 } else { 0121 break; 0122 } 0123 } 0124 view->textCursor().endEditBlock(); 0125 } 0126 return count; 0127 } 0128 0129 int FindUtils::replaceAll(QTextDocument *document, const QRegularExpression ®Exp, const QString &replaceWidget, TextEditFindBarBase::FindFlags searchOptions) 0130 { 0131 QTextCursor c(document); 0132 c.beginEditBlock(); 0133 int count = 0; 0134 // Ignoring FindBackward when replacing all 0135 const QTextDocument::FindFlags flags = FindUtils::convertTextEditFindFlags(searchOptions) & ~QTextDocument::FindBackward; 0136 while (!c.isNull()) { 0137 c = document->find(regExp, c, flags); 0138 if (!c.isNull()) { 0139 // find() selects found text, and insertText() replaces selection 0140 c.insertText(replaceWidget); 0141 count++; 0142 } else { 0143 break; 0144 } 0145 } 0146 c.endEditBlock(); 0147 return count; 0148 } 0149 0150 bool FindUtils::find(QPlainTextEdit *view, const QString &searchText, QTextDocument::FindFlags searchOptions) 0151 { 0152 const QString text = TextUtils::ConvertText::normalize(view->document()->toPlainText()); 0153 QTextDocument doc(text); 0154 QTextCursor c(&doc); 0155 QTextCursor docCusor(view->textCursor()); 0156 c.setPosition(docCusor.position()); 0157 // qDebug() << " docCusor.position() " << docCusor.position(); 0158 c = doc.find(TextUtils::ConvertText::normalize(searchText), c, searchOptions); 0159 if (!c.isNull()) { 0160 // qDebug() << " c.selectionStart() " << c.selectionStart() << "c.selectionEnd() " << c.selectionEnd(); 0161 if (searchOptions & QTextDocument::FindBackward) { 0162 docCusor.setPosition(c.selectionEnd()); 0163 docCusor.setPosition(c.selectionStart(), QTextCursor::KeepAnchor); 0164 } else { 0165 docCusor.setPosition(c.selectionStart()); 0166 docCusor.setPosition(c.selectionEnd(), QTextCursor::KeepAnchor); 0167 } 0168 view->setTextCursor(docCusor); 0169 view->ensureCursorVisible(); 0170 return true; 0171 } 0172 return false; 0173 } 0174 0175 bool FindUtils::find(QTextEdit *view, const QString &searchText, QTextDocument::FindFlags searchOptions) 0176 { 0177 const QString text = TextUtils::ConvertText::normalize(view->document()->toPlainText()); 0178 QTextDocument doc(text); 0179 QTextCursor c(&doc); 0180 QTextCursor docCusor(view->textCursor()); 0181 c.setPosition(docCusor.position()); 0182 // qDebug() << " docCusor.position() " << docCusor.position(); 0183 c = doc.find(TextUtils::ConvertText::normalize(searchText), c, searchOptions); 0184 if (!c.isNull()) { 0185 // qDebug() << " c.selectionStart() " << c.selectionStart() << "c.selectionEnd() " << c.selectionEnd(); 0186 if (searchOptions & QTextDocument::FindBackward) { 0187 docCusor.setPosition(c.selectionEnd()); 0188 docCusor.setPosition(c.selectionStart(), QTextCursor::KeepAnchor); 0189 } else { 0190 docCusor.setPosition(c.selectionStart()); 0191 docCusor.setPosition(c.selectionEnd(), QTextCursor::KeepAnchor); 0192 } 0193 view->setTextCursor(docCusor); 0194 view->ensureCursorVisible(); 0195 return true; 0196 } 0197 return false; 0198 }