Skip to content

fix: remove symbol preprocessing and fix list delegate rect#314

Merged
deepin-bot[bot] merged 2 commits into
linuxdeepin:masterfrom
Kakueeen:master
Jun 2, 2026
Merged

fix: remove symbol preprocessing and fix list delegate rect#314
deepin-bot[bot] merged 2 commits into
linuxdeepin:masterfrom
Kakueeen:master

Conversation

@Kakueeen
Copy link
Copy Markdown
Contributor

@Kakueeen Kakueeen commented Jun 2, 2026

  1. Remove calls to searchHelper->tropeInputSymbol() in file and OCR
    search, using original user input directly
  2. In file search, change info.keyword from regex pattern to original
    content to avoid filtering
  3. Move clearing of text/icon from paint() to initStyleOption() in list
    delegate for proper state drawing
  4. Adjust viewOption rect by -10px right margin before painting select
    state to prevent clipping
  5. Minor code formatting cleanup

Log: Improved keyword matching accuracy; fixed list item display under
select state

Influence:

  1. Test file search with various input symbols (Chinese/English
    brackets, spaces, etc.)
  2. Verify OCR search results with special characters
  3. Check list item appearance when selected – text and icon should not
    be cut off
  4. Confirm delegate paint behavior with different view styles
  5. Ensure right margin is consistent and select state highlight is
    correctly aligned

fix: 移除符号预处理并修复列表代理绘制区域

  1. 移除文件和OCR搜索中对searchHelper->tropeInputSymbol()的调用,直接使用
    原始用户输入
  2. 文件搜索中,将info.keyword从正则表达式改为原始内容,避免不必要的过滤
  3. 将清空文本和图标的操作从paint()移到initStyleOption()中,确保选中状态
    绘制正确
  4. 在绘制选中状态前,将viewOption的右边距增加10px,防止内容被裁剪
  5. 清理部分代码格式

Log: 改进的关键词匹配准确性;修复选中状态下列表项显示问题

Influence:

  1. 测试文件搜索,输入各种符号(中英文括号、空格等)
  2. 验证OCR搜索带有特殊字符的结果
  3. 检查列表项选中时的显示效果——文本和图标不应被裁剪
  4. 确认不同视图样式下委托绘制行为正常
  5. 验证右边距一致,选中状态高亮正确对齐

BUG: https://pms.uniontech.com/bug-view-363989.html

1. Remove calls to searchHelper->tropeInputSymbol() in file and OCR
search, using original user input directly
2. In file search, change info.keyword from regex pattern to original
content to avoid filtering
3. Move clearing of text/icon from paint() to initStyleOption() in list
delegate for proper state drawing
4. Adjust viewOption rect by -10px right margin before painting select
state to prevent clipping
5. Minor code formatting cleanup

Log: Improved keyword matching accuracy; fixed list item display under
select state

Influence:
1. Test file search with various input symbols (Chinese/English
brackets, spaces, etc.)
2. Verify OCR search results with special characters
3. Check list item appearance when selected – text and icon should not
be cut off
4. Confirm delegate paint behavior with different view styles
5. Ensure right margin is consistent and select state highlight is
correctly aligned

fix: 移除符号预处理并修复列表代理绘制区域

1. 移除文件和OCR搜索中对searchHelper->tropeInputSymbol()的调用,直接使用
原始用户输入
2. 文件搜索中,将info.keyword从正则表达式改为原始内容,避免不必要的过滤
3. 将清空文本和图标的操作从paint()移到initStyleOption()中,确保选中状态
绘制正确
4. 在绘制选中状态前,将viewOption的右边距增加10px,防止内容被裁剪
5. 清理部分代码格式

Log: 改进的关键词匹配准确性;修复选中状态下列表项显示问题

Influence:
1. 测试文件搜索,输入各种符号(中英文括号、空格等)
2. 验证OCR搜索带有特殊字符的结果
3. 检查列表项选中时的显示效果——文本和图标不应被裁剪
4. 确认不同视图样式下委托绘制行为正常
5. 验证右边距一致,选中状态高亮正确对齐

BUG: https://pms.uniontech.com/bug-view-363989.html
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Kakueeen, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

