Skip to content

fix: cache printer names to avoid repeated queries - #776

Open
18202781743 wants to merge 1 commit into
linuxdeepin:masterfrom
18202781743:fix-printer-names-cache
Open

fix: cache printer names to avoid repeated queries#776
18202781743 wants to merge 1 commit into
linuxdeepin:masterfrom
18202781743:fix-printer-names-cache

Conversation

@18202781743

@18202781743 18202781743 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

fix: cache printer names to improve print preview performance

  1. Add a cached availablePrinterNames() method that stores printer
    names in printerNames member variable
  2. Initialize the cache lazily with printerNamesInited flag to avoid
    repeated expensive calls to QPrinterInfo::availablePrinterNames()
  3. Clear the printer name cache when the dialog is finished, ensuring
    fresh data on next dialog opening
  4. Replace direct calls to QPrinterInfo::availablePrinterNames() in
    initdata() and isActualPrinter() with the cached method
  5. Fix copyright year in header from 2022 to 2026
  6. Add debug logging for cache initialization and cleanup

Log: Optimized print preview performance by caching printer names

Influence:

  1. Verify printer list displays correctly in the print preview dialog
  2. Test opening and closing the print preview dialog multiple times to
    confirm printer names refresh properly
  3. Test with system printers added/removed while dialog is open to
    verify cache behavior
  4. Verify "Print to PDF" and "Save as Image" options still appear in
    the list
  5. Test print functionality with both actual printers and virtual
    printers

fix: 缓存打印机名称以提升打印预览性能

  1. 新增 availablePrinterNames() 方法,将打印机名称缓存在
    printerNames 成员变量中
  2. 使用 printerNamesInited 标志实现惰性初始化,避免重复调用昂贵的
    QPrinterInfo::availablePrinterNames() 接口
  3. 在对话框关闭时清空打印机名称缓存,确保下次打开时获取最新数据
  4. initdata()isActualPrinter() 中的直接调用替换为缓存方法
  5. 修正头文件版权年份从 2022 到 2026
  6. 添加缓存初始化和清理的调试日志

Log: 通过缓存打印机名称优化打印预览性能

Influence:

  1. 验证打印预览对话框中打印机列表显示正常
  2. 测试多次打开和关闭打印预览对话框,确认打印机名称能正确刷新
  3. 测试在对话框打开期间添加或移除系统打印机,验证缓存行为
  4. 验证"打印到 PDF"和"保存为图片"选项仍正常显示在列表中
  5. 测试使用真实打印机和虚拟打印机的打印功能

PMS: BUG-375053

Summary by Sourcery

Cache printer names within each print preview session to improve performance while clearing the cache when the dialog closes.

Bug Fixes:

  • Refresh printer names when the print preview dialog is reopened while avoiding stale data between dialog sessions.

Enhancements:

  • Cache available printer names during each print preview session to reduce repeated system printer queries.
  • Add debug logging for printer-name cache initialization and cleanup.

Chores:

  • Update the print preview dialog header copyright year.

@18202781743
18202781743 requested review from BLumia and mhduiy August 27, 2026 01:16
@sourcery-ai

sourcery-ai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Reviewer's Guide

The preview dialog now caches QPrinterInfo results per dialog session, clearing the cache when the dialog finishes, which avoids repeated printer queries while retaining refreshed results for subsequent sessions. The PR also adapts checkbox signal connections and state handling to Qt 6 while maintaining Qt 5 compatibility.

Sequence diagram for printer name caching in the preview dialog

sequenceDiagram
    participant Dialog as DPrintPreviewDialog
    participant Private as DPrintPreviewDialogPrivate
    participant Qt as QPrinterInfo

    Dialog->>Private: initdata()
    Private->>Private: availablePrinterNames()
    alt printerNames is empty
        Private->>Qt: availablePrinterNames()
        Qt-->>Private: QStringList
        Private->>Private: printerNames = result
    end
    Private-->>Dialog: addItems(printerNames)

    Private->>Private: isActualPrinter(name)
    Private->>Private: availablePrinterNames()
    Private-->>Private: printerNames.contains(name)

    Dialog-->>Private: finished
    Private->>Private: printerNames.clear()
