From abaf470e286afb1b82ddd8020ad6511810177a6e Mon Sep 17 00:00:00 2001 From: Fozei Date: Sun, 28 Apr 2024 17:14:47 +0800 Subject: [PATCH] feat: Add status label on findbar and replacebar Description: It is convent to know how many results I have and which result now is focused on. --- src/controls/findbar.cpp | 7 ++ src/controls/findbar.h | 2 + src/controls/replacebar.cpp | 8 +++ src/controls/replacebar.h | 2 + src/editor/dtextedit.cpp | 125 ++++++++++++++++++++---------------- src/editor/dtextedit.h | 3 + src/widgets/window.cpp | 22 +++++++ src/widgets/window.h | 2 + 8 files changed, 117 insertions(+), 54 deletions(-) diff --git a/src/controls/findbar.cpp b/src/controls/findbar.cpp index 5c422046..4af41e52 100644 --- a/src/controls/findbar.cpp +++ b/src/controls/findbar.cpp @@ -31,6 +31,7 @@ FindBar::FindBar(QWidget *parent) m_layout->setAlignment(Qt::AlignVCenter); m_findLabel = new QLabel(tr("Find")); m_editLine = new LineBar(); + m_statusLabel = new QLabel(tr("")); m_findPrevButton = new QPushButton(tr("Previous")); m_findNextButton = new QPushButton(tr("Next")); m_closeButton = new DIconButton(DStyle::SP_CloseButton); @@ -49,6 +50,7 @@ FindBar::FindBar(QWidget *parent) lineBarLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding)); m_layout->addLayout(lineBarLayout); + m_layout->addWidget(m_statusLabel); m_layout->addWidget(m_findPrevButton); m_layout->addWidget(m_findNextButton); m_layout->addWidget(m_closeButton); @@ -216,3 +218,8 @@ void FindBar::findPreClicked() emit findPrev(m_editLine->lineEdit()->text()); } } + +void FindBar::setStatusText(QString statusStr) +{ + m_statusLabel->setText(statusStr); +} diff --git a/src/controls/findbar.h b/src/controls/findbar.h index a7185efa..3bcf3557 100644 --- a/src/controls/findbar.h +++ b/src/controls/findbar.h @@ -41,6 +41,7 @@ class FindBar : public DFloatingWidget void receiveText(QString t); void setSearched(bool _); void findPreClicked(); + void setStatusText(QString str); Q_SIGNALS: void pressEsc(); @@ -74,6 +75,7 @@ public Q_SLOTS: LineBar *m_editLine; QHBoxLayout *m_layout; QLabel *m_findLabel; + QLabel *m_statusLabel; QString m_findFile; int m_findFileColumn; int m_findFileRow; diff --git a/src/controls/replacebar.cpp b/src/controls/replacebar.cpp index 898717ee..58ff996c 100644 --- a/src/controls/replacebar.cpp +++ b/src/controls/replacebar.cpp @@ -32,6 +32,7 @@ ReplaceBar::ReplaceBar(QWidget *parent) m_replaceLine = new LineBar(); m_withLabel = new QLabel(tr("Replace With")); m_withLine = new LineBar(); + m_statusLabel = new QLabel(tr("")); m_replaceButton = new QPushButton(tr("Replace")); m_replaceSkipButton = new QPushButton(tr("Skip")); m_replaceRestButton = new QPushButton(tr("Replace Rest")); @@ -46,6 +47,8 @@ ReplaceBar::ReplaceBar(QWidget *parent) m_layout->addLayout(createVerticalLine(m_replaceLine)); m_layout->addWidget(m_withLabel); m_layout->addLayout(createVerticalLine(m_withLine)); + + m_layout->addWidget(m_statusLabel); m_layout->addWidget(m_replaceButton); m_layout->addWidget(m_replaceSkipButton); m_layout->addWidget(m_replaceRestButton); @@ -260,3 +263,8 @@ void ReplaceBar::change() { searched = false; } + +void ReplaceBar::setStatusText(QString str) +{ + m_statusLabel->setText(str); +} diff --git a/src/controls/replacebar.h b/src/controls/replacebar.h index 724ecd8d..c33afc0f 100644 --- a/src/controls/replacebar.h +++ b/src/controls/replacebar.h @@ -32,6 +32,7 @@ class ReplaceBar : public DFloatingWidget void activeInput(QString text, QString file, int row, int column, int scrollOffset); void setMismatchAlert(bool isAlert); void setsearched(bool _); + void setStatusText(QString text); Q_SIGNALS: void pressEsc(); @@ -77,6 +78,7 @@ public Q_SLOTS: QHBoxLayout *m_layout; QLabel *m_replaceLabel; QLabel *m_withLabel; + QLabel *m_statusLabel; QString m_replaceFile; int m_replaceFileColumn; int m_replaceFileRow; diff --git a/src/editor/dtextedit.cpp b/src/editor/dtextedit.cpp index 17c65c4b..94f27853 100644 --- a/src/editor/dtextedit.cpp +++ b/src/editor/dtextedit.cpp @@ -2014,72 +2014,85 @@ bool TextEdit::updateKeywordSelectionsInView(QString keyword, QTextCharFormat ch // Clear keyword selections first. listSelection->clear(); + if (keyword.isEmpty()) { + return false; + } + // Update selections with keyword. - if (!keyword.isEmpty()) { - QTextCursor cursor(document()); - QTextEdit::ExtraSelection extra; - extra.format = charFormat; + QTextCursor cursor(document()); + QTextEdit::ExtraSelection extra; + extra.format = charFormat; + + QScrollBar *pScrollBar = verticalScrollBar(); + QPoint startPoint = QPointF(0, 0).toPoint(); + QTextBlock beginBlock = cursorForPosition(startPoint).block(); + int beginPos = beginBlock.position(); + QTextBlock endBlock; + + if (pScrollBar->maximum() > 0) { + QPoint endPoint = QPointF(0, 1.5 * height()).toPoint(); + endBlock = cursorForPosition(endPoint).block(); + } else { + endBlock = document()->lastBlock(); + } + int endPos = endBlock.position() + endBlock.length() - 1; - QScrollBar *pScrollBar = verticalScrollBar(); - QPoint startPoint = QPointF(0, 0).toPoint(); - QTextBlock beginBlock = cursorForPosition(startPoint).block(); - int beginPos = beginBlock.position(); - QTextBlock endBlock; + // 内部计算时,均视为 \n 结尾 + QLatin1Char endLine('\n'); + QString multiLineText; + QTextDocument::FindFlags flags; + flags |= QTextDocument::FindCaseSensitively; + if (keyword.contains(endLine)) { + auto temp = this->textCursor(); + temp.setPosition(beginPos); + while (temp.position() < endPos) { + temp.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + multiLineText += temp.selectedText(); + multiLineText += endLine; + temp.setPosition(temp.position() + 1); + } + cursor = findCursor(keyword, multiLineText, 0, false, beginPos); + } else { + cursor = document()->find(keyword, beginPos, flags); + } - if (pScrollBar->maximum() > 0) { - QPoint endPoint = QPointF(0, 1.5 * height()).toPoint(); - endBlock = cursorForPosition(endPoint).block(); - } else { - endBlock = document()->lastBlock(); - } - int endPos = endBlock.position() + endBlock.length() - 1; + if (cursor.isNull()) { + return false; + } - // 内部计算时,均视为 \n 结尾 - QLatin1Char endLine('\n'); - QString multiLineText; - QTextDocument::FindFlags flags; - flags |= QTextDocument::FindCaseSensitively; - if (keyword.contains(endLine)) { - auto temp = this->textCursor(); - temp.setPosition(beginPos); - while (temp.position() < endPos) { - temp.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); - multiLineText += temp.selectedText(); - multiLineText += endLine; - temp.setPosition(temp.position() + 1); + QTextCursor currentCursor = textCursor(); + m_headStatusStr = ""; + int start = 0; + + while (!cursor.isNull()) { + extra.cursor = cursor; + /* 查找字符时,查找到完全相等的时候才高亮,如查找小写f时,大写的F不高亮 */ + if (!extra.cursor.selectedText().compare(keyword) || keyword.contains(endLine)) { + start += 1; + listSelection->append(extra); + + // 记录当前cursor在结果列表中的位置 + if(cursor.anchor() == currentCursor.anchor()) + { + m_headStatusStr = QString("%1").arg(start); } - cursor = findCursor(keyword, multiLineText, 0, false, beginPos); - } else { - cursor = document()->find(keyword, beginPos, flags); } - if (cursor.isNull()) { - return false; + if (keyword.contains(endLine)) { + int pos = std::max(extra.cursor.position(), extra.cursor.anchor()); + cursor = findCursor(keyword, multiLineText, pos - beginPos, false, beginPos); + } else { + cursor = document()->find(keyword, cursor, flags); } - while (!cursor.isNull()) { - extra.cursor = cursor; - /* 查找字符时,查找到完全相等的时候才高亮,如查找小写f时,大写的F不高亮 */ - if (!extra.cursor.selectedText().compare(keyword) || keyword.contains(endLine)) { - listSelection->append(extra); - } - - if (keyword.contains(endLine)) { - int pos = std::max(extra.cursor.position(), extra.cursor.anchor()); - cursor = findCursor(keyword, multiLineText, pos - beginPos, false, beginPos); - } else { - cursor = document()->find(keyword, cursor, flags); - } - - if (cursor.position() > endPos) { - break; - } + if (cursor.position() > endPos) { + break; } - - return true; } - return false; + m_tailStatusStr = QString("%1").arg(listSelection->size()); + + return true; } bool TextEdit::searchKeywordSeletion(QString keyword, QTextCursor cursor, bool findNext) @@ -2195,6 +2208,10 @@ void TextEdit::renderAllSelections() // 设置到 QPlainText 中进行渲染 setExtraSelections(finalSelections); + + QString status = m_findMatchSelections.size() == 0 ? QString("No Reuslt") : QString("%1/%2").arg(m_headStatusStr).arg(m_tailStatusStr); + // 发射信号,通知window更新状态文字 + Q_EMIT signal_renderAllFinish(status); } void TextEdit::updateMarkAllSelectColor() diff --git a/src/editor/dtextedit.h b/src/editor/dtextedit.h index 6fcbf50b..a9ea2e82 100644 --- a/src/editor/dtextedit.h +++ b/src/editor/dtextedit.h @@ -476,6 +476,7 @@ class TextEdit : public DPlainTextEdit void popupNotify(QString notify); void signal_readingPath(); void signal_setTitleFocus(); + void signal_renderAllFinish(QString text); public slots: /** * @author liumaochuan ut000616 @@ -861,5 +862,7 @@ private slots: bool m_MidButtonPatse = false; // 鼠标中键黏贴处理 bool m_isPreeditBefore = false; // 上一个输入法时间是否是 preedit int m_preeditLengthBefore = 0; + QString m_headStatusStr; + QString m_tailStatusStr; }; #endif diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index c5babbc4..3182d63c 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -940,6 +940,9 @@ EditWrapper *Window::createEditor() updateJumpLineBar(wrapper->textEditor()); }, Qt::QueuedConnection); + // Editor renderAllSelections执行完毕后,调用onEditorRenderAllFinish更新状态文字 + connect(wrapper->textEditor(),&TextEdit::signal_renderAllFinish,this,&Window::onEditorRenderAllFinish,Qt::QueuedConnection); + bool wordWrap = m_settings->settings->option("base.font.wordwrap")->value().toBool(); wrapper->textEditor()->m_pIsShowCodeFoldArea = m_settings->settings->option("base.font.codeflod")->value().toBool(); wrapper->OnThemeChangeSlot(m_themePath); @@ -1547,6 +1550,10 @@ void Window::popupReplaceBar() m_replaceBar->activeInput(text, tabPath, row, column, scrollOffset); + wrapper->textEditor()->highlightKeywordInView(text); + // set keywords + m_keywordForSearchAll = m_keywordForSearch = text; + QTimer::singleShot(10, this, [ = ] { m_replaceBar->focus(); }); } @@ -3595,6 +3602,21 @@ void Window::setPrintEnabled(bool enabled) } } +void Window::onEditorRenderAllFinish(QString status) +{ + EditWrapper *wrapper = currentWrapper(); + + if (currentWrapper() == nullptr) { + return; + } + if(m_findBar->isVisible()){ + m_findBar->setStatusText(status); + } + if(m_replaceBar->isVisible()){ + m_replaceBar->setStatusText(status); + } +} + QStackedWidget *Window::getStackedWgt() { return m_editorWidget; diff --git a/src/widgets/window.h b/src/widgets/window.h index 67cf028a..88caff73 100644 --- a/src/widgets/window.h +++ b/src/widgets/window.h @@ -242,6 +242,8 @@ public Q_SLOTS: // 接收布局模式变更信号,更新界面布局 Q_SLOT void updateSizeMode(); + Q_SLOT void onEditorRenderAllFinish(QString text); + protected: void resizeEvent(QResizeEvent *event) override; void closeEvent(QCloseEvent *event) override;