diff --git a/common/singleton.h b/common/singleton.h index 0b061f7..beb5da5 100755 --- a/common/singleton.h +++ b/common/singleton.h @@ -15,7 +15,6 @@ #ifndef SINGLETON_H_ #define SINGLETON_H_ - template class Singleton { diff --git a/kybackup/globalbackupinfo.h b/kybackup/globalbackupinfo.h index 9ed0199..e60dcb9 100644 --- a/kybackup/globalbackupinfo.h +++ b/kybackup/globalbackupinfo.h @@ -3,6 +3,8 @@ #include "../common/singleton.h" #include "../common/spinlock_mutex.h" +#include "functypeconverter.h" +#include "globalsignals.h" class GlobelBackupInfo : public Singleton { public: @@ -13,6 +15,7 @@ public: void setIsBusy(bool isBusy) { std::lock_guard lock(m_interMutex); m_isBusy = isBusy; + emit m_globalSignals.busy(isBusy); } // 是否正在进行备份、还原等操作 @@ -31,6 +34,20 @@ public: return m_hasBackupPartition; } + // 设置当前功能类型 + void setFuncType(FuncTypeConverter::FunType type) { + m_funcType = type; + } + + // 获取当前功能类型 + FuncTypeConverter::FunType getFuncType() { + return m_funcType; + } + + GlobalSignals * getGlobalSignals() { + return &m_globalSignals; + } + void lock() { m_outerMutex.lock(); } @@ -48,6 +65,11 @@ private: bool m_isBusy = false; // 是否有备份分区 bool m_hasBackupPartition = true; + // 当前功能类型 + FuncTypeConverter::FunType m_funcType = FuncTypeConverter::FunType::TOTALMODULES; + + // 全局信号对象 + GlobalSignals m_globalSignals; spinlock_mutex m_interMutex; spinlock_mutex m_outerMutex; diff --git a/kybackup/globalsignals.h b/kybackup/globalsignals.h new file mode 100644 index 0000000..86f94f8 --- /dev/null +++ b/kybackup/globalsignals.h @@ -0,0 +1,17 @@ +#ifndef GLOBALSIGNALS_H +#define GLOBALSIGNALS_H + +#include + +class GlobalSignals : public QObject +{ + Q_OBJECT +public: + GlobalSignals() = default; + ~GlobalSignals() = default; + +signals: + void busy(bool isBusy); +}; + +#endif // GLOBALSIGNALS_H diff --git a/kybackup/kybackup.pro b/kybackup/kybackup.pro index 20bb3f7..83c19d5 100644 --- a/kybackup/kybackup.pro +++ b/kybackup/kybackup.pro @@ -49,10 +49,12 @@ HEADERS += \ component/ringsprogressbar.h \ functypeconverter.h \ globalbackupinfo.h \ + globalsignals.h \ gsettingswrapper.h \ leftsiderbarwidget.h \ maindialog.h \ module/systembackup.h \ + module/systemrestore.h \ module/udiskdetector.h \ qtsingleapplication/qtlocalpeer.h \ qtsingleapplication/qtlockedfile.h \ @@ -82,6 +84,7 @@ SOURCES += \ main.cpp \ maindialog.cpp \ module/systembackup.cpp \ + module/systemrestore.cpp \ module/udiskdetector.cpp \ qtsingleapplication/qtlocalpeer.cpp \ qtsingleapplication/qtlockedfile.cpp \ diff --git a/kybackup/leftsiderbarwidget.cpp b/kybackup/leftsiderbarwidget.cpp index 213515c..e090b78 100644 --- a/kybackup/leftsiderbarwidget.cpp +++ b/kybackup/leftsiderbarwidget.cpp @@ -5,7 +5,7 @@ #include #include "../common/mydefine.h" #include "component/myiconbutton.h" -#include +#include "globalbackupinfo.h" LeftsiderbarWidget::LeftsiderbarWidget(QWidget *parent, StartMode mode) : QWidget(parent) @@ -36,17 +36,26 @@ LeftsiderbarWidget::LeftsiderbarWidget(QWidget *parent, StartMode mode) // 功能列表 int funcNum = FuncTypeConverter::FunType::TOTALMODULES; - if (StartMode::livecd == mode) - funcNum = 2; + if (StartMode::livecd == mode) { + m_deplayFuncs << "BACKUP_SYSTEM" << "RESTORE_SYSTEM"; + } else if (StartMode::std_user == mode) { + m_deplayFuncs << "BACKUP_DATA" << "RESTORE_DATA" << "OPERATION_LOG"; + } else { + m_deplayFuncs << "BACKUP_SYSTEM" << "RESTORE_SYSTEM" << "BACKUP_DATA" << "RESTORE_DATA" << "OPERATION_LOG" << "GHOST_IMAGE"; + } + m_funcGroup = new QButtonGroup(this); FuncTypeConverter kvConverter; for (int type = 0; type < funcNum; ++type) { + QString mnameString = kvConverter.keycodeTokeystring(type); //设置TEXT + if (!m_deplayFuncs.contains(mnameString)) + continue ; + QString themeIconName = kvConverter.keycodeToThemeIconString(type); QString mnamei18nString = kvConverter.keycodeTokeyi18nstring(type); //设置TEXT - MyIconButton *funcButton = new MyIconButton(this); - QString btnName = "btn" + QString::number(type + 1); + QString btnName = mnameString; funcButton->setObjectName(btnName); funcButton->setFixedSize(180, 40); funcButton->setDesplayText(mnamei18nString); @@ -56,6 +65,10 @@ LeftsiderbarWidget::LeftsiderbarWidget(QWidget *parent, StartMode mode) funcButton->setThemeIcon(themeIconName, defaultIconName); funcButton->setToolTip(mnamei18nString); funcButton->setCheckable(true); + connect(funcButton, &MyIconButton::clicked, [=](bool checked) { + if (checked) + emit this->selected(type); + }); // 設置無邊框,跟隨背景色 funcButton->setFlat(true); @@ -69,6 +82,12 @@ LeftsiderbarWidget::LeftsiderbarWidget(QWidget *parent, StartMode mode) m_leftSideBarVLayout->addWidget(funcButton); } + connect(GlobelBackupInfo::inst().getGlobalSignals(), &GlobalSignals::busy, this, [=](bool isBusy) { + QList list = this->m_funcGroup->buttons(); + for (QAbstractButton * button : list) { + button->setEnabled(!isBusy); + } + }); m_leftSideBarVLayout->addSpacing(8); diff --git a/kybackup/leftsiderbarwidget.h b/kybackup/leftsiderbarwidget.h index f959e3f..8cdb14d 100644 --- a/kybackup/leftsiderbarwidget.h +++ b/kybackup/leftsiderbarwidget.h @@ -17,11 +17,15 @@ public: // 启动模式,不同模式启动时展示的功能模块不同 enum StartMode { normal, - livecd + livecd, + std_user }; LeftsiderbarWidget(QWidget *parent = nullptr, StartMode mode = StartMode::normal); ~LeftsiderbarWidget(); void paintEvent(QPaintEvent *event); + +signals: + void selected(int func_type); private: int transparency = 0; @@ -29,6 +33,8 @@ private: QLabel *m_mTitleIcon = nullptr; MyLabel *m_titleLabel = nullptr; QButtonGroup *m_funcGroup = nullptr; + + QStringList m_deplayFuncs; }; #endif // LEFTSIDERBARWIDGET_H diff --git a/kybackup/maindialog.cpp b/kybackup/maindialog.cpp index 7ef9fac..f115cf2 100644 --- a/kybackup/maindialog.cpp +++ b/kybackup/maindialog.cpp @@ -9,6 +9,7 @@ #include "../common/mydefine.h" #include "module/systembackup.h" +#include "module/systemrestore.h" #include "backup_manager_interface.h" #include "globalbackupinfo.h" @@ -54,11 +55,7 @@ void MainDialog::initUI() m_titleWidget->setGeometry(QRect(201, 0, 760, 40)); m_rightVLayout->addWidget(m_titleWidget); - // m_stackedWidget = new QStackedWidget(ui->centralwidget); - m_stackedWidget = new SystemBackup(ui->centralwidget); - m_stackedWidget->setObjectName(QString::fromUtf8("m_stackedWidget")); - m_stackedWidget->setGeometry(QRect(201, 40, 760, 600)); - m_rightVLayout->addWidget(m_stackedWidget); + selected(FuncTypeConverter::FunType::BACKUP_SYSTEM); m_totalHLayout->addLayout(m_rightVLayout); @@ -120,7 +117,7 @@ void MainDialog::initStyleSheet() { // 主窗口 // qApp->setWindowIcon(QIcon::fromTheme(THEME_YHKYLIN_BACKUP_TOOLS)); - this->setWindowTitle(tr("Backup and Restore")); + this->setWindowTitle(tr("Backup & Restore")); // 工作区(此处代码加不加一个样,注释掉,留着学习,知道有这么回事) //ui->centralwidget->setStyleSheet("QWidget#centralWidget{background: palette(base); border-radius: 6px;}"); @@ -154,17 +151,13 @@ void MainDialog::initStyleSheet() m_closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic")); // m_closeBtn->setProperty("setIconHighlightEffectDefaultColor", m_closeBtn->palette().color(QPalette::Active, QPalette::Base)); - - // 右侧内容区域 - // m_stackedWidget->setStyleSheet("QStackedWidget#m_stackedWidget{background: palette(base); border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); - m_stackedWidget->setAutoFillBackground(true); - palette = m_stackedWidget->palette(); - palette.setColor(QPalette::Background, palette.color(QPalette::Base)); - m_stackedWidget->setPalette(palette); } void MainDialog::initConnect() { + // 左侧功能选择栏 + connect(m_leftSiderBarWidget, &LeftsiderbarWidget::selected, this, &MainDialog::selected); + // 标题栏右侧按钮区域 // 退出 connect(m_backupExit, &QAction::triggered, this, &MainDialog::closeBtn); @@ -187,6 +180,47 @@ void MainDialog::initConnect() connect(m_closeBtn, &QPushButton::clicked, this, &MainDialog::closeBtn); } +/** + * @brief 左侧功能选择栏响应槽 + * @param func_type,功能类型 + */ +void MainDialog::selected(int func_type) +{ + if (GlobelBackupInfo::inst().getFuncType() == func_type) + return ; + + if (m_stackedWidget) { + m_rightVLayout->removeWidget(m_stackedWidget); + delete m_stackedWidget; + } + + switch (func_type) { + case FuncTypeConverter::FunType::BACKUP_SYSTEM: + m_stackedWidget = new SystemBackup(ui->centralwidget); + GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM); + break; + case FuncTypeConverter::FunType::RESTORE_SYSTEM: + m_stackedWidget = new SystemRestore(ui->centralwidget); + GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::RESTORE_SYSTEM); + break; + default: + m_stackedWidget = new SystemBackup(ui->centralwidget); + GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM); + break; + } + + m_stackedWidget->setObjectName(QString::fromUtf8("m_stackedWidget")); + m_stackedWidget->setGeometry(QRect(201, 40, 760, 600)); + m_rightVLayout->addWidget(m_stackedWidget); + + // 右侧内容区域 + // m_stackedWidget->setStyleSheet("QStackedWidget#m_stackedWidget{background: palette(base); border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); + m_stackedWidget->setAutoFillBackground(true); + QPalette palette = m_stackedWidget->palette(); + palette.setColor(QPalette::Background, palette.color(QPalette::Base)); + m_stackedWidget->setPalette(palette); +} + /** * @brief 多例启动信息槽 * @param msg 信息,里面存放新启动实例的账户id diff --git a/kybackup/maindialog.h b/kybackup/maindialog.h index 55b7294..49f89c5 100644 --- a/kybackup/maindialog.h +++ b/kybackup/maindialog.h @@ -24,6 +24,7 @@ public: public slots: void sltMessageReceived(const QString &msg); void closeBtn(); + void selected(int func_type); private: void initUI(); diff --git a/kybackup/module/systemrestore.cpp b/kybackup/module/systemrestore.cpp new file mode 100644 index 0000000..c67ce30 --- /dev/null +++ b/kybackup/module/systemrestore.cpp @@ -0,0 +1,153 @@ +#include "systemrestore.h" +#include +#include +#include +#include +#include +#include + +#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 "../../common/utils.h" +#include "../globalbackupinfo.h" + +SystemRestore::SystemRestore(QWidget *parent) : + QStackedWidget(parent) +{ + // 界面手写代码创建,作为练手 + initFirstWidget(); +} + +SystemRestore::~SystemRestore() +{} + +/** + * @brief 初始化第一个页面 + */ +void SystemRestore::initFirstWidget() +{ + QWidget *first = new QWidget; + + // 图片 + QLabel *imageRestore_firstPage = new QLabel(first); + imageRestore_firstPage->setGeometry(421, 120, 300, 326); + QPixmap pixmap(":/images/system_restore.svg"); + imageRestore_firstPage->setPixmap(pixmap); + imageRestore_firstPage->setScaledContents(true); + + // 系统还原大字提示 + MyLabel *labelRestore_firstPage = new MyLabel(first); + labelRestore_firstPage->setDeplayText(tr("System Restore")); + labelRestore_firstPage->setFixedWidth(500); + labelRestore_firstPage->setFixedHeight(48); + labelRestore_firstPage->move(41, 120); + // 默认水平左对齐,上下居中对齐;故不需要设置 + // labelRestore_firstPage->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + // labelRestore_firstPage->setText(tr("System Backup")); + QFont font; + font.setBold(true); + font.setPixelSize(36); + labelRestore_firstPage->setFont(font); + // labelRestore_firstPage->setAttribute(Qt::WA_TranslucentBackground); + labelRestore_firstPage->setScaledContents(true); + labelRestore_firstPage->adjustSize(); + + // 系统还原说明 + MyLabel *labelNote_firstPage = new MyLabel(first); + labelNote_firstPage->setFixedWidth(700); + labelNote_firstPage->setFixedHeight(24); + labelNote_firstPage->move(41, 180); + // 在您遇到问题时可将系统还原到以前的状态 + labelNote_firstPage->setDeplayText(tr("You can restore the system to its previous state")); + font.setBold(false); + font.setPixelSize(18); + labelNote_firstPage->setFont(font); + labelNote_firstPage->setScaledContents(true); + labelNote_firstPage->adjustSize(); + + // 多点还原 + MyIconLabel *iconMultiBackup_firstPage = new MyIconLabel(first); + iconMultiBackup_firstPage->setGeometry(41, 244, 180, 36); + iconMultiBackup_firstPage->setThemeIcon("ukui-bf-many-spot-symbolic", ":/symbos/ukui-bf-many-spot-symbolic.png"); + iconMultiBackup_firstPage->setDesplayText(tr("Multi-Spot")); + iconMultiBackup_firstPage->setEnabled(false); + + // 体积小 + MyIconLabel *iconSmallSize_firstPage = new MyIconLabel(first); + iconSmallSize_firstPage->setGeometry(201, 244, 180, 36); + iconSmallSize_firstPage->setThemeIcon("ukui-bf-volume-symbolic", ":/symbos/ukui-bf-volume-symbolic.png"); + iconSmallSize_firstPage->setDesplayText(tr("Small Size")); + iconSmallSize_firstPage->setEnabled(false); + + // 安全 + MyIconLabel *iconSecurity_firstPage = new MyIconLabel(first); + iconSecurity_firstPage->setGeometry(41, 296, 180, 36); + iconSecurity_firstPage->setThemeIcon("ukui-bf-security-symbolic", ":/symbos/ukui-bf-security-symbolic.png"); + iconSecurity_firstPage->setDesplayText(tr("Security")); + iconSecurity_firstPage->setEnabled(false); + + // 操作简单 + MyIconLabel *iconSimple_firstPage = new MyIconLabel(first); + iconSimple_firstPage->setGeometry(201, 296, 180, 36); + iconSimple_firstPage->setThemeIcon("ukui-bf-simple-symbolic", ":/symbos/ukui-bf-simple-symbolic.png"); + iconSimple_firstPage->setDesplayText(tr("Simple")); + iconSimple_firstPage->setEnabled(false); + + // 开始还原按钮 + MyPushButton *beginRestore = new MyPushButton(first); + beginRestore->setGeometry(41, 372, 180, 52); + beginRestore->setText(tr("Start Restore")); + beginRestore->setEnabled(true); + beginRestore->setAutoRepeat(true); + font.setPixelSize(24); + beginRestore->setFont(font); + connect(beginRestore, &MyPushButton::clicked, this, &SystemRestore::on_next_clicked); + + // 保留用户数据复选框 + QCheckBox * retainUserData = new QCheckBox(tr("Retaining User Data"), first); + retainUserData->setGeometry(551, 551, 200, 30); + connect(retainUserData, &QCheckBox::stateChanged, this, &SystemRestore::on_retainUserData_checked); + + addWidget(first); +} + +/** + * @brief “上一步”按钮响应槽 + * @param checked + */ +void SystemRestore::on_pre_clicked(bool checked) +{ + Q_UNUSED(checked) + int index = this->currentIndex() - 1; + if (index >= 0) { + this->setCurrentIndex(index); + } +} + +/** + * @brief “开始备份”“下一步”按钮响应槽 + * @param checked + */ +void SystemRestore::on_next_clicked(bool checked) +{ + Q_UNUSED(checked) + int index = this->currentIndex() + 1; + if (index < this->count()) { + this->setCurrentIndex(index); + } +} + +/** + * @brief 保留用户数据复选框响应槽 + */ +void SystemRestore::on_retainUserData_checked(bool checked) +{ + // TODO +} + diff --git a/kybackup/module/systemrestore.h b/kybackup/module/systemrestore.h new file mode 100644 index 0000000..2f5e841 --- /dev/null +++ b/kybackup/module/systemrestore.h @@ -0,0 +1,44 @@ +#ifndef SYSTEMRESTORE_H +#define SYSTEMRESTORE_H + +#include + +class SystemRestore : public QStackedWidget +{ + Q_OBJECT +public: + enum SystemRestoreState + { + IDEL = 0, // 空闲 + CHECKING, // 环境校验中 + BACKUPING // 备份中 + }; + + enum SystemRestorePage + { + HOME_PAGE, // 首页 + SELECT_PATH_PAGE, // 选择备份路径页 + CHECK_ENV_PAGE, // 环境检测页 + NAME_BACKUP_PAGE, // 备份命名页 + BACKUP_PAGE, // 备份中页 + LAST_PAGE, // 结束页 + }; + +public: + explicit SystemRestore(QWidget *parent = nullptr); + virtual ~SystemRestore(); + +private: + void initFirstWidget(); + +public slots: + void on_pre_clicked(bool checked = false); + void on_next_clicked(bool checked = false); + void on_retainUserData_checked(bool checked = false); + +private: + // 是否保留用户数据 + bool m_isRetainUserData; +}; + +#endif // SYSTEMRESTORE_H