Skip to content

fix: adjust list item height calculation for dynamic rows#317

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

fix: adjust list item height calculation for dynamic rows#317
deepin-bot[bot] merged 2 commits into
linuxdeepin:masterfrom
Kakueeen:master

Conversation

@Kakueeen
Copy link
Copy Markdown
Contributor

@Kakueeen Kakueeen commented Jun 4, 2026

Previously the list item height was fixed to 36px, redefined as
the macro ListItemHeight. This change removes the fixed height
and calculates the row height dynamically based on font metrics,
allowing the list to properly display items with multi-line content.
Additionally, the drawing rectangle for the item name now uses
nameTextMaxWidth instead of the actual text width, ensuring consistent
alignment. The web static text ellipsis handling is also fixed to
correctly subtract the marker width.

Log: Adjusted list item height for dynamic rows in grand search results

Influence:

  1. Test single-line and multi-line item display in grand search results
    list
  2. Verify that row height adapts correctly for items with and without
    second line
  3. Check alignment of item name text when ellipsis is applied
  4. Confirm web static text items show correct marker and ellipsis
    behavior
  5. Test under different font sizes and DPI settings

fix: 调整列表项行高为动态计算

之前列表项高度固定为 36px,定义为宏 ListItemHeight。此更改移除了固定高
度,基于字体度量动态计算行高,使列表能够正常显示多行内容。同时修改了名称
绘制矩形区域,使用 nameTextMaxWidth 确保对齐一致。修复了 web 静态文本
省略号处理中标记宽度的减法逻辑。

Log: 调整全局搜索结果列表行高为动态高度

Influence:

  1. 测试全局搜索结果列表中单行和多行项目的显示效果
  2. 验证有/无第二行时行高是否正确自适应
  3. 检查名称文本省略时的对齐情况
  4. 确认 web 静态文本项目标记和省略行为正确
  5. 在不同字体大小和 DPI 设置下测试

Previously the list item height was fixed to 36px, redefined as
the macro `ListItemHeight`. This change removes the fixed height
and calculates the row height dynamically based on font metrics,
allowing the list to properly display items with multi-line content.
Additionally, the drawing rectangle for the item name now uses
`nameTextMaxWidth` instead of the actual text width, ensuring consistent
alignment. The web static text ellipsis handling is also fixed to
correctly subtract the marker width.

Log: Adjusted list item height for dynamic rows in grand search results

Influence:
1. Test single-line and multi-line item display in grand search results
list
2. Verify that row height adapts correctly for items with and without
second line
3. Check alignment of item name text when ellipsis is applied
4. Confirm web static text items show correct marker and ellipsis
behavior
5. Test under different font sizes and DPI settings

fix: 调整列表项行高为动态计算

之前列表项高度固定为 36px,定义为宏 `ListItemHeight`。此更改移除了固定高
度,基于字体度量动态计算行高,使列表能够正常显示多行内容。同时修改了名称
绘制矩形区域,使用 `nameTextMaxWidth` 确保对齐一致。修复了 web 静态文本
省略号处理中标记宽度的减法逻辑。

Log: 调整全局搜索结果列表行高为动态高度

Influence:
1. 测试全局搜索结果列表中单行和多行项目的显示效果
2. 验证有/无第二行时行高是否正确自适应
3. 检查名称文本省略时的对齐情况
4. 确认 web 静态文本项目标记和省略行为正确
5. 在不同字体大小和 DPI 设置下测试
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

as title

Log: update version
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 4, 2026

TAG Bot

TAG: 6.0.37
EXISTED: no
DISTRIBUTION: unstable

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的Git Diff代码。这次修改主要涉及列表项行高的动态计算优化、文本省略逻辑的调整以及Tooltip区域的修正。

整体来看,这次重构提升了代码的灵活性和逻辑的准确性,但也存在一些潜在的逻辑漏洞、性能瓶颈和安全隐患。以下是我的详细审查意见:

1. 语法与逻辑

问题 1.1:static 修饰符导致的多行/动态内容截断逻辑错误(严重)
drawItemName 函数中:

static const QString markStr = name.right(1);
static const int markWidth = fontMetrics.size(Qt::TextSingleLine, markStr).width();

这里使用了 static 局部变量,意味着 markStrmarkWidth 只会在第一次进入该分支时初始化,后续所有的调用都会复用第一次的值。

  • 逻辑漏洞:如果下一次进入的 name 以不同的字符结尾(极大概率),markStr 仍然是旧的字符,markWidth 也是旧的宽度。这会导致截断宽度计算错误,UI显示异常。
  • 改进建议:去掉 static 关键字,让每次调用都根据当前的 name 计算末尾字符和宽度。

问题 1.2:空字符串潜在的越界风险
drawItemName 函数中:

elidedName = fontMetrics.elidedText(name.left(name.size() - 1), Qt::ElideRight, nameTextMaxWidth - markWidth);

如果 name 为空字符串,name.size() - 1 会发生无符号整数下溢(qsizetype 下同样可能产生巨大值或异常行为),name.left(...) 可能导致崩溃或未定义行为。

  • 改进建议:在执行截断逻辑前,增加对 name 长度的安全检查。

2. 代码性能

问题 2.1:sizeHint 中的高频字体对象构造(性能损耗)
GrandSearchListDelegate::sizeHint 中:

QFontMetrics nameFm(DFontSizeManager::instance()->get(DFontSizeManager::T6));
// ...
if (hasSecondLine) {
    QFontMetrics contextFm(DFontSizeManager::instance()->get(DFontSizeManager::T8));
    // ...
}

