Skip to content

Commit 7b7c20e

Browse files
GongHeng2017deepin-bot[bot]
authored andcommitted
Fix: keep renamed file content during compression
- copy aliased entries into a temp directory before invoking createArchive - update FileEntry paths to point at the real copies and clear aliases - cleanup the temp copies on success, failure, cancel, and reset - ensures libzip sees actual files instead of symlink paths Log: fix bug Bug: https://pms.uniontech.com/bug-view-340081.html
1 parent f26897c commit 7b7c20e

File tree

2 files changed

+149
-2
lines changed

2 files changed

+149
-2
lines changed

src/source/mainwindow.cpp

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,49 @@ DCORE_USE_NAMESPACE
5555
#include <QFormLayout>
5656
#include <QShortcut>
5757
#include <QJsonObject>
58+
#include <QFile>
59+
#include <QFileInfo>
60+
#include <QDir>
61+
#include <QDirIterator>
62+
#include <QUuid>
5863

5964
static QMutex mutex; // 静态全局变量只在定义该变量的源文件内有效
6065
#define FILE_TRUNCATION_LENGTH 70
6166

67+
namespace {
68+
69+
bool copyDirectoryRecursively(const QString &sourcePath, const QString &targetPath)
70+
{
71+
QDir sourceDir(sourcePath);
72+
if (!sourceDir.exists()) {
73+
return false;
74+
}
75+
76+
if (!QDir().mkpath(targetPath)) {
77+
return false;
78+
}
79+
80+
const QFileInfoList entries = sourceDir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files | QDir::Hidden | QDir::System);
81+
for (const QFileInfo &info : entries) {
82+
const QString srcFilePath = info.absoluteFilePath();
83+
const QString dstFilePath = targetPath + QDir::separator() + info.fileName();
84+
if (info.isDir()) {
85+
if (!copyDirectoryRecursively(srcFilePath, dstFilePath)) {
86+
return false;
87+
}
88+
} else {
89+
QFile::remove(dstFilePath);
90+
if (!QFile::copy(srcFilePath, dstFilePath)) {
91+
return false;
92+
}
93+
}
94+
}
95+
96+
return true;
97+
}
98+
99+
} // namespace
100+
62101
MainWindow::MainWindow(QWidget *parent)
63102
: DMainWindow(parent)
64103
, m_strProcessID(QString::number(QCoreApplication::applicationPid())) // 获取应用进程号
@@ -1181,6 +1220,9 @@ void MainWindow::slotCompress(const QVariant &val)
11811220

11821221
// 构建压缩文件数据
11831222
listEntry = m_pCompressPage->getEntrys();
1223+
if (!prepareCompressAliasEntries(listEntry)) {
1224+
return;
1225+
}
11841226
strDestination = m_stCompressParameter.strTargetPath + QDir::separator() + m_stCompressParameter.strArchiveName;
11851227

11861228
// 构建压缩参数
@@ -1255,6 +1297,7 @@ void MainWindow::slotCompress(const QVariant &val)
12551297
m_ePageID = PI_CompressProgress;
12561298
refreshPage();
12571299
} else {
1300+
cleanupCompressAliasEntries();
12581301
// 无可用插件
12591302
showErrorMessage(FI_Compress, EI_NoPlugin);
12601303
}
@@ -1494,6 +1537,8 @@ void MainWindow::handleJobNormalFinished(ArchiveJob::JobType eType, ErrorType eE
14941537
// zip压缩包添加注释
14951538
qDebug() << "Adding archive comment";
14961539
addArchiveComment();
1540+
1541+
cleanupCompressAliasEntries();
14971542
}
14981543
break;
14991544
// 添加文件至压缩包
@@ -1734,6 +1779,7 @@ void MainWindow::handleJobCancelFinished(ArchiveJob::JobType eType)
17341779
} else {
17351780
m_ePageID = PI_Compress;
17361781
}
1782+
cleanupCompressAliasEntries();
17371783
}
17381784
break;
17391785
// 添加文件至压缩包
@@ -1832,7 +1878,7 @@ void MainWindow::handleJobErrorFinished(ArchiveJob::JobType eJobType, ErrorType
18321878
break;
18331879
}
18341880
}
1835-
1881+
cleanupCompressAliasEntries();
18361882
}
18371883
break;
18381884
// 压缩包追加文件错误
@@ -2129,6 +2175,8 @@ void MainWindow::resetMainwindow()
21292175
maxFileSize_ = 0;
21302176
#endif
21312177

2178+
cleanupCompressAliasEntries();
2179+
21322180
m_ePageID = PI_Home;
21332181
m_operationtype = Operation_NULL; // 重置操作类型
21342182
m_iCompressedWatchTimerID = 0; // 初始化定时器返回值
@@ -2294,6 +2342,92 @@ void MainWindow::ConstructAddOptionsByThread(const QString &path)
22942342
}
22952343
}
22962344

