SmartLockerTools/OtaUpdate/Widget.cpp
2024-05-17 10:36:23 +08:00

142 lines
4.5 KiB
C++

#include "Widget.h"
#include "BoostLog.h"
#include "CdcUpdater.h"
#include "DeviceDiscovery.h"
#include <QDropEvent>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QMimeData>
#include <QProgressBar>
#include <QPushButton>
#include <QSerialPortInfo>
#include <QVBoxLayout>
#include <filesystem>
Widget::Widget(QWidget *parent) : QWidget(parent) {
m_fileEditor = new QLineEdit();
m_fileEditor->setPlaceholderText("请选择升级文件或将文件拖入工具中");
m_selectButton = new QPushButton("选择");
connect(m_selectButton, &QPushButton::clicked, this, &Widget::onSelectButtonClicked);
auto fileLayout = new QHBoxLayout();
fileLayout->addWidget(m_fileEditor);
fileLayout->addWidget(m_selectButton);
m_startButton = new QPushButton(this);
m_startButton->setText("开始");
connect(m_startButton, &QPushButton::clicked, this, &Widget::start);
m_progressBar = new QProgressBar();
m_progressBar->setRange(0, 100);
m_progressBar->setValue(0);
m_messageLabel = new QLabel();
m_messageLabel->setText("选择升级文件,点击开始按钮升级模组");
auto statusLayout = new QVBoxLayout();
statusLayout->addWidget(m_progressBar);
statusLayout->addWidget(m_messageLabel);
auto controlLayout = new QHBoxLayout();
controlLayout->addLayout(statusLayout);
controlLayout->addWidget(m_startButton);
auto layout = new QVBoxLayout(this);
layout->addLayout(fileLayout);
layout->addLayout(controlLayout);
setAcceptDrops(true);
}
Widget::~Widget() {}
void Widget::start() {
m_progressBar->setValue(0);
auto filePath = m_fileEditor->text();
if (!std::filesystem::exists(filePath.toStdString())) {
QMessageBox::warning(this, "升级", "升级文件不存在!");
return;
}
auto discovery = std::make_shared<DeviceDiscovery>();
std::error_code error;
setMessage("尝试发现设备......");
auto device = discovery->find("UVC Camera", error);
if (!device) {
QMessageBox::warning(this, "升级", "未检测到模组,请尝试重新插入模组!");
return;
}
setMessage("发现设备成功,进入BOOT模式......");
discovery->enterOtaMode(device, error);
m_updater = std::make_shared<CdcUpdater>();
connect(m_updater.get(), &CdcUpdater::deviceDiscovered, this, &Widget::onCdcDeviceDiscovered);
connect(m_updater.get(), &CdcUpdater::updateFinished, this, &Widget::onUpdateFinished);
connect(m_updater.get(), &CdcUpdater::progressChanged, this, &Widget::setProgress);
connect(m_updater.get(), &CdcUpdater::message, this, &Widget::setMessage);
m_updater->start(filePath);
setControlsEnabled(false);
}
void Widget::onCdcDeviceDiscovered(const QSerialPortInfo &info) {
auto status = m_updater->open(info);
LOG(info) << "open cdc port: " << info.portName().toStdString() << ", status: " << status;
}
void Widget::onSelectButtonClicked() {
auto fileName = QFileDialog::getOpenFileName(this, "升级文件", "", tr("OTA文件 (*.Pkg)"));
m_fileEditor->setText(fileName);
}
void Widget::onUpdateFinished() {
QMessageBox::information(this, "升级", "升级成功!");
setControlsEnabled(true);
}
static QString dragFilePath(const QMimeData *mimeData) {
QString ret;
if (mimeData->hasUrls()) {
auto urls = mimeData->urls();
for (auto &url : urls) {
auto path = url.toLocalFile();
if (path.isEmpty()) continue;
ret = path;
break;
}
}
return ret;
}
void Widget::dragEnterEvent(QDragEnterEvent *event) {
auto path = dragFilePath(event->mimeData());
if (path.endsWith(".Pkg", Qt::CaseInsensitive)) {
event->acceptProposedAction();
} else {
event->ignore();
}
}
void Widget::dropEvent(QDropEvent *event) {
auto path = dragFilePath(event->mimeData());
if (path.endsWith(".Pkg", Qt::CaseInsensitive)) {
m_fileEditor->setText(path);
}
}
void Widget::setControlsEnabled(bool enabled) {
m_startButton->setEnabled(enabled);
m_selectButton->setEnabled(enabled);
m_fileEditor->setEnabled(enabled);
}
void Widget::setProgress(int32_t progress) {
m_progressBar->setValue(progress);
}
void Widget::setMessage(const QString &message) {
m_messageLabel->setText(message);
}