sizeHint 在列表滚动、布局刷新时会被极其频繁地调用。每次调用都通过 DFontSizeManager::instance()->get() 获取字体并构造 QFontMetrics 对象,会带来不必要的性能开销。

  • 改进建议:将 QFontMetrics 缓存为类的成员变量,在字体发生变化时(如系统主题改变)更新缓存,或者至少在函数内部使用 static 缓存(前提是确认应用运行期间字体不会动态变化)。

3. 代码安全与健壮性

问题 3.1:Tooltip 区域宽度过大导致遮挡点击(交互安全/逻辑缺陷)
drawItemName 函数中:

QRect drawRect(textStartX, startY, nameTextMaxWidth, fontMetrics.height());

// 文件名被省略时,记录 tooltip 区域
if (elidedName != name) {
    // ... 使用 drawRect 记录 tooltip 区域
}

旧代码使用的是 actualNameWidth(文本实际渲染宽度),而新代码改成了 nameTextMaxWidth(文本允许的最大宽度)。

  • 逻辑缺陷:当文本被省略时,省略号后面的区域(直到 nameTextMaxWidth)实际上没有任何有效文字,但新代码却把这块空白区域也划入了 Tooltip 响应区域。更严重的是,如果该行右侧还有其他可点击的控件(如按钮),过宽的 Tooltip 区域会遮挡右侧控件的鼠标事件,导致控件无法交互。
  • 改进建议:恢复使用文本的实际渲染宽度(actualNameWidth)来界定 Tooltip 区域。如果是为了解决之前计算不准确的问题,应该重新精确计算 actualNameWidth,而不是盲目扩大到 nameTextMaxWidth

4. 代码质量与可读性

建议 4.1:魔法数字的消除
移除 ListItemHeight 宏是合理的,因为行高现在动态计算了。但代码中仍然存在 name.size() - 1 这样的硬编码逻辑。建议将这种特殊的截断逻辑(保留最后一个字符,前面省略)封装为一个独立的工具函数,例如 elideTextKeepingSuffix,以提高代码复用性和可读性。


综合修改建议代码示例

针对以上问题,我为你提供了修改后的代码片段参考:

// src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistdelegate.cpp

// 1. sizeHint 性能优化 (建议将 QFontMetrics 移至类成员或缓存)
QSize GrandSearchListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    // ... 前置逻辑保持不变 ...

    // 建议: 如果字体在运行期不变,可以声明为 static;否则移至类成员变量中更新
    static QFontMetrics nameFm(DFontSizeManager::instance()->get(DFontSizeManager::T6));
    int totalHeight = ListLineMargin * 2 + nameFm.height();

    if (hasSecondLine) {
        static QFontMetrics contextFm(DFontSizeManager::instance()->get(DFontSizeManager::T8));
        totalHeight += ContextLineSpacing + contextFm.height();
    }

    return QSize(ListRowWidth, totalHeight);
}

// 2. drawItemName 逻辑与安全修复
void GrandSearchListDelegate::drawItemName(QPainter *painter, const QModelIndex &index, ...) 
{
    // ... 前置逻辑 ...
    
    // 修复:移除 static,避免缓存旧的字符和宽度;增加长度安全检查
    if (elidedName != name && GRANDSEARCH_CLASS_WEB_STATICTEXT == searcher) {
        if (name.size() > 0) { // 安全检查,防止 name 为空时越界
            const QString markStr = name.right(1); // 去掉 static
            const int markWidth = fontMetrics.size(Qt::TextSingleLine, markStr).width(); // 去掉 static
            nameTextMaxWidth -= markWidth;
            
            // 安全保护:确保减去标记宽度后可用宽度不为负
            if (nameTextMaxWidth > 0) {
                elidedName = fontMetrics.elidedText(name.left(name.size() - 1), Qt::ElideRight, nameTextMaxWidth);
                elidedName.append(markStr);
            } else {
                // 极端情况:空间连最后一个字符都放不下,直接整体省略
                elidedName = fontMetrics.elidedText(name, Qt::ElideRight, nameTextMaxWidth + markWidth);
            }
        }
    }

    // ... 中间逻辑 ...

    QAbstractTextDocumentLayout::PaintContext paintContext;
    
    // 修复:恢复计算实际宽度,避免 Tooltip 区域过大遮挡其他交互控件
    int actualNameWidth = fontMetrics.size(Qt::TextSingleLine, elidedName).width();
    QRect drawRect(textStartX, startY, actualNameWidth, fontMetrics.height());

    // 文件名被省略时,记录 tooltip 区域
    if (elidedName != name) {
        // ... tooltip 逻辑 ...
    }
}

希望这些审查意见对你有所帮助!如果还有其他代码需要审查,随时告诉我。

@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 4, 2026

/forcemerge

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Jun 4, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit 9b2ddc3 into linuxdeepin:master Jun 4, 2026
10 of 12 checks passed
@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Jun 4, 2026

TAG Bot

Tag created successfully

📋 Tag Details
  • Tag Name: 6.0.37
  • Tag SHA: bc2bf311a2a53687f70d635f99f57e2cecfa9916
  • Commit SHA: 9b2ddc30801fe0f8ff0b379e50c716bf3ae60622
  • Tag Message:
    Release dde-grand-search 6.0.37
    
    
  • Tagger:
    • Name: Kakueeen
  • Distribution: unstable

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