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

2059 lines
79 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 "databackup.h"
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
#include <QMovie>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <unistd.h>
#include "../component/backuppositionselectdialog.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 "../component/pixmapbutton.h"
#include "../component/inputvalidator.h"
#include "../../common/utils.h"
#include "../globalbackupinfo.h"
#include "managebackuppointlist.h"
#include "selectrestorepoint.h"
#include "messageboxutils.h"
#include "../gsettingswrapper.h"
#include "kwidget.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
DataBackup::DataBackup(QWidget *parent /*= nullptr*/) :
QStackedWidget(parent),
m_udector(new UdiskDetector()),
m_isLock(false),
m_isLocal(true),
m_DataBackupState(DataBackupState::IDEL),
m_pInterface(nullptr)
{
// 界面手写代码创建,作为练手
initFirstWidget();
initSecondWidget();
initSecondWidget_inc();
initThirdWidget();
initForthWidget();
initFifthWidget();
initLastWidget();
}
DataBackup::~DataBackup()
{
delete m_udector;
m_udector = nullptr;
delete m_pInterface;
m_pInterface = nullptr;
}
/**
* @brief 初始化第一个页面
*/
void DataBackup::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);
// 图片
PixmapLabel *imageBackup_firstPage = new PixmapLabel(center);
imageBackup_firstPage->setGeometry(421, 120, 300, 326);
imageBackup_firstPage->setScaledContents(true);
imageBackup_firstPage->setLightAndDarkPixmap(":/images/data_backup.png", ":/images/data_backup_dark.png");
// 系统备份大字提示
MyLabel *labelBackup_firstPage = new MyLabel(center);
labelBackup_firstPage->setDeplayText(tr("Data Backup"));
labelBackup_firstPage->setFixedWidth(500);
labelBackup_firstPage->setFixedHeight(48);
labelBackup_firstPage->move(41, 120);
// 默认水平左对齐,上下居中对齐;故不需要设置
// labelBackup_firstPage->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
// labelBackup_firstPage->setText(tr("System Backup"));
QFont font;
font.setBold(true);
font.setPixelSize(36);
labelBackup_firstPage->setFont(font);
// labelBackup_firstPage->setAttribute(Qt::WA_TranslucentBackground);
labelBackup_firstPage->setScaledContents(true);
labelBackup_firstPage->adjustSize();
// 数据备份说明
MyLabel *labelNote_firstPage = new MyLabel(center);
labelNote_firstPage->setFixedWidth(700);
labelNote_firstPage->setFixedHeight(24);
labelNote_firstPage->move(41, 180);
if (Utils::isHuawei990())
labelNote_firstPage->setDeplayText(tr("Only files in the /home, /root, and /data directories can be backed up"));
else
labelNote_firstPage->setDeplayText(tr("Only files in the /home, /root, and /data/usershare directories can be backed up"));
font.setBold(false);
font.setPixelSize(18);
labelNote_firstPage->setFont(font);
labelNote_firstPage->setScaledContents(true);
labelNote_firstPage->adjustSize();
// 多点还原
MyIconLabel *iconMultiBackup_firstPage = new MyIconLabel(center);
iconMultiBackup_firstPage->setGeometry(41, 244, 210, 36);
iconMultiBackup_firstPage->setThemeIcon("ukui-multipoint-symbolic", ":/symbos/ukui-multipoint-symbolic");
iconMultiBackup_firstPage->setDesplayText(tr("Multi-Spot"));
iconMultiBackup_firstPage->setEnabled(false);
// 安全
MyIconLabel *iconSecurity_firstPage = new MyIconLabel(center);
iconSecurity_firstPage->setGeometry(231, 244, 180, 36);
iconSecurity_firstPage->setThemeIcon("ukui-bf-security-symbolic", ":/symbos/ukui-bf-security-symbolic");
iconSecurity_firstPage->setDesplayText(tr("Security"));
iconSecurity_firstPage->setEnabled(false);
// 防止数据丢失
MyIconLabel *iconDataLoss_firstPage = new MyIconLabel(center);
iconDataLoss_firstPage->setGeometry(41, 296, 210, 36);
iconDataLoss_firstPage->setThemeIcon("ukui-bf-dataloss-symbolic", ":/symbos/ukui-bf-dataloss-symbolic");
iconDataLoss_firstPage->setDesplayText(tr("Protect Data"));
iconDataLoss_firstPage->setEnabled(false);
// 方便快捷
MyIconLabel *iconSimple_firstPage = new MyIconLabel(center);
iconSimple_firstPage->setGeometry(231, 296, 180, 36);
iconSimple_firstPage->setThemeIcon("ukui-bf-fast-symbolic", ":/symbos/ukui-bf-fast-symbolic");
iconSimple_firstPage->setDesplayText(tr("Convenient"));
iconSimple_firstPage->setEnabled(false);
// 开始备份按钮
MyPushButton *beginBackup = new MyPushButton(center);
beginBackup->setGeometry(41, 372, 180, 52);
beginBackup->setText(tr("Start Backup"));
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 = "";
this->m_isIncrement = false;
this->setCurrentIndex(SELECT_PATH_PAGE);
emit this->reset();
});
// 增量备份按钮
KBorderButton *incrementBackup = new KBorderButton(center);
// MyPushButton *incrementBackup = new MyPushButton(center);
incrementBackup->setFixedHeight(52);
incrementBackup->move(241, 372);
incrementBackup->setText(tr("Update Backup"));
if (incrementBackup->text() == "Update Backup")
incrementBackup->setFixedWidth(220);
else if (incrementBackup->text() == "备份更新")
incrementBackup->setFixedWidth(180);
else {
QFontMetrics fontMetrics(font);
int fontSize = fontMetrics.width(incrementBackup->text());
incrementBackup->setFixedWidth(fontSize * 1.2);
}
incrementBackup->setEnabled(true);
incrementBackup->setAutoRepeat(true);
font.setPixelSize(24);
incrementBackup->setFont(font);
connect(incrementBackup, &KBorderButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
this->m_uuid = "";
this->m_prefixDestPath = "";
this->m_backupName = "";
this->m_backupPaths.clear();
incrementBackup->clearFocus();
SelectRestorePoint * selectDialog = new SelectRestorePoint(this, SelectRestorePoint::DATA);
connect(selectDialog, &SelectRestorePoint::selected, this, [=](ParseBackupList::BackupPoint backupPoint){
this->m_uuid = backupPoint.m_uuid;
this->m_backupName = backupPoint.m_backupName;
this->m_prefixDestPath = backupPoint.m_path;
this->m_isLocal = backupPoint.m_iPosition == BackupPosition::UDISK || backupPoint.m_iPosition == BackupPosition::OTHER ? false : true;
});
if (QDialog::Accepted == selectDialog->exec()) {
this->m_isIncrement = true;
this->setCurrentIndex(INC_SELECT_PATH_PAGE);
emit this->initIncListWidget();
}
selectDialog->deleteLater();
});
// 底部控件布局
QHBoxLayout *bottomHBoxLayout = new QHBoxLayout;
bottomHBoxLayout->addStretch();
// 备份管理
MyPushButton *backupPointManage = new MyPushButton;
backupPointManage->setText(tr("Backup Management >>"));
backupPointManage->setFlat(true);
backupPointManage->setProperty("useButtonPalette", true);
QPalette pal(backupPointManage->palette());
pal.setColor(QPalette::ButtonText, this->palette().highlight().color());
pal.setColor(QPalette::Button, this->palette().base().color());
backupPointManage->setPalette(pal);
bottomHBoxLayout->addWidget(backupPointManage);
bottomHBoxLayout->addSpacing(20);
bottomHBoxLayout->setAlignment(Qt::AlignRight);
vLayout->addStretch();
vLayout->addLayout(bottomHBoxLayout);
vLayout->addSpacing(20);
first->setLayout(vLayout);
connect(backupPointManage, &MyPushButton::clicked, this, [=]() {
ManageBackupPointList backupManager(first, ManageBackupPointList::DATA);
backupManager.exec();
});
connect(GlobelBackupInfo::inst().getGlobalSignals(), &GlobalSignals::styleNameChanged, this, [=](bool isDark) {
Q_UNUSED(isDark)
// 深浅主题切换时,因为调色板已经更换,高亮等颜色已经改变,所以要重新加载图标。
QPalette pal(backupPointManage->palette());
pal.setColor(QPalette::ButtonText, this->palette().highlight().color());
pal.setColor(QPalette::Button, this->palette().base().color());
backupPointManage->setPalette(pal);
});
connect(GlobelBackupInfo::inst().getGlobalSignals(), &GlobalSignals::themeColorChanged, this, [=]() {
// 强调色更换,高亮等颜色已经改变,所以要重新加载图标。
QPalette pal(backupPointManage->palette());
pal.setColor(QPalette::ButtonText, this->palette().highlight().color());
pal.setColor(QPalette::Button, this->palette().base().color());
backupPointManage->setPalette(pal);
});
addWidget(first);
}
/**
* @brief “上一步”按钮响应槽
* @param checked
*/
void DataBackup::on_pre_clicked(bool checked)
{
Q_UNUSED(checked)
int index = this->currentIndex() - 1;
if (index >= 0) {
this->setCurrentIndex(index);
}
}
/**
* @brief “开始备份”“下一步”按钮响应槽
* @param checked
*/
void DataBackup::on_next_clicked(bool checked)
{
Q_UNUSED(checked)
int index = this->currentIndex() + 1;
if (index < this->count()) {
this->setCurrentIndex(index);
}
}
/**
* @brief 初始化第二个页面(新建备份)
*/
void DataBackup::initSecondWidget()
{
QWidget *second = new QWidget;
// 纵向布局
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
// 第一行
QHBoxLayout * hlayoutLine1 = new QHBoxLayout;
hlayoutLine1->addSpacing(40);
// 备份路径选择提示(新建数据备份时显示)
MyLabel* labelPathSelect = new MyLabel(second);
labelPathSelect->setDeplayText(tr("Please select backup position"));
labelPathSelect->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QFont font;
font.setBold(true);
font.setPixelSize(18);
labelPathSelect->setFont(font);
hlayoutLine1->addWidget(labelPathSelect);
hlayoutLine1->setAlignment(Qt::AlignLeft);
vlayout->addLayout(hlayoutLine1);
// 第二行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine2 = new QHBoxLayout;
hlayoutLine2->addSpacing(40);
// 备份路径选择框
QComboBox* comboSelect = new QComboBox(second);
comboSelect->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
KBorderButton *buttonBrowse = new KBorderButton;
buttonBrowse->setText(tr("Browse"));
hlayoutLine2->addWidget(comboSelect);
hlayoutLine2->addWidget(buttonBrowse);
hlayoutLine2->addSpacing(40);
vlayout->addLayout(hlayoutLine2);
vlayout->addSpacing(32);
// 第三行
QHBoxLayout * hlayoutLine3 = new QHBoxLayout;
hlayoutLine3->addSpacing(40);
// label:选择备份数据
MyLabel* labelDataBackup = new MyLabel;
labelDataBackup->setDeplayText(tr("Select backup data"));
labelDataBackup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
labelDataBackup->setFont(font);
hlayoutLine3->addWidget(labelDataBackup);
hlayoutLine3->addSpacing(40);
vlayout->addLayout(hlayoutLine3);
// 第四行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine4 = new QHBoxLayout;
hlayoutLine4->addSpacing(40);
// 所选备份路径编辑框
QLineEdit *editSelect = new QLineEdit;
editSelect->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
editSelect->setMaxLength(255);
editSelect->setTextMargins(0, 0, 62, 0);
QHBoxLayout *searchLayout = new QHBoxLayout(editSelect);
searchLayout->setMargin(5);
searchLayout->setSpacing(0);
// 删除按钮
PixmapLabel *buttonDelete = new PixmapLabel;
buttonDelete->setFixedSize(24, 24);
buttonDelete->setUkuiIconSchema("window-close-symbolic", ":/symbos/window-close-symbolic");
buttonDelete->setToolTip(tr("Clear"));
buttonDelete->setChangeHover();
connect(buttonDelete, &PixmapLabel::clicked, this, [=]() {
editSelect->setText("");
});
// 添加按钮
PixmapLabel *buttonAdd = new PixmapLabel;
buttonAdd->setFixedSize(24, 24);
buttonAdd->setUkuiIconSchema("object-select-symbolic", ":/symbos/object-select-symbolic");
buttonAdd->setToolTip(tr("Add"));
buttonAdd->setChangeHover();
searchLayout->addWidget(buttonDelete);
searchLayout->addWidget(buttonAdd);
searchLayout->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
buttonDelete->setVisible(false);
buttonAdd->setVisible(false);
connect(editSelect, &QLineEdit::textChanged, this, [=](const QString& text) {
if (!text.isEmpty()) {
buttonDelete->setVisible(true);
buttonAdd->setVisible(true);
} else {
buttonDelete->setVisible(false);
buttonAdd->setVisible(false);
}
});
// 平板中放大点
if (GlobelBackupInfo::inst().isTabletMode()) {
editSelect->setTextMargins(0, 0, 70, 0);
buttonDelete->setFixedSize(28, 28);
buttonDelete->setUkuiIconSchema("window-close-symbolic", ":/symbos/window-close-symbolic", QSize(24, 24));
buttonAdd->setFixedSize(28, 28);
buttonAdd->setUkuiIconSchema("object-select-symbolic", ":/symbos/object-select-symbolic", QSize(24, 24));
}
// 选择按钮
MyPushButton *buttonSelect = new MyPushButton;
buttonSelect->setText(tr("Select"));
buttonSelect->setProperty("isImportant", true);
hlayoutLine4->addWidget(editSelect);
hlayoutLine4->addWidget(buttonSelect);
hlayoutLine4->addSpacing(40);
vlayout->addLayout(hlayoutLine4);
// 第五行
vlayout->addSpacing(15);
QHBoxLayout * hlayoutLine5 = new QHBoxLayout;
hlayoutLine5->addSpacing(40);
// 限制目录
QStringList pathLimits;
QList<QUrl> siderUrls;
getPathsLimit(pathLimits, siderUrls);
// 备份列表
QFrame *listFrame = new QFrame;
listFrame->setFrameShape(QFrame::StyledPanel);
listFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QHBoxLayout * hlayoutFrame = new QHBoxLayout;
listFrame->setLayout(hlayoutFrame);
BackupListWidget *listWidget = new BackupListWidget(listFrame, hlayoutFrame);
listWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
listWidget->setPathLimit(pathLimits);
hlayoutFrame->addWidget(listWidget);
hlayoutLine5->addWidget(listFrame);
hlayoutLine5->addSpacing(40);
vlayout->addLayout(hlayoutLine5);
// 最后一行
vlayout->addSpacing(40);
QHBoxLayout * hlayoutLastLine = new QHBoxLayout;
hlayoutLastLine->setSpacing(16);
hlayoutLastLine->addStretch();
// 上一步按钮
KBorderButton *preStep = new KBorderButton(second);
preStep->setText(tr("Back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &KBorderButton::clicked, this, [=]() {
preStep->clearFocus();
this->setCurrentIndex(HOME_PAGE);
emit this->reset();
});
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(second);
nextStep->setText(tr("Next"));
nextStep->setEnabled(false);
nextStep->setAutoRepeat(true);
nextStep->setProperty("isImportant", true);
hlayoutLastLine->addWidget(preStep);
hlayoutLastLine->addWidget(nextStep);
hlayoutLastLine->addStretch();
hlayoutLastLine->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutLastLine);
vlayout->addSpacing(40);
second->setLayout(vlayout);
addWidget(second);
// 添加本地默认路径、移动设备目录
connect(m_udector, &UdiskDetector::udiskListChanged, this, [=](QList<QStorageInfo> diskList) {
m_isLock = true;
comboSelect->clear();
this->m_udiskPaths.clear();
QIcon iconFolder = QIcon::fromTheme("insync-folder", QIcon(":/images/insync-folder.png"));
// 如果有备份分区,则将本地默认分区备份路径放在第一个
if (GlobelBackupInfo::inst().hasBackupPartition()) {
QString qsLocalDefaultPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_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() + BACKUP_SNAPSHOTS_PATH);
}
if (!this->m_customizePath.isEmpty()) {
comboSelect->setCurrentIndex(-1);
QLineEdit * edit = new QLineEdit;
comboSelect->setLineEdit(edit);
edit->setText(tr("customize path : ") + this->m_customizePath + BACKUP_SNAPSHOTS_PATH);
edit->setReadOnly(true);
} else if (comboSelect->count() > 0 && listWidget->getBackupPaths().size() > 0) {
nextStep->setEnabled(true);
} else {
nextStep->setEnabled(false);
}
m_isLock = false;
});
connect(comboSelect, QOverload<int>::of(&QComboBox::activated), this, [=]() {
if (!m_isLock) {
this->m_customizePath = "";
if (listWidget->getBackupPaths().size() > 0)
nextStep->setEnabled(true);
}
});
m_udector->getStorageInfo();
connect(buttonBrowse, &KBorderButton::clicked, this, [=](){
buttonBrowse->clearFocus();
// 是否自定义路径?自定义路径备份文件不受保护,可能导致备份文件丢失或损坏
if (!MessageBoxUtils::QMESSAGE_BOX_WARNING_CANCEL(GlobelBackupInfo::inst().getMainWidget(), QObject::tr("Information"),
QObject::tr("Are you sure to continue customizing the path?\nThe custom path backup file is not protected, which may cause the backup file to be lost or damaged"),
QObject::tr("Ok"), QObject::tr("Cancel")))
{
return ;
}
BackupPositionSelectDialog fileDialog(this);
if (fileDialog.exec() == QDialog::Accepted) {
QStringList selectFiles = fileDialog.selectedFiles();
if (!selectFiles.isEmpty()) {
QString fileName = selectFiles.at(0);
// sdk重新实现了QFileDialog后很多功能已经丢失需要再次进行过滤真难用
if (fileName == BACKUP_PATH || fileName.contains(BACKUP_SNAPSHOTS_PATH)) {
// 不能嵌套备份,请选择其它目录
MessageBoxUtils::QMESSAGE_BOX_WARNING(GlobelBackupInfo::inst().getMainWidget(), QObject::tr("Information"),
QObject::tr("Cannot nest backups, please select another directory."),
QObject::tr("Ok"));
return ;
} else if (fileName.endsWith(BACKUP_PATH)) {
QString subfile = fileName + "/snapshots";
if (Utils::isDirExist(subfile + "/snapshots")) {
// 不能嵌套备份,请选择其它目录
MessageBoxUtils::QMESSAGE_BOX_WARNING(GlobelBackupInfo::inst().getMainWidget(), QObject::tr("Information"),
QObject::tr("Cannot nest backups, please select another directory."),
QObject::tr("Ok"));
return ;
}
}
if (GlobelBackupInfo::inst().hasBackupPartition() && fileName == Utils::getSysRootPath()) {
comboSelect->setCurrentIndex(0);
this->m_customizePath = "";
} else if (this->m_udiskPaths.contains(fileName)) {
comboSelect->setCurrentIndex(this->m_udiskPaths.indexOf(fileName));
this->m_customizePath = "";
} else {
comboSelect->setCurrentIndex(-1);
this->m_customizePath = fileName;
QLineEdit * edit = new QLineEdit;
comboSelect->setLineEdit(edit);
edit->setText(tr("customize path : ") + QString(fileName + BACKUP_SNAPSHOTS_PATH).replace("//", "/"));
edit->setReadOnly(true);
if (listWidget->getBackupPaths().size() > 0)
nextStep->setEnabled(true);
}
}
}
});
connect(nextStep, &MyPushButton::clicked, this, [=]() {
// 备份路径选择索引
int index = comboSelect->currentIndex();
if (index >= 0) {
// 第一个选项是本地系统备份
this->m_isLocal = GlobelBackupInfo::inst().hasBackupPartition() && (index == 0);
this->m_prefixDestPath = this->m_udiskPaths.at(index);
} else if (this->m_customizePath.isEmpty()) {
MessageBoxUtils::QMESSAGE_BOX_WARNING(GlobelBackupInfo::inst().getMainWidget(), QObject::tr("Warning"),
QObject::tr("Please select backup position"),
QObject::tr("Ok"));
return ;
} else {
// 自定义备份位置的场景
this->m_isLocal = true;
this->m_prefixDestPath = this->m_customizePath;
}
this->m_backupPaths.clear();
this->m_backupPaths.append(listWidget->getBackupPaths());
this->setCurrentIndex(CHECK_ENV_PAGE);
emit this->startCheckEnv();
});
connect(buttonAdd, &PixmapLabel::clicked, this, [=]() {
if (editSelect->text().isEmpty())
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
QObject::tr("Please select a backup file or directory"),
QObject::tr("Ok"));
else {
if (listWidget->appendItem(editSelect->text())) {
editSelect->setText("");
}
}
});
connect(buttonSelect, &MyPushButton::clicked, this, [=](){
MyFileSelect *fileDialog = new MyFileSelect(this);
fileDialog->setWindowTitle(tr("Please select file to backup"));
fileDialog->setSidebarUrls(siderUrls);
if (fileDialog->exec() == QDialog::Accepted) {
QStringList selectFiles = fileDialog->selectedFiles();
if (!selectFiles.isEmpty()) {
QString fileName = selectFiles.at(0);
editSelect->setText(fileName);
editSelect->setFocus();
}
}
delete fileDialog;
});
connect(listWidget, &BackupListWidget::deleteEmpty, this, [=](){
nextStep->setEnabled(false);
});
connect(listWidget, &BackupListWidget::addedItem, this, [=](){
int index = comboSelect->currentIndex();
if (index >= 0 || !this->m_customizePath.isEmpty())
nextStep->setEnabled(true);
});
connect(this, &DataBackup::reset, this, [=]() {
editSelect->setText("");
this->m_backupPaths.clear();
listWidget->clearData();
this->m_udector->getStorageInfo();
});
}
/**
* @brief 文件选择框中左边栏展示用
* @param pathLimits
* @param siderUrls
*/
void DataBackup::getPathsLimit(QStringList &pathLimits, QList<QUrl> &siderUrls)
{
QString curPath = QDir::homePath(); //用户家目录
pathLimits << curPath;
siderUrls << QUrl::fromLocalFile(curPath);
if (GlobelBackupInfo::inst().isManager()) {
QString root = Utils::getSysRootPath() + "/root";
root.replace("//", "/");
pathLimits << root;
siderUrls << QUrl::fromLocalFile(root);
if (Utils::isHuawei990()) {
QString data = Utils::getSysRootPath() + "/data";
data.replace("//", "/");
pathLimits << data;
siderUrls << QUrl::fromLocalFile(data);
} else {
QString data = Utils::getSysRootPath() + "/data/usershare";
data.replace("//", "/");
pathLimits << data;
siderUrls << QUrl::fromLocalFile(data);
}
}
}
/**
* @brief 初始化第二个页面(增量备份)
*/
void DataBackup::initSecondWidget_inc()
{
QWidget *second = new QWidget;
// 纵向布局
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
// 第一行
QHBoxLayout * hlayoutLine1 = new QHBoxLayout;
hlayoutLine1->addSpacing(40);
// 默认备份位置
MyLabel* labelPathSelect = new MyLabel(second);
labelPathSelect->setDeplayText(tr("Default backup location"));
labelPathSelect->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QFont font;
font.setBold(true);
font.setPixelSize(18);
labelPathSelect->setFont(font);
hlayoutLine1->addWidget(labelPathSelect);
hlayoutLine1->setAlignment(Qt::AlignLeft);
vlayout->addLayout(hlayoutLine1);
// 第二行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine2 = new QHBoxLayout;
hlayoutLine2->addSpacing(40);
// 默认备份位置展示
MyLabel* labelBackupPosition = new MyLabel(second);
labelBackupPosition->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
labelBackupPosition->setEnabled(false);
hlayoutLine2->addWidget(labelBackupPosition);
hlayoutLine2->addSpacing(40);
vlayout->addLayout(hlayoutLine2);
vlayout->addSpacing(32);
// 第三行
QHBoxLayout * hlayoutLine3 = new QHBoxLayout;
hlayoutLine3->addSpacing(40);
// label:选择备份数据
MyLabel* labelDataBackup = new MyLabel;
labelDataBackup->setDeplayText(tr("Select backup data"));
labelDataBackup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
labelDataBackup->setFont(font);
hlayoutLine3->addWidget(labelDataBackup);
hlayoutLine3->addSpacing(40);
vlayout->addLayout(hlayoutLine3);
// 第四行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine4 = new QHBoxLayout;
hlayoutLine4->addSpacing(40);
// 所选备份路径编辑框
QLineEdit *editSelect = new QLineEdit;
editSelect->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
editSelect->setMaxLength(255);
editSelect->setTextMargins(0, 0, 62, 0);
QHBoxLayout *searchLayout = new QHBoxLayout(editSelect);
searchLayout->setMargin(5);
searchLayout->setSpacing(0);
// 删除按钮
PixmapLabel *buttonDelete = new PixmapLabel;
buttonDelete->setFixedSize(24, 24);
buttonDelete->setUkuiIconSchema("window-close-symbolic", ":/symbos/window-close-symbolic");
buttonDelete->setToolTip(tr("Clear"));
buttonDelete->setChangeHover();
connect(buttonDelete, &PixmapLabel::clicked, this, [=]() {
editSelect->setText("");
});
// 添加按钮
PixmapLabel *buttonAdd = new PixmapLabel;
buttonAdd->setFixedSize(24, 24);
buttonAdd->setUkuiIconSchema("object-select-symbolic", ":/symbos/object-select-symbolic");
buttonAdd->setToolTip(tr("Add"));
buttonAdd->setChangeHover();
searchLayout->addWidget(buttonDelete);
searchLayout->addWidget(buttonAdd);
searchLayout->setAlignment(Qt::AlignRight);
buttonDelete->setVisible(false);
buttonAdd->setVisible(false);
connect(editSelect, &QLineEdit::textChanged, this, [=](const QString& text) {
if (!text.isEmpty()) {
buttonDelete->setVisible(true);
buttonAdd->setVisible(true);
} else {
buttonDelete->setVisible(false);
buttonAdd->setVisible(false);
}
});
// 选择按钮
MyPushButton *buttonSelect = new MyPushButton;
buttonSelect->setText(tr("Select"));
buttonSelect->setProperty("isImportant", true);
hlayoutLine4->addWidget(editSelect);
hlayoutLine4->addWidget(buttonSelect);
hlayoutLine4->addSpacing(40);
vlayout->addLayout(hlayoutLine4);
// 第五行
vlayout->addSpacing(16);
QHBoxLayout * hlayoutLine5 = new QHBoxLayout;
hlayoutLine5->addSpacing(40);
// 限制目录
QStringList pathLimits;
QList<QUrl> siderUrls;
getPathsLimit(pathLimits, siderUrls);
// 备份列表
QFrame *listFrame = new QFrame;
listFrame->setFrameShape(QFrame::StyledPanel);
listFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QHBoxLayout * hlayoutFrame = new QHBoxLayout;
listFrame->setLayout(hlayoutFrame);
BackupListWidget *listWidget = new BackupListWidget(listFrame, hlayoutFrame);
listWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
listWidget->setPathLimit(pathLimits);
hlayoutFrame->addWidget(listWidget);
hlayoutLine5->addWidget(listFrame);
hlayoutLine5->addSpacing(40);
vlayout->addLayout(hlayoutLine5);
// 最后一行
vlayout->addSpacing(40);
QHBoxLayout * hlayoutLastLine = new QHBoxLayout;
hlayoutLastLine->setSpacing(16);
hlayoutLastLine->addStretch();
// 上一步按钮
KBorderButton *preStep = new KBorderButton(second);
preStep->setText(tr("Back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &KBorderButton::clicked, this, [=]() {
preStep->clearFocus();
this->setCurrentIndex(HOME_PAGE);
emit this->reset();
});
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(second);
nextStep->setText(tr("Next"));
nextStep->setAutoRepeat(true);
nextStep->setProperty("isImportant", true);
hlayoutLastLine->addWidget(preStep);
hlayoutLastLine->addWidget(nextStep);
hlayoutLastLine->addStretch();
hlayoutLastLine->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutLastLine);
vlayout->addSpacing(40);
second->setLayout(vlayout);
connect(buttonAdd, &PixmapLabel::clicked, this, [=]() {
if (editSelect->text().isEmpty())
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
QObject::tr("Please select a backup file or directory"),
QObject::tr("Ok"));
else {
if (listWidget->appendItem(editSelect->text())) {
editSelect->setText("");
}
}
});
connect(buttonSelect, &MyPushButton::clicked, this, [=](){
MyFileSelect *fileDialog = new MyFileSelect(this);
fileDialog->setWindowTitle(tr("Please select file to backup"));
fileDialog->setSidebarUrls(siderUrls);
if (fileDialog->exec() == QDialog::Accepted) {
QStringList selectFiles = fileDialog->selectedFiles();
if (!selectFiles.isEmpty()) {
QString fileName = selectFiles.at(0);
editSelect->setText(fileName);
editSelect->setFocus();
}
}
delete fileDialog;
});
connect(listWidget, &BackupListWidget::deleteEmpty, this, [=](){
nextStep->setEnabled(false);
});
connect(listWidget, &BackupListWidget::addedItem, this, [=](){
nextStep->setEnabled(true);
});
connect(nextStep, &MyPushButton::clicked, this, [=]() {
this->m_backupPaths.clear();
this->m_backupPaths.append(listWidget->getBackupPaths());
this->setCurrentIndex(CHECK_ENV_PAGE);
emit this->startCheckEnv();
});
// 增量备份初始化备份路径列表
connect(this, &DataBackup::initIncListWidget, this, [=]() {
emit this->reset();
this->addOldBackupPaths(listWidget);
nextStep->setEnabled(true);
if (this->m_isLocal && !this->m_prefixDestPath.isEmpty()) {
QString defaultPath = tr("customize path : ") + this->m_prefixDestPath + BACKUP_SNAPSHOTS_PATH;
labelBackupPosition->setDeplayText(defaultPath);
} else if (this->m_isLocal) {
QString qsLocalDefaultPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH;
qsLocalDefaultPath.replace("//", "/");
QString defaultPath = tr("local default path : ") + qsLocalDefaultPath;
labelBackupPosition->setDeplayText(defaultPath);
} else {
QString defaultPath = tr("removable devices path : ") + this->m_prefixDestPath + BACKUP_SNAPSHOTS_PATH;
labelBackupPosition->setDeplayText(defaultPath);
}
});
connect(this, &DataBackup::reset, this, [=]() {
editSelect->setText("");
this->m_backupPaths.clear();
listWidget->clearData();
});
addWidget(second);
}
/**
* @brief 将源备份点的备份路径列表添加到当前列表控件
* @param listWidget
*/
void DataBackup::addOldBackupPaths(BackupListWidget *listWidget)
{
QString pathUserFile = m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_uuid + "/" + PATHS_USER_FILE;
QFile file(pathUserFile);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
if (line.isEmpty())
continue;
listWidget->appendItem(line);
}
}
}
/**
* @brief 初始化第三个页面
*/
void DataBackup::initThirdWidget()
{
QWidget *third = new QWidget;
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
// 流程进度提示栏
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);
CircleLable *three = new CircleLable("3", third);
LineLabel *line3 = new LineLabel(third);
CircleLable *four = new CircleLable("4", third);
QHBoxLayout *hlayoutTopLine1 = new QHBoxLayout;
hlayoutTopLine1->addSpacing(80);
hlayoutTopLine1->addWidget(one);
hlayoutTopLine1->addWidget(line1);
hlayoutTopLine1->addWidget(two);
hlayoutTopLine1->addWidget(line2);
hlayoutTopLine1->addWidget(three);
hlayoutTopLine1->addWidget(line3);
hlayoutTopLine1->addWidget(four);
hlayoutTopLine1->addSpacing(80);
vlayout->addLayout(hlayoutTopLine1);
MyLabel *label1 = new MyLabel(tr("checking"), third);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setFixedWidth(164);
MyLabel *label2 = new MyLabel(tr("preparing"), third);
label2->setEnabled(false);
label2->setFixedWidth(164);
MyLabel *label3 = new MyLabel(tr("backuping"), third);
label3->setEnabled(false);
label3->setFixedWidth(164);
MyLabel *label4 = new MyLabel(tr("finished"), third);
label4->setEnabled(false);
label4->setFixedWidth(164);
QHBoxLayout *hlayoutTopLine2 = new QHBoxLayout;
hlayoutTopLine2->addSpacing(11);
hlayoutTopLine2->addWidget(label1);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label2);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label3);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label4);
hlayoutTopLine2->addSpacing(11);
vlayout->addLayout(hlayoutTopLine2);
vlayout->addSpacing(80);
// ------------ 中部布局begin-------------
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addStretch();
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();
labelCheck2->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, this, [=]() {
preStep->clearFocus();
if (this->m_isIncrement)
this->setCurrentIndex(INC_SELECT_PATH_PAGE);
else
this->setCurrentIndex(SELECT_PATH_PAGE);
});
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->clearBackupName();
});
hlayoutCenterFont5->addWidget(nextStep);
// 重新检测按钮
MyPushButton *recheck = new MyPushButton(centerFont);
recheck->setText(tr("Recheck"));
recheck->setEnabled(true);
recheck->setAutoRepeat(true);
recheck->setProperty("isImportant", true);
connect(recheck, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
emit this->startCheckEnv();
});
hlayoutCenterFont5->addWidget(recheck);
hlayoutCenterFont5->addStretch();
hlayoutCenterFont5->setAlignment(Qt::AlignCenter);
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
centerFont->setLayout(vlayoutCenterFont);
hlayout->addWidget(centerFont);
hlayout->addStretch();
hlayout->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayout);
vlayout->addStretch();
third->setLayout(vlayout);
// ------------ 中部布局end-------------
// 开始检测
connect(this, &DataBackup::startCheckEnv, this, [=]() {
this->m_DataBackupState = DataBackupState::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);
// 备份过程中不要做其它操作,以防数据丢失
labelCheck1->setDeplayText(tr("Do not perform other operations during backup to avoid data loss"));
if (this->m_isLocal) {
// 检测备份分区空间是否充足···
labelCheck2->setDeplayText(tr("Check whether the remaining capacity of the backup partition is sufficient"));
} else {
// 检测移动设备空间是否充足···
labelCheck2->setDeplayText(tr("Check whether the remaining capacity of the removable device is sufficient"));
}
preStep->setVisible(false);
nextStep->setVisible(false);
recheck->setVisible(false);
this->on_checkEnv_start();
emit GlobelBackupInfo::inst().getGlobalSignals()->widthChanged();
});
// 检测结果
connect(this, &DataBackup::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 for backup 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;
}
// 控件labelCheck1的宽度
int len_labelCheck1 = 0;
if (labelCheck1->isVisible()) {
QFontMetrics fontMetrics(labelCheck1->font());
len_labelCheck1 = fontMetrics.width(labelCheck1->getOriginalText());
len_labelCheck1 += LEN_DOT_PRE;
}
// 控件labelCheck2的宽度
int len_labelCheck2 = 0;
if (labelCheck2->isVisible()) {
QFontMetrics fontMetrics(labelCheck2->font());
len_labelCheck2 = fontMetrics.width(labelCheck2->getOriginalText());
len_labelCheck2 += LEN_DOT_PRE;
}
int len_max = len_title > len_labelCheck1 ? len_title : len_labelCheck1;
len_max = len_max > len_labelCheck2 ? len_max : len_labelCheck2;
if (len_max >= this->width())
len_max = this->width();
centerFont->setFixedWidth(len_max);
});
addWidget(third);
}
/**
* @brief 开始进行环境检测
*/
void DataBackup::on_checkEnv_start()
{
GlobelBackupInfo::inst().setIsBusy(true);
m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this);
connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DataBackup::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 = m_isIncrement ? BackupType::INC_BACKUP_DATA : BackupType::BACKUP_DATA;
backupWrapper.m_iPosition = m_isLocal ? (this->m_prefixDestPath.isEmpty() ? BackupPosition::LOCAL : BackupPosition::CUSTOMIZE) : BackupPosition::UDISK;
backupWrapper.m_backupPaths << m_backupPaths;
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 DataBackup::on_checkEnv_end(int result)
{
m_DataBackupState = DataBackupState::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 backup is not enough");
// 建议释放空间后重试
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;
default:
bRst = true;
break;
}
Utils::wait(2);
emit checkEnvResult(bRst, errMsg, errTip);
GlobelBackupInfo::inst().setIsBusy(false);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DataBackup::on_checkEnv_end);
delete m_pInterface;
m_pInterface = nullptr;
}
/**
* @brief 初始化第四个页面
*/
#define MAX_LEN_BACKUPNAME 64
void DataBackup::initForthWidget()
{
QWidget *forth = new QWidget;
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
// 流程进度提示栏
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);
LineLabel *line3 = new LineLabel(forth);
CircleLable *four = new CircleLable("4", forth);
QHBoxLayout *hlayoutTopLine1 = new QHBoxLayout;
hlayoutTopLine1->addSpacing(80);
hlayoutTopLine1->addWidget(one);
hlayoutTopLine1->addWidget(line1);
hlayoutTopLine1->addWidget(two);
hlayoutTopLine1->addWidget(line2);
hlayoutTopLine1->addWidget(three);
hlayoutTopLine1->addWidget(line3);
hlayoutTopLine1->addWidget(four);
hlayoutTopLine1->addSpacing(80);
vlayout->addLayout(hlayoutTopLine1);
MyLabel *label1 = new MyLabel(tr("checking"), forth);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setFixedWidth(164);
MyLabel *label2 = new MyLabel(tr("preparing"), forth);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setFixedWidth(164);
MyLabel *label3 = new MyLabel(tr("backuping"), forth);
label3->setFixedWidth(164);
label3->setEnabled(false);
MyLabel *label4 = new MyLabel(tr("finished"), forth);
label4->setFixedWidth(164);
label4->setEnabled(false);
QHBoxLayout *hlayoutTopLine2 = new QHBoxLayout;
hlayoutTopLine2->addSpacing(11);
hlayoutTopLine2->addWidget(label1);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label2);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label3);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label4);
hlayoutTopLine2->addSpacing(11);
vlayout->addLayout(hlayoutTopLine2);
vlayout->addSpacing(80);
// ------------ 中部布局begin-------------
// 中部第一行
QHBoxLayout *hlayoutCenterLine1 = new QHBoxLayout;
// 备份名称
MyLabel *labelBackupName = new MyLabel(forth);
labelBackupName->setDeplayText(tr("Backup Name"));
QFontMetrics fontMetrics(labelBackupName->font());
int fontSize = fontMetrics.width(labelBackupName->getOriginalText());
labelBackupName->setFixedWidth(fontSize);
MyLineEdit *editBackupName = new MyLineEdit(forth);
editBackupName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
editBackupName->setMinimumWidth(350);
editBackupName->setMaxLength(MAX_LEN_BACKUPNAME);
if (m_backupName.isEmpty())
editBackupName->setPlaceholderText(QDateTime::currentDateTime().toString("yy-MM-dd hh:mm:ss"));
else {
editBackupName->setText(m_backupName);
}
// 支持输入中英文数字和部分字符
// QRegExp regx("^[\u4e00-\u9fa5a-zA-Z0-9~!@#$%^&*()-_+={}':;'\\[\\].<>/? ¥()——;《》‘’:“”、?]+$"); //其中匹配中文[\u4e00-\u9fa5]
QRegExp regx("[^<>,;`|#\\^\\$]+");//regx("^[\u4e00-\u9fa5a-zA-Z0-9-@& +():'()——《》‘’:“”]*$");
InputValidator *validator = new InputValidator(regx);
editBackupName->setValidator(validator);
labelBackupName->setFixedHeight(editBackupName->height());
hlayoutCenterLine1->addStretch();
hlayoutCenterLine1->addWidget(labelBackupName);
hlayoutCenterLine1->addWidget(editBackupName);
hlayoutCenterLine1->addStretch();
hlayoutCenterLine1->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutCenterLine1);
// 中部第二行
// 备份名称错误提示
MyLabel *labelError = new MyLabel(forth);
labelError->setFixedSize(editBackupName->size());
labelError->setFontSize(14);
labelError->setFontColor(Qt::red);
labelError->setVisible(false);
labelError->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
connect(GlobelBackupInfo::inst().getGlobalSignals(), &GlobalSignals::widthChanged, this, [=]{
QFontMetrics fontMetrics(labelBackupName->font());
int fontSize = fontMetrics.width(labelBackupName->getOriginalText());
labelBackupName->setFixedWidth(fontSize);
if (labelError->isVisible())
labelError->move(editBackupName->geometry().left(), editBackupName->geometry().bottom() + 10);
});
connect(validator, &InputValidator::checked, this, [=](bool valid, QString in, int pos, QChar c) {
if (in.isEmpty())
return;
QString text = editBackupName->text();
if (valid) {
if (pos >= MAX_LEN_BACKUPNAME) {
labelError->setDeplayText(tr("Maximum length reached"));
labelError->setVisible(true);
labelError->move(editBackupName->geometry().left(), editBackupName->geometry().bottom() + 10);
} else if (text == in) {
labelError->setVisible(false);
}
} else {
labelError->setDeplayText(tr("Unsupported symbol : ") + c);
labelError->setVisible(true);
labelError->move(editBackupName->geometry().left(), editBackupName->geometry().bottom() + 10);
}
});
connect(editBackupName, &MyLineEdit::textChanged, this, [=](const QString &text) {
if (!text.isEmpty() && text != this->m_backupName && this->isExistsBackupName(text)) {
labelError->setDeplayText(tr("Name already exists"));
labelError->setVisible(true);
labelError->move(editBackupName->geometry().left(), editBackupName->geometry().bottom() + 10);
} else if (text.isEmpty()) {
labelError->setDeplayText("");
labelError->setVisible(false);
} else {
// 这里面的情况包含在了上面的InputValidator::checked信号处理逻辑中
}
});
connect(this, &DataBackup::clearBackupName, this, [=]() {
editBackupName->setText("");
if (this->m_backupName.isEmpty())
editBackupName->setPlaceholderText(QDateTime::currentDateTime().toString("yy-MM-dd hh:mm:ss"));
else
editBackupName->setText(this->m_backupName);
editBackupName->setFocus();
labelError->setDeplayText("");
labelError->setVisible(false);
});
vlayout->addSpacing(56);
// 中部第三行
QHBoxLayout *hlayoutCenterLine3 = new QHBoxLayout;
hlayoutCenterLine3->setSpacing(16);
hlayoutCenterLine3->addStretch();
// 上一步按钮
KBorderButton *preStep = new KBorderButton(forth);
preStep->setText(tr("Back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &KBorderButton::clicked, preStep, &KBorderButton::clearFocus);
connect(preStep, &KBorderButton::clicked, this, &DataBackup::on_pre_clicked);
hlayoutCenterLine3->addWidget(preStep);
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(forth);
nextStep->setText(tr("Next"));
nextStep->setEnabled(true);
nextStep->setAutoRepeat(true);
nextStep->setProperty("isImportant", true);
connect(nextStep, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
/*if (labelError->isVisible()) {
editBackupName->setFocus();
} else*/ {
QString backupName = editBackupName->text();
if (backupName.isEmpty()) {
backupName = editBackupName->placeholderText();
}
if (this->m_backupName != backupName && this->isExistsBackupName(backupName)) {
labelError->setDeplayText(tr("Name already exists"));
labelError->setVisible(true);
editBackupName->setFocus();
} else {
this->m_backupName = backupName;
this->on_next_clicked(checked);
emit this->startBackup();
}
}
});
hlayoutCenterLine3->addWidget(nextStep);
hlayoutCenterLine3->addStretch();
hlayoutCenterLine3->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutCenterLine3);
vlayout->addStretch();
forth->setLayout(vlayout);
addWidget(forth);
}
/**
* @brief 获取本地和移动设备中的备份点
* @return
*/
QList<ParseBackupList::BackupPoint> DataBackup::getBackupPointList()
{
QList<ParseBackupList::BackupPoint> list;
for (QString backupPath : m_udiskPaths) {
if (backupPath.isEmpty())
backupPath = Utils::getSysRootPath();
backupPath += BACKUP_XML_PATH;
QFile xmlFile(backupPath);
if (!xmlFile.exists() || 0 == xmlFile.size()) {
continue;
}
ParseBackupList parse(backupPath);
list.append(parse.getBackupPointList());
}
return list;
}
/**
* @brief DataBackup::isExistsBackupName
* @param backupName
* @return bool true-已存在false-不存在
*/
bool DataBackup::isExistsBackupName(const QString & backupName)
{
// 首先,校验唯一性文件中
QString settingPath = Utils::getSysRootPath() + UDISK_UNIQUE_SETTINGS;
settingPath.replace("//", "/");
QSettings udisk_setting(settingPath, QSettings::IniFormat);
udisk_setting.setIniCodec(QTextCodec::codecForName("utf-8"));
udisk_setting.beginGroup(backupName);
QString uuidFound = udisk_setting.value("uuid").toString();
udisk_setting.endGroup();
if (!uuidFound.isEmpty())
return true;
return false;
// 然后校验xml和log中的备份记录这一步只是为了保险而兼容老版本的备份以前的唯一性文件中只有U盘的备份
// QList<ParseBackupList::BackupPoint> backupPointList = getBackupPointList();
// QList<BackupWrapper> list = Utils::getBackupLogList();
// QSet<QString> setName;
// for (BackupWrapper& wraper : list) {
// if (wraper.m_backupName == wraper.m_uuid) {
// // 如果在xml中不存在则说明是此备份点是之前存在的备份点现在已经删除
// for (const ParseBackupList::BackupPoint & backupPonit : backupPointList) {
// if (backupPonit.m_uuid == wraper.m_uuid) {
// wraper.m_backupName = backupPonit.m_backupName;
// }
// }
// }
// // type==8为删除备份点操作
// if (BackupType::DELETE_BACKUP == wraper.m_type)
// setName.remove(wraper.m_backupName);
// else
// setName.insert(wraper.m_backupName);
// }
// return setName.contains(backupName);
}
/**
* @brief 第五个页面
*/
void DataBackup::initFifthWidget()
{
QWidget *fifth = new QWidget;
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
// 流程进度提示栏
CircleLable *one = new CircleLable("1", fifth, 24, QColor(COLOR_BLUE));
LineLabel *line1 = new LineLabel(fifth, QColor(COLOR_BLUE));
CircleLable *two = new CircleLable("2", fifth, 24, QColor(COLOR_BLUE));
LineLabel *line2 = new LineLabel(fifth, QColor(COLOR_BLUE));
CircleLable *three = new CircleLable("3", fifth, 24, QColor(COLOR_BLUE));
LineLabel *line3 = new LineLabel(fifth, QColor(COLOR_BLUE));
CircleLable *four = new CircleLable("4", fifth);
QHBoxLayout *hlayoutTopLine1 = new QHBoxLayout;
hlayoutTopLine1->addSpacing(80);
hlayoutTopLine1->addWidget(one);
hlayoutTopLine1->addWidget(line1);
hlayoutTopLine1->addWidget(two);
hlayoutTopLine1->addWidget(line2);
hlayoutTopLine1->addWidget(three);
hlayoutTopLine1->addWidget(line3);
hlayoutTopLine1->addWidget(four);
hlayoutTopLine1->addSpacing(80);
vlayout->addLayout(hlayoutTopLine1);
MyLabel *label1 = new MyLabel(tr("checking"), fifth);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setFixedWidth(164);
MyLabel *label2 = new MyLabel(tr("preparing"), fifth);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setFixedWidth(164);
MyLabel *label3 = new MyLabel(tr("backuping"), fifth);
label3->setFontColor(QColor(COLOR_BLUE));
label3->setFixedWidth(164);
MyLabel *label4 = new MyLabel(tr("finished"), fifth);
label4->setFixedWidth(164);
label4->setEnabled(false);
QHBoxLayout *hlayoutTopLine2 = new QHBoxLayout;
hlayoutTopLine2->addSpacing(11);
hlayoutTopLine2->addWidget(label1);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label2);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label3);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label4);
hlayoutTopLine2->addSpacing(11);
vlayout->addLayout(hlayoutTopLine2);
vlayout->addSpacing(80);
// ------------ 中部布局begin-------------
// 中部第一行
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
// 检测等待图标
QLabel *loadingGif = new QLabel(fifth);
// 环境检测等待动画
QMovie *movie = new QMovie(":/images/loading.gif", QByteArray(), fifth);
loadingGif->setMovie(movie);
loadingGif->setFixedSize(24,24);
loadingGif->setVisible(false);
// 进度条
RingsProgressbar *progressBar = new RingsProgressbar(fifth);
progressBar->setFixedSize(100, 100);
hlayoutCenterFont1->addStretch();
hlayoutCenterFont1->addWidget(loadingGif);
hlayoutCenterFont1->addWidget(progressBar);
hlayoutCenterFont1->addStretch();
hlayoutCenterFont1->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutCenterFont1);
// 第二行
vlayout->addSpacing(16);
QHBoxLayout *hlayoutCenterFont2 = new QHBoxLayout;
// 提醒
MyLabel *labelTip = new MyLabel(fifth);
labelTip->setAlignment(Qt::AlignCenter);
labelTip->setIsOriginal(true);
labelTip->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hlayoutCenterFont2->addStretch();
hlayoutCenterFont2->addWidget(labelTip);
hlayoutCenterFont2->addStretch();
hlayoutCenterFont2->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutCenterFont2);
vlayout->addSpacing(56);
// 第三行
QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout;
// 取消按钮
MyPushButton *cancel = new MyPushButton(fifth);
cancel->setText(tr("Cancel"));
cancel->setAutoRepeat(true);
cancel->setProperty("isImportant", true);
hlayoutCenterFont3->addStretch();
hlayoutCenterFont3->addWidget(cancel);
hlayoutCenterFont3->addStretch();
hlayoutCenterFont3->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayoutCenterFont3);
// ------------ 中部布局end-------------
vlayout->addStretch();
fifth->setLayout(vlayout);
connect(this, &DataBackup::backupWarnning, labelTip, [=](const QString& msg) {
labelTip->setDeplayText(msg);
});
// 开始备份
connect(this, &DataBackup::startBackup, this, [=] {
progressBar->setPersent(0);
movie->start();
// 不要使用电脑,以防数据丢失
labelTip->setDeplayText(tr("Do not use computer in case of data loss"));
cancel->setEnabled(true);
if (this->m_isIncrement)
cancel->setVisible(false);
else
cancel->setVisible(true);
// 开始备份
this->on_backup_start();
});
// 进度
connect(this, &DataBackup::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(GlobelBackupInfo::inst().getMainWidget(), 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(fifth);
}
/**
* @brief 开始进行系统备份
*/
void DataBackup::on_backup_start()
{
GlobelBackupInfo::inst().setIsBusy(true);
m_DataBackupState = DataBackupState::BACKUPING;
m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this);
connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DataBackup::on_checkBackup_end);
connect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &DataBackup::progress);
connect(m_pInterface, &ComKylinBackupManagerInterface::backupFinished, this, &DataBackup::on_backup_end);
// 是否已存在备份、还原等操作
bool isActive = false;
if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){
on_checkBackup_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING));
return;
}
BackupWrapper backupWrapper;
backupWrapper.m_backupName = m_backupName;
backupWrapper.m_uuid = m_uuid;
backupWrapper.m_type = m_isIncrement ? BackupType::INC_BACKUP_DATA : BackupType::BACKUP_DATA;
backupWrapper.m_iPosition = m_isLocal ? (this->m_prefixDestPath.isEmpty() ? BackupPosition::LOCAL : BackupPosition::CUSTOMIZE) : BackupPosition::UDISK;
backupWrapper.m_backupPaths << m_backupPaths;
backupWrapper.m_prefixDestPath = m_prefixDestPath;
backupWrapper.m_frontUid = getuid();
backupWrapper.m_frontUserName = qgetenv("USER");
backupWrapper.m_gid = getgid();
m_pInterface->goBackup(backupWrapper);
}
/**
* @brief 系统备份校验结果处理
* @param result
*/
void DataBackup::on_checkBackup_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::BACKUP_CAPACITY_IS_NOT_ENOUGH):
// 备份空间不足
errMsg = tr("The storage for backup is not enough");
// 建议释放空间后重试
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::WRITE_BACKUP_PATHS_TO_USER_FAILED):
case int(BackupResult::WRITE_STORAGEINFO_ADD_ITEM_FAIL):
case int(BackupResult::WRITE_STORAGEINFO_UPDATE_ITEM_FAIL):
// 创建备份点目录失败
errMsg = tr("Failed to create the backup point directory");
// 请检查备份目录是否有写权限
errTip = tr("Please check backup partition permissions");
break;
case int(BackupResult::CANCEL_SUCCESS):
// 已经取消本次备份
errMsg = tr("The backup had been canceled");
// 如需要可重新发起备份
errTip = tr("Re-initiate the backup if necessary");
break;
default:
bRst = true;
break;
}
if (!bRst) {
GlobelBackupInfo::inst().setIsBusy(false);
m_DataBackupState = DataBackupState::IDEL;
this->on_next_clicked(true);
emit this->checkBackupResult(bRst, errMsg, errTip);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DataBackup::on_checkEnv_end);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &DataBackup::progress);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::backupFinished, this, &DataBackup::on_backup_end);
delete m_pInterface;
m_pInterface = nullptr;
}
}
/**
* @brief 系统备份结束
* @param result-false 失败; true 成功
*/
void DataBackup::on_backup_end(bool result)
{
m_DataBackupState = DataBackupState::IDEL;
this->on_next_clicked(true);
if (result) {
emit checkBackupResult(result);
} else {
// 备份过程中出现错误
QString errMsg = tr("An error occurred during backup");
// 错误信息参考日志文件:/var/log/backup.log
QString errTip = tr("Error messages refer to log file : /var/log/backup.log");
emit checkBackupResult(result, errMsg, errTip);
}
GlobelBackupInfo::inst().setIsBusy(false);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DataBackup::on_checkEnv_end);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &DataBackup::progress);
disconnect(m_pInterface, &ComKylinBackupManagerInterface::backupFinished, this, &DataBackup::on_backup_end);
delete m_pInterface;
m_pInterface = nullptr;
}
/**
* @brief 最后备份结果界面
*/
void DataBackup::initLastWidget()
{
QWidget *last = new QWidget;
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(40);
// 流程进度提示栏
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));
LineLabel *line3 = new LineLabel(last, QColor(COLOR_BLUE));
CircleLable *four = new CircleLable("4", last, 24, QColor(COLOR_BLUE));
QHBoxLayout *hlayoutTopLine1 = new QHBoxLayout;
hlayoutTopLine1->addSpacing(80);
hlayoutTopLine1->addWidget(one);
hlayoutTopLine1->addWidget(line1);
hlayoutTopLine1->addWidget(two);
hlayoutTopLine1->addWidget(line2);
hlayoutTopLine1->addWidget(three);
hlayoutTopLine1->addWidget(line3);
hlayoutTopLine1->addWidget(four);
hlayoutTopLine1->addSpacing(80);
vlayout->addLayout(hlayoutTopLine1);
MyLabel *label1 = new MyLabel(tr("checking"), last);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setFixedWidth(164);
MyLabel *label2 = new MyLabel(tr("preparing"), last);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setFixedWidth(164);
MyLabel *label3 = new MyLabel(tr("backuping"), last);
label3->setFontColor(QColor(COLOR_BLUE));
label3->setFixedWidth(164);
MyLabel *label4 = new MyLabel(tr("finished"), last);
label4->setFontColor(QColor(COLOR_BLUE));
label4->setFixedWidth(164);
QHBoxLayout *hlayoutTopLine2 = new QHBoxLayout;
hlayoutTopLine2->addSpacing(11);
hlayoutTopLine2->addWidget(label1);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label2);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label3);
hlayoutTopLine2->addStretch();
hlayoutTopLine2->addWidget(label4);
hlayoutTopLine2->addSpacing(11);
vlayout->addLayout(hlayoutTopLine2);
vlayout->addSpacing(80);
//------------ 中部布局begin-------------
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addStretch();
hlayout->addSpacing(80);
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);
// 第二行
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);
hlayout->addWidget(centerFont);
hlayout->addSpacing(80);
hlayout->addStretch();
hlayout->setAlignment(Qt::AlignCenter);
vlayout->addLayout(hlayout);
vlayout->addStretch();
last->setLayout(vlayout);
//------------ 中部布局end-------------
// 备份检测结果
connect(this, &DataBackup::checkBackupResult, 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("The backup is successful"));
hlayoutCenterFont1->setAlignment(Qt::AlignCenter);
dot1->setVisible(false);
dot2->setVisible(false);
labelError1->setVisible(false);
labelError2->setVisible(false);
retry->setVisible(false);
homePage->setVisible(true);
} else {
resultLogo->setThemeIconSchema("dialog-error", ":/symbos/dialog-error");
resultLogo->setVisible(true);
// 备份失败
bigTitle->setDeplayText(tr("The backup 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);
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(DataBackupPage::NAME_BACKUP_PAGE);
});
// 返回首页
connect(homePage, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
this->setCurrentIndex(DataBackupPage::HOME_PAGE);
});
addWidget(last);
}