yhkylin-backup-tools/kybackup/module/ghostimage.cpp

1274 lines
47 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ghostimage.h"
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
#include <QMovie>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QHostInfo>
#include <unistd.h>
#include "../component/clicklabel.h"
#include "../component/circlelabel.h"
#include "../component/myiconlabel.h"
#include "../component/mylabel.h"
#include "../component/mylineedit.h"
#include "../component/mypushbutton.h"
#include "../component/linelabel.h"
#include "../component/ringsprogressbar.h"
#include "../component/myfileselect.h"
#include "../component/pixmaplabel.h"
#include "../../common/utils.h"
#include "../globalbackupinfo.h"
#include "../gsettingswrapper.h"
#include "selectrestorepoint.h"
#include "messageboxutils.h"
#include "kborderbutton.h"
using namespace kdk;
// bigTitle控件前面的宽度24+spacing
#define LEN_TITLE_PRE 50
// labelCheck1、labelCheck2控件前面的宽度10+6+5
#define LEN_DOT_PRE 50
GhostImage::GhostImage(QWidget *parent) :
QStackedWidget(parent),
m_udector(new UdiskDetector()),
m_isLocal(true),
m_ghostImageState(GhostImageState::IDEL),
m_pInterface(nullptr)
{
m_iPosition = BackupPosition::LOCAL;
// 界面手写代码创建,作为练手
initFirstWidget();
initSecondWidget();
initThirdWidget();
initForthWidget();
initLastWidget();
}
GhostImage::~GhostImage()
{
delete m_udector;
m_udector = nullptr;
delete m_pInterface;
m_pInterface = nullptr;
}
/**
* @brief 初始化第一个页面
*/
void GhostImage::initFirstWidget()
{
QWidget *first = new QWidget;
QVBoxLayout *vLayout = new QVBoxLayout;
vLayout->addStretch();
// 中部布局包含一个独立的窗口,用于大小变化时局部相对不变
QWidget *center = new QWidget;
center->setFixedSize(760, 540);
QHBoxLayout *centerHBoxLayout = new QHBoxLayout;
centerHBoxLayout->addStretch();
centerHBoxLayout->addWidget(center);
centerHBoxLayout->addStretch();
vLayout->addLayout(centerHBoxLayout);
vLayout->addStretch();
vLayout->addSpacing(60);
first->setLayout(vLayout);
// 图片
PixmapLabel *imageGhost_firstPage = new PixmapLabel(center);
imageGhost_firstPage->setGeometry(421, 120, 300, 326);
imageGhost_firstPage->setScaledContents(true);
imageGhost_firstPage->setLightAndDarkPixmap(":/images/ghost_image.png", ":/images/ghost_image_dark.png");
// Ghost Image大字提示
MyLabel *labelGhost_firstPage = new MyLabel(center);
labelGhost_firstPage->setDeplayText(tr("Ghost Image"));
labelGhost_firstPage->setFixedWidth(500);
labelGhost_firstPage->setFixedHeight(48);
labelGhost_firstPage->move(41, 120);
// 默认水平左对齐,上下居中对齐;故不需要设置
// labelGhost_firstPage->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
// labelGhost_firstPage->setText(tr("System Backup"));
QFont font;
font.setBold(true);
font.setPixelSize(36);
labelGhost_firstPage->setFont(font);
// labelGhost_firstPage->setAttribute(Qt::WA_TranslucentBackground);
labelGhost_firstPage->setScaledContents(true);
labelGhost_firstPage->adjustSize();
// Ghost说明
MyLabel *labelNote_firstPage = new MyLabel(center);
labelNote_firstPage->setFixedWidth(700);
labelNote_firstPage->setFixedHeight(24);
labelNote_firstPage->move(41, 180);
// 必须存在本地系统备份,才能制作镜像文件
labelNote_firstPage->setDeplayText(tr("A ghost image file can only be created after backup system to local disk"));
font.setBold(false);
font.setPixelSize(18);
labelNote_firstPage->setFont(font);
labelNote_firstPage->setScaledContents(true);
labelNote_firstPage->adjustSize();
// 操作简单
MyIconLabel *iconSimple_firstPage = new MyIconLabel(center);
iconSimple_firstPage->setGeometry(41, 244, 180, 36);
iconSimple_firstPage->setThemeIcon("ukui-bf-simple-symbolic", ":/symbos/ukui-bf-simple-symbolic");
iconSimple_firstPage->setDesplayText(tr("Simple"));
iconSimple_firstPage->setEnabled(false);
// 快速
MyIconLabel *iconFast_firstPage = new MyIconLabel(center);
iconFast_firstPage->setGeometry(206, 244, 180, 36);
iconFast_firstPage->setThemeIcon("ukui-bf-fast-symbolic", ":/symbos/ukui-bf-fast-symbolic");
iconFast_firstPage->setDesplayText(tr("Fast"));
iconFast_firstPage->setEnabled(false);
// 安全
MyIconLabel *iconSecurity_firstPage = new MyIconLabel(center);
iconSecurity_firstPage->setGeometry(41, 296, 180, 36);
iconSecurity_firstPage->setThemeIcon("ukui-bf-security-symbolic", ":/symbos/ukui-bf-security-symbolic");
iconSecurity_firstPage->setDesplayText(tr("Security"));
iconSecurity_firstPage->setEnabled(false);
// 节省时间
MyIconLabel *iconSimple_firstPage1 = new MyIconLabel(center);
iconSimple_firstPage1->setGeometry(206, 296, 180, 36);
iconSimple_firstPage1->setThemeIcon("document-open-recent-symbolic", ":/symbos/document-open-recent-symbolic");
iconSimple_firstPage1->setDesplayText(tr("Timesaving"));
iconSimple_firstPage1->setEnabled(false);
// 制作镜像按钮
MyPushButton *beginBackup = new MyPushButton(center);
beginBackup->setGeometry(41, 372, 180, 52);
beginBackup->setText(tr("Start Ghost"));
beginBackup->setEnabled(true);
beginBackup->setAutoRepeat(true);
beginBackup->setProperty("isImportant", true);
font.setPixelSize(24);
beginBackup->setFont(font);
connect(beginBackup, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
this->m_uuid = "";
this->m_prefixDestPath = "";
this->m_backupName = "";
SelectRestorePoint * selectDialog = new SelectRestorePoint(this, SelectRestorePoint::SYSTEM, true);
selectDialog->setNeedConfirm(false);
connect(selectDialog, &SelectRestorePoint::selected, this, [=](ParseBackupList::BackupPoint backupPoint){
this->m_uuid = backupPoint.m_uuid;
this->m_backupName = backupPoint.m_backupName;
this->m_iPosition = backupPoint.m_iPosition;
});
if (QDialog::Accepted == selectDialog->exec()) {
this->m_isLocal = true;
this->setCurrentIndex(SELECT_PATH_PAGE);
}
selectDialog->deleteLater();
});
addWidget(first);
}
/**
* @brief “上一步”按钮响应槽
* @param checked
*/
void GhostImage::on_pre_clicked(bool checked)
{
Q_UNUSED(checked)
int index = this->currentIndex() - 1;
if (index >= 0) {
this->setCurrentIndex(index);
}
}
/**
* @brief “开始备份”“下一步”按钮响应槽
* @param checked
*/
void GhostImage::on_next_clicked(bool checked)
{
Q_UNUSED(checked)
int index = this->currentIndex() + 1;
if (index < this->count()) {
this->setCurrentIndex(index);
}
}
/**
* @brief 初始化第二个页面
*/
void GhostImage::initSecondWidget()
{
QWidget *second = new QWidget;
// 纵向布局
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
// 第一行
QHBoxLayout * hlayoutLine1 = new QHBoxLayout;
hlayoutLine1->addSpacing(40);
// 请选择存储位置
MyLabel* labelSelect = new MyLabel(second);
labelSelect->setDeplayText(tr("Please select storage location"));
labelSelect->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QFont font;
font.setBold(true);
font.setPixelSize(18);
labelSelect->setFont(font);
labelSelect->setScaledContents(true);
labelSelect->adjustSize();
hlayoutLine1->addWidget(labelSelect);
hlayoutLine1->setAlignment(Qt::AlignLeft);
vlayout->addLayout(hlayoutLine1);
// 第二行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine2 = new QHBoxLayout;
hlayoutLine2->addSpacing(40);
// 备份路径选择框
QComboBox* comboSelect = new QComboBox(second);
// 添加本地默认路径、移动设备目录
connect(m_udector, &UdiskDetector::udiskListChanged, this, [=](QList<QStorageInfo> diskList) {
comboSelect->clear();
this->m_udiskPaths.clear();
QIcon iconFolder = QIcon::fromTheme("insync-folder", QIcon(":/images/insync-folder.png"));
QString qsLocalDefaultPath = Utils::getSysRootPath() + GHOST_PATH;
qsLocalDefaultPath.replace("//", "/");
this->m_udiskPaths << "";
comboSelect->addItem(iconFolder, tr("local default path : ") + qsLocalDefaultPath);
QString qsPreDevPath(tr("removable devices path : "));
for (QStorageInfo& disk : diskList) {
this->m_udiskPaths << disk.rootPath();
comboSelect->addItem(iconFolder, qsPreDevPath + disk.rootPath() + GHOST_PATH);
}
});
m_udector->getStorageInfo();
hlayoutLine2->addWidget(comboSelect);
hlayoutLine2->addSpacing(40);
vlayout->addLayout(hlayoutLine2);
vlayout->addSpacing(56);
// 第三行
QHBoxLayout * hlayoutLine3 = new QHBoxLayout;
hlayoutLine3->setSpacing(16);
hlayoutLine3->addStretch();
// 上一步按钮
KBorderButton *preStep = new KBorderButton(second);
preStep->setText(tr("Back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &KBorderButton::clicked, preStep, &KBorderButton::clearFocus);
connect(preStep, &KBorderButton::clicked, this, &GhostImage::on_pre_clicked);
hlayoutLine3->addWidget(preStep);
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(second);
nextStep->setText(tr("Next"));
nextStep->setEnabled(true);
nextStep->setAutoRepeat(true);
nextStep->setProperty("isImportant", true);
connect(nextStep, &MyPushButton::clicked, this, [=](bool checked) {
// 备份路径选择索引
int index = comboSelect->currentIndex();
// 第一个选项是本地系统备份
this->m_isLocal = GlobelBackupInfo::inst().hasBackupPartition() && (index == 0);
this->m_prefixDestPath = this->m_udiskPaths.at(index);
this->on_next_clicked(checked);
emit this->startCheckEnv();
});
hlayoutLine3->addWidget(nextStep);
hlayoutLine3->addStretch();
hlayoutLine3->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutLine3);
vlayout->addStretch();
second->setLayout(vlayout);
addWidget(second);
}
/**
* @brief 初始化第三个页面
*/
void GhostImage::initThirdWidget()
{
QWidget *third = new QWidget;
// 流程进度提示栏
CircleLable *one = new CircleLable("1", third, 24, QColor(COLOR_BLUE));
LineLabel *line1 = new LineLabel(third, QColor(COLOR_BLUE));
CircleLable *two = new CircleLable("2", third);
LineLabel *line2 = new LineLabel(third, QColor(COLOR_GRAY));
CircleLable *three = new CircleLable("3", third);
QHBoxLayout *layoutLine1 = new QHBoxLayout;
layoutLine1->addSpacing(128);
layoutLine1->addWidget(one);
layoutLine1->addWidget(line1);
layoutLine1->addWidget(two);
layoutLine1->addWidget(line2);
layoutLine1->addWidget(three);
layoutLine1->addSpacing(128);
MyLabel *label1 = new MyLabel(tr("checking"), third);
label1->setIsOriginal(true);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setFixedWidth(164);
MyLabel *label2 = new MyLabel(tr("ghosting"), third);
label2->setIsOriginal(true);
label2->setEnabled(false);
label2->setFixedWidth(164);
MyLabel *label3 = new MyLabel(tr("finished"), third);
label3->setIsOriginal(true);
label3->setEnabled(false);
label3->setFixedWidth(164);
QHBoxLayout *layoutLine2 = new QHBoxLayout;
layoutLine2->addSpacing(54);
layoutLine2->addWidget(label1);
layoutLine2->addStretch();
layoutLine2->addWidget(label2);
layoutLine2->addStretch();
layoutLine2->addWidget(label3);
layoutLine2->addSpacing(54);
// ------------ 中部布局begin-------------
QWidget *centerFont = new QWidget(third);
centerFont->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QVBoxLayout *vlayoutCenterFont = new QVBoxLayout;
// 第一行
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
// 检测等待图标
QLabel *loadingGif = new QLabel(centerFont);
loadingGif->setFixedSize(24,24);
// 环境检测等待动画
QMovie *movie = new QMovie(":/images/loading.gif", QByteArray(), centerFont);
loadingGif->setMovie(movie);
hlayoutCenterFont1->addWidget(loadingGif);
// 检测结果对错图标
PixmapLabel *resultLogo = new PixmapLabel(centerFont);
resultLogo->setFixedSize(24,24);
hlayoutCenterFont1->addWidget(resultLogo);
// 检测中大标题
MyLabel *bigTitle = new MyLabel(centerFont);
bigTitle->setFontSize(24);
bigTitle->setIsOriginal(true);
bigTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont1->addWidget(bigTitle);
hlayoutCenterFont1->setAlignment(Qt::AlignLeft);
vlayoutCenterFont->addLayout(hlayoutCenterFont1);
vlayoutCenterFont->addSpacing(16);
// 第二行
QHBoxLayout *hlayoutCenterFont2 = new QHBoxLayout;
hlayoutCenterFont2->addSpacing(10);
// 检测中的记录黑点1和文字1
CircleLable *dot1 = new CircleLable(QString(""), centerFont, 6, Qt::black);
hlayoutCenterFont2->addWidget(dot1);
hlayoutCenterFont2->addSpacing(5);
MyLabel *labelCheck1 = new MyLabel(centerFont);
labelCheck1->setIsOriginal(true);
labelCheck1->setWordWrap(true);
labelCheck1->adjustSize();
labelCheck1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont2->addWidget(labelCheck1);
hlayoutCenterFont2->setAlignment(Qt::AlignLeft);
vlayoutCenterFont->addLayout(hlayoutCenterFont2);
// 第三行
QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout;
hlayoutCenterFont3->addSpacing(10);
// 检测中的记录黑点2和文字2
CircleLable *dot2 = new CircleLable(QString(""), centerFont, 6, Qt::black);
hlayoutCenterFont3->addWidget(dot2);
hlayoutCenterFont3->addSpacing(5);
MyLabel *labelCheck2 = new MyLabel(centerFont);
labelCheck2->setIsOriginal(true);
labelCheck2->setWordWrap(true);
labelCheck2->adjustSize();
labelCheck1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont3->addWidget(labelCheck2);
hlayoutCenterFont3->setAlignment(Qt::AlignLeft);
vlayoutCenterFont->addLayout(hlayoutCenterFont3);
// 第四行
vlayoutCenterFont->addSpacing(56);
// 第五行
QHBoxLayout *hlayoutCenterFont5 = new QHBoxLayout;
hlayoutCenterFont5->setSpacing(16);
hlayoutCenterFont5->addStretch();
// 上一步按钮
KBorderButton *preStep = new KBorderButton(centerFont);
preStep->setText(tr("Back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &KBorderButton::clicked, preStep, &KBorderButton::clearFocus);
connect(preStep, &KBorderButton::clicked, this, &GhostImage::on_pre_clicked);
hlayoutCenterFont5->addWidget(preStep);
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(centerFont);
nextStep->setText(tr("Next"));
nextStep->setEnabled(true);
nextStep->setAutoRepeat(true);
nextStep->setProperty("isImportant", true);
connect(nextStep, &MyPushButton::clicked, this, [=](bool checked) {
this->on_next_clicked(checked);
emit this->startGhost();
});
hlayoutCenterFont5->addWidget(nextStep);
// 重新检测按钮
MyPushButton *recheck = new MyPushButton(centerFont);
recheck->setText(tr("Recheck"));
recheck->setEnabled(true);
recheck->setAutoRepeat(true);
recheck->setProperty("isImportant", true);
hlayoutCenterFont5->addWidget(recheck);
hlayoutCenterFont5->addStretch();
hlayoutCenterFont5->setAlignment(Qt::AlignCenter);
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
centerFont->setLayout(vlayoutCenterFont);
QHBoxLayout *layoutLine3 = new QHBoxLayout;
layoutLine3->addStretch();
layoutLine3->addSpacing(80);
layoutLine3->addWidget(centerFont);
layoutLine3->addSpacing(80);
layoutLine3->addStretch();
layoutLine3->setAlignment(Qt::AlignCenter);
// ------------ 中部布局end-------------
// 布局
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
vlayout->addLayout(layoutLine1);
vlayout->addLayout(layoutLine2);
vlayout->addSpacing(80);
vlayout->addLayout(layoutLine3);
vlayout->addStretch();
third->setLayout(vlayout);
// 开始检测
connect(this, &GhostImage::startCheckEnv, this, [=]() {
this->m_ghostImageState = GhostImageState::CHECKING;
loadingGif->setVisible(true);
movie->start();
resultLogo->setVisible(false);
// 环境检测中,请等待
bigTitle->setDeplayText(tr("Checking, wait a moment ..."));
dot1->setBackgroundColor(Qt::black);
dot2->setBackgroundColor(Qt::black);
labelCheck1->setFontColor(Qt::black);
labelCheck2->setFontColor(Qt::black);
// 检测是否具备制作Ghost镜像条件
labelCheck1->setDeplayText(tr("Check whether the conditions for creating an ghost image are met"));
// 制作Ghost镜像期间不要做其它操作以防数据丢失
labelCheck2->setDeplayText(tr("Do not perform other operations to avoid data loss"));
preStep->setVisible(false);
nextStep->setVisible(false);
recheck->setVisible(false);
this->on_checkEnv_start();
emit GlobelBackupInfo::inst().getGlobalSignals()->widthChanged();
});
// 检测结果
connect(this, &GhostImage::checkEnvResult, this, [=](bool result, const QString &errMsg, const QString &errTip) {
loadingGif->setVisible(false);
movie->stop();
if (result) {
resultLogo->setThemeIconSchema("ukui-dialog-success", ":/symbos/ukui-dialog-success");
resultLogo->setVisible(true);
// 检测成功
bigTitle->setDeplayText(tr("Check success"));
// 存储空间充足
labelCheck1->setDeplayText(tr("The storage space is enough"));
dot2->setBackgroundColor(COLOR_YELLOW);
labelCheck2->setFontColor(COLOR_YELLOW);
labelCheck2->setFontWordWrap(true);
// 请确保电脑已连接电源或电量超过60%
labelCheck2->setDeplayText(tr("Make sure the computer is plugged in or the battery level is above 60%"));
dot1->setVisible(true);
dot2->setVisible(true);
labelCheck1->setVisible(true);
labelCheck2->setVisible(true);
nextStep->setVisible(true);
recheck->setVisible(false);
} else {
resultLogo->setThemeIconSchema("dialog-error", ":/symbos/dialog-error");
resultLogo->setVisible(true);
// 环境校验失败
bigTitle->setDeplayText(tr("Check failure"));
labelCheck1->setDeplayText(errMsg);
labelCheck2->setDeplayText(errTip);
if (errMsg.isEmpty()) {
dot1->setVisible(false);
labelCheck1->setVisible(false);
} else {
dot1->setVisible(true);
labelCheck1->setVisible(true);
}
if (errTip.isEmpty()) {
dot2->setVisible(false);
labelCheck2->setVisible(false);
} else {
dot2->setVisible(true);
labelCheck2->setVisible(true);
}
recheck->setVisible(true);
nextStep->setVisible(false);
}
preStep->setVisible(true);
emit GlobelBackupInfo::inst().getGlobalSignals()->widthChanged();
});
// 调整中部控件大小
connect(GlobelBackupInfo::inst().getGlobalSignals(), &GlobalSignals::widthChanged, this, [=](){
// 控件bigTitle的宽度
int len_title = 0;
if (bigTitle->isVisible()) {
QFontMetrics fontMetrics(bigTitle->font());
len_title = fontMetrics.width(bigTitle->getOriginalText());
len_title += LEN_TITLE_PRE;
}
// 控件labelError1的宽度
int len_labelError1 = 0;
if (labelCheck1->isVisible()) {
QFontMetrics fontMetrics(labelCheck1->font());
len_labelError1 = fontMetrics.width(labelCheck1->getOriginalText());
len_labelError1 += LEN_DOT_PRE;
}
// 控件labelError2的宽度
int len_labelError2 = 0;
if (labelCheck2->isVisible()) {
QFontMetrics fontMetrics(labelCheck2->font());
len_labelError2 = fontMetrics.width(labelCheck2->getOriginalText());
len_labelError2 += LEN_DOT_PRE;
}
int len_max = len_title > len_labelError1 ? len_title : len_labelError1;
len_max = len_max > len_labelError2 ? len_max : len_labelError2;
if (len_max >= this->width())
len_max = this->width();
centerFont->setFixedWidth(len_max);
});
// 重新检查
connect(recheck, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
emit this->startCheckEnv();
});
addWidget(third);
}
/**
* @brief 开始进行环境检测
*/
void GhostImage::on_checkEnv_start()
{
GlobelBackupInfo::inst().setIsBusy(true);
m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this);
connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &GhostImage::on_checkEnv_end);
// 是否已存在备份、还原等操作
bool isActive = false;
if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){
on_checkEnv_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING));
return;
}
BackupWrapper backupWrapper;
backupWrapper.m_uuid = m_uuid;
backupWrapper.m_type = BackupType::GHOST_IMAGE;
backupWrapper.m_backupName = createGhostImageName(m_backupName);
QString prePath = Utils::getSysRootPath() + "/media";
prePath = prePath.replace("//", "/");
if (m_iPosition != BackupPosition::CUSTOMIZE && m_prefixDestPath.startsWith(prePath)) {
backupWrapper.m_iPosition = BackupPosition::UDISK;
} else {
backupWrapper.m_iPosition = m_iPosition;
}
backupWrapper.m_prefixDestPath = m_prefixDestPath;
backupWrapper.m_frontUid = getuid();
backupWrapper.m_frontUserName = qgetenv("USER");
backupWrapper.m_gid = getgid();
m_pInterface->checkEnv(backupWrapper);
}
/**
* @brief 环境检测结束
* @param result, 环境校验结果
*/
void GhostImage::on_checkEnv_end(int result)
{
m_ghostImageState = GhostImageState::IDEL;
bool bRst = false;
QString errMsg, errTip;
switch (result) {
case int(BackupResult::LOCK_PROGRAM_FAIL):
// 程序锁定失败,请重试
errMsg = tr("Program lock failed, please retry");
// 可能有其它备份/还原等任务在执行
errTip = tr("There may be other backups or restores being performed");
break;
case int(BackupResult::NO_FOUND_DEALCLASS):
// 不支持的任务类型
errMsg = tr("Unsupported task type");
// 没有找到相应的处理逻辑
errTip = tr("No processing logic was found in the service");
break;
case int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL):
// 备份分区挂载失败
errMsg = tr("Failed to mount the backup partition");
// 检查是否有备份分区
errTip = tr("Check whether there is a backup partition");
break;
case int(BackupResult::UDISK_FILESYSTEM_TYPE_IS_VFAT):
// 移动设备的文件系统是vfat格式
errMsg = tr("The filesystem of device is vfat format");
// 请换成ext4、ntfs等格式
errTip = tr("Please change filesystem format to ext3、ext4 or ntfs");
break;
case int(BackupResult::UDISK_FILESYSTEM_IS_READONLY):
// 移动设备是只读的
errMsg = tr("The device is read only");
// 请修改为可读写权限的
errTip = tr("Please chmod to rw");
break;
case int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH):
// 镜像空间不足
errMsg = tr("The storage for ghost is not enough");
// 建议释放空间后重试
errTip = tr("Retry after release space");
break;
case int(BackupResult::BACKUP_CAPACITY_FOR_UDISKIMG_IS_NOT_ENOUGH):
// 没有足够的空间存放临时.kyimg文件
errMsg = tr("There is not enough space for temporary .kyimg file");
// 建议释放空间后重试
errTip = tr("Retry after release space");
break;
case int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING):
// 其它备份还原等操作正在执行
errMsg = tr("Other backup or restore task is being performed");
// 请稍后重试
errTip = tr("Please try again later");
break;
case int(BackupResult::GHOST_CANNOT_FIND_BACKUPPOINT):
case int(BackupResult::GHOST_SRC_DIRECTORY_IS_NOT_EXIST):
// 备份节点已不存在
errMsg = tr("The backup node does not exist");
// 请检查刚刚是否有删除备份点操作
errTip = tr("Check whether the backup point has been deleted");
break;
default:
bRst = true;
break;
}
Utils::wait(2);
emit checkEnvResult(bRst, errMsg, errTip);
GlobelBackupInfo::inst().setIsBusy(false);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &GhostImage::on_checkEnv_end);
delete m_pInterface;
m_pInterface = nullptr;
}
/**
* @brief 创建ghost镜像名称
* @param comment
* @return
*/
QString GhostImage::createGhostImageName(const QString& backupName)
{
QString localHostName = QHostInfo::localHostName();
QRegExp rx = QRegExp("([0-9a-zA-Z_\\-])+");
QString destFile = "ghost";
if (rx.exactMatch(localHostName))
destFile = localHostName;
//使用uname -m获取体系结构
QString result;
Utils::executeCMD("uname -m", result);
QString arch = result.trimmed();
//用comment
QString mycomment = backupName;
mycomment.replace("-", "");
mycomment.replace(":", "");
mycomment.replace(" ", "");
destFile = destFile + "-" + arch + "-" + mycomment + ".kyimg";
return destFile;
}
/**
* @brief 第四个页面
*/
void GhostImage::initForthWidget()
{
QWidget *forth = new QWidget;
// 流程进度提示栏
CircleLable *one = new CircleLable("1", forth, 24, QColor(COLOR_BLUE));
LineLabel *line1 = new LineLabel(forth, QColor(COLOR_BLUE));
CircleLable *two = new CircleLable("2", forth, 24, QColor(COLOR_BLUE));
LineLabel *line2 = new LineLabel(forth, QColor(COLOR_BLUE));
CircleLable *three = new CircleLable("3", forth);
QHBoxLayout *layoutLine1 = new QHBoxLayout;
layoutLine1->addSpacing(128);
layoutLine1->addWidget(one);
layoutLine1->addWidget(line1);
layoutLine1->addWidget(two);
layoutLine1->addWidget(line2);
layoutLine1->addWidget(three);
layoutLine1->addSpacing(128);
MyLabel *label1 = new MyLabel(tr("checking"), forth);
label1->setIsOriginal(true);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setFixedWidth(164);
MyLabel *label2 = new MyLabel(tr("ghosting"), forth);
label2->setIsOriginal(true);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setFixedWidth(164);
MyLabel *label3 = new MyLabel(tr("finished"), forth);
label3->setIsOriginal(true);
label3->setEnabled(false);
label3->setFixedWidth(164);
QHBoxLayout *layoutLine2 = new QHBoxLayout;
layoutLine2->addSpacing(54);
layoutLine2->addWidget(label1);
layoutLine2->addStretch();
layoutLine2->addWidget(label2);
layoutLine2->addStretch();
layoutLine2->addWidget(label3);
layoutLine2->addSpacing(54);
// ------------ 中部布局begin-------------
// 中部第一行
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
// 检测等待图标
QLabel *loadingGif = new QLabel(forth);
// 环境检测等待动画
QMovie *movie = new QMovie(":/images/loading.gif", QByteArray(), forth);
loadingGif->setMovie(movie);
loadingGif->setFixedSize(24,24);
loadingGif->setVisible(false);
// 进度条
RingsProgressbar *progressBar = new RingsProgressbar(forth);
progressBar->setFixedSize(100, 100);
hlayoutCenterFont1->addStretch();
hlayoutCenterFont1->addWidget(loadingGif);
hlayoutCenterFont1->addWidget(progressBar);
hlayoutCenterFont1->addStretch();
hlayoutCenterFont1->setAlignment(Qt::AlignCenter);
// 第二行
QHBoxLayout *hlayoutCenterFont2 = new QHBoxLayout;
// 提醒
MyLabel *labelTip = new MyLabel(forth);
labelTip->setAlignment(Qt::AlignCenter);
labelTip->setIsOriginal(true);
labelTip->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont2->addStretch();
hlayoutCenterFont2->addWidget(labelTip);
hlayoutCenterFont2->addStretch();
hlayoutCenterFont2->setAlignment(Qt::AlignCenter);
// 第二行
QHBoxLayout *hlayoutCenterFont2_1 = new QHBoxLayout;
// 备份过程提醒信息
MyLabel *labelTip_1 = new MyLabel(forth);
labelTip_1->setAlignment(Qt::AlignCenter);
labelTip_1->setIsOriginal(true);
labelTip_1->setFontWordWrap(true);
labelTip_1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
labelTip_1->setDeplayText("");
hlayoutCenterFont2_1->addStretch();
hlayoutCenterFont2_1->addWidget(labelTip_1);
hlayoutCenterFont2_1->addStretch();
hlayoutCenterFont2_1->setAlignment(Qt::AlignCenter);
// 第三行
QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout;
// 取消按钮
MyPushButton *cancel = new MyPushButton(forth);
cancel->setText(tr("Cancel"));
cancel->setEnabled(true);
cancel->setAutoRepeat(true);
cancel->setProperty("isImportant", true);
hlayoutCenterFont3->addStretch();
hlayoutCenterFont3->addWidget(cancel);
hlayoutCenterFont3->addStretch();
hlayoutCenterFont3->setAlignment(Qt::AlignCenter);
// ------------ 中部布局end-------------
// 布局
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
vlayout->addLayout(layoutLine1);
vlayout->addLayout(layoutLine2);
vlayout->addSpacing(80);
vlayout->addLayout(hlayoutCenterFont1);
vlayout->addSpacing(16);
vlayout->addLayout(hlayoutCenterFont2);
vlayout->addLayout(hlayoutCenterFont2_1);
vlayout->addSpacing(56);
vlayout->addLayout(hlayoutCenterFont3);
vlayout->addStretch();
forth->setLayout(vlayout);
// 开始制作ghost镜像
connect(this, &GhostImage::startGhost, this, [=] {
progressBar->setPersent(0);
movie->start();
// 不要使用电脑,以防数据丢失
labelTip->setDeplayText(tr("Do not use computer in case of data loss"));
labelTip_1->setVisible(false);
labelTip_1->setDeplayText("");
cancel->setEnabled(true);
// 开始备份
this->on_ghost_start();
});
connect(this, &GhostImage::backupWarnning, labelTip_1, [=](const QString& msg) {
labelTip_1->setVisible(true);
labelTip_1->setDeplayText(msg);
});
// 进度
connect(this, &GhostImage::progress, this, [=](int state, int rate) {
Q_UNUSED(state)
progressBar->setPersent(rate);
});
// 取消备份
connect(cancel, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
// 确定取消当前操作?
if (!MessageBoxUtils::QMESSAGE_BOX_WARNING_CANCEL(this, QObject::tr("Information"), QObject::tr("Are you sure to cancel the operation"), QObject::tr("Ok"), QObject::tr("Cancel"))) {
return ;
}
cancel->setEnabled(false);
if (m_pInterface)
m_pInterface->cancel();
});
addWidget(forth);
}
/**
* @brief 开始进行系统备份
*/
void GhostImage::on_ghost_start()
{
GlobelBackupInfo::inst().setIsBusy(true);
m_ghostImageState = GhostImageState::GHOSTING;
m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this);
connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &GhostImage::on_checkGhost_end);
connect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &GhostImage::progress);
connect(m_pInterface, &ComKylinBackupManagerInterface::sendGhostBackupResult, this, &GhostImage::on_ghost_end);
// 是否已存在备份、还原等操作
bool isActive = false;
if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){
on_checkGhost_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING));
return;
}
BackupWrapper backupWrapper;
backupWrapper.m_uuid = m_uuid;
backupWrapper.m_type = BackupType::GHOST_IMAGE;
backupWrapper.m_backupName = createGhostImageName(m_backupName);
QString prePath = Utils::getSysRootPath() + "/media";
prePath = prePath.replace("//", "/");
if (m_iPosition != BackupPosition::CUSTOMIZE && m_prefixDestPath.startsWith(prePath)) {
backupWrapper.m_iPosition = BackupPosition::UDISK;
} else {
backupWrapper.m_iPosition = m_iPosition;
}
backupWrapper.m_prefixDestPath = m_prefixDestPath;
backupWrapper.m_frontUid = getuid();
backupWrapper.m_frontUserName = qgetenv("USER");
backupWrapper.m_gid = getgid();
m_pInterface->ghostBackup(backupWrapper);
}
/**
* @brief 系统备份校验结果处理
* @param result
*/
void GhostImage::on_checkGhost_end(int result)
{
bool bRst = false;
QString errMsg, errTip;
switch (result) {
case int(BackupResult::LOCK_PROGRAM_FAIL):
// 程序锁定失败,请重试
errMsg = tr("Program lock failed, please retry");
// 可能有其它备份/还原等任务在执行
errTip = tr("There may be other backups or restores being performed");
break;
case int(BackupResult::NO_FOUND_DEALCLASS):
// 不支持的任务类型
errMsg = tr("Unsupported task type");
// 没有找到相应的处理逻辑
errTip = tr("No processing logic was found in the service");
break;
case int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL):
// 备份分区挂载失败
errMsg = tr("Failed to mount the backup partition");
// 检查是否有备份分区
errTip = tr("Check whether there is a backup partition");
break;
case int(BackupResult::UDISK_FILESYSTEM_TYPE_IS_VFAT):
// 移动设备的文件系统是vfat格式
errMsg = tr("The filesystem of device is vfat format");
// 请换成ext4、ntfs等格式
errTip = tr("Please change filesystem format to ext3、ext4 or ntfs");
break;
case int(BackupResult::UDISK_FILESYSTEM_IS_READONLY):
// 移动设备是只读的
errMsg = tr("The device is read only");
// 请修改为可读写权限的
errTip = tr("Please chmod to rw");
break;
case int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH):
// 镜像空间不足
errMsg = tr("The storage for ghost is not enough");
// 建议释放空间后重试
errTip = tr("Retry after release space");
break;
case int(BackupResult::BACKUP_CAPACITY_FOR_UDISKIMG_IS_NOT_ENOUGH):
// 没有足够的空间存放临时.kyimg文件
errMsg = tr("There is not enough space for temporary .kyimg file");
// 建议释放空间后重试
errTip = tr("Retry after release space");
break;
case int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING):
// 其它备份还原等操作正在执行
errMsg = tr("Other backup or restore task is being performed");
// 请稍后重试
errTip = tr("Please try again later");
break;
case int(BackupResult::GHOST_CANNOT_FIND_BACKUPPOINT):
case int(BackupResult::GHOST_SRC_DIRECTORY_IS_NOT_EXIST):
// 备份节点已不存在
errMsg = tr("The backup node does not exist");
// 请检查刚刚是否有删除备份点操作
errTip = tr("Check whether the backup point has been deleted");
break;
case int(BackupResult::GHOST_START_SUCCESS):
// 正压缩数据到本地磁盘,请耐心等待...
errTip = tr("The data is being compressed to the local disk, please wait patiently...");
emit this->backupWarnning(errTip);
return;
case int(BackupResult::MKSQUASHFS_DO_SUCCESS):
// 正在传输image文件到移动设备即将完成...
errTip = tr("Transferring image file to mobile device, about to be completed...");
emit this->backupWarnning(errTip);
return;
case int(BackupResult::CANCEL_SUCCESS):
// 已经取消本次镜像制作
errMsg = tr("The image creation had been canceled");
// 如需要可重新发起镜像制作
errTip = tr("Re-initiate the image creation if necessary");
break;
default:
bRst = true;
break;
}
if (!bRst) {
GlobelBackupInfo::inst().setIsBusy(false);
m_ghostImageState = GhostImageState::IDEL;
this->on_next_clicked(true);
emit this->checkGhostResult(bRst, errMsg, errTip);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &GhostImage::on_checkEnv_end);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &GhostImage::progress);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendGhostBackupResult, this, &GhostImage::on_ghost_end);
delete m_pInterface;
m_pInterface = nullptr;
}
}
/**
* @brief 系统备份结束
* @param result-false 失败; true 成功
*/
void GhostImage::on_ghost_end(bool result)
{
m_ghostImageState = GhostImageState::IDEL;
this->on_next_clicked(true);
if (result) {
emit checkGhostResult(result);
} else {
// 备份过程中出现错误
QString errMsg = tr("An error occurred during make ghost image");
// 错误信息参考日志文件:/var/log/backup.log
QString errTip = tr("Error messages refer to log file : /var/log/backup.log");
emit checkGhostResult(result, errMsg, errTip);
}
GlobelBackupInfo::inst().setIsBusy(false);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &GhostImage::on_checkEnv_end);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &GhostImage::progress);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendGhostBackupResult, this, &GhostImage::on_ghost_end);
delete m_pInterface;
m_pInterface = nullptr;
}
/**
* @brief 最后备份结果界面
*/
void GhostImage::initLastWidget()
{
QWidget *last = new QWidget;
// 流程进度提示栏
CircleLable *one = new CircleLable("1", last, 24, QColor(COLOR_BLUE));
LineLabel *line1 = new LineLabel(last, QColor(COLOR_BLUE));
CircleLable *two = new CircleLable("2", last, 24, QColor(COLOR_BLUE));
LineLabel *line2 = new LineLabel(last, QColor(COLOR_BLUE));
CircleLable *three = new CircleLable("3", last, 24, QColor(COLOR_BLUE));
QHBoxLayout *layoutLine1 = new QHBoxLayout;
layoutLine1->addSpacing(128);
layoutLine1->addWidget(one);
layoutLine1->addWidget(line1);
layoutLine1->addWidget(two);
layoutLine1->addWidget(line2);
layoutLine1->addWidget(three);
layoutLine1->addSpacing(128);
MyLabel *label1 = new MyLabel(tr("checking"), last);
label1->setIsOriginal(true);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setFixedWidth(164);
MyLabel *label2 = new MyLabel(tr("ghosting"), last);
label2->setIsOriginal(true);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setFixedWidth(164);
MyLabel *label3 = new MyLabel(tr("finished"), last);
label3->setIsOriginal(true);
label3->setFontColor(QColor(COLOR_BLUE));
label3->setFixedWidth(164);
QHBoxLayout *layoutLine2 = new QHBoxLayout;
layoutLine2->addSpacing(54);
layoutLine2->addWidget(label1);
layoutLine2->addStretch();
layoutLine2->addWidget(label2);
layoutLine2->addStretch();
layoutLine2->addWidget(label3);
layoutLine2->addSpacing(54);
//------------ 中部布局begin-------------
QWidget *centerFont = new QWidget(last);
centerFont->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QVBoxLayout *vlayoutCenterFont = new QVBoxLayout;
// 第一行
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
// 备份结果对错图标
PixmapLabel *resultLogo = new PixmapLabel(centerFont);
resultLogo->setFixedSize(24,24);
hlayoutCenterFont1->addWidget(resultLogo);
// 检测中大标题
MyLabel *bigTitle = new MyLabel(centerFont);
bigTitle->setFontSize(24);
bigTitle->setIsOriginal(true);
bigTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont1->addWidget(bigTitle);
// hlayoutCenterFont1->setAlignment(Qt::AlignLeft);
vlayoutCenterFont->addLayout(hlayoutCenterFont1);
vlayoutCenterFont->addSpacing(16);
// 第二行
QHBoxLayout *hlayoutCenterFont2 = new QHBoxLayout;
hlayoutCenterFont2->addSpacing(10);
// 备份结果错误提示:黑点和文字
CircleLable *dot1 = new CircleLable(QString(""), centerFont, 6, Qt::black);
hlayoutCenterFont2->addWidget(dot1);
hlayoutCenterFont2->addSpacing(5);
MyLabel *labelError1 = new MyLabel(centerFont);
labelError1->setIsOriginal(true);
labelError1->setWordWrap(true);
labelError1->adjustSize();
labelError1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont2->addWidget(labelError1);
// hlayoutCenterFont2->setAlignment(Qt::AlignLeft);
vlayoutCenterFont->addLayout(hlayoutCenterFont2);
// 第三行
QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout;
hlayoutCenterFont3->addSpacing(10);
// 检测中的记录黑点2和文字2
CircleLable *dot2 = new CircleLable(QString(""), centerFont, 6, Qt::black);
hlayoutCenterFont3->addWidget(dot2);
hlayoutCenterFont3->addSpacing(5);
MyLabel *labelError2 = new MyLabel(centerFont);
labelError2->setIsOriginal(true);
labelError2->setWordWrap(true);
labelError2->adjustSize();
labelError2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont3->addWidget(labelError2);
hlayoutCenterFont3->setAlignment(Qt::AlignLeft);
vlayoutCenterFont->addLayout(hlayoutCenterFont3);
// 第四行
vlayoutCenterFont->addSpacing(56);
// 第五行
QHBoxLayout *hlayoutCenterFont5 = new QHBoxLayout;
hlayoutCenterFont5->setSpacing(16);
hlayoutCenterFont5->addStretch();
// 返回首页
MyPushButton *homePage = new MyPushButton(centerFont);
homePage->setText(tr("Home Page"));
homePage->setEnabled(true);
homePage->setAutoRepeat(true);
homePage->setProperty("isImportant", true);
hlayoutCenterFont5->addWidget(homePage);
// 再试一次
KBorderButton *retry = new KBorderButton(centerFont);
retry->setText(tr("Retry"));
retry->setEnabled(true);
retry->setAutoRepeat(true);
hlayoutCenterFont5->addWidget(retry);
hlayoutCenterFont5->addStretch();
hlayoutCenterFont5->setAlignment(Qt::AlignCenter);
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
centerFont->setLayout(vlayoutCenterFont);
QHBoxLayout *layoutLine3 = new QHBoxLayout;
layoutLine3->addStretch();
layoutLine3->addSpacing(80);
layoutLine3->addWidget(centerFont);
layoutLine3->addSpacing(80);
layoutLine3->addStretch();
//------------ 中部布局end-------------
// 布局
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
vlayout->addLayout(layoutLine1);
vlayout->addLayout(layoutLine2);
vlayout->addSpacing(80);
vlayout->addLayout(layoutLine3);
vlayout->addStretch();
last->setLayout(vlayout);
// 检测结果
connect(this, &GhostImage::checkGhostResult, this, [=](bool result, const QString &errMsg, const QString &errTip) {
if (result) {
resultLogo->setThemeIconSchema("ukui-dialog-success", ":/symbos/ukui-dialog-success");
resultLogo->setVisible(true);
// 镜像制作成功
bigTitle->setDeplayText(tr("Ghost image creation is successful"));
QFontMetrics fontMetrics(bigTitle->font());
int fontSize = fontMetrics.width(bigTitle->getOriginalText());
bigTitle->setFixedWidth(fontSize);
hlayoutCenterFont1->setAlignment(Qt::AlignCenter);
QString imgPath = m_prefixDestPath + GHOST_PATH;
imgPath.replace("//", "/");
labelError1->setDeplayText(tr("You can view it in the directory : %1").arg(imgPath));
dot1->setVisible(false);
dot2->setVisible(false);
labelError1->setVisible(true);
labelError2->setVisible(false);
labelError1->setAlignment(Qt::AlignCenter);
hlayoutCenterFont2->setAlignment(Qt::AlignCenter);
retry->setVisible(false);
homePage->setVisible(true);
} else {
resultLogo->setThemeIconSchema("dialog-error", ":/symbos/dialog-error");
resultLogo->setVisible(true);
// 镜像制作失败
bigTitle->setDeplayText(tr("Ghost image creation is failed"));
bigTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont1->setAlignment(Qt::AlignLeft);
dot1->setVisible(true);
dot2->setVisible(true);
labelError1->setVisible(true);
labelError2->setVisible(true);
labelError1->setDeplayText(errMsg);
labelError2->setDeplayText(errTip);
labelError1->setAlignment(Qt::AlignLeft);
hlayoutCenterFont2->setAlignment(Qt::AlignLeft);
retry->setVisible(true);
homePage->setVisible(true);
}
emit GlobelBackupInfo::inst().getGlobalSignals()->widthChanged();
});
// 调整中部控件大小
connect(GlobelBackupInfo::inst().getGlobalSignals(), &GlobalSignals::widthChanged, this, [=](){
// 控件bigTitle的宽度
int len_title = 0;
if (bigTitle->isVisible()) {
QFontMetrics fontMetrics(bigTitle->font());
len_title = fontMetrics.width(bigTitle->getOriginalText());
len_title += LEN_TITLE_PRE;
}
// 控件labelError1的宽度
int len_labelError1 = 0;
if (labelError1->isVisible()) {
QFontMetrics fontMetrics(labelError1->font());
len_labelError1 = fontMetrics.width(labelError1->getOriginalText());
len_labelError1 += LEN_DOT_PRE;
}
// 控件labelError2的宽度
int len_labelError2 = 0;
if (labelError2->isVisible()) {
QFontMetrics fontMetrics(labelError2->font());
len_labelError2 = fontMetrics.width(labelError2->getOriginalText());
len_labelError2 += LEN_DOT_PRE;
}
int len_max = len_title > len_labelError1 ? len_title : len_labelError1;
len_max = len_max > len_labelError2 ? len_max : len_labelError2;
if (len_max >= this->width())
len_max = this->width();
centerFont->setFixedWidth(len_max);
});
// 再试一次
connect(retry, &KBorderButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
retry->clearFocus();
this->setCurrentIndex(GhostImagePage::GHOSTING_PAGE);
emit this->startGhost();
});
// 返回首页
connect(homePage, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
this->setCurrentIndex(GhostImagePage::HOME_PAGE);
});
addWidget(last);
}