1. Replace global item ToolTipRole with per-region tooltip detection
2. Add TooltipRegion struct to record omitted text bounding rect and
full content
3. Cache omitted regions per row in m_tooltipRegionCache
4. Update paint to clear row cache, and record regions when drawing
elided name, context, or tail text
5. Modify helpEvent to check if mouse is over any omitted region; show
tooltip only there, otherwise hide
6. Remove old ToolTipRole setting in GrandSearchListView::setData to let
delegate handle it
7. Change tail text elision from ElideLeft to ElideMiddle for better
readability
8. Expose clearTooltipCache() to reset cache when list is cleared

Log: Optimized tooltip display: now tooltips appear only when hovering
over truncated text areas (file name, match context, tail text),
providing a cleaner view.

Influence:
1. Verify tooltip appears correctly when mouse hovers over truncated
file name, context, or tail text
2. Verify tooltip does not appear when hovering over non-truncated areas
3. Test tooltip disappearance when moving mouse away from truncated area
4. Verify tail text shows middle ellipsis correctly (e.g., long paths)
5. Test list clear and reload to ensure tooltip cache is cleared
properly
6. Verify no regression in general list rendering and interaction

feat: 优化tooltip仅在省略文本区域显示

1. 用逐区域tooltip检测替代全局item的ToolTipRole
2. 添加TooltipRegion结构体,记录省略文本的绘制矩形和完整内容
3. 按行缓存省略区域到m_tooltipRegionCache
4. 在paint中清空行缓存,并在绘制省略的文件名、摘要或拖尾文本时记录区域
5. 修改helpEvent,检查鼠标是否位于任意省略区域内;仅在区域内显示
tooltip,否则隐藏
6. 移除GrandSearchListView::setData中旧的ToolTipRole设置,交由delegate
处理
7. 将拖尾文本省略方向从ElideLeft改为ElideMiddle,提升可读性
8. 提供clearTooltipCache()方法,在列表清空时重置缓存

Log: 优化tooltip显示:现在仅在悬停在被截断的文本区域(文件名、摘要、拖
尾)时才出现提示,界面更简洁

Influence:
1. 验证鼠标悬停在截断的文件名、摘要或拖尾文本上时正确显示tooltip
2. 验证鼠标在非截断区域时不显示tooltip
3. 测试鼠标移出截断区域后tooltip消失
4. 验证拖尾文本中间省略显示是否正确(如长路径)
5. 测试清空并重新加载列表,确保tooltip缓存正确清除
6. 验证列表整体渲染和交互无回归问题

BUG: https://pms.uniontech.com/bug-view-364065.html
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX,你的智能编程助手。我已经仔细审查了你提供的Git Diff。本次代码变更主要涉及两个方面:一是搜索关键词处理逻辑的简化(去除了tropeInputSymbol和正则拼接),二是列表项Delegate中Tooltip区域缓存机制的引入和文本省略方式的调整。

以下是我对语法逻辑、代码质量、代码性能和代码安全方面的详细审查意见及改进建议:

1. 语法与逻辑

1.1 关键词正则转纯文本匹配的潜在逻辑风险

  • 问题:在 filesearchutils.cpp 中,原逻辑 info.keyword = QString(R"((%1).*)").arg(keywordList.join('|')); 被替换为 info.keyword = content;。原逻辑使用 | 将多个关键词拼接成正则表达式,而新逻辑直接使用原始输入 content
  • 风险:如果下游的搜索引擎依赖正则表达式进行多词匹配(例如:输入"A B",原本会生成 (A|B).* 匹配包含A或B的内容),现在变成纯文本匹配 "A B",可能导致搜索逻辑从**“多关键词或匹配”退化为“完整字符串精确匹配”**。
  • 建议:请确认下游搜索引擎的解析机制。如果它支持空格分隔的多词匹配,则此改动无碍;如果它依然依赖正则,建议至少改为:info.keyword = keywordList.join('|');(需注意正则特殊字符转义)。

