From 0469c1a28ab43c61270fed057011a70b83eb1256 Mon Sep 17 00:00:00 2001 From: zhaominyong Date: Mon, 6 Dec 2021 14:55:00 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=B6=E6=AE=B5=E6=80=A7=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=EF=BC=8C=E5=A4=87=E4=BB=BD=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backup-daemon/backup-daemon.pro | 2 + backup-daemon/deletebackupproxy.cpp | 70 +++++++ backup-daemon/deletebackupproxy.h | 25 +++ backup-daemon/mybackupmanager.cpp | 25 ++- backup-daemon/parsebackuplist.cpp | 5 +- backup-daemon/workerfactory.cpp | 6 +- common/utils.cpp | 45 ++++- common/utils.h | 12 ++ kybackup/backuppointlistdialog.cpp | 139 ++++++++++---- kybackup/backuppointlistdialog.h | 39 +++- kybackup/component/mylabel.cpp | 37 +++- kybackup/component/mylabel.h | 3 +- kybackup/component/ringsprogressbar.cpp | 8 + kybackup/deletebackupdialog.cpp | 223 ++++++++++++++++++++++ kybackup/deletebackupdialog.h | 49 +++++ kybackup/deletebackupdialog.ui | 19 ++ kybackup/kybackup.pro | 7 + kybackup/messageboxutils.cpp | 15 -- kybackup/module/managebackuppointlist.cpp | 162 ++++++++++++++++ kybackup/module/managebackuppointlist.h | 32 ++++ kybackup/module/selectrestorepoint.cpp | 156 +++++++++++++++ kybackup/module/selectrestorepoint.h | 28 +++ kybackup/module/systembackup.cpp | 14 +- kybackup/module/systembackup.h | 1 - kybackup/module/systemrestore.cpp | 4 +- kybackup/module/udiskdetector.cpp | 7 + kybackup/module/udiskdetector.h | 9 +- 27 files changed, 1039 insertions(+), 103 deletions(-) create mode 100644 backup-daemon/deletebackupproxy.cpp create mode 100644 backup-daemon/deletebackupproxy.h create mode 100644 kybackup/deletebackupdialog.cpp create mode 100644 kybackup/deletebackupdialog.h create mode 100644 kybackup/deletebackupdialog.ui create mode 100644 kybackup/module/managebackuppointlist.cpp create mode 100644 kybackup/module/managebackuppointlist.h create mode 100644 kybackup/module/selectrestorepoint.cpp create mode 100644 kybackup/module/selectrestorepoint.h diff --git a/backup-daemon/backup-daemon.pro b/backup-daemon/backup-daemon.pro index 3da6736..662dc37 100755 --- a/backup-daemon/backup-daemon.pro +++ b/backup-daemon/backup-daemon.pro @@ -30,6 +30,7 @@ HEADERS += \ ../common/spinlock_mutex.h \ ../common/utils.h \ backupmanager_adaptor.h \ + deletebackupproxy.h \ mybackupmanager.h \ mymountproxy.h \ myprocess/calcbackupsize.h \ @@ -49,6 +50,7 @@ SOURCES += \ ../common/reflect.cpp \ ../common/utils.cpp \ backupmanager_adaptor.cpp \ + deletebackupproxy.cpp \ main.cpp \ mybackupmanager.cpp \ mymountproxy.cpp \ diff --git a/backup-daemon/deletebackupproxy.cpp b/backup-daemon/deletebackupproxy.cpp new file mode 100644 index 0000000..4c68020 --- /dev/null +++ b/backup-daemon/deletebackupproxy.cpp @@ -0,0 +1,70 @@ +#include "deletebackupproxy.h" +#include +#include +#include "../common/utils.h" + +IMPLEMENT_DYNCREATE(DeleteBackupProxy) + +DeleteBackupProxy::DeleteBackupProxy() +{} + +DeleteBackupProxy::~DeleteBackupProxy() +{} + +void DeleteBackupProxy::doWorkEx() +{ + // 1、删除/backup/snapshots/backuplist.xml对应项 + if (!deleteXmlBackupPoint()) + return; + + // 2、删除/backup/snapshots/{uuid}对应目录 + deleteBackupPointDir(); + + // 3、同时删除唯一识别文件中对应的条目 + Utils::deleteBackupUniqueRecord(m_backupWrapper.m_backupName); + + // 删除成功信号 + emit workResult(true); +} + +/** + * @brief 删除/backup/snapshots/backuplist.xml对应项 + */ +bool DeleteBackupProxy::deleteXmlBackupPoint() +{ + QString xmlPath; + if (m_backupWrapper.m_iPosition == BackupPosition::LOCAL) + xmlPath = Utils::getSysRootPath() + BACKUP_XML_PATH; + else + xmlPath = m_backupWrapper.m_prefixDestPath + BACKUP_XML_PATH; + + xmlPath.replace("//", "/"); + ParseBackupList parse(xmlPath); + if (parse.deleteItem(m_backupWrapper.m_uuid) != ParseBackupList::SUCCESS) { + qCritical() << QString("failed to delete %1 from backuplist.xml!").arg(m_backupWrapper.m_uuid); + emit workResult(false); + return false; + } + + return true; +} + +/** + * @brief 删除/backup/snapshots/uuid对应目录 + */ +void DeleteBackupProxy::deleteBackupPointDir() +{ + QString uuidPath; + if (m_backupWrapper.m_iPosition == BackupPosition::LOCAL) + uuidPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid; + else + uuidPath = m_backupWrapper.m_prefixDestPath + BACKUP_SNAPSHOTS_PATH + "/" + m_backupWrapper.m_uuid; + + uuidPath.replace("//", "/"); + + QStringList args; + args << "-rf"; + args << uuidPath; + QProcess::execute("rm", args); +} + diff --git a/backup-daemon/deletebackupproxy.h b/backup-daemon/deletebackupproxy.h new file mode 100644 index 0000000..c53f894 --- /dev/null +++ b/backup-daemon/deletebackupproxy.h @@ -0,0 +1,25 @@ +#ifndef DELETEBACKUPPROXY_H +#define DELETEBACKUPPROXY_H + +#include "workerfactory.h" +#include "parsebackuplist.h" + +class DeleteBackupProxy : public Worker +{ + Q_OBJECT + DECLARE_DYNCREATE(DeleteBackupProxy) +public: + explicit DeleteBackupProxy(); + virtual ~DeleteBackupProxy(); + +public: + // 任务处理 + virtual void doWorkEx(); + +private: + bool deleteXmlBackupPoint(); + + void deleteBackupPointDir(); +}; + +#endif // DELETEBACKUPPROXY_H diff --git a/backup-daemon/mybackupmanager.cpp b/backup-daemon/mybackupmanager.cpp index 9889980..23a8f28 100755 --- a/backup-daemon/mybackupmanager.cpp +++ b/backup-daemon/mybackupmanager.cpp @@ -170,8 +170,29 @@ int MyBackupManager::goRestore(const BackupWrapper& backupWrapper) */ int MyBackupManager::deleteBackupPoint(const BackupWrapper& backupWrapper) { - Q_UNUSED(backupWrapper) - return 0; + if (m_isActive || !lock(backupWrapper.m_frontUid)) { + emit sendEnvCheckResult(int(BackupResult::LOCK_PROGRAM_FAIL)); + return int(BackupResult::LOCK_PROGRAM_FAIL); + } + + Worker* worker = WorkerFactory::createWorker(backupWrapper.m_type, backupWrapper.m_iPosition); + if (nullptr == worker) { + emit sendEnvCheckResult(int(BackupResult::NO_FOUND_DEALCLASS)); + return int(BackupResult::NO_FOUND_DEALCLASS); + } + + worker->setParam(backupWrapper); + connect(worker, &Worker::workResult, this, [&] (bool result) { + emit this->sendDeleteResult(result); + this->finished(); + }); + worker->moveToThread(&workerThread); + connect(&workerThread, &MyThread::started, worker, &Worker::doWork); + connect(&workerThread, &MyThread::finished, worker, &Worker::deleteLater); + + workerThread.start(); + + return int(BackupResult::BACKUP_RESULT_INIT); } /** diff --git a/backup-daemon/parsebackuplist.cpp b/backup-daemon/parsebackuplist.cpp index ec4085f..8a6869f 100755 --- a/backup-daemon/parsebackuplist.cpp +++ b/backup-daemon/parsebackuplist.cpp @@ -328,6 +328,9 @@ void ParseBackupList::elementNodeToBackupPoint(const QDomElement& node, BackupPo QDomElement eleArchDetect = node.firstChildElement(ARCHDETECT); if (!eleArchDetect.isNull()) backupPoint.m_archdetect = eleArchDetect.text(); + + backupPoint.m_path = m_xmlPath; + backupPoint.m_path.replace(BACKUP_XML_PATH, ""); } /** @@ -508,7 +511,7 @@ QList ParseBackupList::getBackupPointList() backupPointList << backupPoint; } - std::sort(backupPointList.begin(), backupPointList.end()); + // std::sort(backupPointList.begin(), backupPointList.end()); return backupPointList; } diff --git a/backup-daemon/workerfactory.cpp b/backup-daemon/workerfactory.cpp index 77dea36..2a53acd 100755 --- a/backup-daemon/workerfactory.cpp +++ b/backup-daemon/workerfactory.cpp @@ -92,11 +92,7 @@ Worker * WorkerFactory::createWorker(int type, int position) } break; case BackupType::DELETE_BACKUP: - if (BackupPosition::UDISK == position) { - className = "UDiskDeleteProxy"; - } else { - className = "DeleteProxy"; - } + className = "DeleteBackupProxy"; break; case BackupType::GHOST_IMAGE: if (BackupPosition::UDISK == position) { diff --git a/common/utils.cpp b/common/utils.cpp index 9e3b1b7..726407b 100755 --- a/common/utils.cpp +++ b/common/utils.cpp @@ -386,6 +386,32 @@ void Utils::excludeFstabBindPath(QStringList &excludes) file.close(); } +/** + * @brief 备份还原时,需要一些用户家目录下的路径,因为这些路径备份还原程序无权操作 + * @param excludes,存放需要排除的路径 + */ +void Utils::excludeSomeHomePath(QStringList &excludes) +{ + QSet homeSet; + // 获取/home下的用户家目录 + QString homePath = Utils::m_sysRootPath + "/home"; + homePath.replace("//", "/"); + QDir dir(homePath); + QStringList list = dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs); + for (const QString& item : list) { + // /home/oem跳过 + if (item == "oem") + continue ; + + QString home("/home/"); + home += item; + excludes << home + "/.box"; + QString dataHome("/data/home/"); + dataHome += item; + excludes << dataHome + "/.box"; + } +} + /** * @brief 生成rsync --exclude-from排除路径规则文件 * @return @@ -430,6 +456,7 @@ bool Utils::generateExcludePathsFile() // 系统安装后有的会将/data/home /data/root挂载到的/home /root上,实际文件是存放在/data/home /data/root下面,为了统一标准保留/home /root排除/data/home /data/root QStringList excludes; Utils::excludeFstabBindPath(excludes); + Utils::excludeSomeHomePath(excludes); for (const QString& item : excludes) { in << item << endl; } @@ -482,6 +509,7 @@ QStringList Utils::getFromExcludePathsFile() // 系统安装后有的会将/data/home /data/root挂载到的/home /root上,实际文件是存放在/data/home /data/root下面 QStringList excludes; Utils::excludeFstabBindPath(excludes); + Utils::excludeSomeHomePath(excludes); for (const QString& item : excludes) { list << item; } @@ -1027,8 +1055,8 @@ qint64 Utils::getDirOrFileSize(const QString &path) /** * @brief 记录下备份点uuid及其名称 - * @param uuid - * @param backupName + * @param uuid 备份点识别码 + * @param backupName 备份点名称 */ void Utils::update_backup_unique_settings(const QString &uuid, const QString &backupName) { @@ -1041,3 +1069,16 @@ void Utils::update_backup_unique_settings(const QString &uuid, const QString &ba udisk_unique_settings.setValue("uuid", uuid); udisk_unique_settings.endGroup(); } + +/** + * @brief 根据备份点名称,删除备份点uuid记录 + * @param backupName 备份点名称 + */ +void Utils::deleteBackupUniqueRecord(const QString& backupName) +{ + QString backupUniqueSetting = Utils::getSysRootPath() + UDISK_UNIQUE_SETTINGS; + backupUniqueSetting.replace("//", "/"); + QSettings udisk_unique_settings(backupUniqueSetting, QSettings::IniFormat); + udisk_unique_settings.setIniCodec(QTextCodec::codecForName("utf-8")); + udisk_unique_settings.remove(backupName); +} diff --git a/common/utils.h b/common/utils.h index 7453d96..5b092a7 100755 --- a/common/utils.h +++ b/common/utils.h @@ -104,6 +104,12 @@ public: */ static void excludeFstabBindPath(QStringList &excludes); + /** + * @brief 备份还原时,需要一些用户家目录下的路径,因为这些路径备份还原程序无权操作 + * @param excludes,存放需要排除的路径 + */ + static void excludeSomeHomePath(QStringList &excludes); + /** * @brief 生成rsync --exclude-from排除路径规则文件 * @return @@ -268,6 +274,12 @@ public: */ static void update_backup_unique_settings(const QString &uuid, const QString &backupName); + /** + * @brief 根据备份点名称,删除备份点uuid记录 + * @param backupName 备份点名称 + */ + static void deleteBackupUniqueRecord(const QString& backupName); + private: // 系统根目录,默认"/" static QString m_sysRootPath; diff --git a/kybackup/backuppointlistdialog.cpp b/kybackup/backuppointlistdialog.cpp index 79ae573..8f01ab3 100755 --- a/kybackup/backuppointlistdialog.cpp +++ b/kybackup/backuppointlistdialog.cpp @@ -1,12 +1,17 @@ #include "backuppointlistdialog.h" #include "ui_backuppointlistdialog.h" #include +#include #include "component/mylabel.h" #include "component/mypushbutton.h" +#include "../common/utils.h" +#include "globalbackupinfo.h" -BackupPointListDialog::BackupPointListDialog(QWidget *parent) : +BackupPointListDialog::BackupPointListDialog(QWidget *parent, bool isOnlyShowLocal) : QDialog(parent), - ui(new Ui::BackupPointListDialog) + ui(new Ui::BackupPointListDialog), + m_udector(new UdiskDetector()), + m_onlyShowLocal(isOnlyShowLocal) { ui->setupUi(this); // 到各个子类中去设置 @@ -15,6 +20,8 @@ BackupPointListDialog::BackupPointListDialog(QWidget *parent) : // this->setWindowFlags(Qt::WindowCloseButtonHint); // this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setMinimumSize(QSize(800, 368)); + // 设置背景色 this->setAutoFillBackground(true); QPalette palette = this->palette(); @@ -25,76 +32,128 @@ BackupPointListDialog::BackupPointListDialog(QWidget *parent) : QVBoxLayout *vlayout = new QVBoxLayout; vlayout->setContentsMargins(20, 0, 20, 10); - QStringList headerList; - headerList << tr("Backup Name") << tr("UUID") << tr("Backup Time") << tr("Backup Device") << QObject::tr("Backup State") << QObject::tr("PrefixPath"); + QStringList headerLabels; + // 注意:此处的列需要和枚举Column_Index一一对应 + headerLabels << tr("Backup Name") << tr("UUID") << tr("Backup Time") << tr("Backup Device") << QObject::tr("Backup State") << QObject::tr("PrefixPath"); m_tableWidget = new QTableWidget; - m_tableWidget->setColumnCount(headerList.size()); - m_tableWidget->setHorizontalHeaderLabels(headerList); + m_tableWidget->setColumnCount(headerLabels.size()); + m_tableWidget->setHorizontalHeaderLabels(headerLabels); + m_tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter); m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - m_tableWidget->setShowGrid(false); + m_tableWidget->horizontalHeader()->setTextElideMode( Qt::ElideRight); + m_tableWidget->horizontalHeader()->setFixedHeight(30); + m_tableWidget->verticalHeader()->setHidden(true); // 好像隐藏不掉 + m_tableWidget->verticalHeader()->setVisible(false); //左侧标题不可见 + m_tableWidget->verticalHeader()->setDefaultSectionSize(30); // 设置行高 m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); - // m_tableWidget->resizeColumnsToContents(); - m_tableWidget->hideColumn(5); + m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); + m_tableWidget->hideColumn(Column_Index::Prefix_Path); + m_tableWidget->setSortingEnabled(false); // 等录入完数据后再排序 + m_tableWidget->setAlternatingRowColors(true); + m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); vlayout->addWidget(m_tableWidget); - MyLabel *note = new MyLabel; - // 您可以删除不需要的备份,更多细节请参考“操作日志” - note->setDeplayText(tr("You can delete backup point")); - - MyPushButton * buttonDelete = new MyPushButton; - buttonDelete->setText(tr("Delete")); - m_bottomLayout = new QHBoxLayout; - m_bottomLayout->addWidget(note); - m_bottomLayout->addStretch(); - m_bottomLayout->addWidget(buttonDelete); - vlayout->addLayout(m_bottomLayout); this->setLayout(vlayout); + + // 添加本地默认路径、移动设备目录 + connect(m_udector, &UdiskDetector::udiskListChanged, this, [=](QList diskList) { + this->m_udiskPaths.clear(); + // 如果有备份分区,则将本地默认分区备份路径放在第一个 + if (GlobelBackupInfo::inst().hasBackupPartition()) { + this->m_udiskPaths << Utils::getSysRootPath(); + } + + if (this->m_onlyShowLocal) + return; + + // 移动设备挂载路径 + for (QStorageInfo& disk : diskList) { + this->m_udiskPaths << disk.rootPath(); + } + + emit this->udiskChange(); + }); + m_udector->getStorageInfo(); } BackupPointListDialog::~BackupPointListDialog() { + delete m_udector; delete ui; - delete m_tableWidget; } /** * @brief 获取本地和移动设备中的备份点 * @return */ -QList BackupPointListDialog::getBackupPointList(const QStringList& pathList) +QList BackupPointListDialog::getBackupPointList() { - QList list; - for (QString backupPath : pathList) { + QList list; + for (QString backupPath : m_udiskPaths) { backupPath += BACKUP_XML_PATH; + backupPath.replace("//", "/"); QFile xmlFile(backupPath); if (!xmlFile.exists() || 0 == xmlFile.size()) { continue; } - parseBackupList parse(backupPath); + ParseBackupList parse(backupPath); list.append(parse.getBackupPointList()); } return list; } -void BackupPointListDialog::updateTargetList() +/** + * @brief 屏蔽部分键盘 + * @param event + * @note 没有限制住QTableWidget子控件接收按键输入 + */ +void BackupPointListDialog::keyPressEvent(QKeyEvent* event) { - m_hasUsefulBackup = false; //是否存在有效备份 - m_hasOneBackup = false; //是否存在一个备份(包括有效和失败的备份) - m_tableWidget->clear(); - - QStringList allPaths; - allPaths << ""; //"" is / -// if (!m_onlyshowlocal) { -// QStringList udiskPaths = m_proxy->getAllUdiskPaths(); -// for (auto& path : udiskPaths) { -// allPaths << path; -// } -// } -// // readEveryPathBackupStorage(allPaths); -// insertLines(getBackupPointList(allPaths)); + switch (event->key()) { + case Qt::Key_Escape: + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Left: + case Qt::Key_Right: + //忽略,什么都不做 + break; + default: + QWidget::keyPressEvent(event); + } } + +/** + * @brief 设置QTableWidget的单元格内容 + * @param row + * @param column + * @param text + */ +void BackupPointListDialog::setItem(int row, int column, const QString& text, int alignFlag) +{ + QTableWidgetItem *item = new QTableWidgetItem; + item->setText(text); + item->setToolTip(text); + item->setTextAlignment(alignFlag); + m_tableWidget->setItem(row, column, item); +} + +/** + * @brief 获取单元格的内容 + * @param row + * @param column + * @return QString,单元格的内容 + */ +QString BackupPointListDialog::text(int row, int column) +{ + QTableWidgetItem *item = m_tableWidget->item(row, column); + if (item) + return item->text(); + else + return ""; +} + diff --git a/kybackup/backuppointlistdialog.h b/kybackup/backuppointlistdialog.h index 6ba34eb..6ef8132 100755 --- a/kybackup/backuppointlistdialog.h +++ b/kybackup/backuppointlistdialog.h @@ -5,6 +5,8 @@ #include #include #include +#include "../backup-daemon/parsebackuplist.h" +#include "./module/udiskdetector.h" namespace Ui { class BackupPointListDialog; @@ -13,21 +15,44 @@ class BackupPointListDialog; class BackupPointListDialog : public QDialog { Q_OBJECT - public: - explicit BackupPointListDialog(QWidget *parent = nullptr); - ~BackupPointListDialog(); + enum Column_Index { + Backup_Name = 0, + UUID, + Backup_Time, + Backup_Device, + Backup_State, + Prefix_Path + }; - void updateTargetList(); + explicit BackupPointListDialog(QWidget *parent = nullptr, bool isOnlyShowLocal = false); + virtual ~BackupPointListDialog(); + + QList getBackupPointList(); + + bool isOnlyShowLocal() const { return m_onlyShowLocal; } + +signals: + void udiskChange(); + void selected(ParseBackupList::BackupPoint); protected: + void keyPressEvent(QKeyEvent* event); + + void setItem(int row, int column, const QString& text, int alignFlag = Qt::AlignCenter); + QString text(int row, int column); + + QTableWidget *m_tableWidget; QHBoxLayout *m_bottomLayout = nullptr; private: Ui::BackupPointListDialog *ui; - QTableWidget * m_tableWidget; - bool m_hasUsefulBackup = false; //是否存在有效备份 - bool m_hasOneBackup = false; //是否存在一个备份(包括有效和失败的备份) + // U盘探测 + UdiskDetector* m_udector; + // U盘挂载路径列表 + QStringList m_udiskPaths; + // 是否只展示本地备份 + bool m_onlyShowLocal; }; #endif // BackupPointListDialog_H diff --git a/kybackup/component/mylabel.cpp b/kybackup/component/mylabel.cpp index 0e0fb4b..545e36d 100755 --- a/kybackup/component/mylabel.cpp +++ b/kybackup/component/mylabel.cpp @@ -4,6 +4,21 @@ #include #include +/** + * @brief 通用构造Label方法 + * @param parent + */ +MyLabel::MyLabel(QWidget* parent) : + QLabel(parent) +{ +} + +/** + * @brief 构造固定大小、颜色、内容居中等的label,一般用于label控件不会变化重绘的场景 + * @param text + * @param parent + * @param color + */ MyLabel::MyLabel(const QString& text, QWidget* parent /*= nullptr*/, QColor color /*= QColor(0xCC, 0xCC, 0xCC)*/) : QLabel(parent), m_text(text) @@ -16,11 +31,6 @@ MyLabel::MyLabel(const QString& text, QWidget* parent /*= nullptr*/, QColor colo this->setText(text); } -MyLabel::MyLabel(QWidget* parent) : - QLabel(parent) -{ -} - MyLabel::~MyLabel() {} @@ -41,24 +51,31 @@ void MyLabel::setFontSize(int size) this->setFont(font); } +/** + * @brief 设置字体是否自动换行展示 + * @param on + * @note 一般用于setGeometry固定label位置和大小的场景 + */ void MyLabel::setFontWordWrap(bool on) { m_bWordWrap = on; setWordWrap(on); - if (on) { - m_width = this->width(); - m_height = this->height(); - m_rect = geometry(); - } + m_width = this->width(); + m_height = this->height(); + m_rect = geometry(); } void MyLabel::paintEvent(QPaintEvent *event) { + // 1、场景一:布局动态变化场景,使用原始的QLabel绘制 if (m_isOriginal) { + this->setText(m_text); QLabel::paintEvent(event); + return ; } + // 2、场景二:setGeometry固定label位置和大小的场景 QFontMetrics fontMetrics(this->font()); int fontSize = fontMetrics.width(m_text); if (m_bWordWrap && m_width > 0) { diff --git a/kybackup/component/mylabel.h b/kybackup/component/mylabel.h index df8486f..89c6749 100755 --- a/kybackup/component/mylabel.h +++ b/kybackup/component/mylabel.h @@ -8,8 +8,8 @@ class MyLabel : public QLabel { Q_OBJECT public: - MyLabel(const QString& text, QWidget* parent = nullptr, QColor color = QColor(0xCC, 0xCC, 0xCC)); MyLabel(QWidget* parent = nullptr); + MyLabel(const QString& text, QWidget* parent = nullptr, QColor color = QColor(0xCC, 0xCC, 0xCC)); virtual ~MyLabel(); void setDeplayText(const QString& text) { m_text = text; QLabel::setText(text);} @@ -27,6 +27,7 @@ private: int m_width = 0; int m_height = 0; bool m_isOriginal = false; + bool m_needResize = false; QRect m_rect; }; diff --git a/kybackup/component/ringsprogressbar.cpp b/kybackup/component/ringsprogressbar.cpp index 62e2dac..587d848 100755 --- a/kybackup/component/ringsprogressbar.cpp +++ b/kybackup/component/ringsprogressbar.cpp @@ -24,14 +24,22 @@ void RingsProgressbar::paintEvent(QPaintEvent *) QString valueStr = QString("%1%").arg(QString::number(m_persent)); //画外圆 + QPen pen = p.pen(); p.setPen(Qt::NoPen); p.setBrush(QBrush(QColor(COLOR_LIGHT_BLUE))); p.drawEllipse(outRect); p.setBrush(QBrush(QColor(COLOR_BLUE))); + + //画圆弧 + pen.setCapStyle(Qt::RoundCap); + p.setPen(pen); p.drawPie(QRectF(5 , 5, side - 10, side - 10), (90-m_rotateAngle)*16, m_rotateAngle*16); + //画遮罩 + p.setPen(Qt::NoPen); p.setBrush(palette().window().color()); p.drawEllipse(inRect); + //画文字 QFont f = this->font(); f.setBold(true); diff --git a/kybackup/deletebackupdialog.cpp b/kybackup/deletebackupdialog.cpp new file mode 100644 index 0000000..6d2d098 --- /dev/null +++ b/kybackup/deletebackupdialog.cpp @@ -0,0 +1,223 @@ +#include "deletebackupdialog.h" +#include "ui_deletebackupdialog.h" +#include +#include +#include +#include +#include "xatom-helper.h" +#include "globalbackupinfo.h" +#include "../common/mydefine.h" +#include "../common/utils.h" +#include "messageboxutils.h" + +DeleteBackupDialog::DeleteBackupDialog(ParseBackupList::BackupPoint backupPonit, QWidget *parent) : + QDialog(parent), + ui(new Ui::DeleteBackupDialog), + m_backupPonit(backupPonit), + m_pInterface(nullptr) +{ + ui->setupUi(this); + setMinimumSize(450, 138); + setMaximumSize(450, 200); + + // 添加窗管协议 + MotifWmHints hints; + hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; + hints.functions = MWM_FUNC_ALL; + hints.decorations = MWM_DECOR_BORDER; + XAtomHelper::getInstance()->setWindowMotifHint(winId(), hints); + setWindowModality(Qt::WindowModal); + + // 设置背景色 + this->setAutoFillBackground(true); + QPalette palette = this->palette(); + palette.setColor(QPalette::Background, palette.color(QPalette::Base)); + this->setPalette(palette); + + // 设置标题栏 + QHBoxLayout * titleLayout = new QHBoxLayout(); + + // logo + m_mTitleIcon = new QLabel; + m_mTitleIcon->setFixedSize(24, 24); + QIcon titleIcon = QIcon::fromTheme(THEME_YHKYLIN_BACKUP_TOOLS); + m_mTitleIcon->setPixmap(titleIcon.pixmap(titleIcon.actualSize(QSize(24, 24)))); + + // 标题 + m_titleLabel = new MyLabel; + m_titleLabel->setFixedSize(380, 30); + m_titleLabel->setDeplayText(tr("Please wait while data is being removed")); + m_titleLabel->setToolTip(tr("Please wait while data is being removed")); + + // 关闭按钮 + m_buttonClose = new QPushButton; + m_buttonClose->setProperty("isWindowButton", 0x2); + m_buttonClose->setProperty("useIconHighlightEffect", 0x8); + m_buttonClose->setFlat(true); + m_buttonClose->setFixedSize(30, 30); + m_buttonClose->setIcon(QIcon::fromTheme("window-close-symbolic")); + + titleLayout->addWidget(m_mTitleIcon); + titleLayout->addWidget(m_titleLabel); + titleLayout->addStretch(); + titleLayout->addWidget(m_buttonClose); + + // 提示信息 + m_labelMessage = new MyLabel; + m_labelMessage->setIsOriginal(true); + m_labelMessage->setWordWrap(true); + // 正在删除备份点 + m_labelMessage->setDeplayText(tr("Removing backup point...")); + + // 等待图标 + m_loadingGif = new QLabel; + m_loadingGif->setFixedSize(24,24); + // 等待动画 + m_movie = new QMovie(":/images/loading.gif", QByteArray(), this); + m_loadingGif->setMovie(m_movie); + + QHBoxLayout *layoutTop = new QHBoxLayout; + layoutTop->addSpacing(20); + layoutTop->addWidget(m_labelMessage); + layoutTop->addWidget(m_loadingGif); + layoutTop->addSpacing(20); + + // 确定按钮 + m_buttonOk = new MyPushButton; + m_buttonOk->setText(tr("Ok")); + + QHBoxLayout *layoutBottom = new QHBoxLayout; + layoutBottom->addStretch(); + layoutBottom->addWidget(m_buttonOk); + + QVBoxLayout *vlayout = new QVBoxLayout; + vlayout->addLayout(titleLayout); + vlayout->addStretch(); + vlayout->addLayout(layoutTop); + vlayout->addStretch(); + vlayout->addLayout(layoutBottom); + + connect(m_buttonClose, &MyPushButton::clicked, this, &DeleteBackupDialog::close); + connect(m_buttonOk, &MyPushButton::clicked, this, &DeleteBackupDialog::close); + + setLayout(vlayout); + + deleteBackupPoint(); +} + +DeleteBackupDialog::~DeleteBackupDialog() +{ + delete ui; + delete m_pInterface; +} + +/** + * @brief 删除备份点 + * @param backupPonit + */ +void DeleteBackupDialog::deleteBackupPoint() +{ + m_buttonClose->hide(); + m_buttonOk->setEnabled(false); + m_movie->start(); + + GlobelBackupInfo::inst().setIsBusy(true); + m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this); + connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DeleteBackupDialog::on_checkEnv_end); + connect(m_pInterface, &ComKylinBackupManagerInterface::sendDeleteResult, this, &DeleteBackupDialog::on_deleteBackup_end); + + // 是否已存在备份、还原等操作 + bool isActive = false; + if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){ + m_labelMessage->setDeplayText(tr("Other backup or restore task is being performed")); + m_buttonClose->show(); + m_buttonOk->setEnabled(true); + m_movie->stop(); + m_loadingGif->hide(); + emit deleteFinished(false); + + GlobelBackupInfo::inst().setIsBusy(false); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DeleteBackupDialog::on_checkEnv_end); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendDeleteResult, this, &DeleteBackupDialog::on_deleteBackup_end); + delete m_pInterface; + m_pInterface = nullptr; + + return; + } + + BackupWrapper backupWrapper; + backupWrapper.m_backupName = m_backupPonit.m_backupName; + backupWrapper.m_uuid = m_backupPonit.m_uuid; + backupWrapper.m_prefixDestPath = m_backupPonit.m_path; + backupWrapper.m_type = BackupType::DELETE_BACKUP; + QString udiskPrePath = Utils::getSysRootPath(); + udiskPrePath += "/media"; + udiskPrePath.replace("//", "/"); + backupWrapper.m_iPosition = m_backupPonit.m_path.startsWith(udiskPrePath) ? BackupPosition::UDISK : BackupPosition::LOCAL; + backupWrapper.m_frontUid = getuid(); + backupWrapper.m_gid = getgid(); + m_pInterface->deleteBackupPoint(backupWrapper); +} + +/** + * @brief 环境校验结果 + * @param result + */ +void DeleteBackupDialog::on_checkEnv_end(int result) +{ + bool bRst = false; + QString errMsg; + switch (result) { + case int(BackupResult::LOCK_PROGRAM_FAIL): + // 程序锁定失败,请重试 + errMsg = tr("Program lock failed, please retry"); + break; + case int(BackupResult::NO_FOUND_DEALCLASS): + // 不支持的任务类型 + errMsg = tr("Unsupported task type"); + break; + default: + bRst = true; + } + + if (!bRst) { + m_labelMessage->setDeplayText(errMsg); + m_buttonClose->show(); + m_buttonOk->setEnabled(true); + m_movie->stop(); + m_loadingGif->hide(); + emit deleteFinished(false); + + GlobelBackupInfo::inst().setIsBusy(false); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DeleteBackupDialog::on_checkEnv_end); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendDeleteResult, this, &DeleteBackupDialog::on_deleteBackup_end); + delete m_pInterface; + m_pInterface = nullptr; + } +} + +/** + * @brief 删除备份点结果 + * @param result + */ +void DeleteBackupDialog::on_deleteBackup_end(bool result) +{ + if (result) { + // 备份删除成功 + m_labelMessage->setDeplayText(tr("Deleted backup successfully.")); + } else + m_labelMessage->setDeplayText(tr("Failed to delete backup.")); + + m_buttonClose->show(); + m_buttonOk->setEnabled(true); + m_movie->stop(); + m_loadingGif->hide(); + emit deleteFinished(result); + + GlobelBackupInfo::inst().setIsBusy(false); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &DeleteBackupDialog::on_checkEnv_end); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendDeleteResult, this, &DeleteBackupDialog::on_deleteBackup_end); + delete m_pInterface; + m_pInterface = nullptr; +} + diff --git a/kybackup/deletebackupdialog.h b/kybackup/deletebackupdialog.h new file mode 100644 index 0000000..6d5ff1a --- /dev/null +++ b/kybackup/deletebackupdialog.h @@ -0,0 +1,49 @@ +#ifndef DELETEBACKUPDIALOG_H +#define DELETEBACKUPDIALOG_H + +#include +#include +#include +#include "component/mylabel.h" +#include "component/mypushbutton.h" +#include "backup_manager_interface.h" +#include "../backup-daemon/parsebackuplist.h" + +namespace Ui { +class DeleteBackupDialog; +} + +class DeleteBackupDialog : public QDialog +{ + Q_OBJECT + +public: + explicit DeleteBackupDialog(ParseBackupList::BackupPoint backupPonit, QWidget *parent = nullptr); + ~DeleteBackupDialog(); + +signals: + void deleteFinished(bool result); + +public slots: + void on_checkEnv_end(int result); + void on_deleteBackup_end(bool result); + +private: + void deleteBackupPoint(); + + Ui::DeleteBackupDialog *ui; + ParseBackupList::BackupPoint m_backupPonit; + + QLabel *m_mTitleIcon; + MyLabel *m_titleLabel; + QPushButton *m_buttonClose; + MyLabel *m_labelMessage; + QLabel *m_loadingGif; + QMovie *m_movie; + MyPushButton *m_buttonOk; + + // dbus接口 + ComKylinBackupManagerInterface *m_pInterface; +}; + +#endif // DELETEBACKUPDIALOG_H diff --git a/kybackup/deletebackupdialog.ui b/kybackup/deletebackupdialog.ui new file mode 100644 index 0000000..10133ad --- /dev/null +++ b/kybackup/deletebackupdialog.ui @@ -0,0 +1,19 @@ + + + DeleteBackupDialog + + + + 0 + 0 + 400 + 138 + + + + Dialog + + + + + diff --git a/kybackup/kybackup.pro b/kybackup/kybackup.pro index 1aed805..467757b 100755 --- a/kybackup/kybackup.pro +++ b/kybackup/kybackup.pro @@ -49,6 +49,7 @@ HEADERS += \ component/mylineedit.h \ component/mypushbutton.h \ component/ringsprogressbar.h \ + deletebackupdialog.h \ functypeconverter.h \ globalbackupinfo.h \ globalsignals.h \ @@ -56,6 +57,8 @@ HEADERS += \ leftsiderbarwidget.h \ maindialog.h \ messageboxutils.h \ + module/managebackuppointlist.h \ + module/selectrestorepoint.h \ module/systembackup.h \ module/systemrestore.h \ module/udiskdetector.h \ @@ -83,12 +86,15 @@ SOURCES += \ component/mylineedit.cpp \ component/mypushbutton.cpp \ component/ringsprogressbar.cpp \ + deletebackupdialog.cpp \ functypeconverter.cpp \ gsettingswrapper.cpp \ leftsiderbarwidget.cpp \ main.cpp \ maindialog.cpp \ messageboxutils.cpp \ + module/managebackuppointlist.cpp \ + module/selectrestorepoint.cpp \ module/systembackup.cpp \ module/systemrestore.cpp \ module/udiskdetector.cpp \ @@ -100,6 +106,7 @@ SOURCES += \ FORMS += \ backuppointlistdialog.ui \ + deletebackupdialog.ui \ maindialog.ui TRANSLATIONS += qt_zh_CN.ts diff --git a/kybackup/messageboxutils.cpp b/kybackup/messageboxutils.cpp index 92f7f6f..df1f12d 100755 --- a/kybackup/messageboxutils.cpp +++ b/kybackup/messageboxutils.cpp @@ -10,13 +10,8 @@ void MessageBoxUtils::QMESSAGE_BOX_WARNING(QWidget* q_parent, const QString& typ box.setIcon(QMessageBox::Warning); box.setWindowTitle(typelabel); box.setText(message); - box.setStandardButtons(QMessageBox::Ok); box.setButtonText(QMessageBox::Ok, label); - //add title icon - QIcon titleIcon = QIcon::fromTheme("yhkylin-backup-tools"); - box.setWindowIcon(titleIcon); - GSettingsWrapper::connectUkuiStyleSchema(&box); box.exec(); } @@ -27,14 +22,9 @@ bool MessageBoxUtils::QMESSAGE_BOX_WARNING_CANCEL(QWidget *q_parent, const QStri box.setIcon(QMessageBox::Warning); box.setWindowTitle(typelabel); box.setText(message); - box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); box.setButtonText(QMessageBox::Ok, label_yes); box.setButtonText(QMessageBox::Cancel, label_no); - //add title icon - QIcon titleIcon = QIcon::fromTheme("yhkylin-backup-tools"); - box.setWindowIcon(titleIcon); - GSettingsWrapper::connectUkuiStyleSchema(&box); if (box.exec() != QMessageBox::Ok) return false; return true; @@ -46,12 +36,7 @@ void MessageBoxUtils::QMESSAGE_BOX_CRITICAL(QWidget* q_parent, const QString& ty box.setIcon(QMessageBox::Critical); box.setWindowTitle(typelabel); box.setText(message); - box.setStandardButtons(QMessageBox::Ok); box.setButtonText(QMessageBox::Ok, label); - //add title icon - QIcon titleIcon = QIcon::fromTheme("yhkylin-backup-tools"); - box.setWindowIcon(titleIcon); - GSettingsWrapper::connectUkuiStyleSchema(&box); box.exec(); } diff --git a/kybackup/module/managebackuppointlist.cpp b/kybackup/module/managebackuppointlist.cpp new file mode 100644 index 0000000..73aa2a3 --- /dev/null +++ b/kybackup/module/managebackuppointlist.cpp @@ -0,0 +1,162 @@ +#include "managebackuppointlist.h" +#include +#include +#include +#include "component/mylabel.h" +#include "component/mypushbutton.h" +#include "../../common/utils.h" +#include "../globalbackupinfo.h" +#include "../deletebackupdialog.h" +#include "messageboxutils.h" + +ManageBackupPointList::ManageBackupPointList(QWidget *parent, BackupPointType backupType) : + BackupPointListDialog(parent), + m_backupType(backupType) +{ + if (BackupPointType::SYSTEM == backupType) { + this->setWindowTitle(tr("System Backup Information")); + } else { + this->setWindowTitle(tr("Data Backup Information")); + } + + // 隐藏备份点状态Backup State字段 + initTableWidget(); + + // 您可以删除不需要的备份,更多细节请参考“操作日志” + MyLabel *labelTips = new MyLabel; + labelTips->setIsOriginal(true); + labelTips->setWordWrap(true); + //labelTips->adjustSize(); + labelTips->setDeplayText(tr("You can delete the backup that is't needed, refer operation logs for more details")); + + MyPushButton * buttonDelete = new MyPushButton; + buttonDelete->setText(tr("Delete")); + + m_bottomLayout->addWidget(labelTips); + m_bottomLayout->addStretch(); + m_bottomLayout->addWidget(buttonDelete); + + connect(buttonDelete, &MyPushButton::clicked, this, [=](){ + // 判断是否已经选中备份点 + QList selectList = this->m_tableWidget->selectedItems(); + if (selectList.isEmpty()) { + MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"), QObject::tr("Please select one backup to continue."), QObject::tr("Ok")); + return; + } + + // 是否确认删除此备份 + if (MessageBoxUtils::QMESSAGE_BOX_WARNING_CANCEL(this, QObject::tr("Warning"), QObject::tr("Are you sure to delete the backup ?"), QObject::tr("Ok"), QObject::tr("Cancel"))) { + int curRow = this->m_tableWidget->currentRow(); + ParseBackupList::BackupPoint backupPoint; + backupPoint.m_backupName = this->text(curRow, Column_Index::Backup_Name); + backupPoint.m_uuid = this->text(curRow, Column_Index::UUID); + backupPoint.m_time = this->text(curRow, Column_Index::Backup_Time); + backupPoint.m_path = this->text(curRow, Column_Index::Prefix_Path); + m_deleteRow = curRow; + + emit selected(backupPoint); + } + }); + + connect(this, &ManageBackupPointList::selected, this, &ManageBackupPointList::deleteBackupPoint); + connect(this, &ManageBackupPointList::udiskChange, this, &ManageBackupPointList::initTableWidget); +} + +ManageBackupPointList::~ManageBackupPointList() +{ + +} + +void ManageBackupPointList::initTableWidget() +{ + m_tableWidget->clearContents(); + m_tableWidget->setRowCount(0); + m_tableWidget->setSortingEnabled(false); // 等录入完数据后再排序 + insertLines(getBackupPointList()); +} + +void ManageBackupPointList::insertLines(const QList &backupPoints) +{ + QString settingPath = Utils::getSysRootPath() + UDISK_UNIQUE_SETTINGS; + settingPath.replace("//", "/"); + QSettings udisk_setting(settingPath, QSettings::IniFormat); + udisk_setting.setIniCodec(QTextCodec::codecForName("utf-8")); + + int indexOfRow = 0; + QString preDevPath(Utils::getSysRootPath()); + preDevPath += "/media"; + preDevPath.replace("//", "/"); + for (const ParseBackupList::BackupPoint& backupPoint : backupPoints) { + // 系统备份排除非系统备份且非增量系统备份 + if (BackupPointType::SYSTEM == m_backupType && + int(BackupType::BACKUP_SYSTEM) != backupPoint.m_type && + int(BackupType::INC_BACKUP_SYSTEM) != backupPoint.m_type) + continue; + else if (BackupPointType::DATA == m_backupType && + int(BackupType::BACKUP_DATA) != backupPoint.m_type && + int(BackupType::INC_BACKUP_DATA) != backupPoint.m_type) + continue; + + //hide factory backup + if (backupPoint.m_uuid == FACTORY_BACKUP_UUID) + continue; + + //udisk unique + if (backupPoint.m_path.startsWith(preDevPath)) { + udisk_setting.beginGroup(backupPoint.m_backupName); + QString localuuid = udisk_setting.value("uuid").toString(); + udisk_setting.endGroup(); + if (localuuid != backupPoint.m_uuid) { + continue; + } + } + + m_tableWidget->insertRow(indexOfRow); + setItem(indexOfRow, Column_Index::Backup_Name, backupPoint.m_backupName); + setItem(indexOfRow, Column_Index::UUID, backupPoint.m_uuid, Qt::AlignLeft | Qt::AlignVCenter); + setItem(indexOfRow, Column_Index::Backup_Time, backupPoint.m_time); + + QString prefixPath_to_device; + if (backupPoint.m_path.startsWith(preDevPath)) { + QStringList ql = backupPoint.m_path.split("/"); + QString udiskName = ql.last(); + prefixPath_to_device = QObject::tr("Udisk Device:") + " " + udiskName; + } else { + prefixPath_to_device = QObject::tr("Local Disk"); + } + setItem(indexOfRow, Column_Index::Backup_Device, prefixPath_to_device); + if (backupPoint.m_state == BACKUP_PARSE_STATE_SUCCESS_STRTING) { + setItem(indexOfRow, Column_Index::Backup_State, tr("backup finished")); + } else { + setItem(indexOfRow, Column_Index::Backup_State, tr("backup unfinished")); + } + setItem(indexOfRow, Column_Index::Prefix_Path, backupPoint.m_path); + + ++indexOfRow; + } + + if (0 < indexOfRow) { + m_tableWidget->setSortingEnabled(true); // 等录入完数据后再排序 + m_tableWidget->sortItems(Column_Index::Backup_Time, Qt::DescendingOrder); + } else { + // TODO: 无记录时展示图片 + } +} + +/** + * @brief 删除备份点 + * @param backupPonit + */ +void ManageBackupPointList::deleteBackupPoint(ParseBackupList::BackupPoint backupPonit) +{ + DeleteBackupDialog *deleteDialog = new DeleteBackupDialog(backupPonit, this); + connect(deleteDialog, &DeleteBackupDialog::deleteFinished, this, [=](bool result) { + if (result) + this->m_tableWidget->removeRow(m_deleteRow); + m_deleteRow = -1; + }); + deleteDialog->exec(); + deleteDialog->deleteLater(); +} + + diff --git a/kybackup/module/managebackuppointlist.h b/kybackup/module/managebackuppointlist.h new file mode 100644 index 0000000..b61c097 --- /dev/null +++ b/kybackup/module/managebackuppointlist.h @@ -0,0 +1,32 @@ +#ifndef MANAGEBACKUPPOINTLIST_H +#define MANAGEBACKUPPOINTLIST_H + +#include "../backuppointlistdialog.h" + +class ManageBackupPointList : public BackupPointListDialog +{ + Q_OBJECT +public: + enum BackupPointType { + DATA, + SYSTEM + }; + + explicit ManageBackupPointList(QWidget *parent = nullptr, BackupPointType backupType = BackupPointType::SYSTEM); + virtual ~ManageBackupPointList(); + +public slots: + void initTableWidget(); + void deleteBackupPoint(ParseBackupList::BackupPoint backupPonit); + +private: + void insertLines(const QList &backupPoints); + +private: + // 备份点类型,如系统备份、数据备份 + BackupPointType m_backupType; + // 删除的行索引 + int m_deleteRow = -1; +}; + +#endif // MANAGEBACKUPPOINTLIST_H diff --git a/kybackup/module/selectrestorepoint.cpp b/kybackup/module/selectrestorepoint.cpp new file mode 100644 index 0000000..b3d04a2 --- /dev/null +++ b/kybackup/module/selectrestorepoint.cpp @@ -0,0 +1,156 @@ +#include "selectrestorepoint.h" +#include +#include +#include "component/mypushbutton.h" +#include "../../common/utils.h" +#include "messageboxutils.h" + +SelectRestorePoint::SelectRestorePoint(QWidget *parent, BackupPointType backupType) : + BackupPointListDialog(parent), + m_backupType(backupType) +{ + if (BackupPointType::SYSTEM == backupType) { + this->setWindowTitle(tr("System Backup Information")); + } else { + this->setWindowTitle(tr("Data Backup Information")); + } + + // 隐藏备份点状态Backup State字段 + m_tableWidget->hideColumn(Column_Index::Backup_State); + initTableWidget(); + + MyPushButton * buttonOk = new MyPushButton; + buttonOk->setText(tr("Ok")); + MyPushButton * buttonCancel = new MyPushButton; + buttonCancel->setText(tr("Cancel")); + + m_bottomLayout->addStretch(); + m_bottomLayout->addWidget(buttonOk); + m_bottomLayout->addWidget(buttonCancel); + + connect(buttonCancel, &MyPushButton::clicked, this, [=]() { + this->close(); + }); + + connect(this, &SelectRestorePoint::udiskChange, this, &SelectRestorePoint::initTableWidget); + + connect(buttonOk, &MyPushButton::clicked, this, [=](){ + // 判断是否已经选中备份点 + QList selectList = this->m_tableWidget->selectedItems(); + if (selectList.isEmpty()) { + MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"), QObject::tr("Please select one backup to continue."), QObject::tr("Ok")); + return; + } + + // 还原相应备份点 + if (MessageBoxUtils::QMESSAGE_BOX_WARNING_CANCEL(this, QObject::tr("Warning"), QObject::tr("Do you want to continue?"), QObject::tr("Continue"), QObject::tr("Cancel"))) { + int curRow = this->m_tableWidget->currentRow(); + ParseBackupList::BackupPoint backupPoint; + backupPoint.m_backupName = this->text(curRow, Column_Index::Backup_Name); + backupPoint.m_uuid = this->text(curRow, Column_Index::UUID); + backupPoint.m_time = this->text(curRow, Column_Index::Backup_Time); + backupPoint.m_path = this->text(curRow, Column_Index::Prefix_Path); + + emit selected(backupPoint); + this->close(); + } + }); +} + +SelectRestorePoint::~SelectRestorePoint() +{} + +void SelectRestorePoint::initTableWidget() +{ + m_tableWidget->clearContents(); + m_tableWidget->setRowCount(0); + m_tableWidget->setSortingEnabled(false); // 等录入完数据后再排序 + insertLines(getBackupPointList()); +} + +void SelectRestorePoint::insertLines(const QList &backupPoints) +{ + QString settingPath = Utils::getSysRootPath() + UDISK_UNIQUE_SETTINGS; + settingPath.replace("//", "/"); + QSettings udisk_setting(settingPath, QSettings::IniFormat); + udisk_setting.setIniCodec(QTextCodec::codecForName("utf-8")); + + int indexOfRow = 0; + for (const ParseBackupList::BackupPoint& backupPoint : backupPoints) { + // 系统备份排除非系统备份且非增量系统备份 + if (BackupPointType::SYSTEM == m_backupType && + int(BackupType::BACKUP_SYSTEM) != backupPoint.m_type && + int(BackupType::INC_BACKUP_SYSTEM) != backupPoint.m_type) + continue; + else if (BackupPointType::DATA == m_backupType && + int(BackupType::BACKUP_DATA) != backupPoint.m_type && + int(BackupType::INC_BACKUP_DATA) != backupPoint.m_type) + continue; + + // 不展示未完成的备份点 + if (BACKUP_PARSE_STATE_SUCCESS_STRTING != backupPoint.m_state) + continue; + + //hide factory backup + if (backupPoint.m_uuid == FACTORY_BACKUP_UUID) + continue; + + //udisk unique + bool isOther = false; + QString preDevPath(Utils::getSysRootPath()); + preDevPath += "/media"; + preDevPath.replace("//", "/"); + if (backupPoint.m_path.startsWith(preDevPath)) { + udisk_setting.beginGroup(backupPoint.m_backupName); + QString localuuid = udisk_setting.value("uuid").toString(); + udisk_setting.endGroup(); + if (localuuid != backupPoint.m_uuid) { + if (BackupPointType::SYSTEM != m_backupType) + continue; + + if ( + backupPoint.m_os.left(backupPoint.m_os.length() - 1) != SystemInfo::m_os.left(SystemInfo::m_os.length() - 1) + || backupPoint.m_arch != SystemInfo::m_arch + || backupPoint.m_archdetect != SystemInfo::m_archDetect + ) { + qDebug() << "localuuid is " << localuuid << ", backupUUID is " << backupPoint.m_uuid; + continue; + } else { + isOther = true; + } + + } + } + + m_tableWidget->insertRow(indexOfRow); + setItem(indexOfRow, Column_Index::Backup_Name, backupPoint.m_backupName); + setItem(indexOfRow, Column_Index::UUID, backupPoint.m_uuid, Qt::AlignLeft | Qt::AlignVCenter); + setItem(indexOfRow, Column_Index::Backup_Time, backupPoint.m_time); + + QString prefixPath_to_device; + if (backupPoint.m_path.startsWith(preDevPath)) { + QStringList ql = backupPoint.m_path.split("/"); + QString udiskName = ql.last(); + if (isOther) + prefixPath_to_device = QObject::tr("Other machine:") + " " + udiskName; + else + prefixPath_to_device = QObject::tr("Udisk Device:") + " " + udiskName; + } else { + prefixPath_to_device = QObject::tr("Local Disk"); + } + setItem(indexOfRow, Column_Index::Backup_Device, prefixPath_to_device); + setItem(indexOfRow, Column_Index::Backup_State, backupPoint.m_state); + setItem(indexOfRow, Column_Index::Prefix_Path, backupPoint.m_path); + + ++indexOfRow; + } + + if (0 < indexOfRow) { + m_tableWidget->setSortingEnabled(true); // 等录入完数据后再排序 + m_tableWidget->sortItems(Column_Index::Backup_Time, Qt::DescendingOrder); + } else { + // TODO: 无记录时展示图片 + } +} + + diff --git a/kybackup/module/selectrestorepoint.h b/kybackup/module/selectrestorepoint.h new file mode 100644 index 0000000..ec87496 --- /dev/null +++ b/kybackup/module/selectrestorepoint.h @@ -0,0 +1,28 @@ +#ifndef SELECTRESTOREPOINT_H +#define SELECTRESTOREPOINT_H + +#include "../backuppointlistdialog.h" + +class SelectRestorePoint : public BackupPointListDialog +{ + Q_OBJECT +public: + enum BackupPointType { + DATA, + SYSTEM + }; + + explicit SelectRestorePoint(QWidget *parent = nullptr, BackupPointType backupType = BackupPointType::SYSTEM); + virtual ~SelectRestorePoint(); + +public slots: + void initTableWidget(); + +private: + void insertLines(const QList &backupPoints); + +private: + BackupPointType m_backupType; +}; + +#endif // SELECTRESTOREPOINT_H diff --git a/kybackup/module/systembackup.cpp b/kybackup/module/systembackup.cpp index a308238..3ef8144 100755 --- a/kybackup/module/systembackup.cpp +++ b/kybackup/module/systembackup.cpp @@ -17,6 +17,7 @@ #include "../component/ringsprogressbar.h" #include "../../common/utils.h" #include "../globalbackupinfo.h" +#include "managebackuppointlist.h" SystemBackup::SystemBackup(QWidget *parent /*= nullptr*/) : QStackedWidget(parent), @@ -141,7 +142,10 @@ void SystemBackup::initFirstWidget() bottomHBoxLayout->addWidget(backupPointManage); bottomHBoxLayout->addSpacing(20); - connect(backupPointManage, &ClickLabel::clicked, this, &SystemBackup::on_systemBackupManage_clicked); + connect(backupPointManage, &ClickLabel::clicked, this, [=]() { + ManageBackupPointList backupManager(first); + backupManager.exec(); + }); addWidget(first); } @@ -172,14 +176,6 @@ void SystemBackup::on_next_clicked(bool checked) } } -/** - * @brief 系统备份管理响应槽 - */ -void SystemBackup::on_systemBackupManage_clicked() -{ - // TODO:创建系统备份点管理界面 -} - /** * @brief 初始化第二个页面 */ diff --git a/kybackup/module/systembackup.h b/kybackup/module/systembackup.h index 27a29ae..b2884b6 100755 --- a/kybackup/module/systembackup.h +++ b/kybackup/module/systembackup.h @@ -52,7 +52,6 @@ signals: public slots: void on_pre_clicked(bool checked = false); void on_next_clicked(bool checked = false); - void on_systemBackupManage_clicked(); void on_checkEnv_start(); void on_checkEnv_end(int result); void on_backup_start(); diff --git a/kybackup/module/systemrestore.cpp b/kybackup/module/systemrestore.cpp index 668841f..f30a22f 100755 --- a/kybackup/module/systemrestore.cpp +++ b/kybackup/module/systemrestore.cpp @@ -20,7 +20,7 @@ #include "../../common/utils.h" #include "../globalbackupinfo.h" #include "messageboxutils.h" -#include "backuppointlistdialog.h" +#include "selectrestorepoint.h" SystemRestore::SystemRestore(QWidget *parent) : QStackedWidget(parent) @@ -200,7 +200,7 @@ void SystemRestore::on_button_beginRestore_clicked(bool checked) m_uuid = FACTORY_BACKUP_UUID; } else { // 系统备份点列表中选择备份点 - BackupPointListDialog *backupPointListDialog = new BackupPointListDialog(this); + SelectRestorePoint *backupPointListDialog = new SelectRestorePoint(this); backupPointListDialog->exec(); } } diff --git a/kybackup/module/udiskdetector.cpp b/kybackup/module/udiskdetector.cpp index 91ff088..dbd5d22 100755 --- a/kybackup/module/udiskdetector.cpp +++ b/kybackup/module/udiskdetector.cpp @@ -49,6 +49,13 @@ void UdiskDetector::getStorageInfo() emit udiskListChanged(m_udiskList); } +void UdiskDetector::setDiskList(QList udiskList) +{ + m_udiskList.clear(); + m_udiskList.append(udiskList); + emit udiskListChanged(m_udiskList); +} + void UdiskDetector::refreshDiskList() { if (diskRefreshDelay->isActive()) { diff --git a/kybackup/module/udiskdetector.h b/kybackup/module/udiskdetector.h index ede4a4e..af647d0 100755 --- a/kybackup/module/udiskdetector.h +++ b/kybackup/module/udiskdetector.h @@ -23,14 +23,7 @@ public: } public slots: - void setDiskList(QList udiskList) - { - if (m_udiskList == udiskList) - return; - - m_udiskList = udiskList; - emit udiskListChanged(m_udiskList); - } + void setDiskList(QList udiskList); signals: void udiskListChanged(QList udiskList);