454 lines
17 KiB
C++
Executable File
454 lines
17 KiB
C++
Executable File
#include "maindialog.h"
|
||
#include "ui_maindialog.h"
|
||
|
||
#include <QMenu>
|
||
#include <QProcess>
|
||
#include <QMessageBox>
|
||
#include <KWindowSystem>
|
||
#include <KWindowEffects>
|
||
#include <unistd.h>
|
||
#include "xatom-helper.h"
|
||
#include "../common/mydefine.h"
|
||
#include "module/systembackup.h"
|
||
#include "module/systemrestore.h"
|
||
#include "module/databackup.h"
|
||
#include "module/datarestore.h"
|
||
#include "module/operationlog.h"
|
||
#include "module/ghostimage.h"
|
||
#include "backup_manager_interface.h"
|
||
#include "globalbackupinfo.h"
|
||
#include "messageboxutils.h"
|
||
#include "aboutdialog.h"
|
||
#include "gsettingswrapper.h"
|
||
#include "component/mywidget.h"
|
||
#include <ukuistylehelper/ukuistylehelper.h>
|
||
#include <windowmanager/windowmanager.h>
|
||
|
||
MainDialog::MainDialog(QWidget *parent)
|
||
: QMainWindow(parent)
|
||
, ui(new Ui::MainDialog)
|
||
{
|
||
ui->setupUi(this);
|
||
// 主窗口
|
||
this->setWindowTitle(tr("Backup & Restore"));
|
||
// 窗口背景透明化;setWindowOpacity可使得窗口及其上控件都透明或半透明-w.setWindowOpacity(0.7);
|
||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||
// 使得窗口无边框
|
||
// w.setWindowFlag(Qt::FramelessWindowHint);
|
||
// 指示窗口管理器模糊给定窗口后面指定区域的背景(毛玻璃化背景)
|
||
// KWindowEffects::enableBlurBehind(this->winId(), true);
|
||
// 或使用设置毛玻璃属性的方式实现毛玻璃背景(两者都行,可使用其一)
|
||
this->setProperty("useSystemStyleBlur", true);
|
||
this->setAutoFillBackground(true);
|
||
|
||
// 添加窗管协议
|
||
if (GlobelBackupInfo::inst().isWayland()){
|
||
// 去除窗管标题栏,传入参数为QWidget *
|
||
kdk::UkuiStyleHelper::self()->removeHeader(this);
|
||
} else {
|
||
MotifWmHints hints;
|
||
hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
|
||
hints.functions = MWM_FUNC_ALL;
|
||
hints.decorations = MWM_DECOR_BORDER;
|
||
XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints);
|
||
}
|
||
|
||
GlobelBackupInfo::inst().setMainWidget(this);
|
||
|
||
// 注册BackupWrapper类型,之后qdbus接口才能使用
|
||
BackupWrapper::registerMetaType();
|
||
mountBackupPartition();
|
||
|
||
initUI();
|
||
initConnect();
|
||
}
|
||
|
||
MainDialog::~MainDialog()
|
||
{
|
||
delete ui;
|
||
}
|
||
|
||
void MainDialog::initUI()
|
||
{
|
||
// 总体布局为横向布局,分为左侧和右侧
|
||
m_totalHLayout = new QHBoxLayout;
|
||
m_totalHLayout->setSpacing(0);
|
||
m_totalHLayout->setObjectName(QString::fromUtf8("m_totalHLayout"));
|
||
m_totalHLayout->setContentsMargins(0, 0, 0, 0);
|
||
m_totalHLayout->setSpacing(0);
|
||
ui->centralwidget->setLayout(m_totalHLayout);
|
||
|
||
// 左栏窗口
|
||
if (GlobelBackupInfo::inst().isManager())
|
||
m_leftSiderBarWidget = new LeftsiderbarWidget(ui->centralwidget);
|
||
else
|
||
m_leftSiderBarWidget = new LeftsiderbarWidget(ui->centralwidget, LeftsiderbarWidget::StartMode::std_user);
|
||
m_leftSiderBarWidget->setObjectName(QString::fromUtf8("m_leftSiderBarWidget"));
|
||
m_leftSiderBarWidget->setFixedWidth(200);
|
||
m_leftSiderBarWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||
m_leftSiderBarWidget->initUi();
|
||
|
||
m_totalHLayout->addWidget(m_leftSiderBarWidget);
|
||
|
||
// 右侧窗口
|
||
m_rightWidget = new MyWidget;
|
||
m_totalHLayout->addWidget(m_rightWidget);
|
||
|
||
m_rightVLayout = new QVBoxLayout;
|
||
m_rightVLayout->setObjectName(QString::fromUtf8("m_rightVLayout"));
|
||
m_rightVLayout->setContentsMargins(0, 0, 0, 0);
|
||
m_rightVLayout->setSpacing(0);
|
||
|
||
// 右侧窗口:标题栏
|
||
m_titleWidget = new DoubleClickWidget;
|
||
m_titleWidget->setObjectName(QString::fromUtf8("m_titleWidget"));
|
||
m_titleWidget->setFixedHeight(40);
|
||
m_rightVLayout->addWidget(m_titleWidget);
|
||
|
||
// 右侧窗口:工作区
|
||
m_workWidget = new QWidget;
|
||
m_workWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||
m_rightVLayout->addWidget(m_workWidget);
|
||
m_rightWidget->setLayout(m_rightVLayout);
|
||
|
||
// 工作区随左边框功能切换界面
|
||
m_workVLayout = new QVBoxLayout;
|
||
if (GlobelBackupInfo::inst().isManager() && GlobelBackupInfo::inst().hasArgRestore())
|
||
selected(FuncTypeConverter::FunType::RESTORE_SYSTEM);
|
||
else if (!GlobelBackupInfo::inst().isManager() && GlobelBackupInfo::inst().hasArgRestore())
|
||
selected(FuncTypeConverter::FunType::RESTORE_DATA);
|
||
else if (!GlobelBackupInfo::inst().isManager())
|
||
selected(FuncTypeConverter::FunType::BACKUP_DATA);
|
||
else
|
||
selected(FuncTypeConverter::FunType::BACKUP_SYSTEM);
|
||
m_workWidget->setLayout(m_workVLayout);
|
||
|
||
initTileBar();
|
||
}
|
||
|
||
#define PC_TITLE_BAR_SIZE 30
|
||
#define TABLET_TITLE_BAR_SIZE 48
|
||
void MainDialog::initTileBar()
|
||
{
|
||
m_titleLayout = new QHBoxLayout;
|
||
m_titleLayout->setContentsMargins(8, 4, 4, 0);
|
||
m_titleLayout->setSpacing(4);
|
||
|
||
m_menuOptionBtn = new QToolButton;
|
||
m_minBtn = new QPushButton;
|
||
m_maxBtn = new QPushButton;
|
||
m_closeBtn = new QPushButton;
|
||
|
||
m_menuOptionBtn->setToolTip(tr("Main menu"));
|
||
m_minBtn->setToolTip(tr("Minimize"));
|
||
m_maxBtn->setToolTip(tr("Maximize"));
|
||
m_closeBtn->setToolTip(tr("Close"));
|
||
|
||
m_menuOptionBtn->setProperty("isWindowButton", 0x1);
|
||
m_menuOptionBtn->setProperty("useIconHighlightEffect", 0x2);
|
||
m_menuOptionBtn->setIcon(QIcon::fromTheme("open-menu-symbolic"));
|
||
m_menuOptionBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_menuOptionBtn->setAutoRaise(true);
|
||
m_menuOptionBtn->setPopupMode(QToolButton::InstantPopup);
|
||
|
||
m_minBtn->setProperty("isWindowButton", 0x1);
|
||
m_minBtn->setProperty("useIconHighlightEffect", 0x2);
|
||
m_minBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_minBtn->setFlat(true);
|
||
m_minBtn->setIcon(QIcon::fromTheme("window-minimize-symbolic"));
|
||
|
||
m_maxBtn->setProperty("isWindowButton", 0x1);
|
||
m_maxBtn->setProperty("useIconHighlightEffect", 0x2);
|
||
m_maxBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_maxBtn->setFlat(true);
|
||
m_maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic"));
|
||
|
||
m_closeBtn->setProperty("isWindowButton", 0x2);
|
||
m_closeBtn->setProperty("useIconHighlightEffect", 0x8);
|
||
m_closeBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_closeBtn->setFlat(true);
|
||
m_closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));
|
||
|
||
QMenu* backupMain = new QMenu(m_titleWidget);
|
||
backupMain->setObjectName("mainMenu");
|
||
m_menuOptionBtn->setMenu(backupMain);
|
||
|
||
// 暂时只需跟随主题,浅色主题和深色主题后续可能会独立出来
|
||
// QAction* backupTheme = new QAction(tr("Theme"), m_titleWidget);
|
||
// backupMain->addAction(backupTheme);
|
||
// QMenu* selectTheme = new QMenu( m_titleWidget);
|
||
// selectTheme->setObjectName("selectTheme");
|
||
// backupTheme->setMenu(selectTheme);
|
||
// QAction* defaultTheme = new QAction(tr("Auto"), m_titleWidget);
|
||
// selectTheme->addAction(defaultTheme);
|
||
// QAction* lightTheme = new QAction(tr("Light"), m_titleWidget);
|
||
// selectTheme->addAction(lightTheme);
|
||
// QAction* darkTheme = new QAction(tr("Dark"), m_titleWidget);
|
||
// selectTheme->addAction(darkTheme);
|
||
|
||
m_backupHelp = new QAction(tr("Help"), m_titleWidget);
|
||
// 设计竟然让快捷键标记不能在页面中提示出来,要悄默默的快捷,奇葩。需要重定义键盘事件代替通用快捷键设置方法。
|
||
// m_backupHelp->setShortcut(QKeySequence::HelpContents);
|
||
backupMain->addAction(m_backupHelp);
|
||
m_backupAbout = new QAction(tr("About"), m_titleWidget);
|
||
backupMain->addAction(m_backupAbout);
|
||
m_backupExit = new QAction(tr("Exit"), m_titleWidget);
|
||
backupMain->addAction(m_backupExit);
|
||
|
||
m_titleLayout->addStretch();
|
||
m_titleLayout->addWidget(m_menuOptionBtn);
|
||
m_titleLayout->addWidget(m_minBtn);
|
||
m_titleLayout->addWidget(m_maxBtn);
|
||
m_titleLayout->addWidget(m_closeBtn);
|
||
m_titleWidget->setLayout(m_titleLayout);
|
||
}
|
||
|
||
void MainDialog::initConnect()
|
||
{
|
||
// 左侧功能选择栏
|
||
connect(m_leftSiderBarWidget, &LeftsiderbarWidget::selected, this, &MainDialog::selected);
|
||
|
||
// 标题栏右侧按钮区域
|
||
// 退出
|
||
connect(m_backupExit, &QAction::triggered, this, &MainDialog::closeBtn);
|
||
|
||
// 关于
|
||
connect(m_backupAbout, &QAction::triggered, this, [=] {
|
||
AboutDialog *about = new AboutDialog(this);
|
||
about->exec();
|
||
about->deleteLater();
|
||
});
|
||
|
||
connect(m_backupHelp, &QAction::triggered, this, [=] {
|
||
QProcess process(this);
|
||
process.startDetached("kylin-user-guide -A yhkylin-backup-tools");
|
||
});
|
||
|
||
//最小化按钮
|
||
connect(m_minBtn, &QPushButton::clicked, this, &MainDialog::showMinimized);
|
||
|
||
//最大化按钮
|
||
connect(m_maxBtn, &QPushButton::clicked, this, [=] {
|
||
if (isMaximized()) {
|
||
showNormal();
|
||
} else {
|
||
showMaximized();
|
||
}
|
||
});
|
||
connect(m_titleWidget, &DoubleClickWidget::doubleClicked, m_maxBtn, &QPushButton::click);
|
||
connect(m_leftSiderBarWidget, &LeftsiderbarWidget::doubleClicked, m_maxBtn, &QPushButton::click);
|
||
|
||
//关闭按钮
|
||
connect(m_closeBtn, &QPushButton::clicked, this, &MainDialog::closeBtn);
|
||
|
||
//监听平板模式切换
|
||
m_statusSessionDbus = new QDBusInterface("com.kylin.statusmanager.interface",
|
||
"/",
|
||
"com.kylin.statusmanager.interface",
|
||
QDBusConnection::sessionBus(),
|
||
this);
|
||
if (m_statusSessionDbus->isValid()) {
|
||
QDBusReply<bool> is_tabletmode = m_statusSessionDbus->call("get_current_tabletmode");
|
||
GlobelBackupInfo::inst().setIsTabletMode(is_tabletmode);
|
||
tabletModeChange(is_tabletmode);
|
||
connect(m_statusSessionDbus, SIGNAL(mode_change_signal(bool)), this, SLOT(tabletModeChange(bool)));
|
||
} else {
|
||
GlobelBackupInfo::inst().setIsTabletMode(false);
|
||
m_maxBtn->setVisible(true);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 平板模式切换
|
||
* @param isTabletMode true-平板模式;false-PC模式
|
||
*/
|
||
void MainDialog::tabletModeChange(bool isTabletMode)
|
||
{
|
||
GlobelBackupInfo::inst().setIsTabletMode(isTabletMode);
|
||
if(isTabletMode){
|
||
m_menuOptionBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
|
||
m_minBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
|
||
m_maxBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
|
||
m_closeBtn->setFixedSize(TABLET_TITLE_BAR_SIZE, TABLET_TITLE_BAR_SIZE);
|
||
m_titleWidget->setFixedHeight(56);
|
||
m_maxBtn->setVisible(false);
|
||
} else {
|
||
m_menuOptionBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_minBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_maxBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_closeBtn->setFixedSize(PC_TITLE_BAR_SIZE, PC_TITLE_BAR_SIZE);
|
||
m_titleWidget->setFixedHeight(40);
|
||
m_maxBtn->setVisible(true);
|
||
}
|
||
}
|
||
|
||
void MainDialog::changeEvent(QEvent *event)
|
||
{
|
||
if (QEvent::WindowStateChange == event->type()) {
|
||
Qt::WindowStates state = this->windowState();
|
||
switch (state) {
|
||
case Qt::WindowMaximized:
|
||
case Qt::WindowFullScreen:
|
||
m_maxBtn->setIcon(QIcon::fromTheme("window-restore-symbolic"));
|
||
m_maxBtn->setToolTip(tr("Normal"));
|
||
|
||
break;
|
||
case Qt::WindowNoState:
|
||
m_maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic"));
|
||
m_maxBtn->setToolTip(tr("Maximize"));
|
||
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
QMainWindow::changeEvent(event);
|
||
}
|
||
|
||
void MainDialog::keyPressEvent(QKeyEvent *event)
|
||
{
|
||
if (event->key() == Qt::Key_F1)
|
||
emit m_backupHelp->triggered();
|
||
|
||
QMainWindow::keyPressEvent(event);
|
||
}
|
||
|
||
/**
|
||
* @brief 左侧功能选择栏响应槽
|
||
* @param func_type,功能类型
|
||
*/
|
||
void MainDialog::selected(int func_type)
|
||
{
|
||
if (GlobelBackupInfo::inst().getFuncType() == func_type)
|
||
return ;
|
||
|
||
if (m_stackedWidget) {
|
||
m_workVLayout->removeWidget(m_stackedWidget);
|
||
delete m_stackedWidget;
|
||
}
|
||
|
||
switch (func_type) {
|
||
case FuncTypeConverter::FunType::BACKUP_SYSTEM:
|
||
m_stackedWidget = new SystemBackup(m_workWidget);
|
||
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM);
|
||
break;
|
||
case FuncTypeConverter::FunType::RESTORE_SYSTEM:
|
||
m_stackedWidget = new SystemRestore(m_workWidget);
|
||
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::RESTORE_SYSTEM);
|
||
break;
|
||
case FuncTypeConverter::FunType::BACKUP_DATA:
|
||
m_stackedWidget = new DataBackup(m_workWidget);
|
||
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_DATA);
|
||
break;
|
||
case FuncTypeConverter::FunType::RESTORE_DATA:
|
||
m_stackedWidget = new DataRestore(m_workWidget);
|
||
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::RESTORE_DATA);
|
||
break;
|
||
case FuncTypeConverter::FunType::OPERATION_LOG:
|
||
m_stackedWidget = new OperationLog(m_workWidget);
|
||
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::OPERATION_LOG);
|
||
break;
|
||
case FuncTypeConverter::FunType::GHOST_IMAGE:
|
||
m_stackedWidget = new GhostImage(m_workWidget);
|
||
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::GHOST_IMAGE);
|
||
break;
|
||
default:
|
||
m_stackedWidget = new SystemBackup(m_workWidget);
|
||
GlobelBackupInfo::inst().setFuncType(FuncTypeConverter::FunType::BACKUP_SYSTEM);
|
||
break;
|
||
}
|
||
|
||
m_stackedWidget->setObjectName(QString::fromUtf8("m_stackedWidget"));
|
||
// m_stackedWidget->setMinimumSize(760, 600);
|
||
m_workVLayout->addWidget(m_stackedWidget);
|
||
|
||
m_leftSiderBarWidget->setCheckedFunc(func_type);
|
||
}
|
||
|
||
/**
|
||
* @brief 多例启动信息槽
|
||
* @param msg 信息,里面存放新启动实例的账户id
|
||
*/
|
||
void MainDialog::sltMessageReceived(const QString &msg)
|
||
{
|
||
QString user = QString::number(getuid());
|
||
if (msg == user) {
|
||
// this->setWindowFlag(Qt::WindowStaysOnTopHint,true);
|
||
// this->setWindowFlag(Qt::WindowStaysOnTopHint,false);
|
||
KWindowSystem::forceActiveWindow(this->winId());
|
||
this->show();
|
||
}
|
||
}
|
||
|
||
void MainDialog::mountBackupPartition()
|
||
{
|
||
// 挂载/backup分区
|
||
ComKylinBackupManagerInterface intf("com.kylin.backup", "/", QDBusConnection::systemBus());
|
||
QDBusPendingReply<int> reply = intf.Mount_backup_partition();
|
||
reply.waitForFinished();
|
||
if (reply.isError()) {
|
||
// 挂载分区时出现异常
|
||
MessageBoxUtils::QMESSAGE_BOX_CRITICAL(this, QObject::tr("Warning"),
|
||
QObject::tr("An exception occurred when mounting backup partition."),
|
||
QObject::tr("Ok"));
|
||
|
||
// 此时还未进入应用的事件循环中,故不能使用qApp->quit();
|
||
exit(1);
|
||
} else if (int(MountResult::CANNOT_GET_BACKUPUUID) == reply.value()) {
|
||
// 没有找到备份分区,只能备份到移动设备中
|
||
// MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Information"),
|
||
// QObject::tr("Please check if the backup partition exists which can be created when you install the Operating System."),
|
||
// QObject::tr("Ok"));
|
||
// // 此时还未进入应用的事件循环中,故不能使用qApp->quit();
|
||
// exit(1);
|
||
GlobelBackupInfo::inst().setHasBackupPartition(false);
|
||
} else if (int(MountResult::MOUNTED) != reply.value()) {
|
||
// 挂载备份分区失败
|
||
MessageBoxUtils::QMESSAGE_BOX_CRITICAL(this, QObject::tr("Warning"),
|
||
QObject::tr("Failed to mount backup partition."),
|
||
QObject::tr("Ok"));
|
||
|
||
// 此时还未进入应用的事件循环中,故不能使用qApp->quit();
|
||
exit(1);
|
||
}
|
||
}
|
||
|
||
void MainDialog::umountBackupPartition()
|
||
{
|
||
// 卸载/backup分区
|
||
ComKylinBackupManagerInterface intf("com.kylin.backup", "/", QDBusConnection::systemBus());
|
||
intf.umountBackupPartition();
|
||
}
|
||
|
||
void MainDialog::closeEvent(QCloseEvent *e)
|
||
{
|
||
if (GlobelBackupInfo::inst().isBusy()) {
|
||
// 系统正忙,请稍等
|
||
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
|
||
QObject::tr("It's busy, please wait"),
|
||
QObject::tr("Ok"));
|
||
|
||
e->ignore();
|
||
return;
|
||
}
|
||
|
||
if (GlobelBackupInfo::inst().hasBackupPartition())
|
||
umountBackupPartition();
|
||
|
||
e->accept();
|
||
}
|
||
|
||
void MainDialog::resizeEvent(QResizeEvent *event) {
|
||
emit GlobelBackupInfo::inst().getGlobalSignals()->widthChanged();
|
||
QMainWindow::resizeEvent(event);
|
||
}
|
||
|
||
void MainDialog::closeBtn()
|
||
{
|
||
if (this->close()) {
|
||
qApp->quit();
|
||
}
|
||
}
|
||
|