Skip to content
Merged
Show file tree
Hide file tree
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
31 changes: 31 additions & 0 deletions 3rdparty/interface/archiveinterface/cliinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <QUrl>
#include <QScopedPointer>
#include <QTemporaryDir>
#include <QTimer>

#include "common.h"
#include <linux/limits.h>
Expand Down Expand Up @@ -73,6 +74,16 @@ PluginFinishType CliInterface::list()

m_workStatus = WT_List;

// 是否支持seek
if(!m_common->isSupportSeek(m_strArchiveName)) {
Copy link

Choose a reason for hiding this comment

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

issue (complexity): Consider refactoring the repeated QTimer error-handling code into a helper function and macro to reduce duplication.

Here’s one way to collapse those three identical QTimer blocks into a single helper + guard macro. This preserves your exact return-values but only writes the “error timer” code once.

// In CliInterface.h (or a common private section)
private:
    void emitSeekErrorAndFinish() {
        QTimer::singleShot(1000, this, [this]() {
            m_eErrorType = ET_FileSeekError;
            emit signalprogress(100);
            emit signalFinished(PFT_Error);
        });
    }

#define RETURN_IF_NO_SEEK(retval)           \
    do {                                    \
      if (!m_common->isSupportSeek(m_strArchiveName)) { \
        emitSeekErrorAndFinish();           \
        return retval;                      \
      }                                     \
    } while (0)

Then your three methods collapse to:

PluginFinishType CliInterface::list() {
    setPassword(QString());
    DataManager::get_instance().resetArchiveData();
    m_setHasRootDirs.clear();
    m_setHasHandlesDirs.clear();
    m_workStatus = WT_List;

    RETURN_IF_NO_SEEK(PFT_Error);

    bool ret = runProcess( /**/ );
    return ret ? PFT_Nomral : PFT_Error;
}

PluginFinishType CliInterface::extractFiles(...) {
    RETURN_IF_NO_SEEK(PFT_Nomral);

    // … rest of extractFiles …
}

PluginFinishType CliInterface::addFiles(...) {
    // only guard when files not empty
    if (!files.isEmpty()) {
        RETURN_IF_NO_SEEK(PFT_Nomral);
    }

    // … rest of addFiles …
}

That removes three copies of the QTimer+lambda while keeping every return‐value exactly as before.

QTimer::singleShot(1000, this, [=]() {
m_eErrorType = ET_FileSeekError;
emit signalprogress(100);
emit signalFinished(PFT_Error);
});
return PFT_Error;
}

bool ret = false;

ret = runProcess(m_cliProps->property("listProgram").toString(), m_cliProps->listArgs(m_strArchiveName, DataManager::get_instance().archiveData().strPassword));
Expand All @@ -89,6 +100,16 @@ PluginFinishType CliInterface::testArchive()

PluginFinishType CliInterface::extractFiles(const QList<FileEntry> &files, const ExtractionOptions &options)
{
// 是否支持seek
if(!m_common->isSupportSeek(m_strArchiveName)) {
QTimer::singleShot(1000, this, [=]() {
m_eErrorType = ET_FileSeekError;
emit signalprogress(100);
emit signalFinished(PFT_Error);
});
return PFT_Nomral;
Copy link

Choose a reason for hiding this comment

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

issue (typo): Typo in return value: 'PFT_Nomral' should be 'PFT_Normal'.

Please update the return value to 'PFT_Normal' to ensure correctness.

Suggested change
return PFT_Nomral;
+ return PFT_Normal;

}

bool bDlnfs = m_common->isSubpathOfDlnfs(options.strTargetPath);
setProperty("dlnfs", bDlnfs);
ArchiveData arcData = DataManager::get_instance().archiveData();
Expand Down Expand Up @@ -302,6 +323,16 @@ bool CliInterface::doKill()

PluginFinishType CliInterface::addFiles(const QList<FileEntry> &files, const CompressOptions &options)
{
// 是否支持seek
if (!files.isEmpty() && !m_common->isSupportSeek(m_strArchiveName)) {
QTimer::singleShot(1000, this, [=]() {
m_eErrorType = ET_FileSeekError;
emit signalprogress(100);
emit signalFinished(PFT_Error);
});
return PFT_Nomral;
}

setPassword(QString());
m_workStatus = WT_Add;
m_files = files;
Expand Down
39 changes: 39 additions & 0 deletions 3rdparty/interface/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <QDebug>
#include <QFileInfo>
#include <QDir>
#include <QTemporaryFile>

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <QRegularExpression>
Expand Down Expand Up @@ -445,6 +446,44 @@ bool Common::isSubpathOfDlnfs(const QString &path)
});
}

bool Common::isSupportSeek(QString sFileName)
{
QFileInfo info(sFileName);
if(info.exists()) {
QFile file(sFileName);
if(file.open(QIODevice::ReadOnly)) {
if (file.seek(0)) {
file.close();
return true; // 支持 seek
}
}
file.close();
} else {
// 指定临时文件的目录
QString tempDir = info.absoluteDir().path(); // 替换为你的目录路径
QString fileTemplate = tempDir + "/tempfile_XXXXXX"; // 文件名模板
// 创建 QTemporaryFile
QTemporaryFile tempFile(fileTemplate);
tempFile.setAutoRemove(true);
// 尝试打开临时文件
if (tempFile.open()) {
tempFile.write("test\n");
tempFile.flush();
}
tempFile.close();
QString sFileName = tempFile.fileName();
Copy link

Choose a reason for hiding this comment

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

nitpick: Variable shadowing of sFileName may cause confusion.

Consider renaming the inner 'sFileName' variable to avoid shadowing the function parameter and improve code clarity.

QFile file(sFileName);
if(file.open(QIODevice::ReadOnly)) {
if (file.seek(0)) {
file.close();
return true; // 支持 seek
}
}
file.close();
}
return false;
}

bool Common::findDlnfsPath(const QString &target, Compare func)
{
Q_ASSERT(func);
Expand Down
5 changes: 5 additions & 0 deletions 3rdparty/interface/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ class Common: public QObject
QString handleLongNameforPath(const QString &strFilePath, const QString &entryName, QMap<QString, int> &mapLongDirName, QMap<QString, int> &mapRealDirValue);
//当前文件系统是否支持长文件
bool isSubpathOfDlnfs(const QString &path);
/**
* @brief isSupportSeek 是否支持seek操作
* @param sFileName 文件名
*/
bool isSupportSeek(QString sFileName);
private:
//通过mount对应方法判断文件系统是否支持长文件
bool findDlnfsPath(const QString &target, Compare func);
Expand Down
1 change: 1 addition & 0 deletions 3rdparty/interface/commonstruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum ErrorType {

ET_UserCancelOpertion, // 用户取消操作
ET_ExistVolume, // 分卷已存在
ET_FileSeekError // 文件不支持seek
};

//加密类型
Expand Down
5 changes: 5 additions & 0 deletions 3rdparty/libarchive/libarchive/libarchiveplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ PluginFinishType LibarchivePlugin::list()
QString fileName = fInfo.fileName();
//因为tar.bz2、tar.lzma、tar.Z直接list时间较长,所以先用7z解压再list处理
if (fileName.endsWith(".tar.bz2") || fileName.endsWith(".tar.lzma") || fileName.endsWith(".tar.Z")) {
// 是否支持seek
if (!m_common->isSupportSeek(m_strArchiveName)) {
m_eErrorType = ET_FileSeekError;
return PFT_Error;
}
// 设置解压临时路径
QString strProcessID = QString::number(QCoreApplication::applicationPid()); // 获取应用进程号
QString tempFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation)
Expand Down
12 changes: 12 additions & 0 deletions 3rdparty/libzipplugin/libzipplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ PluginFinishType LibzipPlugin::list()
int errcode = 0;
zip_error_t err;

// 是否支持seek
if (!m_common->isSupportSeek(m_strArchiveName)) {
m_eErrorType = ET_FileSeekError;
return PFT_Error;
}

// 打开压缩包文件
zip_t *archive = zip_open(QFile::encodeName(m_strArchiveName).constData(), ZIP_RDONLY, &errcode); // 打开压缩包文件
zip_error_init_with_code(&err, errcode);
Expand Down Expand Up @@ -136,6 +142,12 @@ PluginFinishType LibzipPlugin::extractFiles(const QList<FileEntry> &files, const
// m_bHandleCurEntry = false; //false:提取使用选中文件及子文件 true:提取使用选中文件
zip_error_t err;

// 是否支持seek
if (!m_common->isSupportSeek(m_strArchiveName)) {
m_eErrorType = ET_FileSeekError;
return PFT_Error;
}

// 打开压缩包
zip_t *archive = zip_open(QFile::encodeName(m_strArchiveName).constData(), ZIP_RDONLY, &errcode);
zip_error_init_with_code(&err, errcode);
Expand Down
1 change: 1 addition & 0 deletions src/source/common/uistruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ enum ErrorInfo {
EI_InsufficientDiskSpace, // 磁盘空间不足
EI_ArchiveNoData, // 压缩包无数据
EI_ExistVolume, // 分卷已存在
EI_FileSeekError // seek失败
};

// 启动应用的方式
Expand Down
24 changes: 24 additions & 0 deletions src/source/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,10 @@ void MainWindow::handleJobErrorFinished(ArchiveJob::JobType eJobType, ErrorType
case ET_ExistVolume:
showErrorMessage(FI_Compress, EI_ExistVolume, true);
break;
// ftp目录不支持seek操作
case ET_FileSeekError:
showErrorMessage(FI_Compress, EI_FileSeekError, true);
break;
default: {
showErrorMessage(FI_Compress, EI_CreatArchiveFailed, true);
break;
Expand Down Expand Up @@ -1863,6 +1867,10 @@ void MainWindow::handleJobErrorFinished(ArchiveJob::JobType eJobType, ErrorType
case ET_WrongPassword:
showErrorMessage(FI_Load, EI_WrongPassword);
break;
// ftp目录不支持seek操作
case ET_FileSeekError:
showErrorMessage(FI_Load, EI_FileSeekError);
break;
default:
showErrorMessage(FI_Load, EI_ArchiveDamaged);
break;
Expand Down Expand Up @@ -1949,6 +1957,10 @@ void MainWindow::handleJobErrorFinished(ArchiveJob::JobType eJobType, ErrorType
!(StartupType::ST_ExtractHere == m_eStartupType || StartupType::ST_Extractto == m_eStartupType));
break;
}
// ftp目录不支持seek操作
case ET_FileSeekError:
showErrorMessage(FI_Uncompress, EI_FileSeekError);
break;
case ET_PluginError: {
// 无可用插件
showErrorMessage(FI_Uncompress, EI_NoPlugin);
Expand Down Expand Up @@ -2317,6 +2329,10 @@ void MainWindow::showErrorMessage(FailureInfo fFailureInfo, ErrorInfo eErrorInfo
m_pFailurePage->setFailureDetail(tr("The compressed volumes already exist"));
}
break;
case EI_FileSeekError: {
m_pFailurePage->setFailureDetail(tr("No compression support in current directory. Download the files to a local device."));
}
break;
default:
break;
}
Expand All @@ -2343,6 +2359,10 @@ void MainWindow::showErrorMessage(FailureInfo fFailureInfo, ErrorInfo eErrorInfo
m_pFailurePage->setFailureDetail(tr("Some volumes are missing"));
}
break;
case EI_FileSeekError: {
m_pFailurePage->setFailureDetail(tr("Can't open compressed packages in current directory. Download the compressed package to a local device."));
}
break;
default:
break;
}
Expand Down Expand Up @@ -2384,6 +2404,10 @@ void MainWindow::showErrorMessage(FailureInfo fFailureInfo, ErrorInfo eErrorInfo
m_pFailurePage->setFailureDetail(tr("Insufficient disk space"));
}
break;
case EI_FileSeekError: {
m_pFailurePage->setFailureDetail(tr("No extraction support in current directory. Download the compressed package to a local device."));
}
break;
default:
break;
}
Expand Down