diff --git a/.vscode/settings.json b/.vscode/settings.json index eaca38c..bc93b49 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -147,7 +147,8 @@ "qxmlstreamwriter": "cpp", "qgraphicsdropshadoweffect": "cpp", "qpushbutton": "cpp", - "qpainter": "cpp" + "qpainter": "cpp", + "qdialog": "cpp" }, "editor.tokenColorCustomizations": { "textMateRules": [ diff --git a/ClientCore/ClientCore.cpp b/ClientCore/ClientCore.cpp index fdf166e..7b8e1ee 100644 --- a/ClientCore/ClientCore.cpp +++ b/ClientCore/ClientCore.cpp @@ -82,6 +82,29 @@ void ClientCore::onDisconnected() emit sigDisconnect(); } +void ClientCore::handleAsk(QSharedPointer frame) +{ + InfoMsg msg = infoUnpack(frame->data); + // TODO: 处理询问请求 + if (msg.command == STRMSG_REQUEST_CHECK_FILE_EXIST) { + InfoMsg ans; + ans.command = STRMSG_ANSWER_CHECK_FILE_EXIST; + for (const auto& filePath : msg.list) { + if (!Util::FileExist(filePath)) { + ans.list.append(filePath); + } + } + if (!Send(ans, FBT_MSGINFO_ANSWER, frame->fid)) { + auto logMsg = tr("给") + frame->fid + tr("返回检查文件存在性消息失败。"); + qCritical() << logMsg; + return; + } + return; + } + // 未知信息 + qWarning() << QString(tr("未知询问信息类型:%1")).arg(msg.command); +} + void ClientCore::UseFrame(QSharedPointer frame) { switch (frame->type) { @@ -182,7 +205,7 @@ void ClientCore::UseFrame(QSharedPointer frame) break; } case FBT_MSGINFO_ASK: { - emit sigMsgAsk(frame); + handleAsk(frame); break; } case FBT_MSGINFO_ANSWER: { diff --git a/ClientCore/ClientCore.h b/ClientCore/ClientCore.h index bb700b6..33aa6a6 100644 --- a/ClientCore/ClientCore.h +++ b/ClientCore/ClientCore.h @@ -89,6 +89,7 @@ signals: private: void onReadyRead(); void onDisconnected(); + void handleAsk(QSharedPointer frame); private: void UseFrame(QSharedPointer frame); diff --git a/Gui/Form/Loading.cpp b/Gui/Form/Loading.cpp index ce6be89..033bd9f 100644 --- a/Gui/Form/Loading.cpp +++ b/Gui/Form/Loading.cpp @@ -106,8 +106,11 @@ void LoadingDialog::moveToCenter(QWidget* pParent) */ void LoadingDialog::cancelBtnClicked() { - emit cancelWaiting(); - this->done(USER_CANCEL); + if (isShow_) { + isShow_ = false; + emit cancelWaiting(); + this->done(USER_CANCEL); + } } /** @@ -129,6 +132,12 @@ void LoadingDialog::paintEvent(QPaintEvent* event) QWidget::paintEvent(event); } +int LoadingDialog::exec() +{ + isShow_ = true; + return QDialog::exec(); +} + LoadingDialog::~LoadingDialog() { delete m_pLoadingMovie; diff --git a/Gui/Form/Loading.h b/Gui/Form/Loading.h index 9af0c81..783eb6f 100644 --- a/Gui/Form/Loading.h +++ b/Gui/Form/Loading.h @@ -23,16 +23,19 @@ public: // 移动到指定窗口中间显示 void moveToCenter(QWidget* pParent); +public: + int exec() override; + protected: void paintEvent(QPaintEvent* event) override; private: void initUi(); - + Q_SIGNALS: void cancelWaiting(); -private slots: +public slots: void cancelBtnClicked(); private: @@ -40,6 +43,7 @@ private: QLabel* m_pMovieLabel; QMovie* m_pLoadingMovie; QLabel* m_pTipsLabel; + bool isShow_{}; QPushButton* m_pCancelBtn; }; #endif // LOADINGDIALOG_H \ No newline at end of file diff --git a/Gui/Form/Transform.cpp b/Gui/Form/Transform.cpp index dcf0331..7d07554 100644 --- a/Gui/Form/Transform.cpp +++ b/Gui/Form/Transform.cpp @@ -1,5 +1,6 @@ #include "Transform.h" +#include #include #include "ui_Transform.h" @@ -146,3 +147,105 @@ void TransForm::closeEvent(QCloseEvent* event) exis_ = true; QDialog::closeEvent(event); } + +CheckCondition::CheckCondition(QObject* parent) : QThread(parent) +{ +} + +void CheckCondition::SetClientCore(ClientCore* clientCore) +{ + clientCore_ = clientCore; +} + +void CheckCondition::SetTasks(const QVector& tasks) +{ + tasks_ = tasks; +} + +void CheckCondition::recvFrame(QSharedPointer frame) +{ + InfoMsg info = infoUnpack(frame->data); + if (info.command == STRMSG_ANSWER_CHECK_FILE_EXIST) { + remoteNotExits_ = info.list; + qInfo() << tr("检查结束,远端不存在的文件数:") << remoteNotExits_.size(); + msg_ = info.command; + return; + } + msg_ = tr("收到未知信息,认为判断失败:") + info.command; + qInfo() << msg_; +} + +void CheckCondition::interrupCheck() +{ + if (!isAlreadyInter_) { + isAlreadyInter_ = true; + qWarning() << tr("中断文件校验......"); + emit sigCheckOver(); + } +} + +void CheckCondition::run() +{ + qInfo() << tr("开始文件校验......"); + + resultMsgMap_.clear(); + checkRet_.clear(); + isRun_ = true; + msg_.clear(); + isAlreadyInter_ = false; + + // 先检查本地文件是否存在 + for (const auto& task : tasks_) { + if (task.isUpload && !Util::FileExist(task.localPath)) { + resultMsgMap_[CCR_CHECK_LOCAL_NOT_EXIT].push_back(task.localPath); + if (!checkRet_.contains(CCR_CHECK_LOCAL_NOT_EXIT)) { + checkRet_.push_back(CCR_CHECK_LOCAL_NOT_EXIT); + } + } + if (!task.isUpload && Util::FileExist(task.localPath)) { + resultMsgMap_[CCR_CHECK_LOCAL_EXIT].push_back(task.localPath); + if (!checkRet_.contains(CCR_CHECK_LOCAL_EXIT)) { + checkRet_.push_back(CCR_CHECK_LOCAL_EXIT); + } + } + } + + // 再检查远程文件是否存在 + InfoMsg msg; + msg.command = STRMSG_REQUEST_CHECK_FILE_EXIST; + for (const auto& task : tasks_) { + msg.list.push_back(task.remotePath); + } + + auto f = clientCore_->GetBuffer(msg, FBT_MSGINFO_ASK, clientCore_->GetRemoteID()); + if (!ClientCore::syncInvoke(clientCore_, f)) { + auto errMsg = tr("检查远程文件存在性数据发送失败。"); + if (!checkRet_.contains(CCR_CHECK_FAILED)) { + checkRet_.push_back(CCR_CHECK_FAILED); + resultMsgMap_[CCR_CHECK_FAILED].push_back(errMsg); + } + emit sigCheckOver(); + qCritical() << errMsg; + return; + } + while (isRun_) { + QThread::msleep(10); + if (msg_.isEmpty()) { + continue; + } + if (msg_ != STRMSG_ANSWER_CHECK_FILE_EXIST) { + if (!checkRet_.contains(CCR_CHECK_FAILED)) { + checkRet_.push_back(CCR_CHECK_FAILED); + resultMsgMap_[CCR_CHECK_FAILED].push_back(msg_); + } + } else { + if (!checkRet_.contains(CCR_CHECK_PASSED)) { + checkRet_.push_back(CCR_CHECK_PASSED); + } + } + break; + } + isAlreadyInter_ = true; + emit sigCheckOver(); + qInfo() << tr("文件校验结束......"); +} diff --git a/Gui/Form/Transform.h b/Gui/Form/Transform.h index f672979..bc73d9f 100644 --- a/Gui/Form/Transform.h +++ b/Gui/Form/Transform.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace Ui { class TransForm; @@ -33,7 +34,7 @@ signals: void sigTaskNum(const QString& data); private: - void setProgress(double val); + void setProgress(double val); void handleFailed(); void handleDone(); void handleUI(const TransTask& task); @@ -41,12 +42,12 @@ private: protected: void showEvent(QShowEvent* event) override; - void closeEvent(QCloseEvent* event) override; + void closeEvent(QCloseEvent* event) override; private: - bool exis_{ false }; + bool exis_{false}; TranFromTh* workTh_{}; - qint32 curTaskNum_{ 0 }; + qint32 curTaskNum_{0}; QVector tasks_; FileTrans* fileTrans_{}; ClientCore* clientCore_{}; @@ -61,6 +62,7 @@ public: explicit TranFromTh(TransForm* tf, QObject* parent = nullptr) : QThread(parent), tf_(tf) { } + protected: void run() override { @@ -73,4 +75,47 @@ private: TransForm* tf_; }; -#endif // TRANSFORM_H +enum CondCheckResult { + CCR_NO_CHECK = 0, + CCR_CHECK_PASSED, + CCR_CHECK_FAILED, + CCR_CHECK_INTERRUPT, + CCR_CHECK_LOCAL_EXIT, + CCR_CHECK_REMOTE_EXIT, + CCR_CHECK_LOCAL_NOT_EXIT, + CCR_CHECK_REMOTE_NOT_EXIT +}; + +class CheckCondition : public QThread +{ + Q_OBJECT + +public: + CheckCondition(QObject* parent = nullptr); + +public: + void SetClientCore(ClientCore* clientCore); + void SetTasks(const QVector& tasks); + +Q_SIGNALS: + void sigCheckOver(); + +public Q_SLOTS: + void interrupCheck(); + void recvFrame(QSharedPointer frame); + +protected: + void run() override; + +private: + QString msg_; + bool isRun_; + bool isAlreadyInter_; + QVector tasks_; + ClientCore* clientCore_{}; + QVector remoteNotExits_; + QVector checkRet_; + std::unordered_map> resultMsgMap_; +}; + +#endif // TRANSFORM_H \ No newline at end of file diff --git a/Gui/frelayGUI.cpp b/Gui/frelayGUI.cpp index 56bf2af..3bbeaf3 100644 --- a/Gui/frelayGUI.cpp +++ b/Gui/frelayGUI.cpp @@ -1,5 +1,6 @@ #include "frelayGUI.h" +#include
#include #include #include @@ -35,7 +36,7 @@ frelayGUI::frelayGUI(QWidget* parent) : QDialog(parent), ui(new Ui::frelayGUI) // QLabel* permanent = new QLabel(this); // permanent->setFrameStyle(QFrame::Box | QFrame::Sunken); // permanent->setText(QString("%1 on %2").arg(VERSION_GIT_COMMIT, VERSION_GIT_BRANCH)); - //this->statusBar()->addPermanentWidget(permanent); + // this->statusBar()->addPermanentWidget(permanent); } frelayGUI::~frelayGUI() @@ -142,6 +143,22 @@ void frelayGUI::HandleTask(const QVector& tasks) return; } transform_->SetTasks(tasks); + + // 检查文件 + CheckCondition checkThread(this); + checkThread.SetTasks(tasks); + checkThread.SetClientCore(clientCore_); + + LoadingDialog checking(this); + checking.setTipsText("正在检查文件..."); + + connect(&checkThread, &CheckCondition::sigCheckOver, &checking, &LoadingDialog::cancelBtnClicked); + connect(&checking, &LoadingDialog::cancelWaiting, &checkThread, &CheckCondition::interrupCheck); + connect(clientCore_, &ClientCore::sigMsgAnswer, &checkThread, &CheckCondition::recvFrame); + + checkThread.start(); + checking.exec(); + transform_->exec(); } diff --git a/Protocol/Protocol.h b/Protocol/Protocol.h index cc03af2..fcc3b57 100644 --- a/Protocol/Protocol.h +++ b/Protocol/Protocol.h @@ -42,9 +42,8 @@ enum FrameBufferType : uint16_t { }; // 字符串标识 -#define STRMSG_CHECK_FILE_EXIST "checkFileExist" -#define STRMSG_FILE_EXIST "fileExist" -#define STRMSG_FILE_NOT_EXIST "fileNotExist" +#define STRMSG_REQUEST_CHECK_FILE_EXIST "requestCheckFileExist" +#define STRMSG_ANSWER_CHECK_FILE_EXIST "answerCheckFileExist" struct FrameBuffer { QByteArray data; diff --git a/Util/Util.cpp b/Util/Util.cpp index 46e84fb..bbfd52c 100644 --- a/Util/Util.cpp +++ b/Util/Util.cpp @@ -125,6 +125,16 @@ QString Util::GetVersion() return ver; } +bool Util::FileExist(const QString& path) +{ + return QFile::exists(path); +} + +bool Util::DirExist(const QString& path) +{ + return QDir(path).exists(); +} + QString DirFileHelper::GetErr() const { return QString(); diff --git a/Util/Util.h b/Util/Util.h index 95cb3b1..2d116b0 100644 --- a/Util/Util.h +++ b/Util/Util.h @@ -49,6 +49,8 @@ public: static QString GetCurConfigPath(const QString& sub); static void ConsoleMsgHander(QtMsgType type, const QMessageLogContext& context, const QString& msg); static QString GetVersion(); + static bool FileExist(const QString& path); + static bool DirExist(const QString& path); }; class DirFileHelper : public QObject