yhkylin-backup-tools/kybackup/maindialog.cpp

454 lines
17 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "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();
}
}