2059 lines
79 KiB
C++
2059 lines
79 KiB
C++
![]() |
#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);
|
|||
|
}
|
|||
|
|