1.2 Tooltip区域坐标系不一致导致错位

  • 问题:在 drawItemNamedrawMatchedContextdrawTailText 中,记录到 TooltipRegionQRect 坐标是基于当前 QStyleOptionViewItemrect 计算的。然而,在 helpEvent 中,event->pos() 返回的是**整个 Item(QModelIndex对应区域)**的相对坐标。
  • 风险:由于你在 paint 方法中执行了 viewOption.rect.adjust(0, 0, -10, 0);(右边距调整),这会导致绘制坐标系与事件坐标系产生偏差。特别是 drawMatchedContextdrawTailText 传入的 startXstartY 已经是经过偏移后的坐标,直接用它们构建 QRect 并与 event->pos() 对比,会导致 Tooltip 触发区域与实际绘制区域严重错位
  • 建议
    • paint 方法中记录坐标时,必须统一使用 option.rect 的原始坐标系(即未 adjust 前的坐标系),或者将相对坐标转换为 Item 的绝对相对坐标。
    • 更好的做法是:drawRect 的坐标应基于 option.rect 计算,而不是基于 startX/startY。例如在 drawItemName 中:QRect drawRect(textStartX, startY - option.rect.topLeft().y(), ...) (需根据实际布局换算)。

1.3 m_tooltipRegionCache 缓存未随数据更新而局部清理

  • 问题clearTooltipCache() 仅在 GrandSearchListView::clear() 时被调用。如果列表中的某一项数据发生更新(例如异步加载缩略图完成触发了 dataChanged),Delegate 会重新 paint,此时会向 m_tooltipRegionCache[row] 追加新的区域,但旧的区域并未被移除。
  • 风险:同一个 row 会累积多个 TooltipRegion,导致鼠标悬停时可能命中旧的错误区域,显示错误的 Tooltip,同时造成内存泄漏。
  • 建议:在 paint 方法开始绘制某一行的文本前,先清空该行的缓存:
    // 在 paint() 方法开头,清除该行的 tooltip 区域缓存
    m_tooltipRegionCache[index.row()].clear(); // 你已经加了这行,非常好!
    但注意:如果模型使用的是动态排序或过滤模型(如 QSortFilterProxyModel),index.row() 会随着排序变化,此时用 row 做 Key 会导致错乱。更安全的做法是使用 item 的唯一标识(如数据源的ID)或 QPersistentModelIndex 作为 Hash 的 Key。

2. 代码质量

2.1 Tooltip 换行逻辑硬编码

  • 问题:在 helpEvent 中,存在硬编码的换行逻辑 const int nlong = 32; 和循环 mid(i * nlong, nlong)
  • 风险:这种强制每32个字符加换行符的做法非常粗暴,完全不考虑文本的语义(可能会把一个英文单词或中文字词从中间截断),且在不同分辨率和字体下,32个字符的宽度差异巨大,可能导致 Tooltip 超出屏幕。
  • 建议:Qt 的 QToolTip 本身支持富文本。建议使用 Qt::convertFromPlainText 或者使用 <br> 标签结合 QFontMetrics 动态计算文本换行,而不是按字符数硬切。
    // 更优雅的 Qt 原生换行处理
    QString richText = QString("<p>%1</p>").arg(region.fullText.toHtmlEscaped());
    QToolTip::showText(event->globalPos(), richText, view, region.rect);

2.2 省略号策略变更 (Qt::ElideLeft -> Qt::ElideMiddle)

  • 问题:在 calcTailShowDataByMaxWidthcalcTailShowDataByOptimalWidth 中,文本省略方式从 Qt::ElideLeft(左侧省略,如 ...xt)改为了 Qt::ElideMiddle(中间省略,如 te...xt)。
  • 风险:对于文件路径或后缀名有意义的字符串(如 .docx, .txt),中间省略会破坏后缀名的可读性;对于拖尾文本,左侧省略通常更符合用户预期(保留最新/最右侧的信息)。
  • 建议:请确认产品需求。如果拖尾文本是时间、大小等信息,ElideLeft 通常是更好的选择;如果是文件名,ElideRight 是规范;ElideMiddle 适用于长串无明显后缀意义的标识符。

2.3 QHash 的隐式共享与 mutable 修饰

  • 问题m_tooltipRegionCache 被声明为 mutable,因为 paint 等方法是 const 的。
  • 风险:在 paint 中频繁调用 m_tooltipRegionCache[row].append(),由于 Qt 的隐式共享机制(Copy-on-Write),在 const 方法中修改 mutable 成员可能会触发深拷贝,带来额外的性能开销。
  • 建议:当前实现可以接受,但如果发现绘制卡顿,可考虑在 paint 入口处使用 QHash::operator[] 提前获取引用(需注意C++的const正确性约束),或者将缓存移出 Delegate,由 View 层在非 const 方法中维护。