Loading

Sequence diagram for Qt 6 checkbox state handling

sequenceDiagram
    participant CheckBox as DCheckBox
    participant Dialog as DPrintPreviewDialog
    participant Private as DPrintPreviewDialogPrivate

    CheckBox-->>Dialog: checkStateChanged(Qt::CheckState)
    Dialog->>Private: _q_checkStateChanged(int(state))
    CheckBox-->>Dialog: checkStateChanged(Qt::CheckState)
    alt state is Qt::Unchecked
        Dialog->>Private: setPageLayoutEnable(false)
    end
Loading

File-Level Changes

Change Details Files
Cache printer discovery results for the lifetime of each preview dialog and refresh them when the dialog finishes.
  • Route printer list initialization and printer-name validation through a private cached accessor.
  • Store the cached names in dialog-private state and clear them on the finished signal.
  • Add debug logging around printer discovery and cache invalidation.
src/widgets/dprintpreviewdialog.cpp
src/widgets/private/dprintpreviewdialog_p.h
Update checkbox signal handling for Qt 6 APIs while preserving Qt 5 compatibility.
  • Use Qt::CheckState with the Qt 6 DCheckBox signal and compare against Qt::Unchecked.
  • Bridge the Qt 6 checkbox signal to the existing integer-based slot.
  • Read the checkbox's current checked state directly when updating settings.
src/widgets/dprintpreviewdialog.cpp
src/widgets/dsettingswidgetfactory.cpp
Update SPDX copyright years for modified widget sources.
  • Extend copyright ranges through 2026.
src/widgets/dsettingswidgetfactory.cpp
src/widgets/private/dprintpreviewdialog_p.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/widgets/dprintpreviewdialog.cpp" line_range="2255-2257" />
<code_context>

