Repository navigation
fix: column edit undo/redo cursor mutation causes wrong selection - #700
pppanghu77 wants to merge 1 commit into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: pppanghu77 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideFix column-edit undo/redo selection corruption by retaining original cursor positions, applying redo edits through temporary cursors, and synchronizing restored selections with the editor’s rendered state. Sequence diagram for stable column-edit undo and redosequenceDiagram
participant Command as UndoCommand
participant Selection as ColumnEditSelections
participant TempCursor as TemporaryCursor
participant Editor as TextEdit
Command->>Selection: Construct and store originalPositions
Command->>TempCursor: redo() uses cursor position
TempCursor->>TempCursor: insertText() or deletePreviousChar()
Note over Selection: Selection cursors remain unchanged
Command->>Selection: undo() restores text at originalPositions
Selection->>Selection: removeSelectedText() or insertText()
Command->>Editor: syncColumnEditSelections(selections)
Editor->>Editor: renderAllSelections()
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
1. Root cause: redo() mutates m_ColumnEditSelections[i].cursor in place via insertText()/deletePreviousChar(), undo() then operates on wrong positions via deleteChar()/insertText() 2. Fix: save original cursor positions in constructors, redo() uses temp cursors to avoid mutation, undo() uses original positions with removeSelectedText(), sync restored selections to TextEdit 3. Impact: InsertTextUndoCommand, DeleteTextUndoCommand, DeleteTextUndoCommand2 column-edit paths fixed; single-cursor paths unchanged Log: fix column edit undo/redo cursor mutation causing wrong selection Influence: 1. Test column edit cut then undo restores all selections 2. Test column edit insert then undo removes inserted text correctly 3. Test column edit delete then undo restores deleted text 4. Verify single-cursor undo/redo unaffected fix: 修复列编辑模式撤销重做光标变异导致选中状态错误 1. 根因:redo() 原地变异 m_ColumnEditSelections[i].cursor 位置, undo() 的 deleteChar()/insertText() 在错误位置操作 2. 方案:构造时保存原始 cursor 位置,redo() 使用临时 cursor 不变异 selections,undo() 基于原始位置 removeSelectedText(),恢复后 同步 selections 到 TextEdit 3. 影响:InsertTextUndoCommand、DeleteTextUndoCommand、 DeleteTextUndoCommand2 列编辑路径已修复;单 cursor 路径不变 Log: 修复列编辑模式下剪切后撤销选中状态错误的问题 Influence: 1. 测试列编辑剪切后撤销是否恢复所有选中 2. 测试列编辑插入后撤销是否正确删除插入文本 3. 测试列编辑删除后撤销是否恢复删除文本 4. 验证单 cursor 撤销/重做不受影响 Bug: https://pms.uniontech.com/bug-view-241613.html PMS: BUG-241613 BUG-254289
e27f298 to
e3b6c68
Compare
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 语法正确,逻辑清晰 ✅ 通过 潜在问题: 建议: ['逻辑正确,无需修改'] 2. 代码质量 ✅评价: 代码结构清晰,注释完整 ✅ 通过 潜在问题: 建议: ['建议将 qobject_cast + syncColumnEditSelections 模式提取为公共方法,减少重复代码', '建议在 m_originalPositions 相关代码处添加简要注释说明 cursor mutation 问题及修复原理'] 3. 代码性能 ✅评价: 性能良好,资源使用合理 ✅ 通过 潜在问题: 建议: ['性能良好,无需优化'] 4. 代码安全 🔒评价: 存在0个安全漏洞 ✅ 通过
安全漏洞详情: 建议: ['安全合规,无需加固'] 💡 改进建议代码示例// 建议提取 sync 同步模式为公共辅助方法,减少重复代码
// 可在基类或工具函数中定义:
static void syncColumnEditSelectionsToEdit(QPlainTextEdit *edit, const QList<QTextEdit::ExtraSelection> &selections)
{
if (!edit || selections.isEmpty()) {
return;
}
TextEdit *pEdit = qobject_cast<TextEdit*>(edit);
if (pEdit) {
pEdit->syncColumnEditSelections(selections);
}
edit->setTextCursor(selections.last().cursor);
}
// 在各 undo 方法中调用:
// syncColumnEditSelectionsToEdit(m_edit, m_ColumnEditSelections);本报告由 AI 代码审查工具自动生成 |
修复:列编辑模式撤销/重做光标变异导致选中状态错误(PMS 241613 / 254289)
根因
redo()在m_ColumnEditSelections[i].cursor上直接调用insertText()/deletePreviousChar(),导致 cursor 位置被永久变异。undo()随后在变异后的位置调用deleteChar()/insertText(),删除了错误位置的字符。修复方案(根因层修复,4 步)
InsertTextUndoCommand、DeleteTextUndoCommand、DeleteTextUndoCommand2列编辑构造函数中记录每个 selection 的原始 position 到m_originalPositionsm_ColumnEditSelections[i].cursor不变setPosition(originalPos, MoveAnchor)+setPosition(originalPos + text.length(), KeepAnchor)选中范围后removeSelectedText(),替代deleteChar()影响范围
InsertTextUndoCommand列编辑路径(redo/undo)DeleteTextUndoCommand列编辑路径(redo/undo)DeleteTextUndoCommand2列编辑路径(redo/undo)TextEdit::syncColumnEditSelections()同步逻辑验证
PyQt5 最小 demo 旁路验证(
repro/demo/demo.py):'Xaa\nXbb\nXcc',BUG REPRODUCED: True'aaa\nbbb\nccc',FIX VERIFIED: True//测试:FIX VERIFIED (multi-char): True关联
syncColumnEditSelections()未修复 redo() cursor 变异,已被用户拒绝PMS: BUG-241613 BUG-254289
Summary by Sourcery
Fix column-edit undo/redo cursor handling so selections and restored text remain correct across repeated operations.
Bug Fixes:
Enhancements: