Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/widgets/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,14 @@ bool Window::closeTab(const QString &filePath)
}
} else {
qDebug() << "File is not a backup file, saving normally";
if (wrapper->saveFile()) {
// 源文件可能已被外部删除(如移入回收站),需先检查文件是否存在
if (!fileInfo.exists()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 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.

qDebug() << "File no longer exists, using Save As instead";
if (!saveAsFile()) {
qWarning() << "Save as file cancelled or failed, keep tab open";
return false;
}
Comment on lines +1109 to +1112

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 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.

} else if (wrapper->saveFile()) {
qDebug() << "File saved, removing wrapper and closing tab";
removeWrapper(filePath, true);
m_tabbar->closeCurrentTab(filePath);
Expand Down Expand Up @@ -1557,7 +1564,10 @@ QString Window::saveAsFileToDisk()
dialog.selectFile(match.captured(0) + ".txt");
qDebug() << "Setting dialog file name to draft file name:" << match.captured(0) + ".txt";
} else {
dialog.setDirectory(fileInfo.dir());
// 源文件已被删除(如移入回收站)时,使用默认保存路径而非原始文件目录
if (fileInfo.exists()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 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`.

dialog.setDirectory(fileInfo.dir());
}
dialog.selectFile(fileInfo.fileName());
qDebug() << "Setting dialog file name to current file name:" << fileInfo.fileName();
}
Expand Down Expand Up @@ -1685,7 +1695,10 @@ QString Window::saveBlankFileToDisk()
dialog.selectFile(match.captured(0) + ".txt");
qDebug() << "Setting dialog file name to draft file name:" << match.captured(0) + ".txt";
} else {
dialog.setDirectory(fileInfo.dir());
// 源文件已被删除(如移入回收站)时,使用默认保存路径而非原始文件目录
if (fileInfo.exists()) {
dialog.setDirectory(fileInfo.dir());
}
dialog.selectFile(fileInfo.fileName());
qDebug() << "Setting dialog file name to current file name:" << fileInfo.fileName();
}
Expand Down Expand Up @@ -1734,7 +1747,10 @@ bool Window::saveAsOtherTabFile(EditWrapper *wrapper)
dialog.selectFile(match.captured(0) + ".txt");
qDebug() << "Setting dialog file name to draft file name:" << match.captured(0) + ".txt";
} else {
dialog.setDirectory(fileInfo.dir());
// 源文件已被删除(如移入回收站)时,使用默认保存路径而非原始文件目录
if (fileInfo.exists()) {
dialog.setDirectory(fileInfo.dir());
}
dialog.selectFile(fileInfo.fileName());
qDebug() << "Setting dialog file name to current file name:" << fileInfo.fileName();
}
Expand Down
Loading