2345+
bool MainWindow::prepareCompressAliasEntries(QList<FileEntry> &listEntry)
2346+
{
2347+
m_needCleanupCompressAlias = false;
2348+
m_strCompressAliasRoot.clear();
2349+
2350+
bool hasAlias = false;
2351+
QString aliasRoot;
2352+
2353+
for (FileEntry &entry : listEntry) {
2354+
if (entry.strAlias.isEmpty()) {
2355+
continue;
2356+
}
2357+
2358+
if (entry.strFullPath.isEmpty()) {
2359+
continue;
2360+
}
2361+
2362+
if (!hasAlias) {
2363+
const QString baseDir = TEMPPATH + QDir::separator() + m_strProcessID + QDir::separator() + "compress_alias";
2364+
if (!QDir().mkpath(baseDir)) {
2365+
showWarningDialog(tr("Failed to create temporary directory, please check and try again."));
2366+
return false;
2367+
}
2368+
aliasRoot = baseDir + QDir::separator() + QUuid::createUuid().toString(QUuid::WithoutBraces);
2369+
if (!QDir().mkpath(aliasRoot)) {
2370+
showWarningDialog(tr("Failed to create temporary directory, please check and try again."));
2371+
return false;
2372+
}
2373+
}
2374+
2375+
const QString aliasName = entry.strAlias;
2376+
const QString targetPath = aliasRoot + QDir::separator() + aliasName;
2377+
2378+
if (entry.isDirectory) {
2379+
QDir(targetPath).removeRecursively();
2380+
if (!copyDirectoryRecursively(entry.strFullPath, targetPath)) {
2381+
showWarningDialog(tr("Failed to prepare renamed item \"%1\" for compression, please check permissions and available space.")
2382+
.arg(aliasName));
2383+
if (!aliasRoot.isEmpty()) {
2384+
QDir(aliasRoot).removeRecursively();
2385+
}
2386+
return false;
2387+
}
2388+
} else {
2389+
QFile::remove(targetPath);
2390+
if (!QFile::copy(entry.strFullPath, targetPath)) {
2391+
showWarningDialog(tr("Failed to prepare renamed item \"%1\" for compression, please check permissions and available space.")
2392+
.arg(aliasName));
2393+
if (!aliasRoot.isEmpty()) {
2394+
QDir(aliasRoot).removeRecursively();
2395+
}
2396+
return false;
2397+
}
2398+
}
2399+
2400+
entry.strFullPath = targetPath;
2401+
entry.strAlias.clear();
2402+
hasAlias = true;
2403+
}
2404+
2405+
if (hasAlias) {
2406+
m_strCompressAliasRoot = aliasRoot;
2407+
m_needCleanupCompressAlias = true;
2408+
} else {
2409+
m_strCompressAliasRoot.clear();
2410+
m_needCleanupCompressAlias = false;
2411+
}
2412+
2413+
return true;
2414+
}
2415+
2416+
void MainWindow::cleanupCompressAliasEntries()
2417+
{
2418+
if (m_strCompressAliasRoot.isEmpty()) {
2419+
m_needCleanupCompressAlias = false;
2420+
return;
2421+
}
2422+
2423+
QDir aliasRoot(m_strCompressAliasRoot);
2424+
if (aliasRoot.exists()) {
2425+
aliasRoot.removeRecursively();
2426+
}
2427+
m_strCompressAliasRoot.clear();
2428+
m_needCleanupCompressAlias = false;
2429+
}
2430+
22972431
void MainWindow::showSuccessInfo(SuccessInfo eSuccessInfo, ErrorType eErrorType)
22982432
{
22992433
m_pSuccessPage->setSuccessType(eSuccessInfo);

src/source/mainwindow.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,18 @@ public :
215215
*/
216216
void ConstructAddOptionsByThread(const QString &path);
217217

218+
/**
219+
* @brief prepareCompressAliasEntries 为重命名文件准备临时别名文件
220+
* @param listEntry 待压缩的文件信息
221+
* @return 是否准备成功
222+
*/
223+
bool prepareCompressAliasEntries(QList<FileEntry> &listEntry);
224+
225+
/**
226+
* @brief cleanupCompressAliasEntries 清理临时别名文件
227+
*/
228+
void cleanupCompressAliasEntries();
229+
218230
/**
219231
* @brief showSuccessInfo 显示成功信息
220232
* @param eSuccessInfo 成功信息
@@ -576,7 +588,8 @@ private Q_SLOTS:
576588
#endif
577589

578590
QString m_strCurrentName;
579-
591+
QString m_strCompressAliasRoot;
592+
bool m_needCleanupCompressAlias = false;
580593
ApplicationAdaptor *m_compressorInterface = nullptr; // DBus interface
581594
};
582595

0 commit comments

Comments
 (0)