+QStringList DPrintPreviewDialogPrivate::availablePrinterNames()
+{
+    if (printerNames.isEmpty()) {
+        qDebug(dPrintPreview) << "Get printer names from QPrinterInfo.";
+        printerNames = QPrinterInfo::availablePrinterNames();
+        qDebug(dPrintPreview) << "Available printer names:" << printerNames;
+    }
</code_context>
<issue_to_address>
**nitpick (performance):** An empty result is treated as an uninitialized cache, so `availablePrinterNames()` calls `QPrinterInfo::availablePrinterNames()` on every invocation when the system has no printers. Repeated `isActualPrinter()` checks therefore retain the system-query overhead the cache was intended to remove.

**Triggers:** When the system has no available printers and multiple preview controls trigger `isActualPrinter()`.

**Suggested fix:** Track cache initialization separately from the list contents, such as with a boolean flag, so an empty printer list is cached as a valid result.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/widgets/dprintpreviewdialog.cpp Outdated
@18202781743
18202781743 force-pushed the fix-printer-names-cache branch from c143ca1 to 303d3c8 Compare August 27, 2026 02:35
@18202781743 18202781743 changed the title fix printer names cache fix: cache printer names to avoid repeated queries Aug 27, 2026
@18202781743
18202781743 force-pushed the fix-printer-names-cache branch 2 times, most recently from 393ead4 to d4623b5 Compare August 27, 2026 03:27
1. Replace direct QPrinterInfo::availablePrinterNames() calls with a
cached wrapper
2. Add printerNames and printerNamesInited members to
DPrintPreviewDialogPrivate
3. Implement availablePrinterNames() to fetch printer names only once
and cache them
4. Clear cached printer names when the dialog is finished to prevent
stale data
5. Update isActualPrinter() to use the cached printer names list

This change improves performance by avoiding repeated calls to
QPrinterInfo::availablePrinterNames(), which can be expensive,
especially when the printer list is large. The cache is properly
invalidated when the dialog closes, ensuring fresh data on the next
dialog opening.

Influence:
1. Open the print preview dialog and verify the printer list loads
correctly
2. Add or remove a printer while the dialog is open and verify the list
does not refresh (expected behavior with caching)
3. Close the dialog and reopen it to verify printer list updates with
new system printers
4. Test print-to-PDF and save-as-image options still appear correctly in
the dropdown
5. Verify print job submission works correctly with cached printer names

style: 重构打印机名称获取逻辑,使用缓存列表

1. 将直接的 QPrinterInfo::availablePrinterNames() 调用替换为带缓存的封装
方法
2. 在 DPrintPreviewDialogPrivate 中添加 printerNames 和
printerNamesInited 成员变量
3. 实现 availablePrinterNames() 方法,仅获取一次打印机名称并进行缓存
4. 对话框结束时清除缓存的打印机名称,防止数据过期
5. 更新 isActualPrinter() 方法以使用缓存的打印机名称列表

此更改通过避免重复调用 QPrinterInfo::availablePrinterNames() 来提升性
能,该调用在打印机列表较大时可能消耗较多资源。对话框关闭时会正确失效缓
存,确保下次打开时获取最新数据。

Influence:
1. 打开打印预览对话框,验证打印机列表能正确加载
2. 在对话框打开期间添加或删除打印机,验证列表不会刷新(缓存行为的预期
表现)
3. 关闭对话框后重新打开,验证打印机列表会随系统打印机变化而更新
4. 测试打印到 PDF 和另存为图片选项在下拉列表中仍然正常显示
5. 验证使用缓存的打印机名称提交打印任务能正常工作

PMS: BUG-375053
@18202781743
18202781743 force-pushed the fix-printer-names-cache branch from d4623b5 to 6c22fba Compare August 27, 2026 03:39
@deepin-ci-robot

Copy link
Copy Markdown
Contributor

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 97 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 总体评分 97 分,大于 70 分通过阈值,代码质量优秀。本次提交通过缓存打印机名称优化打印预览性能,实现清晰,无安全漏洞。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 代码语法正确,懒加载缓存模式实现清晰。lambda 捕获 this 指针安全(连接接收者为 q 即 DPrintPreviewDialog 对象,Qt 会在对象销毁时自动断开连接,不存在悬空指针风险)。initdata() 和 isActualPrinter() 中的调用替换正确,逻辑一致。


2. 代码质量 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. src/widgets/private/dprintpreviewdialog_p.h:95 - 新增方法 availablePrinterNames() 缺少函数注释,建议添加说明缓存行为的注释

建议: 建议为 availablePrinterNames() 方法添加注释,说明其缓存机制、惰性初始化行为以及缓存清除时机(对话框关闭时)。调试日志(qDebug)符合 PR 描述中添加日志的目的,属于合规代码。


3. 代码性能 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. src/widgets/dprintpreviewdialog.cpp:2258 - availablePrinterNames() 返回 QStringList 值类型,建议改为 const QStringList & 避免潜在拷贝(OCR 发现)

建议: 建议将 availablePrinterNames() 返回类型改为 const QStringList &,以明确表达不修改意图并避免潜在的隐式共享 detach。本次缓存优化本身效果显著,将 QPrinterInfo::availablePrinterNames() 的昂贵系统调用从多次降为一次。


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: 未发现安全漏洞。调试日志仅输出打印机名称列表,不包含敏感信息。无用户输入处理变更,无注入风险,无硬编码凭据。代码安全合规。


💡 改进建议代码示例

// 建议优化:返回 const 引用避免潜在拷贝
const QStringList &DPrintPreviewDialogPrivate::availablePrinterNames()
{
    if (!printerNamesInited) {
        qDebug(dPrintPreview) << "Get printer names from QPrinterInfo.";
        printerNamesInited = true;
        printerNames = QPrinterInfo::availablePrinterNames();
        qDebug(dPrintPreview) << "Available printer names:" << printerNames;
    }
    return printerNames;
}

// 头文件声明也需同步修改
// const QStringList &availablePrinterNames();

本报告由 AI 代码审查工具自动生成

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia

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

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