Repository navigation
Conversation
1. Root cause: closeTab() saved to original file path without checking if the file still existed, recreating a deleted file at its original location and conflicting with trash entries showing "locked" state 2. Fix: add fileInfo.exists() check in closeTab() save branch to call saveAsFile() when file is deleted; guard dialog.setDirectory() with fileInfo.exists() in saveAsFileToDisk(), saveBlankFileToDisk(), and saveAsOtherTabFile() to use default save path when file is deleted 3. Impact: only affects files deleted externally while open in editor, normal save behavior unchanged for existing files Log: fix file showing locked in trash after editor save Influence: 1. Test editing a file, deleting it externally, then closing editor 2. Test saving deleted file triggers Save As dialog with default path 3. Test Save As / Save Blank / Save As Other Tab with deleted source file 4. Verify normal save still works for existing files fix: 修复源文件删除后编辑器保存导致回收站显示锁定 1. 根因:closeTab() 保存时未检查文件是否仍存在,直接保存到原始路径 导致已删除文件在原路径重建,与回收站条目冲突显示"锁定"状态 2. 方案:closeTab() 保存分支增加 fileInfo.exists() 检查,文件已删 除时调用 saveAsFile();saveAsFileToDisk()、saveBlankFileToDisk() 和 saveAsOtherTabFile() 在文件不存在时不覆盖默认保存路径,避免 使用原始文件目录 3. 影响:仅影响被外部删除后仍打开的文件,正常保存行为不受影响 Log: 修复源文件删除后编辑器保存导致回收站显示锁定 Influence: 1. 测试编辑文件后外部删除,再关闭编辑器保存 2. 测试保存已删除文件时弹出另存为对话框并使用默认路径 3. 测试另存为/空白文件另存/其他标签页另存时源文件已删除的场景 4. 验证正常文件保存功能不受影响 PMS: BUG-366573
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: pengfeixx 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 GuideUpdates close-time saving and related save-dialog setup to detect externally deleted files, use Save As with the default save location instead of recreating the original path, and preserve existing behavior for files that still exist. Sequence diagram for saving an externally deleted file on tab closesequenceDiagram
participant User
participant Window
participant QFileInfo
participant EditWrapper
participant SaveDialog
User->>Window: closeTab(filePath)
Window->>QFileInfo: exists()
alt file no longer exists
Window->>Window: saveAsFile()
Window->>SaveDialog: setDirectory(default save path)
User->>SaveDialog: choose destination
SaveDialog-->>Window: selected path
else file still exists
Window->>EditWrapper: saveFile()
EditWrapper-->>Window: save result
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/widgets/window.cpp" line_range="1568" />
<code_context>
} else {
- dialog.setDirectory(fileInfo.dir());
+ // 源文件已被删除(如移入回收站)时,使用默认保存路径而非原始文件目录
+ if (fileInfo.exists()) {
+ dialog.setDirectory(fileInfo.dir());
+ }
</code_context>
<issue_to_address>
**Save As recreates deleted file**
When the source is deleted and the configured Save As directory still points to its existing parent, `saveAsFileToDisk()` keeps the directory selected by `getCurrentOpenFilePath()`, and `selectFile()` preselects the original filename. Accepting the defaults therefore saves to the deleted file’s original path and recreates it.
When the source no longer exists, use the default Save As directory and avoid preselecting the deleted file’s original path.
Also at `src/widgets/window.cpp:1569-1570`.
</issue_to_address>
### Comment 2
<location path="src/widgets/window.cpp" line_range="1107" />
<code_context>
qDebug() << "File is not a backup file, saving normally";
- if (wrapper->saveFile()) {
+ // 源文件可能已被外部删除(如移入回收站),需先检查文件是否存在
+ if (!fileInfo.exists()) {
+ qDebug() << "File no longer exists, using Save As instead";
+ if (!saveAsFile()) {
</code_context>
<issue_to_address>
**Preview save recreates deleted file**
When the source of an edited invalid-character preview is deleted and the user chooses “Save Anyway”, the preview branch in `closeTab()` calls `forceSaveInvalidCharFile()` before the existence check, so it writes directly to the original path and recreates the deleted file.
Route “Save Anyway” through a path that checks for a missing source and does not write to its original path.
</issue_to_address>
### Comment 3
<location path="src/widgets/window.cpp" line_range="1109-1112" />
<code_context>
+ // 源文件可能已被外部删除(如移入回收站),需先检查文件是否存在
+ if (!fileInfo.exists()) {
+ qDebug() << "File no longer exists, using Save As instead";
+ if (!saveAsFile()) {
+ qWarning() << "Save as file cancelled or failed, keep tab open";
+ return false;
+ }
+ } else if (wrapper->saveFile()) {
qDebug() << "File saved, removing wrapper and closing tab";
</code_context>
<issue_to_address>
**Saved tab remains open**
When a deleted file is being closed and Save As succeeds, `closeTab()` returns success without removing the wrapper or closing the tab, so callers such as `closeAllFiles()` count it as closed while it remains visible.
After Save As succeeds, remove the wrapper and close the requested tab before reporting success.
</issue_to_address>| } else { | ||
| dialog.setDirectory(fileInfo.dir()); | ||
| // 源文件已被删除(如移入回收站)时,使用默认保存路径而非原始文件目录 | ||
| if (fileInfo.exists()) { |
There was a problem hiding this comment.
🟠 High · Save As recreates deleted file
When the source is deleted and the configured Save As directory still points to its existing parent, saveAsFileToDisk() keeps the directory selected by getCurrentOpenFilePath(), and selectFile() preselects the original filename. Accepting the defaults therefore saves to the deleted file’s original path and recreates it.
When the source no longer exists, use the default Save As directory and avoid preselecting the deleted file’s original path.
Also at src/widgets/window.cpp:1569-1570.
Prompt for AI agents
In `src/widgets/window.cpp` at line 1568:
**Save As recreates deleted file**
When the source is deleted and the configured Save As directory still points to its existing parent, `saveAsFileToDisk()` keeps the directory selected by `getCurrentOpenFilePath()`, and `selectFile()` preselects the original filename. Accepting the defaults therefore saves to the deleted file’s original path and recreates it.
When the source no longer exists, use the default Save As directory and avoid preselecting the deleted file’s original path.
Also at `src/widgets/window.cpp:1569-1570`.| qDebug() << "File is not a backup file, saving normally"; | ||
| if (wrapper->saveFile()) { | ||
| // 源文件可能已被外部删除(如移入回收站),需先检查文件是否存在 | ||
| if (!fileInfo.exists()) { |
There was a problem hiding this comment.
🟡 Medium · Preview save recreates deleted file
When the source of an edited invalid-character preview is deleted and the user chooses “Save Anyway”, the preview branch in closeTab() calls forceSaveInvalidCharFile() before the existence check, so it writes directly to the original path and recreates the deleted file.
Route “Save Anyway” through a path that checks for a missing source and does not write to its original path.
Prompt for AI agents
In `src/widgets/window.cpp` at line 1107:
**Preview save recreates deleted file**
When the source of an edited invalid-character preview is deleted and the user chooses “Save Anyway”, the preview branch in `closeTab()` calls `forceSaveInvalidCharFile()` before the existence check, so it writes directly to the original path and recreates the deleted file.
Route “Save Anyway” through a path that checks for a missing source and does not write to its original path.| if (!saveAsFile()) { | ||
| qWarning() << "Save as file cancelled or failed, keep tab open"; | ||
| return false; | ||
| } |
There was a problem hiding this comment.
🟡 Medium · Saved tab remains open
When a deleted file is being closed and Save As succeeds, closeTab() returns success without removing the wrapper or closing the tab, so callers such as closeAllFiles() count it as closed while it remains visible.
After Save As succeeds, remove the wrapper and close the requested tab before reporting success.
Prompt for AI agents
In `src/widgets/window.cpp` at lines 1109-1112:
**Saved tab remains open**
When a deleted file is being closed and Save As succeeds, `closeTab()` returns success without removing the wrapper or closing the tab, so callers such as `closeAllFiles()` count it as closed while it remains visible.
After Save As succeeds, remove the wrapper and close the requested tab before reporting success.
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 语法正确,逻辑清晰 ✅ 通过 潜在问题: 建议: [] 2. 代码质量 ✅评价: 代码结构清晰,注释完整 ✅ 通过 潜在问题: 建议: ['可选优化:saveAsFileToDisk/saveBlankFileToDisk/saveAsOtherTabFile 三处对 fileInfo.exists() 的守卫逻辑相同,后续可考虑抽取为公共辅助方法以进一步减少重复,但当前不构成扣分项。'] 3. 代码性能 ✅评价: 性能良好,资源使用合理 ✅ 通过 潜在问题: 建议: [] 4. 代码安全 🔒评价: 存在0个安全漏洞 ✅ 通过
安全漏洞详情: 建议: [] 💡 改进建议代码示例// 当前实现已正确修复问题,无需额外修改。
// 如需进一步减少重复,可抽取公共守卫方法:
// void setDialogDirectoryIfFileExists(QFileDialog &dialog, const QFileInfo &fileInfo) {
// if (fileInfo.exists()) {
// dialog.setDirectory(fileInfo.dir());
// }
// }本报告由 AI 代码审查工具自动生成 |
fix: prevent file recreation at original path after deletion
if the file still existed, recreating a deleted file at its original
location and conflicting with trash entries showing "locked" state
saveAsFile() when file is deleted; guard dialog.setDirectory() with
fileInfo.exists() in saveAsFileToDisk(), saveBlankFileToDisk(), and
saveAsOtherTabFile() to use default save path when file is deleted
normal save behavior unchanged for existing files
Log: fix file showing locked in trash after editor save
Influence:
fix: 修复源文件删除后编辑器保存导致回收站显示锁定
导致已删除文件在原路径重建,与回收站条目冲突显示"锁定"状态
除时调用 saveAsFile();saveAsFileToDisk()、saveBlankFileToDisk()
和 saveAsOtherTabFile() 在文件不存在时不覆盖默认保存路径,避免
使用原始文件目录
Log: 修复源文件删除后编辑器保存导致回收站显示锁定
Influence:
PMS: BUG-366573
Summary by Sourcery
Preserve deleted-file state by routing saves to Save As instead of restoring files at their original paths.
Bug Fixes: