From edf2f994e5f91b79d614dedfd0a8b5fdd011a92a Mon Sep 17 00:00:00 2001 From: iaom Date: Fri, 17 Jun 2022 10:45:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=85=B3=E9=94=AE=E8=AF=8D?= =?UTF-8?q?=E9=AB=98=E4=BA=AE=E6=96=B9=E6=A1=88=EF=BC=8C=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E9=A1=B9=E6=98=BE=E7=A4=BA=E6=95=88=E6=9E=9C=E9=80=82=E9=85=8D?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=E6=A1=86=E6=9E=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/view/result-view-delegate.cpp | 122 ++++++++++--------------- frontend/view/result-view-delegate.h | 30 +++++- 2 files changed, 72 insertions(+), 80 deletions(-) diff --git a/frontend/view/result-view-delegate.cpp b/frontend/view/result-view-delegate.cpp index 6cd149c..ce0cc25 100644 --- a/frontend/view/result-view-delegate.cpp +++ b/frontend/view/result-view-delegate.cpp @@ -3,15 +3,15 @@ using namespace UkuiSearch; static ResultItemStyle *global_instance_of_item_style = nullptr; -ResultViewDelegate::ResultViewDelegate(QObject *parent) : QStyledItemDelegate(parent) +ResultViewDelegate::ResultViewDelegate(QObject *parent) : QStyledItemDelegate(parent), + m_textDoc(new QTextDocument(this)), + m_hightLightEffectHelper(new HightLightEffectHelper(this)) { - } void ResultViewDelegate::setSearchKeyword(const QString ®FindKeyWords) { - m_regFindKeyWords.clear(); - m_regFindKeyWords = regFindKeyWords; + m_hightLightEffectHelper->setExpression(regFindKeyWords); } QSize ResultViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -21,90 +21,33 @@ QSize ResultViewDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo return size; } -void ResultViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { +void ResultViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ QStyleOptionViewItem opt = option; initStyleOption(&opt, index); - QStyle *style = opt.widget->style(); + opt.displayAlignment = Qt::Alignment(Qt::AlignLeft|Qt::AlignVCenter); QString text = opt.text; - if(text.isEmpty()) { - return; - } opt.text = QString(); + + QStyle *style = opt.widget->style(); style->proxy()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); //绘制非文本区域内容 opt.text = text; - QTextDocument doc; - doc.setHtml(getHtmlText(painter, opt, index)); //提取富文本 - QAbstractTextDocumentLayout* layout = doc.documentLayout(); - const double height = layout->documentSize().height(); - - QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &opt, opt.widget); - //使图标和文本间隔与原来保持一致,故文本区域右移4 -// textRect.adjust(4, 0, 0, 0); - double y = textRect.y(); - y += (textRect.height() - height) / 2; - - QAbstractTextDocumentLayout::PaintContext context; - - QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled - ? QPalette::Normal : QPalette::Disabled; - if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) - cg = QPalette::Inactive; - - if(opt.state & QStyle::State_Selected) { - painter->setPen(opt.palette.color(cg, QPalette::HighlightedText)); - } else { - painter->setPen(opt.palette.color(cg, QPalette::Text)); - } painter->save(); - painter->translate(QPointF(textRect.x(), y)); - layout->draw(painter, context); //绘制文本区域内容 - painter->restore(); - -} - -QString ResultViewDelegate::getHtmlText(QPainter *painter, const QStyleOptionViewItem &itemOption, const QModelIndex &index) const -{ - int indexFindLeft = 0; - QString indexString = index.model()->data(index, Qt::DisplayRole).toString(); - QFont ft(painter->font().family(), GlobalSettings::getInstance()->getValue(FONT_SIZE_KEY).toInt()); - QFontMetrics fm(ft); - QString indexColString = fm.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() - 30 - 10); //当字体超过Item的长度时显示为省略号 - QString htmlString; - if((indexColString.toUpper()).contains((m_regFindKeyWords.toUpper()))) { - indexFindLeft = indexColString.toUpper().indexOf(m_regFindKeyWords.toUpper()); //得到查找字体在当前整个Item字体中的位置 - htmlString = escapeHtml(indexColString.left(indexFindLeft)) + "" + escapeHtml(indexColString.mid(indexFindLeft, m_regFindKeyWords.length())) + "" + escapeHtml(indexColString.right(indexColString.length() - indexFindLeft - m_regFindKeyWords.length())); + if(opt.state & QStyle::State_Selected) { + m_hightLightEffectHelper->setTextColor(QBrush(opt.palette.highlightedText().color())); } else { - bool boldOpenned = false; - for(int i = 0; i < indexColString.length(); i++) { - if((m_regFindKeyWords.toUpper()).contains(QString(indexColString.at(i)).toUpper())) { - if(! boldOpenned) { - boldOpenned = true; - htmlString.append(QString("")); - } - htmlString.append(escapeHtml(QString(indexColString.at(i)))); - } else { - if(boldOpenned) { - boldOpenned = false; - htmlString.append(QString("")); - } - htmlString.append(escapeHtml(QString(indexColString.at(i)))); - - } - } + m_hightLightEffectHelper->setTextColor(QBrush(opt.palette.text().color())); } -// qDebug()<"<" + htmlString + ""; -} + painter->translate(textRect.topLeft()); -QString ResultViewDelegate::escapeHtml(const QString &str) const -{ - QString temp = str; - temp.replace("<", "<"); - temp.replace(">", ">"); - return temp; + m_textDoc->setHtml("
" + text + "
"); + m_hightLightEffectHelper->setDocument(m_textDoc); + m_hightLightEffectHelper->rehighlight(); + m_textDoc->drawContents(painter); + painter->restore(); } ResultItemStyle *ResultItemStyle::getStyle() @@ -259,3 +202,32 @@ void ResultItemStyle::drawControl(QStyle::ControlElement element, const QStyleOp break; } } + +HightLightEffectHelper::HightLightEffectHelper(QObject *parent) : QSyntaxHighlighter(parent) +{ + m_expression.setCaseSensitivity(Qt::CaseInsensitive); +} + +void HightLightEffectHelper::setExpression(const QString &text) +{ + m_expression.setPattern(text); +} + +void HightLightEffectHelper::setTextColor(const QBrush &brush) +{ + m_textCharFormat.setForeground(brush); +} + +void HightLightEffectHelper::highlightBlock(const QString &text) +{ + setFormat(0, text.length(), m_textCharFormat); + + m_textCharFormat.setFontWeight(QFont::Bold); + int index = text.indexOf(m_expression); + while(index >= 0){ + int length = m_expression.matchedLength(); + setFormat(index, length, m_textCharFormat); + index = text.indexOf(m_expression, index+length); + } + m_textCharFormat.setFontWeight(QFont::Normal); +} diff --git a/frontend/view/result-view-delegate.h b/frontend/view/result-view-delegate.h index 1263fbd..d6a177a 100644 --- a/frontend/view/result-view-delegate.h +++ b/frontend/view/result-view-delegate.h @@ -27,10 +27,29 @@ #include #include #include +#include +#include +#include #include "global-settings.h" namespace UkuiSearch { -class ResultViewDelegate : public QStyledItemDelegate { +class HightLightEffectHelper : public QSyntaxHighlighter +{ +public: + explicit HightLightEffectHelper(QObject *parent = nullptr); + void setExpression(const QString &text); + void setTextColor(const QBrush &brush); + +protected: + void highlightBlock(const QString &text); + +private: + QRegExp m_expression; + QTextCharFormat m_textCharFormat; +}; + +class ResultViewDelegate : public QStyledItemDelegate +{ Q_OBJECT public: explicit ResultViewDelegate(QObject *parent = nullptr); @@ -38,11 +57,12 @@ public: void setSearchKeyword(const QString &); protected: QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; -private: - QString m_regFindKeyWords = 0; void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override; - QString getHtmlText(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const; - QString escapeHtml(const QString&) const; + +private: + QTextDocument *m_textDoc = nullptr; + HightLightEffectHelper *m_hightLightEffectHelper = nullptr; + }; class ResultItemStyle : public QProxyStyle