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

1618 lines
59 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/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 "../../common/utils.h"
#include "../globalbackupinfo.h"
#include "managebackuppointlist.h"
#include "selectrestorepoint.h"
#include "messageboxutils.h"
DataBackup::DataBackup(QWidget *parent /*= nullptr*/) :
QStackedWidget(parent),
m_udector(new UdiskDetector()),
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;
// 图片
QLabel *imageBackup_firstPage = new QLabel(first);
imageBackup_firstPage->setGeometry(421, 120, 300, 326);
QPixmap pixmap(":/images/data_backup.svg");
imageBackup_firstPage->setPixmap(pixmap);
imageBackup_firstPage->setScaledContents(true);
// 系统备份大字提示
MyLabel *labelBackup_firstPage = new MyLabel(first);
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(first);
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(first);
iconMultiBackup_firstPage->setGeometry(41, 244, 180, 36);
iconMultiBackup_firstPage->setThemeIcon("ukui-bf-many-spot-symbolic", ":/symbos/ukui-bf-many-spot-symbolic.png");
iconMultiBackup_firstPage->setDesplayText(tr("Multi-Spot"));
iconMultiBackup_firstPage->setEnabled(false);
// 安全
MyIconLabel *iconSecurity_firstPage = new MyIconLabel(first);
iconSecurity_firstPage->setGeometry(206, 244, 180, 36);
iconSecurity_firstPage->setThemeIcon("ukui-bf-security-symbolic", ":/symbos/ukui-bf-security-symbolic.png");
iconSecurity_firstPage->setDesplayText(tr("Security"));
iconSecurity_firstPage->setEnabled(false);
// 防止数据丢失
MyIconLabel *iconDataLoss_firstPage = new MyIconLabel(first);
iconDataLoss_firstPage->setGeometry(41, 296, 180, 36);
iconDataLoss_firstPage->setThemeIcon("ukui-bf-dataloss-symbolic", ":/symbos/ukui-bf-dataloss-symbolic.png");
iconDataLoss_firstPage->setDesplayText(tr("Protect Data"));
iconDataLoss_firstPage->setEnabled(false);
// 方便快捷
MyIconLabel *iconSimple_firstPage = new MyIconLabel(first);
iconSimple_firstPage->setGeometry(206, 296, 180, 36);
iconSimple_firstPage->setThemeIcon("ukui-bf-fast-symbolic", ":/symbos/ukui-bf-fast-symbolic.png");
iconSimple_firstPage->setDesplayText(tr("Convenient"));
iconSimple_firstPage->setEnabled(false);
// 开始备份按钮
MyPushButton *beginBackup = new MyPushButton(first);
beginBackup->setGeometry(41, 372, 180, 52);
beginBackup->setText(tr("Start Backup"));
beginBackup->setEnabled(true);
beginBackup->setAutoRepeat(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();
});
// 增量备份按钮
MyPushButton *incrementBackup = new MyPushButton(first);
incrementBackup->setGeometry(241, 372, 180, 52);
incrementBackup->setText(tr("Update Backup"));
incrementBackup->setEnabled(true);
incrementBackup->setAutoRepeat(true);
font.setPixelSize(24);
incrementBackup->setFont(font);
connect(incrementBackup, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
this->m_uuid = "";
this->m_prefixDestPath = "";
this->m_backupName = "";
this->m_backupPaths.clear();
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;
});
if (QDialog::Accepted == selectDialog->exec()) {
QString udiskFlag = Utils::getSysRootPath() + "/media";
udiskFlag.replace("//", "/");
this->m_isLocal = this->m_prefixDestPath.startsWith(udiskFlag) ? false : true;
this->m_isIncrement = true;
this->setCurrentIndex(INC_SELECT_PATH_PAGE);
emit this->initIncListWidget();
}
selectDialog->deleteLater();
});
// 底部控件布局
QHBoxLayout *bottomHBoxLayout = new QHBoxLayout;
bottomHBoxLayout->addStretch();
// 备份管理
ClickLabel * backupPointManage = new ClickLabel(tr("Backup Management >>"));
QPalette pal(backupPointManage->palette());
pal.setColor(QPalette::WindowText, QColor(Qt::blue));
backupPointManage->setPalette(pal);
backupPointManage->setToolTip(tr("Backup Management >>"));
bottomHBoxLayout->addWidget(backupPointManage);
bottomHBoxLayout->addSpacing(20);
QVBoxLayout *bottomVBoxLayout = new QVBoxLayout;
bottomVBoxLayout->addStretch();
bottomVBoxLayout->addLayout(bottomHBoxLayout);
bottomVBoxLayout->addSpacing(20);
first->setLayout(bottomVBoxLayout);
connect(backupPointManage, &ClickLabel::clicked, this, [=]() {
ManageBackupPointList backupManager(first, ManageBackupPointList::DATA);
backupManager.exec();
});
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(30);
// 备份路径选择提示(新建数据备份时显示)
MyLabel* labelPathSelect = new MyLabel(second);
labelPathSelect->setDeplayText(tr("Please select backup position"));
labelPathSelect->setFixedWidth(600);
labelPathSelect->setFixedHeight(27);
QFont font;
font.setBold(true);
font.setPixelSize(18);
labelPathSelect->setFont(font);
hlayoutLine1->addWidget(labelPathSelect);
hlayoutLine1->addStretch();
vlayout->addLayout(hlayoutLine1);
// 第二行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine2 = new QHBoxLayout;
hlayoutLine2->addSpacing(30);
// 备份路径选择框
QComboBox* comboSelect = new QComboBox(second);
QPalette palette = comboSelect->palette();
comboSelect->setFixedSize(680, 36);
// 添加本地默认路径、移动设备目录
connect(m_udector, &UdiskDetector::udiskListChanged, this, [=](QList<QStorageInfo> diskList) {
comboSelect->clear();
this->m_udiskPaths.clear();
QIcon iconFolder = QIcon::fromTheme("insync-folder.png", QIcon(":/images/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);
}
});
m_udector->getStorageInfo();
hlayoutLine2->addWidget(comboSelect);
hlayoutLine2->addStretch();
vlayout->addLayout(hlayoutLine2);
vlayout->addSpacing(30);
// 第三行
QHBoxLayout * hlayoutLine3 = new QHBoxLayout;
hlayoutLine3->addSpacing(30);
// label:选择备份数据
MyLabel* labelDataBackup = new MyLabel;
labelDataBackup->setDeplayText(tr("Select backup data"));
labelDataBackup->setFixedWidth(600);
labelDataBackup->setFixedHeight(27);
labelDataBackup->setFont(font);
hlayoutLine3->addWidget(labelDataBackup);
hlayoutLine3->addStretch();
vlayout->addLayout(hlayoutLine3);
// 第四行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine4 = new QHBoxLayout;
hlayoutLine4->addSpacing(30);
// 所选备份路径编辑框
QLineEdit *editSelect = new QLineEdit;
editSelect->setFixedSize(480, 36);
editSelect->setMaxLength(255);
// 删除按钮
QPushButton *buttonDelete = new QPushButton;
buttonDelete->setProperty("isWindowButton", 0x2);
buttonDelete->setProperty("useIconHighlightEffect", 0x8);
buttonDelete->setFlat(true);
buttonDelete->setIcon(QIcon::fromTheme("window-close-symbolic"));
connect(buttonDelete, &QPushButton::clicked, this, [=]() {
editSelect->setText("");
});
// 添加按钮
MyPushButton *buttonAdd = new MyPushButton;
buttonAdd->setFixedSize(70, 36);
buttonAdd->setText(tr("Add"));
// 选择按钮
MyPushButton *buttonSelect = new MyPushButton;
buttonSelect->setFixedSize(70, 36);
buttonSelect->setText(tr("Select"));
hlayoutLine4->addWidget(editSelect);
hlayoutLine4->addWidget(buttonDelete);
hlayoutLine4->addWidget(buttonAdd);
hlayoutLine4->addWidget(buttonSelect);
hlayoutLine4->addStretch();
vlayout->addLayout(hlayoutLine4);
// 第五行
vlayout->addSpacing(15);
QHBoxLayout * hlayoutLine5 = new QHBoxLayout;
hlayoutLine5->addSpacing(30);
// 限制目录
QStringList pathLimits;
QList<QUrl> siderUrls;
getPathsLimit(pathLimits, siderUrls);
// 备份列表
BackupListWidget *listWidget = new BackupListWidget;
listWidget->setFixedSize(680, 240);
listWidget->setPathLimit(pathLimits);
hlayoutLine5->addWidget(listWidget);
hlayoutLine5->addStretch();
vlayout->addLayout(hlayoutLine5);
connect(buttonAdd, &QPushButton::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);
}
}
delete fileDialog;
});
// 最后一行
vlayout->addSpacing(25);
QHBoxLayout * hlayoutLastLine = new QHBoxLayout;
hlayoutLastLine->addStretch();
// 上一步按钮
MyPushButton *preStep = new MyPushButton(second);
preStep->setGeometry(271, 176, 97, 36);
preStep->setText(tr("back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &MyPushButton::clicked, this, [=]() {
this->setCurrentIndex(HOME_PAGE);
emit this->reset();
});
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(second);
nextStep->setGeometry(389, 176, 97, 36);
nextStep->setText(tr("next"));
nextStep->setEnabled(true);
nextStep->setAutoRepeat(true);
connect(nextStep, &MyPushButton::clicked, this, [=]() {
// 备份路径选择索引
int index = comboSelect->currentIndex();
// 第一个选项是本地系统备份
this->m_isLocal = GlobelBackupInfo::inst().hasBackupPartition() && (index == 0);
this->m_prefixDestPath = this->m_udiskPaths.at(index);
this->m_backupPaths.clear();
this->m_backupPaths.append(listWidget->getBackupPaths());
this->setCurrentIndex(CHECK_ENV_PAGE);
emit this->startCheckEnv();
});
hlayoutLastLine->addWidget(preStep);
hlayoutLastLine->addSpacing(20);
hlayoutLastLine->addWidget(nextStep);
hlayoutLastLine->addStretch();
vlayout->addLayout(hlayoutLastLine);
vlayout->addStretch();
second->setLayout(vlayout);
connect(this, &DataBackup::reset, this, [=]() {
editSelect->setText("");
this->m_backupPaths.clear();
listWidget->clearData();
comboSelect->setCurrentIndex(0);
});
addWidget(second);
}
/**
* @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(30);
// 默认备份位置
MyLabel* labelPathSelect = new MyLabel(second);
labelPathSelect->setDeplayText(tr("Default backup location"));
labelPathSelect->setFixedWidth(600);
labelPathSelect->setFixedHeight(27);
QFont font;
font.setBold(true);
font.setPixelSize(18);
labelPathSelect->setFont(font);
hlayoutLine1->addWidget(labelPathSelect);
hlayoutLine1->addStretch();
vlayout->addLayout(hlayoutLine1);
// 第二行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine2 = new QHBoxLayout;
hlayoutLine2->addSpacing(30);
// 默认备份位置展示
MyLabel* labelBackupPosition = new MyLabel(second);
labelBackupPosition->setFixedWidth(700);
if (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 : ") + m_prefixDestPath;
labelBackupPosition->setDeplayText(defaultPath);
}
labelBackupPosition->setEnabled(false);
hlayoutLine2->addWidget(labelBackupPosition);
hlayoutLine2->addStretch();
vlayout->addLayout(hlayoutLine2);
vlayout->addSpacing(30);
// 第三行
QHBoxLayout * hlayoutLine3 = new QHBoxLayout;
hlayoutLine3->addSpacing(30);
// label:选择备份数据
MyLabel* labelDataBackup = new MyLabel;
labelDataBackup->setDeplayText(tr("Select backup data"));
labelDataBackup->setFixedWidth(600);
labelDataBackup->setFixedHeight(27);
labelDataBackup->setFont(font);
hlayoutLine3->addWidget(labelDataBackup);
hlayoutLine3->addStretch();
vlayout->addLayout(hlayoutLine3);
// 第四行
vlayout->addSpacing(5);
QHBoxLayout * hlayoutLine4 = new QHBoxLayout;
hlayoutLine4->addSpacing(30);
// 所选备份路径编辑框
QLineEdit *editSelect = new QLineEdit;
editSelect->setFixedSize(480, 36);
editSelect->setMaxLength(255);
// 删除按钮
QPushButton *buttonDelete = new QPushButton;
buttonDelete->setProperty("isWindowButton", 0x2);
buttonDelete->setProperty("useIconHighlightEffect", 0x8);
buttonDelete->setFlat(true);
buttonDelete->setIcon(QIcon::fromTheme("window-close-symbolic"));
connect(buttonDelete, &QPushButton::clicked, this, [=]() {
editSelect->setText("");
});
// 添加按钮
MyPushButton *buttonAdd = new MyPushButton;
buttonAdd->setFixedSize(70, 36);
buttonAdd->setText(tr("Add"));
// 选择按钮
MyPushButton *buttonSelect = new MyPushButton;
buttonSelect->setFixedSize(70, 36);
buttonSelect->setText(tr("Select"));
hlayoutLine4->addWidget(editSelect);
hlayoutLine4->addWidget(buttonDelete);
hlayoutLine4->addWidget(buttonAdd);
hlayoutLine4->addWidget(buttonSelect);
hlayoutLine4->addStretch();
vlayout->addLayout(hlayoutLine4);
// 第五行
vlayout->addSpacing(15);
QHBoxLayout * hlayoutLine5 = new QHBoxLayout;
hlayoutLine5->addSpacing(30);
// 限制目录
QStringList pathLimits;
QList<QUrl> siderUrls;
getPathsLimit(pathLimits, siderUrls);
// 备份列表
BackupListWidget *listWidget = new BackupListWidget;
listWidget->setFixedSize(680, 240);
listWidget->setPathLimit(pathLimits);
hlayoutLine5->addWidget(listWidget);
hlayoutLine5->addStretch();
vlayout->addLayout(hlayoutLine5);
connect(buttonAdd, &QPushButton::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, [=](){
QFileDialog *fileDialog = new QFileDialog(this);
fileDialog->setViewMode(QFileDialog::List);
fileDialog->setWindowTitle(tr("Please select file to backup"));
fileDialog->setSidebarUrls(siderUrls);
fileDialog->setFilter(QDir::System | QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
if (fileDialog->exec() == QDialog::Accepted) {
QStringList selectFiles = fileDialog->selectedFiles();
if (!selectFiles.isEmpty()) {
QString fileName = selectFiles.at(0);
editSelect->setText(fileName);
}
}
delete fileDialog;
});
// 增量备份初始化备份路径列表
connect(this, &DataBackup::initIncListWidget, this, [=]() {
emit this->reset();
this->addOldBackupPaths(listWidget);
});
// 最后一行
vlayout->addSpacing(25);
QHBoxLayout * hlayoutLastLine = new QHBoxLayout;
hlayoutLastLine->addStretch();
// 上一步按钮
MyPushButton *preStep = new MyPushButton(second);
preStep->setGeometry(271, 176, 97, 36);
preStep->setText(tr("back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &MyPushButton::clicked, this, [=]() {
this->setCurrentIndex(HOME_PAGE);
emit this->reset();
});
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(second);
nextStep->setGeometry(389, 176, 97, 36);
nextStep->setText(tr("next"));
nextStep->setEnabled(true);
nextStep->setAutoRepeat(true);
connect(nextStep, &MyPushButton::clicked, this, [=]() {
this->m_backupPaths.clear();
this->m_backupPaths.append(listWidget->getBackupPaths());
this->setCurrentIndex(CHECK_ENV_PAGE);
emit this->startCheckEnv();
});
hlayoutLastLine->addWidget(preStep);
hlayoutLastLine->addSpacing(20);
hlayoutLastLine->addWidget(nextStep);
hlayoutLastLine->addStretch();
vlayout->addLayout(hlayoutLastLine);
vlayout->addStretch();
second->setLayout(vlayout);
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;
// 流程进度提示栏
CircleLable *one = new CircleLable("1", third, 24, QColor(COLOR_BLUE));
one->move(QPoint(81, 41));
LineLabel *line1 = new LineLabel(third, QColor(COLOR_BLUE));
line1->move(QPoint(108, 41));
CircleLable *two = new CircleLable("2", third);
two->move(QPoint(261, 41));
LineLabel *line2 = new LineLabel(third);
line2->move(QPoint(288, 41));
CircleLable *three = new CircleLable("3", third);
three->move(QPoint(441, 41));
LineLabel *line3 = new LineLabel(third);
line3->move(QPoint(468, 41));
CircleLable *four = new CircleLable("4", third);
four->move(QPoint(621, 41));
MyLabel *label1 = new MyLabel(tr("checking"), third);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setGeometry(11, 72, 164, 30);
MyLabel *label2 = new MyLabel(tr("preparing"), third);
label2->setGeometry(191, 72, 164, 30);
MyLabel *label3 = new MyLabel(tr("backuping"), third);
label3->setGeometry(371, 72, 164, 30);
MyLabel *label4 = new MyLabel(tr("finished"), third);
label4->setGeometry(551, 72, 164, 30);
// ------------ 中部布局begin-------------
QVBoxLayout *vlayout = new QVBoxLayout(third);
vlayout->addSpacing(180);
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addStretch();
QWidget *centerFont = new QWidget(third);
QVBoxLayout *vlayoutCenterFont = new QVBoxLayout;
// 第一行
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
// 检测等待图标
QLabel *loadingGif = new QLabel(centerFont);
loadingGif->setFixedSize(20,20);
// 环境检测等待动画
QMovie *movie = new QMovie(":/images/loading.gif", QByteArray(), centerFont);
loadingGif->setMovie(movie);
hlayoutCenterFont1->addWidget(loadingGif);
// 检测结果对错图标
QLabel *resultLogo = new QLabel(centerFont);
resultLogo->setFixedSize(20,20);
hlayoutCenterFont1->addWidget(resultLogo);
// 检测中大标题
MyLabel *bigTitle = new MyLabel(centerFont);
bigTitle->setFontSize(24);
bigTitle->setMaximumWidth(550);
bigTitle->setIsOriginal(true);
hlayoutCenterFont1->addWidget(bigTitle);
hlayoutCenterFont1->addStretch();
vlayoutCenterFont->addLayout(hlayoutCenterFont1);
// 第二行
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->setMinimumWidth(400);
labelCheck1->setMaximumWidth(500);
labelCheck1->setIsOriginal(true);
labelCheck1->setWordWrap(true);
labelCheck1->adjustSize();
hlayoutCenterFont2->addWidget(labelCheck1);
hlayoutCenterFont2->addStretch();
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->setMinimumWidth(400);
labelCheck2->setMaximumWidth(500);
labelCheck2->setIsOriginal(true);
labelCheck2->setWordWrap(true);
labelCheck2->adjustSize();
hlayoutCenterFont3->addWidget(labelCheck2);
hlayoutCenterFont3->addStretch();
vlayoutCenterFont->addLayout(hlayoutCenterFont3);
// 第四行
vlayoutCenterFont->addSpacing(30);
// 第五行
QHBoxLayout *hlayoutCenterFont5 = new QHBoxLayout;
// hlayoutCenterFont5->addStretch();
hlayoutCenterFont5->addSpacing(30);
// 上一步按钮
MyPushButton *preStep = new MyPushButton(centerFont);
preStep->setFixedSize(97, 36);
preStep->setText(tr("back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &MyPushButton::clicked, this, [=]() {
if (this->m_isIncrement)
this->setCurrentIndex(INC_SELECT_PATH_PAGE);
else
this->setCurrentIndex(SELECT_PATH_PAGE);
});
hlayoutCenterFont5->addWidget(preStep);
hlayoutCenterFont5->addSpacing(20);
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(centerFont);
nextStep->setFixedSize(97, 36);
nextStep->setText(tr("next"));
nextStep->setEnabled(true);
nextStep->setAutoRepeat(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->setFixedSize(97, 36);
recheck->setText(tr("recheck"));
recheck->setEnabled(true);
recheck->setAutoRepeat(true);
connect(recheck, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
emit this->startCheckEnv();
});
hlayoutCenterFont5->addWidget(recheck);
hlayoutCenterFont5->addStretch();
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
centerFont->setLayout(vlayoutCenterFont);
hlayout->addWidget(centerFont);
hlayout->addStretch();
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();
});
// 检测结果
connect(this, &DataBackup::checkEnvResult, this, [=](bool result, const QString &errMsg, const QString &errTip) {
loadingGif->setVisible(false);
movie->stop();
if (result) {
QIcon icon = QIcon::fromTheme("ukui-dialog-success", QIcon(":/symbos/ukui-dialog-success.png"));
resultLogo->setPixmap(icon.pixmap(QSize(20,20)));
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 {
QIcon icon = QIcon::fromTheme("dialog-error.png", QIcon(":/symbos/dialog-error.png"));
resultLogo->setPixmap(icon.pixmap(QSize(20,20)));
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);
});
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 ? BackupPosition::LOCAL : 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 初始化第四个页面
*/
void DataBackup::initForthWidget()
{
QWidget *forth = new QWidget;
// 流程进度提示栏
CircleLable *one = new CircleLable("1", forth, 24, QColor(COLOR_BLUE));
one->move(QPoint(81, 41));
LineLabel *line1 = new LineLabel(forth, QColor(COLOR_BLUE));
line1->move(QPoint(108, 41));
CircleLable *two = new CircleLable("2", forth, 24, QColor(COLOR_BLUE));
two->move(QPoint(261, 41));
LineLabel *line2 = new LineLabel(forth, QColor(COLOR_BLUE));
line2->move(QPoint(288, 41));
CircleLable *three = new CircleLable("3", forth);
three->move(QPoint(441, 41));
LineLabel *line3 = new LineLabel(forth);
line3->move(QPoint(468, 41));
CircleLable *four = new CircleLable("4", forth);
four->move(QPoint(621, 41));
MyLabel *label1 = new MyLabel(tr("checking"), forth);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setGeometry(11, 72, 164, 30);
MyLabel *label2 = new MyLabel(tr("preparing"), forth);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setGeometry(191, 72, 164, 30);
MyLabel *label3 = new MyLabel(tr("backuping"), forth);
label3->setGeometry(371, 72, 164, 30);
MyLabel *label4 = new MyLabel(tr("finished"), forth);
label4->setGeometry(551, 72, 164, 30);
// 备份名称
MyLabel *labelBackupName = new MyLabel(forth);
labelBackupName->setGeometry(81, 178, 150, 30);
labelBackupName->setAlignment(Qt::AlignRight);
labelBackupName->setDeplayText(tr("Backup Name"));
MyLineEdit *editBackupName = new MyLineEdit(forth);
editBackupName->setGeometry(238, 172, 350, 40);
editBackupName->setMaxLength(64);
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("^[\u4e00-\u9fa5a-zA-Z0-9-@& +():']*$");
QValidator *validator = new QRegExpValidator(regx);
editBackupName->setValidator(validator);
// 备份名称错误提示
MyLabel *labelError = new MyLabel(forth);
labelError->setGeometry(238, 215, 500, 30);
labelError->setFontSize(14);
labelError->setFontColor(Qt::red);
labelError->setVisible(false);
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);
} else {
labelError->setDeplayText("");
labelError->setVisible(false);
}
});
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);
});
// 上一步按钮
MyPushButton *preStep = new MyPushButton(forth);
preStep->setGeometry(271, 268, 97, 36);
preStep->setText(tr("back"));
preStep->setEnabled(true);
preStep->setAutoRepeat(true);
connect(preStep, &MyPushButton::clicked, this, &DataBackup::on_pre_clicked);
// 下一步按钮
MyPushButton *nextStep = new MyPushButton(forth);
nextStep->setGeometry(389, 268, 97, 36);
nextStep->setText(tr("next"));
nextStep->setEnabled(true);
nextStep->setAutoRepeat(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();
}
}
});
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;
// 然后校验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;
// 流程进度提示栏
CircleLable *one = new CircleLable("1", fifth, 24, QColor(COLOR_BLUE));
one->move(QPoint(81, 41));
LineLabel *line1 = new LineLabel(fifth, QColor(COLOR_BLUE));
line1->move(QPoint(108, 41));
CircleLable *two = new CircleLable("2", fifth, 24, QColor(COLOR_BLUE));
two->move(QPoint(261, 41));
LineLabel *line2 = new LineLabel(fifth, QColor(COLOR_BLUE));
line2->move(QPoint(288, 41));
CircleLable *three = new CircleLable("3", fifth, 24, QColor(COLOR_BLUE));
three->move(QPoint(441, 41));
LineLabel *line3 = new LineLabel(fifth, QColor(COLOR_BLUE));
line3->move(QPoint(468, 41));
CircleLable *four = new CircleLable("4", fifth);
four->move(QPoint(621, 41));
MyLabel *label1 = new MyLabel(tr("checking"), fifth);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setGeometry(11, 72, 164, 30);
MyLabel *label2 = new MyLabel(tr("preparing"), fifth);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setGeometry(191, 72, 164, 30);
MyLabel *label3 = new MyLabel(tr("backuping"), fifth);
label3->setFontColor(QColor(COLOR_BLUE));
label3->setGeometry(371, 72, 164, 30);
MyLabel *label4 = new MyLabel(tr("finished"), fifth);
label4->setGeometry(551, 72, 164, 30);
// ------------ 中部布局begin-------------
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->addSpacing(180);
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addStretch();
QWidget *centerFont = new QWidget(fifth);
QVBoxLayout *vlayoutCenterFont = new QVBoxLayout;
// 中部第一行
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
// 检测等待图标
QLabel *loadingGif = new QLabel(centerFont);
// 环境检测等待动画
QMovie *movie = new QMovie(":/images/loading.gif", QByteArray(), centerFont);
loadingGif->setMovie(movie);
loadingGif->setFixedSize(20,20);
// 进度条
RingsProgressbar *progressBar = new RingsProgressbar(centerFont);
progressBar->setFixedSize(100, 100);
hlayoutCenterFont1->addStretch();
hlayoutCenterFont1->addWidget(loadingGif);
hlayoutCenterFont1->addWidget(progressBar);
hlayoutCenterFont1->addSpacing(20);
hlayoutCenterFont1->addStretch();
// 第二行
QHBoxLayout *hlayoutCenterFont2 = new QHBoxLayout;
// 提醒
MyLabel *labelTip = new MyLabel(centerFont);
labelTip->setAlignment(Qt::AlignCenter);
labelTip->setIsOriginal(true);
labelTip->setFontWordWrap(true);
labelTip->setMinimumWidth(700);
hlayoutCenterFont2->addStretch();
hlayoutCenterFont2->addWidget(labelTip);
hlayoutCenterFont2->addStretch();
// 第三行
QHBoxLayout *hlayoutCenterFont3 = new QHBoxLayout;
// 取消按钮
MyPushButton *cancel = new MyPushButton(fifth);
cancel->setFixedSize(97, 36);
cancel->setText(tr("cancel"));
cancel->setAutoRepeat(true);
hlayoutCenterFont3->addStretch();
hlayoutCenterFont3->addWidget(cancel);
hlayoutCenterFont3->addStretch();
vlayoutCenterFont->addLayout(hlayoutCenterFont1);
vlayoutCenterFont->addLayout(hlayoutCenterFont2);
vlayoutCenterFont->addSpacing(40);
vlayoutCenterFont->addLayout(hlayoutCenterFont3);
vlayoutCenterFont->addStretch();
centerFont->setLayout(vlayoutCenterFont);
centerFont->setLayout(vlayoutCenterFont);
hlayout->addWidget(centerFont);
hlayout->addStretch();
vlayout->addLayout(hlayout);
vlayout->addStretch();
fifth->setLayout(vlayout);
// ------------ 中部布局end-------------
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);
Utils::wait(2);
// 开始备份
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(this, QObject::tr("Warning"), 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 ? BackupPosition::LOCAL : 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;
// 流程进度提示栏
CircleLable *one = new CircleLable("1", last, 24, QColor(COLOR_BLUE));
one->move(QPoint(81, 41));
LineLabel *line1 = new LineLabel(last, QColor(COLOR_BLUE));
line1->move(QPoint(108, 41));
CircleLable *two = new CircleLable("2", last, 24, QColor(COLOR_BLUE));
two->move(QPoint(261, 41));
LineLabel *line2 = new LineLabel(last, QColor(COLOR_BLUE));
line2->move(QPoint(288, 41));
CircleLable *three = new CircleLable("3", last, 24, QColor(COLOR_BLUE));
three->move(QPoint(441, 41));
LineLabel *line3 = new LineLabel(last, QColor(COLOR_BLUE));
line3->move(QPoint(468, 41));
CircleLable *four = new CircleLable("4", last, 24, QColor(COLOR_BLUE));
four->move(QPoint(621, 41));
MyLabel *label1 = new MyLabel(tr("checking"), last);
label1->setFontColor(QColor(COLOR_BLUE));
label1->setGeometry(11, 72, 164, 30);
MyLabel *label2 = new MyLabel(tr("preparing"), last);
label2->setFontColor(QColor(COLOR_BLUE));
label2->setGeometry(191, 72, 164, 30);
MyLabel *label3 = new MyLabel(tr("backuping"), last);
label3->setFontColor(QColor(COLOR_BLUE));
label3->setGeometry(371, 72, 164, 30);
MyLabel *label4 = new MyLabel(tr("finished"), last);
label4->setFontColor(QColor(COLOR_BLUE));
label4->setGeometry(551, 72, 164, 30);
//------------ 中部布局begin-------------
QVBoxLayout *vlayout = new QVBoxLayout(last);
vlayout->addSpacing(180);
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addStretch();
QWidget *centerFont = new QWidget(last);
QVBoxLayout *vlayoutCenterFont = new QVBoxLayout;
// 第一行
QHBoxLayout *hlayoutCenterFont1 = new QHBoxLayout;
// 备份结果对错图标
QLabel *resultLogo = new QLabel(centerFont);
resultLogo->setFixedSize(20,20);
hlayoutCenterFont1->addWidget(resultLogo);
// 检测中大标题
MyLabel *bigTitle = new MyLabel(centerFont);
bigTitle->setFontSize(24);
bigTitle->setMaximumWidth(550);
bigTitle->setIsOriginal(true);
hlayoutCenterFont1->addWidget(bigTitle);
hlayoutCenterFont1->addStretch();
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->setMinimumWidth(400);
labelError1->setMaximumWidth(500);
labelError1->setIsOriginal(true);
labelError1->setWordWrap(true);
labelError1->adjustSize();
hlayoutCenterFont2->addWidget(labelError1);
hlayoutCenterFont2->addStretch();
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->setMinimumWidth(400);
labelError2->setMaximumWidth(500);
labelError2->setIsOriginal(true);
labelError2->setWordWrap(true);
labelError2->adjustSize();
hlayoutCenterFont3->addWidget(labelError2);
hlayoutCenterFont3->addStretch();
vlayoutCenterFont->addLayout(hlayoutCenterFont3);
// 第四行
vlayoutCenterFont->addSpacing(30);
// 第五行
QHBoxLayout *hlayoutCenterFont5 = new QHBoxLayout;
// hlayoutCenterFont5->addStretch();
hlayoutCenterFont5->addSpacing(30);
// 返回首页
MyPushButton *homePage = new MyPushButton(centerFont);
homePage->setFixedSize(97, 36);
homePage->setText(tr("home page"));
homePage->setEnabled(true);
homePage->setAutoRepeat(true);
hlayoutCenterFont5->addWidget(homePage);
hlayoutCenterFont5->addSpacing(20);
// 再试一次
MyPushButton *retry = new MyPushButton(centerFont);
retry->setFixedSize(97, 36);
retry->setText(tr("retry"));
retry->setEnabled(true);
retry->setAutoRepeat(true);
hlayoutCenterFont5->addWidget(retry);
hlayoutCenterFont5->addSpacing(20);
hlayoutCenterFont5->addStretch();
vlayoutCenterFont->addLayout(hlayoutCenterFont5);
centerFont->setLayout(vlayoutCenterFont);
hlayout->addWidget(centerFont);
hlayout->addStretch();
vlayout->addLayout(hlayout);
vlayout->addStretch();
last->setLayout(vlayout);
//------------ 中部布局end-------------
// 备份检测结果
connect(this, &DataBackup::checkBackupResult, this, [=](bool result, const QString &errMsg, const QString &errTip) {
if (result) {
QIcon icon = QIcon::fromTheme("ukui-dialog-success", QIcon(":/symbos/ukui-dialog-success.png"));
resultLogo->setPixmap(icon.pixmap(QSize(20,20)));
resultLogo->setVisible(true);
// 备份成功
bigTitle->setDeplayText(tr("The backup is successful"));
dot1->setVisible(false);
dot2->setVisible(false);
labelError1->setVisible(false);
labelError2->setVisible(false);
retry->setVisible(false);
homePage->setVisible(true);
} else {
QIcon icon = QIcon::fromTheme("dialog-error.png", QIcon(":/symbos/dialog-error.png"));
resultLogo->setPixmap(icon.pixmap(QSize(20,20)));
resultLogo->setVisible(true);
// 备份失败
bigTitle->setDeplayText(tr("The backup is failed"));
dot1->setVisible(true);
dot2->setVisible(true);
labelError1->setVisible(true);
labelError2->setVisible(true);
labelError1->setDeplayText(errMsg);
labelError2->setDeplayText(errTip);
retry->setVisible(true);
homePage->setVisible(true);
}
});
// 再试一次
connect(retry, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
this->setCurrentIndex(DataBackupPage::NAME_BACKUP_PAGE);
});
// 返回首页
connect(homePage, &MyPushButton::clicked, this, [=](bool checked) {
Q_UNUSED(checked)
this->setCurrentIndex(DataBackupPage::HOME_PAGE);
});
addWidget(last);
}