3. 代码性能

3.1 helpEvent 中的线性查找

  • 问题helpEvent 中遍历 regions 列表:for (const TooltipRegion &region : regions)
  • 风险:通常一个 Item 中被省略的区域不会超过3-5个,线性查找性能影响微乎其微。但如果未来界面变复杂,区域增多,可能会有轻微影响。
  • 建议:当前无需修改,保持代码简洁即可。

3.2 JSON 解析性能(OCR模块)

  • 问题QJsonDocument::fromJson(context.toLocal8Bit())
  • 风险toLocal8Bit() 会进行一次字符串编码转换(通常从 UTF-16 转 UTF-8),然后再进行 JSON 解析。
  • 建议:Qt 的 QJsonDocument::fromJson 接受 QByteArray。如果源数据本身就是 UTF-8,可以直接构造;如果不是,此处的转换是必要的。无需特别修改,但需注意不要在极高频的循环中调用。

4. 代码安全

4.1 去除 tropeInputSymbol 带来的正则注入风险

  • 问题:原代码中 searchHelper->tropeInputSymbol(key) 的作用很可能是对正则表达式的特殊字符(如 *, ?, +, $ 等)进行转义。
  • 风险:在 filesearchutils.cpp 中,虽然你移除了正则拼接(info.keyword = content;),但如果后续有其他代码依然将 info.keyword 当作正则使用,用户输入的特殊字符将导致正则表达式注入,可能引发程序崩溃或ReDoS(正则表达式拒绝服务攻击)。
  • 建议:如果确认整个搜索链路已不再使用正则匹配,则移除 tropeInputSymbol 是安全的;如果底层依然有正则引擎,必须保留转义逻辑或使用 QRegularExpression::escape()

4.2 Tooltip 内容的富文本注入

  • 问题:在 helpEvent 中,region.fullText 被直接传递给 QToolTip::showText
  • 风险:Qt 的 Tooltip 默认支持富文本(HTML)。如果 fullText 中包含 HTML 标签(如 <b>, <script> 等),会被 Qt 解析渲染。如果是来自用户数据或文件名,可能存在轻微的富文本注入风险(虽然Qt屏蔽了JS执行,但可能破坏布局)。
  • 建议:对文本进行 HTML 转义:
    QString safeText = region.fullText.toHtmlEscaped();
    // 然后再对 safeText 进行换行处理或显示

总结与修改建议代码片段

针对最严重的 Tooltip 坐标错位问题缓存累积问题,建议进行如下修正:

1. 修正 Tooltip 区域的坐标记录(以 drawItemName 为例):

// 记录时,rect 必须是相对于整个 Item (option.rect) 的坐标
if (elidedName != name) {
    // drawRect 目前的坐标是基于 textStartX 和 startY 的,需转换为 Item 相对坐标
    // 假设 textStartX 和 startY 已经是相对 option.rect 的偏移量,则无需修改
    // 但如果 startY 是绝对坐标,需要减去 option.rect.y()
    QRect itemRelativeRect(drawRect.x(), drawRect.y() - option.rect.y(), drawRect.width(), drawRect.height());
    recordTooltipRegion(index.row(), itemRelativeRect, name);
}

2. 优化 Tooltip 的换行显示逻辑(避免粗暴截断):

// 在 helpEvent 中
if (region.rect.contains(itemLocalPos)) {
    // 使用 HTML 实现自动换行,避免按字符硬切
    QString escapedText = region.fullText.toHtmlEscaped();
    QString tooltipHtml = QString("<p style='white-space: pre-wrap;'>%1</p>").arg(escapedText);
    QToolTip::showText(event->globalPos(), tooltipHtml, view, region.rect);
    return true;
}

3. 确保数据更新时缓存被正确清理:
你在 paint() 函数开头加了 m_tooltipRegionCache[index.row()].clear();,这非常棒!但请确保如果列表使用了 Proxy Model,需使用不变的身份标识代替 index.row()

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Johnson-zs, Kakueeen

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Kakueeen
Copy link
Copy Markdown
Contributor Author

Kakueeen commented Jun 2, 2026

/forcemerge

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Jun 2, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit 9c2dd4c into linuxdeepin:master Jun 2, 2026
9 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants