初步完成文件夹传输。
This commit is contained in:
@@ -12,6 +12,9 @@ void ClientCore::Instance()
|
|||||||
socket_ = new QTcpSocket(this);
|
socket_ = new QTcpSocket(this);
|
||||||
connect(socket_, &QTcpSocket::readyRead, this, &ClientCore::onReadyRead);
|
connect(socket_, &QTcpSocket::readyRead, this, &ClientCore::onReadyRead);
|
||||||
connect(socket_, &QTcpSocket::disconnected, this, &ClientCore::onDisconnected);
|
connect(socket_, &QTcpSocket::disconnected, this, &ClientCore::onDisconnected);
|
||||||
|
clearWaitTimer_ = new QTimer(this);
|
||||||
|
clearWaitTimer_->setInterval(10000);
|
||||||
|
connect(clearWaitTimer_, &QTimer::timeout, this, [this]() { clearWaitTask(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientCore::~ClientCore()
|
ClientCore::~ClientCore()
|
||||||
@@ -145,11 +148,79 @@ void ClientCore::handleAsk(QSharedPointer<FrameBuffer> frame)
|
|||||||
// 这个请求的处理可能是耗时的,需要开线程处理。
|
// 这个请求的处理可能是耗时的,需要开线程处理。
|
||||||
if (msg.command == STRMSG_AC_ALL_DIRFILES) {
|
if (msg.command == STRMSG_AC_ALL_DIRFILES) {
|
||||||
msg.command = STRMSG_AC_ANSWER_ALL_DIRFILES;
|
msg.command = STRMSG_AC_ANSWER_ALL_DIRFILES;
|
||||||
|
QMutexLocker locker(&waitTaskMut_);
|
||||||
|
if (waitTask_.contains(frame->fid)) {
|
||||||
|
msg.msg = STRMSG_ST_COMMAND_ALREADY_RUNNING;
|
||||||
|
if (!Send<InfoMsg>(msg, FBT_MSGINFO_ANSWER, frame->fid)) {
|
||||||
|
auto logMsg = tr("给") + frame->fid + tr("返回获取文件列表结果消息失败。");
|
||||||
|
qCritical() << logMsg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
waitTask_[frame->fid] = WaitTask();
|
||||||
|
auto& wt = waitTask_[frame->fid];
|
||||||
|
QString fid = frame->fid;
|
||||||
|
wt.wo = new WaitOperOwn(this);
|
||||||
|
wt.wo->SetClient(this);
|
||||||
|
wt.wo->fid = fid;
|
||||||
|
wt.wo->infoMsg_ = msg;
|
||||||
|
wt.wo->func_ = [this, &wt, fid]() {
|
||||||
|
auto& infoMsg = wt.wo->infoMsg_;
|
||||||
|
infoMsg.command = STRMSG_AC_ANSWER_ALL_DIRFILES;
|
||||||
|
bool success = false;
|
||||||
|
//infoMsg.infos.clear();
|
||||||
|
for (auto& item : infoMsg.infos.keys()) {
|
||||||
|
auto fullDir = Util::Join(infoMsg.fst.root, item);
|
||||||
|
if (!DirFileHelper::GetAllFiles(fullDir, infoMsg.list)) {
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto& vec = infoMsg.infos[item];
|
||||||
|
for (const auto& dd : std::as_const(infoMsg.list)) {
|
||||||
|
FileStruct fst;
|
||||||
|
fst.root = infoMsg.fst.root;
|
||||||
|
fst.mid = item;
|
||||||
|
fst.relative = dd;
|
||||||
|
vec.push_back(fst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
};
|
||||||
|
wt.wo->start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// 未知信息
|
// 未知信息
|
||||||
qWarning() << QString(tr("未知询问信息类型:%1")).arg(msg.command);
|
qWarning() << QString(tr("未知询问信息类型:%1")).arg(msg.command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientCore::clearWaitTask()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&waitTaskMut_);
|
||||||
|
QList<QString> completedTasks;
|
||||||
|
|
||||||
|
for (auto it = waitTask_.begin(); it != waitTask_.end(); ++it) {
|
||||||
|
WaitTask& task = it.value();
|
||||||
|
if (task.wo && task.wo->isFinished()) {
|
||||||
|
completedTasks.append(it.key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const QString& taskId : completedTasks) {
|
||||||
|
auto it = waitTask_.find(taskId);
|
||||||
|
if (it != waitTask_.end()) {
|
||||||
|
WaitTask& task = it.value();
|
||||||
|
if (task.wo) {
|
||||||
|
task.wo->wait();
|
||||||
|
delete task.wo;
|
||||||
|
task.wo = nullptr;
|
||||||
|
}
|
||||||
|
waitTask_.erase(it);
|
||||||
|
qDebug() << "清理完成的任务:" << taskId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClientCore::UseFrame(QSharedPointer<FrameBuffer> frame)
|
void ClientCore::UseFrame(QSharedPointer<FrameBuffer> frame)
|
||||||
{
|
{
|
||||||
switch (frame->type) {
|
switch (frame->type) {
|
||||||
@@ -430,13 +501,12 @@ void WaitOper::run()
|
|||||||
isRun_ = true;
|
isRun_ = true;
|
||||||
recvMsg_ = false;
|
recvMsg_ = false;
|
||||||
|
|
||||||
InfoMsg msg;
|
infoMsg_.command = sendStrType_;
|
||||||
msg.command = sendStrType_;
|
infoMsg_.fromPath = stra_;
|
||||||
msg.fromPath = stra_;
|
infoMsg_.toPath = strb_;
|
||||||
msg.toPath = strb_;
|
infoMsg_.type = type_;
|
||||||
msg.type = type_;
|
|
||||||
|
|
||||||
auto f = cli_->GetBuffer<InfoMsg>(msg, FBT_MSGINFO_ASK, cli_->GetRemoteID());
|
auto f = cli_->GetBuffer<InfoMsg>(infoMsg_, FBT_MSGINFO_ASK, cli_->GetRemoteID());
|
||||||
if (!ClientCore::syncInvoke(cli_, f)) {
|
if (!ClientCore::syncInvoke(cli_, f)) {
|
||||||
auto errMsg = QString(tr("向%1发送%2请求失败。")).arg(cli_->GetRemoteID()).arg(sendStrType_);
|
auto errMsg = QString(tr("向%1发送%2请求失败。")).arg(cli_->GetRemoteID()).arg(sendStrType_);
|
||||||
emit sigCheckOver();
|
emit sigCheckOver();
|
||||||
@@ -473,7 +543,12 @@ void WaitOper::SetPath(const QString& stra, const QString& strb, const QString&
|
|||||||
type_ = type;
|
type_ = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoMsg WaitOper::GetMsg() const
|
InfoMsg WaitOper::GetMsgConst() const
|
||||||
|
{
|
||||||
|
return infoMsg_;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoMsg& WaitOper::GetMsgRef()
|
||||||
{
|
{
|
||||||
return infoMsg_;
|
return infoMsg_;
|
||||||
}
|
}
|
||||||
@@ -502,12 +577,19 @@ WaitOperOwn::WaitOperOwn(QObject* parent) : WaitThread(parent)
|
|||||||
|
|
||||||
void WaitOperOwn::run()
|
void WaitOperOwn::run()
|
||||||
{
|
{
|
||||||
|
auto execRet = false;
|
||||||
if (func_) {
|
if (func_) {
|
||||||
func_();
|
execRet = func_();
|
||||||
|
}
|
||||||
|
if (!fid.isEmpty()) {
|
||||||
|
if (!cli_->syncInvoke(cli_, cli_->GetBuffer<InfoMsg>(infoMsg_, FBT_MSGINFO_ANSWER, fid))) {
|
||||||
|
qCritical() << QString(tr("向%1发送%2请求失败。")).arg(fid).arg(infoMsg_.command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
emit sigOver();
|
emit sigOver();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitOperOwn::recvFrame(QSharedPointer<FrameBuffer> frame)
|
void WaitOperOwn::recvFrame(QSharedPointer<FrameBuffer> frame)
|
||||||
{
|
{
|
||||||
|
qDebug() << "不应该被调用的地方:" << __FUNCTION__;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,14 @@
|
|||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTimer>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
class WaitOperOwn;
|
||||||
|
struct WaitTask {
|
||||||
|
QString id;
|
||||||
|
WaitOperOwn* wo;
|
||||||
|
};
|
||||||
class ClientCore : public QObject
|
class ClientCore : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -93,6 +99,7 @@ private:
|
|||||||
void onReadyRead();
|
void onReadyRead();
|
||||||
void onDisconnected();
|
void onDisconnected();
|
||||||
void handleAsk(QSharedPointer<FrameBuffer> frame);
|
void handleAsk(QSharedPointer<FrameBuffer> frame);
|
||||||
|
void clearWaitTask();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UseFrame(QSharedPointer<FrameBuffer> frame);
|
void UseFrame(QSharedPointer<FrameBuffer> frame);
|
||||||
@@ -121,6 +128,10 @@ public:
|
|||||||
|
|
||||||
bool connected_{false};
|
bool connected_{false};
|
||||||
LocalFile localFile_;
|
LocalFile localFile_;
|
||||||
|
|
||||||
|
QTimer* clearWaitTimer_{};
|
||||||
|
QMutex waitTaskMut_;
|
||||||
|
QMap<QString, WaitTask> waitTask_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 工作线程。
|
// 工作线程。
|
||||||
@@ -194,7 +205,8 @@ public:
|
|||||||
void run() override;
|
void run() override;
|
||||||
void SetType(const QString& sendType, const QString& ansType);
|
void SetType(const QString& sendType, const QString& ansType);
|
||||||
void SetPath(const QString& stra, const QString& strb, const QString& type);
|
void SetPath(const QString& stra, const QString& strb, const QString& type);
|
||||||
InfoMsg GetMsg() const;
|
InfoMsg GetMsgConst() const;
|
||||||
|
InfoMsg& GetMsgRef();
|
||||||
void interrupCheck() override;
|
void interrupCheck() override;
|
||||||
void recvFrame(QSharedPointer<FrameBuffer> frame) override;
|
void recvFrame(QSharedPointer<FrameBuffer> frame) override;
|
||||||
|
|
||||||
@@ -224,8 +236,9 @@ public:
|
|||||||
void recvFrame(QSharedPointer<FrameBuffer> frame) override;
|
void recvFrame(QSharedPointer<FrameBuffer> frame) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
QString fid;
|
||||||
InfoMsg infoMsg_{};
|
InfoMsg infoMsg_{};
|
||||||
std::function<void()> func_;
|
std::function<bool()> func_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLIENTCORE_H
|
#endif // CLIENTCORE_H
|
||||||
@@ -511,60 +511,103 @@ void FileManager::UpDown()
|
|||||||
QMessageBox::information(this, tr("提示"), tr("请选择完整的行。"));
|
QMessageBox::information(this, tr("提示"), tr("请选择完整的行。"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
要注意这一块的逻辑,本软件的所讲的【上传】【下载】都是针对本地。
|
||||||
|
这里的任务拼接和 DropEvent 有所不同,
|
||||||
|
DropEvent 是接收方负责拼接任务,但是这里是发送方拼接任务。
|
||||||
|
|
||||||
|
所以这里的拼接逻辑需要注意。
|
||||||
|
*/
|
||||||
|
QVector<FileStruct> resultFiles;
|
||||||
|
|
||||||
|
if (isRemote_) {
|
||||||
|
// 远程等待别人。
|
||||||
|
WaitOper wi(this);
|
||||||
|
wi.SetClient(cliCore_);
|
||||||
|
wi.SetType(STRMSG_AC_ALL_DIRFILES, STRMSG_AC_ANSWER_ALL_DIRFILES);
|
||||||
|
auto& infoMsg = wi.GetMsgRef();
|
||||||
|
infoMsg.infos.clear();
|
||||||
|
infoMsg.fst.root = GlobalData::Ins()->GetRemoteRoot();
|
||||||
|
|
||||||
//
|
|
||||||
WaitOperOwn wo(this);
|
|
||||||
auto getAllItems = [this, &datas, &wo]() {
|
|
||||||
wo.infoMsg_.list.clear();
|
|
||||||
for (int i = 0; i < (datas.size() / 5); ++i) {
|
for (int i = 0; i < (datas.size() / 5); ++i) {
|
||||||
|
FileStruct fst;
|
||||||
|
fst.root = GlobalData::Ins()->GetRemoteRoot();
|
||||||
|
fst.mid = datas[i * 5 + 1]->text();
|
||||||
const auto& curType = datas[i * 5 + 3]->text();
|
const auto& curType = datas[i * 5 + 3]->text();
|
||||||
if (curType == "File") {
|
if (curType == "File") {
|
||||||
wo.infoMsg_.list << datas[i * 5 + 1]->text();
|
fst.relative = datas[i * 5 + 1]->text();
|
||||||
|
resultFiles << fst;
|
||||||
} else {
|
} else {
|
||||||
QVector<QString> fs;
|
infoMsg.infos[datas[i * 5 + 1]->text()] = QVector<FileStruct>{};
|
||||||
DirFileHelper::GetAllFiles(datas[i * 5 + 1]->text(), fs);
|
|
||||||
if (!fs.isEmpty()) {
|
|
||||||
wo.infoMsg_.list << fs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
wo.func_ = getAllItems;
|
|
||||||
|
|
||||||
LoadingDialog checking(this);
|
LoadingDialog checking(this);
|
||||||
checking.setTipsText("正在获取文件列表...");
|
checking.setTipsText("正在等待对方获取文件列表...");
|
||||||
checking.setCanCancel(false);
|
connect(&wi, &WaitOper::sigCheckOver, &checking, &LoadingDialog::cancelBtnClicked);
|
||||||
connect(&wo, &WaitOperOwn::sigOver, &checking, &LoadingDialog::cancelBtnClicked);
|
connect(cliCore_, &ClientCore::sigMsgAnswer, &wi, &WaitOper::recvFrame);
|
||||||
|
|
||||||
wo.start();
|
wi.start();
|
||||||
checking.exec();
|
checking.exec();
|
||||||
|
|
||||||
|
if (!infoMsg.list.isEmpty()) {
|
||||||
|
for (const auto& item : infoMsg.infos.keys()) {
|
||||||
|
resultFiles << infoMsg.infos[item];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 本地自己等待。
|
||||||
|
WaitOperOwn wo(this);
|
||||||
|
wo.func_ = [this, &datas, &resultFiles]() {
|
||||||
|
resultFiles.clear();
|
||||||
|
for (int i = 0; i < (datas.size() / 5); ++i) {
|
||||||
|
FileStruct fst;
|
||||||
|
fst.root = GlobalData::Ins()->GetLocalRoot();
|
||||||
|
|
||||||
|
const auto& curType = datas[i * 5 + 3]->text();
|
||||||
|
if (curType == "File") {
|
||||||
|
fst.mid = datas[i * 5 + 1]->text();
|
||||||
|
resultFiles.push_back(fst);
|
||||||
|
} else {
|
||||||
|
QVector<FileStruct> fst;
|
||||||
|
DirFileHelper::GetAllFiles(GlobalData::Ins()->GetLocalRoot(), datas[i * 5 + 1]->text(), fst);
|
||||||
|
if (!fst.isEmpty()) {
|
||||||
|
resultFiles << fst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
LoadingDialog checking(this);
|
||||||
|
checking.setTipsText("正在获取文件列表...");
|
||||||
|
checking.setCanCancel(false);
|
||||||
|
connect(&wo, &WaitOperOwn::sigOver, &checking, &LoadingDialog::cancelBtnClicked);
|
||||||
|
|
||||||
|
wo.start();
|
||||||
|
checking.exec();
|
||||||
|
}
|
||||||
|
|
||||||
QVector<TransTask> tasks;
|
QVector<TransTask> tasks;
|
||||||
for (int i = 0; i < (datas.size() / 5); ++i) {
|
|
||||||
if (datas[i * 5 + 3]->text() != "File") {
|
|
||||||
qDebug() << QString(tr("暂不支持传输文件夹:%1")).arg(datas[i * 5 + 3]->text());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
要注意这一块的逻辑,本软件的所讲的【上传】【下载】都是针对本地。
|
|
||||||
这里的任务拼接和 DropEvent 有所不同,
|
|
||||||
DropEvent 是接收方负责拼接任务,但是这里是发送方拼接任务。
|
|
||||||
|
|
||||||
所以这里的拼接逻辑需要注意。
|
// 这里的 file 是相对路径,不再是特定的文件名称。
|
||||||
*/
|
for (const auto& file : std::as_const(resultFiles)) {
|
||||||
TransTask task;
|
TransTask task;
|
||||||
task.taskUUID = Util::UUID();
|
task.taskUUID = Util::UUID();
|
||||||
task.isUpload = !isRemote_;
|
task.isUpload = !isRemote_;
|
||||||
task.localId = cliCore_->GetOwnID();
|
task.localId = cliCore_->GetOwnID();
|
||||||
task.remoteId = cliCore_->GetRemoteID();
|
task.remoteId = cliCore_->GetRemoteID();
|
||||||
if (isRemote_) {
|
if (isRemote_) {
|
||||||
task.remotePath = Util::Join(GlobalData::Ins()->GetRemoteRoot(), datas[i * 5 + 1]->text());
|
task.remotePath = Util::Join(file.root, file.mid, file.relative);
|
||||||
task.localPath = GlobalData::Ins()->GetLocalRoot();
|
auto filePath = Util::Join(GlobalData::Ins()->GetLocalRoot(), file.mid, file.relative);
|
||||||
|
task.localPath = Util::GetFileDir(filePath);
|
||||||
} else {
|
} else {
|
||||||
task.remotePath = GlobalData::Ins()->GetRemoteRoot();
|
auto filePath = Util::Join(GlobalData::Ins()->GetRemoteRoot(), file.mid, file.relative);
|
||||||
task.localPath = Util::Join(GlobalData::Ins()->GetLocalRoot(), datas[i * 5 + 1]->text());
|
task.remotePath = Util::GetFileDir(filePath);
|
||||||
|
task.localPath = Util::Join(file.root, file.mid, file.relative);
|
||||||
}
|
}
|
||||||
tasks.push_back(task);
|
tasks.append(task);
|
||||||
}
|
}
|
||||||
if (tasks.isEmpty()) {
|
if (tasks.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@@ -633,7 +676,7 @@ void FileManager::OperNewFolder()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查结果
|
// 检查结果
|
||||||
auto msg = oper.GetMsg();
|
auto msg = oper.GetMsgConst();
|
||||||
if (msg.msg == STR_NONE || !msg.msg.isEmpty()) {
|
if (msg.msg == STR_NONE || !msg.msg.isEmpty()) {
|
||||||
QMessageBox::information(this, tr("提示"), QString(tr("新建失败=>%1")).arg(msg.msg));
|
QMessageBox::information(this, tr("提示"), QString(tr("新建失败=>%1")).arg(msg.msg));
|
||||||
} else {
|
} else {
|
||||||
@@ -643,7 +686,8 @@ void FileManager::OperNewFolder()
|
|||||||
nf.type = Dir;
|
nf.type = Dir;
|
||||||
nf.fullPath = folder;
|
nf.fullPath = folder;
|
||||||
nf.name = text;
|
nf.name = text;
|
||||||
nf.lastModified = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
// nf.lastModified = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||||
|
nf.lastModified = QDateTime::currentMSecsSinceEpoch();
|
||||||
ui->tableWidget->insertRow(0);
|
ui->tableWidget->insertRow(0);
|
||||||
ShowFileItem(nf, 0);
|
ShowFileItem(nf, 0);
|
||||||
}
|
}
|
||||||
@@ -700,7 +744,7 @@ void FileManager::OperDelete()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查结果
|
// 检查结果
|
||||||
auto msg = oper.GetMsg();
|
auto msg = oper.GetMsgConst();
|
||||||
if (msg.msg == STR_NONE || !msg.msg.isEmpty()) {
|
if (msg.msg == STR_NONE || !msg.msg.isEmpty()) {
|
||||||
QMessageBox::information(this, tr("提示"), QString(tr("删除失败=>%1")).arg(msg.msg));
|
QMessageBox::information(this, tr("提示"), QString(tr("删除失败=>%1")).arg(msg.msg));
|
||||||
} else {
|
} else {
|
||||||
@@ -787,7 +831,7 @@ void FileManager::OperRename()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检查结果
|
// 检查结果
|
||||||
auto msg = oper.GetMsg();
|
auto msg = oper.GetMsgConst();
|
||||||
if (msg.msg == STR_NONE || !msg.msg.isEmpty()) {
|
if (msg.msg == STR_NONE || !msg.msg.isEmpty()) {
|
||||||
QMessageBox::information(this, tr("提示"), QString(tr("重命名失败=>%1")).arg(msg.msg));
|
QMessageBox::information(this, tr("提示"), QString(tr("重命名失败=>%1")).arg(msg.msg));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ enum FileCheckState {
|
|||||||
#define STRMSG_ST_FILENOEXIT "fileNotExist"
|
#define STRMSG_ST_FILENOEXIT "fileNotExist"
|
||||||
#define STRMSG_ST_DIREXIT "dirExist"
|
#define STRMSG_ST_DIREXIT "dirExist"
|
||||||
#define STRMSG_ST_DIRNOEXIT "dirNotExist"
|
#define STRMSG_ST_DIRNOEXIT "dirNotExist"
|
||||||
|
#define STRMSG_ST_COMMAND_ALREADY_RUNNING "commandAlreadyRunning"
|
||||||
|
|
||||||
#define STR_FILE "File"
|
#define STR_FILE "File"
|
||||||
#define STR_DIR "Dir"
|
#define STR_DIR "Dir"
|
||||||
|
|||||||
@@ -8,6 +8,12 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
|
struct FileStruct {
|
||||||
|
QString root;
|
||||||
|
QString mid;
|
||||||
|
QString relative;
|
||||||
|
};
|
||||||
|
|
||||||
struct PropertyData {
|
struct PropertyData {
|
||||||
QString uuid;
|
QString uuid;
|
||||||
QString command;
|
QString command;
|
||||||
@@ -27,21 +33,40 @@ struct InfoMsg {
|
|||||||
QString type;
|
QString type;
|
||||||
quint64 size{};
|
quint64 size{};
|
||||||
quint32 permissions{};
|
quint32 permissions{};
|
||||||
|
QVector<QString> listSend;
|
||||||
QVector<QString> list;
|
QVector<QString> list;
|
||||||
QMap<QString, PropertyData> mapData;
|
QMap<QString, PropertyData> mapData;
|
||||||
|
FileStruct fst;
|
||||||
|
QMap<QString, QVector<FileStruct>> infos;
|
||||||
|
|
||||||
void serialize(QDataStream& data) const
|
void serialize(QDataStream& data) const
|
||||||
{
|
{
|
||||||
data << mark << command << msg << fromPath << toPath << type << size << permissions;
|
data << mark << command << msg << fromPath << toPath << type << size << permissions;
|
||||||
|
|
||||||
|
data << static_cast<qint32>(listSend.size());
|
||||||
|
for (const auto& item : listSend) {
|
||||||
|
data << item;
|
||||||
|
}
|
||||||
|
|
||||||
data << static_cast<qint32>(list.size());
|
data << static_cast<qint32>(list.size());
|
||||||
for (const auto& item : list) {
|
for (const auto& item : list) {
|
||||||
data << item;
|
data << item;
|
||||||
}
|
}
|
||||||
|
|
||||||
data << static_cast<qint32>(mapData.size());
|
data << static_cast<qint32>(mapData.size());
|
||||||
for (auto it = mapData.constBegin(); it != mapData.constEnd(); ++it) {
|
for (auto it = mapData.constBegin(); it != mapData.constEnd(); ++it) {
|
||||||
data << it.key();
|
data << it.key();
|
||||||
data << it.value().uuid << it.value().command << it.value().userAction
|
data << it.value().uuid << it.value().command << it.value().userAction << it.value().localPath
|
||||||
<< it.value().localPath << it.value().remotePath << it.value().state << it.value().properE;
|
<< it.value().remotePath << it.value().state << it.value().properE;
|
||||||
|
}
|
||||||
|
data << fst.root << fst.mid << fst.relative;
|
||||||
|
data << static_cast<qint32>(infos.size());
|
||||||
|
for (auto it = infos.constBegin(); it != infos.constEnd(); ++it) {
|
||||||
|
data << it.key();
|
||||||
|
data << static_cast<qint32>(it.value().size());
|
||||||
|
for (const auto& fileStruct : it.value()) {
|
||||||
|
data << fileStruct.root << fileStruct.mid << fileStruct.relative;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +75,12 @@ struct InfoMsg {
|
|||||||
data >> mark >> command >> msg >> fromPath >> toPath >> type >> size >> permissions;
|
data >> mark >> command >> msg >> fromPath >> toPath >> type >> size >> permissions;
|
||||||
|
|
||||||
qint32 listSize;
|
qint32 listSize;
|
||||||
|
data >> listSize;
|
||||||
|
listSend.resize(listSize);
|
||||||
|
for (auto& item : listSend) {
|
||||||
|
data >> item;
|
||||||
|
}
|
||||||
|
|
||||||
data >> listSize;
|
data >> listSize;
|
||||||
list.resize(listSize);
|
list.resize(listSize);
|
||||||
for (auto& item : list) {
|
for (auto& item : list) {
|
||||||
@@ -63,10 +94,28 @@ struct InfoMsg {
|
|||||||
QString key;
|
QString key;
|
||||||
PropertyData prop;
|
PropertyData prop;
|
||||||
data >> key;
|
data >> key;
|
||||||
data >> prop.uuid >> prop.command >> prop.userAction >> prop.localPath
|
data >> prop.uuid >> prop.command >> prop.userAction >> prop.localPath >> prop.remotePath >> prop.state >>
|
||||||
>> prop.remotePath >> prop.state >> prop.properE;
|
prop.properE;
|
||||||
mapData.insert(key, prop);
|
mapData.insert(key, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data >> fst.root >> fst.mid >> fst.relative;
|
||||||
|
|
||||||
|
data >> mapSize;
|
||||||
|
infos.clear();
|
||||||
|
for (int i = 0; i < mapSize; ++i) {
|
||||||
|
QString key;
|
||||||
|
data >> key;
|
||||||
|
|
||||||
|
qint32 vectorSize;
|
||||||
|
data >> vectorSize;
|
||||||
|
QVector<FileStruct> fileVector;
|
||||||
|
fileVector.resize(vectorSize);
|
||||||
|
for (int j = 0; j < vectorSize; ++j) {
|
||||||
|
data >> fileVector[j].root >> fileVector[j].mid >> fileVector[j].relative;
|
||||||
|
}
|
||||||
|
infos.insert(key, fileVector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
QDataStream& operator<<(QDataStream& data, const InfoMsg& info);
|
QDataStream& operator<<(QDataStream& data, const InfoMsg& info);
|
||||||
|
|||||||
@@ -71,6 +71,11 @@ QString Util::Join(const QString& path, const QString& name)
|
|||||||
return QDir::cleanPath(path + QDir::separator() + name);
|
return QDir::cleanPath(path + QDir::separator() + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Util::Join(const QString& path, const QString& mid, const QString& name)
|
||||||
|
{
|
||||||
|
return QDir::cleanPath(path + QDir::separator() + mid + QDir::separator() + name);
|
||||||
|
}
|
||||||
|
|
||||||
void Util::InitLogger(const QString& logPath, const QString& mark)
|
void Util::InitLogger(const QString& logPath, const QString& mark)
|
||||||
{
|
{
|
||||||
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath.toStdString(), 1024 * 1024 * 50, 3);
|
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath.toStdString(), 1024 * 1024 * 50, 3);
|
||||||
@@ -83,6 +88,12 @@ void Util::InitLogger(const QString& logPath, const QString& mark)
|
|||||||
spdlog::register_logger(logger);
|
spdlog::register_logger(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Util::GetFileDir(const QString& path)
|
||||||
|
{
|
||||||
|
QFileInfo fileInfo(path);
|
||||||
|
return fileInfo.absolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
// do not check exit
|
// do not check exit
|
||||||
QString Util::Get2FilePath(const QString& file, const QString& directory)
|
QString Util::Get2FilePath(const QString& file, const QString& directory)
|
||||||
{
|
{
|
||||||
@@ -178,7 +189,7 @@ QVector<QString> Util::GetLocalDrivers()
|
|||||||
{
|
{
|
||||||
QVector<QString> result;
|
QVector<QString> result;
|
||||||
auto drivers = QStorageInfo::mountedVolumes();
|
auto drivers = QStorageInfo::mountedVolumes();
|
||||||
for (const auto& driver : drivers) {
|
for (const auto& driver : std::as_const(drivers)) {
|
||||||
if (driver.isValid() && driver.isReady()) {
|
if (driver.isValid() && driver.isReady()) {
|
||||||
result.push_back(driver.rootPath());
|
result.push_back(driver.rootPath());
|
||||||
}
|
}
|
||||||
@@ -218,6 +229,38 @@ bool DirFileHelper::GetAllFiles(const QString& rootPath, QVector<QString>& files
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DirFileHelper::GetAllFiles(const QString& rootPath, const QString& mid, QVector<FileStruct>& files)
|
||||||
|
{
|
||||||
|
auto fileRoot = Util::Join(rootPath, mid);
|
||||||
|
QDir rootDir(fileRoot);
|
||||||
|
|
||||||
|
if (!rootDir.exists()) {
|
||||||
|
qWarning() << "目录不存在:" << fileRoot;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString absoluteRootPath = rootDir.absolutePath();
|
||||||
|
QDirIterator it(absoluteRootPath, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
QFileInfo fileInfo = it.fileInfo();
|
||||||
|
if (fileInfo.isFile()) {
|
||||||
|
QString absoluteFilePath = fileInfo.absoluteFilePath();
|
||||||
|
QString relativePath = absoluteFilePath.mid(absoluteRootPath.length());
|
||||||
|
if (relativePath.startsWith('/') || relativePath.startsWith('\\')) {
|
||||||
|
relativePath = relativePath.mid(1);
|
||||||
|
}
|
||||||
|
FileStruct fst;
|
||||||
|
fst.root = rootPath;
|
||||||
|
fst.mid = mid;
|
||||||
|
fst.relative = relativePath;
|
||||||
|
files.append(fst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DirFileHelper::DirFileHelper(QObject* parent) : QObject(parent)
|
DirFileHelper::DirFileHelper(QObject* parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define UTIL_H
|
#define UTIL_H
|
||||||
|
|
||||||
#include <InfoDirFile.h>
|
#include <InfoDirFile.h>
|
||||||
|
#include <InfoMsg.h>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@@ -45,7 +46,9 @@ public:
|
|||||||
static QString GetUserHome();
|
static QString GetUserHome();
|
||||||
static void InitLogger(const QString& logPath, const QString& mark);
|
static void InitLogger(const QString& logPath, const QString& mark);
|
||||||
static QString Get2FilePath(const QString& file, const QString& directory);
|
static QString Get2FilePath(const QString& file, const QString& directory);
|
||||||
|
static QString GetFileDir(const QString& path);
|
||||||
static QString Join(const QString& path, const QString& name);
|
static QString Join(const QString& path, const QString& name);
|
||||||
|
static QString Join(const QString& path, const QString& mid, const QString& name);
|
||||||
static QString GetCurConfigPath(const QString& sub);
|
static QString GetCurConfigPath(const QString& sub);
|
||||||
static void ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg);
|
static void ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg);
|
||||||
static QString GetVersion();
|
static QString GetVersion();
|
||||||
@@ -68,6 +71,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
QString GetErr() const;
|
QString GetErr() const;
|
||||||
static bool GetAllFiles(const QString& rootPath, QVector<QString>& files);
|
static bool GetAllFiles(const QString& rootPath, QVector<QString>& files);
|
||||||
|
static bool GetAllFiles(const QString& rootPath, const QString& mid, QVector<FileStruct>& files);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sigHome(const QString& path, const QVector<QString>& drivers);
|
void sigHome(const QString& path, const QVector<QString>& drivers);
|
||||||
|
|||||||
Reference in New Issue
Block a user