261 lines
9.0 KiB
C++
Executable File
261 lines
9.0 KiB
C++
Executable File
#include "maindialog.h"
|
||
|
||
#include <QApplication>
|
||
#include <QLibraryInfo>
|
||
#include <QTextCodec>
|
||
#include <QTranslator>
|
||
#include <QCommandLineParser>
|
||
#include <QtDBus>
|
||
#include <QMessageBox>
|
||
#include <QDesktopWidget>
|
||
#include <signal.h>
|
||
#include <unistd.h>
|
||
#include "qtsingleapplication/qtsingleapplication.h"
|
||
#include "../common/utils.h"
|
||
#include "xatom-helper.h"
|
||
#include "globalbackupinfo.h"
|
||
#include "messageboxutils.h"
|
||
#include <ukuistylehelper/ukuistylehelper.h>
|
||
#include <windowmanager/windowmanager.h>
|
||
#include "backup_manager_interface.h"
|
||
|
||
// 声明
|
||
void initApp(QApplication& a);
|
||
bool isManager();
|
||
void remountPartitionsForCasperMode();
|
||
void centerToScreen(QWidget* widget);
|
||
|
||
int main(int argc, char *argv[])
|
||
{
|
||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
|
||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||
#endif
|
||
|
||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||
#endif
|
||
|
||
QtSingleApplication a ("kybackup", argc, argv);
|
||
initApp(a);
|
||
|
||
if (a.isRunning()) {
|
||
QString strUid = QString::number(getuid());
|
||
QString ack = a.sendMessage(strUid, 3000);
|
||
|
||
if (strUid != ack) {
|
||
MessageBoxUtils::QMESSAGE_BOX_WARNING(nullptr, QObject::tr("Information"),
|
||
QObject::tr("Another user had opened kybackup, you can not start it again."),
|
||
QObject::tr("OK"));
|
||
}
|
||
|
||
return EXIT_SUCCESS;
|
||
}
|
||
|
||
QString platform = QGuiApplication::platformName();
|
||
if(platform.startsWith(QLatin1String("wayland"),Qt::CaseInsensitive) || QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") {
|
||
GlobelBackupInfo::instance().setIsWayland(true);
|
||
}
|
||
MainDialog w;
|
||
// 居中窗口
|
||
// centerToScreen(&w);
|
||
a.setWindowIcon(QIcon::fromTheme(THEME_YHKYLIN_BACKUP_TOOLS, QIcon(":/images/yhkylin-backup-tools.png")));
|
||
a.setActivationWindow(&w, true);
|
||
a.setApplicationName(QObject::tr("Backup & Restore"));
|
||
a.setApplicationVersion("4.1.0.0-0k17.18");
|
||
|
||
//如果是第一个实例,则绑定,方便下次调用
|
||
QObject::connect(&a,SIGNAL(messageReceived(const QString&)),&w,SLOT(sltMessageReceived(const QString&)));
|
||
|
||
w.show();
|
||
kdk::WindowManager::setGeometry(w.windowHandle(),
|
||
QRect(qApp->desktop()->geometry().center() - w.geometry().center(),
|
||
QSize(w.size())));
|
||
return a.exec();
|
||
}
|
||
|
||
/**
|
||
* @brief 应用初始化
|
||
* @param a
|
||
* @note new出来的两个QTranslator不用删除,需要整个生命周期内有效,应用结束由操作系统收回即可
|
||
*/
|
||
void initApp(QApplication& a)
|
||
{
|
||
// 前端向后端传递QString参数,若参数中含有中文则保证不会乱码
|
||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||
|
||
// 区分中英文
|
||
QString locale = QLocale::system().name();
|
||
|
||
// QT自身标准的翻译
|
||
#ifndef QT_NO_TRANSLATION
|
||
QTranslator *selfTransOfQt = new QTranslator();
|
||
if (selfTransOfQt->load(QLocale(), QString("qt"), QString("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
|
||
a.installTranslator(selfTransOfQt);
|
||
else
|
||
qDebug() << "load qt translator file failed!";
|
||
#endif
|
||
|
||
// 部分sdk控件用到翻译文件
|
||
QTranslator *transGui = new QTranslator();
|
||
if (locale == "zh_CN") {
|
||
if (transGui->load(":/translations/gui_zh_CN.qm"))
|
||
{
|
||
a.installTranslator(transGui);
|
||
}
|
||
} else if (locale == "bo_CN") {
|
||
if (transGui->load(":/translations/gui_bo_CN.qm"))
|
||
{
|
||
a.installTranslator(transGui);
|
||
}
|
||
} else if (locale == "mn_MN" || locale == "mn") {
|
||
if (transGui->load(":/translations/gui_mn.qm")) {
|
||
a.installTranslator(transGui);
|
||
}
|
||
} else if (locale == "zh_HK") {
|
||
if(transGui->load(":/translations/gui_zh_HK.qm")) {
|
||
a.installTranslator(transGui);
|
||
}
|
||
}
|
||
|
||
// 应用内的翻译
|
||
QTranslator *translator = new QTranslator();
|
||
QString translatorResourceName(":/language/qt_");
|
||
translatorResourceName += locale;
|
||
translatorResourceName += ".qm";
|
||
if (!translator->load(translatorResourceName)) //qtcreator启动后看到在资源目录下
|
||
qDebug() << translatorResourceName << "load translator file failed!";
|
||
else {
|
||
a.installTranslator(translator);
|
||
qDebug() << translatorResourceName << "load translator file success!";
|
||
}
|
||
// if (locale == "zh_CN") {
|
||
// //中文需要翻译
|
||
// if (!translator->load(":/language/qt_zh_CN.qm")) //qtcreator启动后看到在资源目录下
|
||
// qDebug() << "load translator file failed!";
|
||
// else
|
||
// a.installTranslator(translator);
|
||
// } else if (locale == "bo_CN") {
|
||
// //藏文需要翻译
|
||
// if (!translator->load(":/language/qt_bo_CN.qm")) //qtcreator启动后看到在资源目录下
|
||
// qDebug() << "load translator file failed!";
|
||
// else
|
||
// a.installTranslator(translator);
|
||
// } else if (locale == "mn_MN") {
|
||
// //蒙古文需要翻译
|
||
// if (!translator->load(":/language/qt_mn_MN.qm")) //qtcreator启动后看到在资源目录下
|
||
// qDebug() << "load translator file failed!";
|
||
// else
|
||
// a.installTranslator(translator);
|
||
// }
|
||
|
||
// 命令行参数
|
||
QCommandLineParser parser;
|
||
parser.setApplicationDescription("kybackup helper");
|
||
parser.addHelpOption();
|
||
parser.addVersionOption();
|
||
// 启动后进入的页面
|
||
QCommandLineOption functionOption(QStringList() << "r" << "restore", QCoreApplication::translate("restore", "system restore"));
|
||
parser.addOption(functionOption);
|
||
parser.process(a);
|
||
GlobelBackupInfo::instance().setHasArgRestore(parser.isSet(functionOption));
|
||
|
||
Utils::initSysRootPath();
|
||
Utils::initSystemInfo();
|
||
|
||
// 初始化日志
|
||
QString logFile = QDir::homePath() + "/.log/kybackup.log";
|
||
logFile.replace("//", "/");
|
||
Utils::setLogFile(logFile);
|
||
qInstallMessageHandler(Utils::customMessageHandler);
|
||
|
||
// 当前操作员是否管理员用户
|
||
GlobelBackupInfo::instance().setIsManager(isManager());
|
||
|
||
// 试用模式运行时需要将原系统的根分区挂载到/target目录,并将其它分区分别挂载,以备后面系统还原使用
|
||
if (GlobelBackupInfo::instance().isCasper())
|
||
{
|
||
remountPartitionsForCasperMode();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 判断启动账号是否管理员账号
|
||
* @return true-相当于是;false-不是
|
||
*/
|
||
bool isManager()
|
||
{
|
||
uid_t uid = getuid();
|
||
QString sid = QString::number(uid);
|
||
GlobelBackupInfo::instance().setCurUserId(sid);
|
||
|
||
QString rootPath = Utils::getSysRootPath();
|
||
// 只正常启动程序时需校验是否管理员账号启动
|
||
if ("/" != rootPath) {
|
||
// 试用模式运行
|
||
GlobelBackupInfo::instance().setIsCasper(true);
|
||
return true;
|
||
}
|
||
|
||
// root用户
|
||
if (0 == uid)
|
||
return true;
|
||
|
||
QString userObject = "/org/freedesktop/Accounts/User" + sid;
|
||
|
||
// 创建QDBusInterface
|
||
QDBusInterface iface("org.freedesktop.Accounts", userObject, "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
|
||
if (!iface.isValid()) {
|
||
qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message());
|
||
exit(1);
|
||
}
|
||
|
||
int result = 0;
|
||
QDBusReply<QDBusVariant> reply = iface.call("Get", QString("org.freedesktop.Accounts.User"), QString("AccountType"));
|
||
if (reply.isValid()) {
|
||
QVariant val = reply.value().variant();
|
||
result = val.toInt();
|
||
}
|
||
|
||
return 0 == result ? false : true;
|
||
}
|
||
|
||
/**
|
||
* @brief CasperMode重新挂载分区
|
||
* @note 试用模式使用备份还原时需将各个分区挂载到/target目录,当前进入试用模式后,各个分区是挂载到/media/xxx/目录下的,为了方便还原重新挂载到/target目录
|
||
*/
|
||
void remountPartitionsForCasperMode()
|
||
{
|
||
// 卸载/backup分区
|
||
ComKylinBackupManagerInterface intf("com.kylin.backup", "/", QDBusConnection::systemBus());
|
||
intf.remountPartitionsForCasperMode();
|
||
}
|
||
|
||
/**
|
||
* @brief 居中显示窗口
|
||
* @param widget
|
||
*/
|
||
#include <QScreen>
|
||
void centerToScreen(QWidget* widget)
|
||
{
|
||
if (!widget)
|
||
return;
|
||
int x = widget->width();
|
||
int y = widget->height();
|
||
|
||
if (GlobelBackupInfo::instance().isWayland()){
|
||
// center window
|
||
int sw=QGuiApplication::primaryScreen()->availableGeometry().width();
|
||
int sh=QGuiApplication::primaryScreen()->availableGeometry().height();
|
||
kdk::WindowManager::setGeometry(widget->windowHandle(), QRect((sw - x)/2, (sh - y)/2, x, y));
|
||
} else {
|
||
QDesktopWidget* m = QApplication::desktop();
|
||
// QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos()));
|
||
QRect desk_rect = m->screenGeometry(widget);
|
||
int desk_x = desk_rect.width();
|
||
int desk_y = desk_rect.height();
|
||
widget->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top());
|
||
}
|
||
}
|
||
|