diff --git a/common/mydefine.h b/common/mydefine.h index 1abb676..1845b63 100755 --- a/common/mydefine.h +++ b/common/mydefine.h @@ -38,6 +38,9 @@ #define PID_STRING_LEN 1024 +#define COLOR_BLUE "#3790FA" +#define COLOR_GRAY "#CCCCCC" + /** * @brief 备份还原操作类型 diff --git a/common/utils.cpp b/common/utils.cpp index 0ec3a2a..f2b77fc 100755 --- a/common/utils.cpp +++ b/common/utils.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "mylittleparse.h" #include "mydefine.h" @@ -522,3 +523,74 @@ QString Utils::StringBySize(qint64 size) else return QString(QString::number(fcount / KB, 10, 2) + "KB"); } + +/** + * @brief 获取挂接的移动设备列表 + * @return MOUNTPOINT,PATH键值对列表 + * @author zhaominyong + * @since 2021/06/07 + * @note + * for bug 59636 【cpm】【HUAWEI】【KOS】【L0】【V3试制】备份时选择移动设备,会出现一个dev/sdc的路径(一般+必现+不常用功能) + * QStorageInfo::mountedVolumes获取的磁盘列表区分不出来是否移动设备 + */ +QHash Utils::getRemovableStorages() +{ + QHash removalbeStorages; + + QProcess process_lsblk; + process_lsblk.start("lsblk -P -o PATH,RM,TYPE,MOUNTPOINT,TRAN"); + if (!process_lsblk.waitForStarted(-1)) { + return removalbeStorages; + } + if (!process_lsblk.waitForFinished(-1)) { + return removalbeStorages; + } + QString result = process_lsblk.readAllStandardOutput(); + /* + result like bellow : + PATH="/dev/sdb" RM="1" TYPE="disk" MOUNTPOINT="" TRAN="usb" + PATH="/dev/sdb4" RM="1" TYPE="part" MOUNTPOINT="/media/zhaominyong/31 GB" TRAN="" + PATH="/dev/sr0" RM="1" TYPE="rom" MOUNTPOINT="/media/zhaominyong/Kylin-Desktop-V10-SP1" TRAN="" + */ + QStringList items = result.split("\n"); + QStringList usbDevs; + for (QStringList::const_iterator it = items.constBegin(); it != items.constEnd(); ++it) { + const QString &line = (*it); + if (line.contains(" TRAN=\"usb\"")) { + QStringList storageAttrs = line.split("\" "); + if (5 != storageAttrs.size()) + continue ; + QString path = storageAttrs.at(0); + path = path.replace("PATH=\"", ""); + usbDevs.append(path); + } + if (line.contains(" RM=\"1\" ") || line.contains(" MOUNTPOINT=\"/media/")) { + if (line.contains(" TYPE=\"rom\" ")) + continue; + if (line.contains(" MOUNTPOINT=\"\"")) + continue; + + // "PATH RM TYPE MOUNTPOINT TRAN" for each row, split by "\" " + QStringList storageAttrs = line.split("\" "); + if (5 != storageAttrs.size()) + continue ; + QString path = storageAttrs.at(0); + path = path.replace("PATH=\"", ""); + bool isSubPart = false; + for (const QString& usbDev : usbDevs) { + if (path.contains(usbDev)) { + isSubPart = true; + break; + } + } + if (!isSubPart) + continue; + QString mount_point = storageAttrs.at(3); + mount_point = mount_point.replace("MOUNTPOINT=\"", ""); + mount_point = mount_point.left(mount_point.length() - 1); + removalbeStorages.insert(path, mount_point); + } + } + + return removalbeStorages; +} diff --git a/common/utils.h b/common/utils.h index 0405cc1..1f08110 100755 --- a/common/utils.h +++ b/common/utils.h @@ -154,6 +154,17 @@ public: */ static QString StringBySize(qint64 size); + /** + * @brief 获取挂接的移动设备列表 + * @return MOUNTPOINT,PATH键值对列表(path中如果含有空格时显示不对,建议不用此值) + * @author zhaominyong + * @since 2021/06/07 + * @note + * for bug 59636 【cpm】【HUAWEI】【KOS】【L0】【V3试制】备份时选择移动设备,会出现一个dev/sdc的路径(一般+必现+不常用功能) + * QStorageInfo::mountedVolumes获取的磁盘列表区分不出来是否移动设备 + */ + static QHash getRemovableStorages(); + private: // 系统根目录,默认"/" static QString m_sysRootPath; diff --git a/kybackup/app.qrc b/kybackup/app.qrc index 6e71169..5590f9a 100644 --- a/kybackup/app.qrc +++ b/kybackup/app.qrc @@ -4,12 +4,31 @@ resource/images/data_restore.svg resource/images/ghost_image.svg resource/images/sysem_restore.svg - resource/images/system_backup.png resource/images/system_backup.svg resource/images/data_backup_dark.svg resource/images/data_restore_dark.svg resource/images/ghost_image_dark.svg resource/images/sysem_restore_dark.svg resource/images/system_backup_dark.svg + resource/images/folder.png + resource/images/loading.gif + resource/symbos/dialog-error.png + resource/symbos/document-properties-symbolic.png + resource/symbos/list-add-symbolic.png + resource/symbos/object-rotate-left-symbolic.png + resource/symbos/ukui-bf-damage-symbolic.png + resource/symbos/ukui-bf-data-backup-symbolic.png + resource/symbos/ukui-bf-data-restore-symbolic.png + resource/symbos/ukui-bf-dataloss-symbolic.png + resource/symbos/ukui-bf-fast-symbolic.png + resource/symbos/ukui-bf-ghost-mirror-symbolic.png + resource/symbos/ukui-bf-many-spot-symbolic.png + resource/symbos/ukui-bf-operation-log-symbolic.png + resource/symbos/ukui-bf-security-symbolic.png + resource/symbos/ukui-bf-simple-symbolic.png + resource/symbos/ukui-bf-system-backup-symbolic.png + resource/symbos/ukui-bf-system-restore-symbolic.png + resource/symbos/ukui-bf-volume-symbolic.png + resource/symbos/ukui-dialog-success.png diff --git a/kybackup/component/circlelabel.cpp b/kybackup/component/circlelabel.cpp new file mode 100644 index 0000000..a2daf27 --- /dev/null +++ b/kybackup/component/circlelabel.cpp @@ -0,0 +1,32 @@ +#include "circlelabel.h" +#include +#include +#include + +CircleLable::CircleLable(const QString& text, QWidget* parent /*= nullptr*/, int size /*= 24*/, QColor backgroundColor /*= QColor(0xCC, 0xCC, 0xCC)*/) : + m_text(text), + m_backgroundColor(backgroundColor), + QLabel(parent) +{ + setFixedSize(QSize(size, size)); +} + +CircleLable::~CircleLable() +{} + +void CircleLable::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; + painter.setBrush(QBrush(m_backgroundColor)); + painter.setPen(Qt::white); + QRect rect = this->rect(); + // 也可用QPainterPath 绘制代替 painter.drawRoundedRect(rect, 15, 15); { QPainterPath painterPath; painterPath.addRoundedRect(rect, 15, 15); p.drawPath(painterPath); } + painter.drawRoundedRect(rect, rect.width()/2, rect.width()/2); + + // drawText + rect.setHeight(rect.height() - 2); + painter.drawText(rect, Qt::AlignCenter, m_text); + + QLabel::paintEvent(event); +} diff --git a/kybackup/component/circlelabel.h b/kybackup/component/circlelabel.h new file mode 100644 index 0000000..84702ff --- /dev/null +++ b/kybackup/component/circlelabel.h @@ -0,0 +1,24 @@ +#ifndef CIRCLELABEL_H +#define CIRCLELABEL_H + +#include +#include +#include + +class CircleLable : public QLabel +{ + Q_OBJECT +public: + CircleLable(const QString& text, QWidget* parent = nullptr, int size = 24, QColor backgroundColor = QColor(0xCC, 0xCC, 0xCC)); + virtual ~CircleLable(); + void setText(const QString& text) { m_text = text; } + +protected: + virtual void paintEvent(QPaintEvent *); + +private: + QString m_text; + QColor m_backgroundColor; +}; + +#endif // CIRCLELABEL_H diff --git a/kybackup/component/imageutil.cpp b/kybackup/component/imageutil.cpp index 631dd18..ab51698 100644 --- a/kybackup/component/imageutil.cpp +++ b/kybackup/component/imageutil.cpp @@ -43,6 +43,22 @@ const QPixmap ImageUtil::loadSvgTheme(const QString &theme, const QString& color return drawSymbolicColoredPixmap(pixmap, color); } +const QPixmap ImageUtil::loadPixmap(QIcon &icon, const QString &color, int size) +{ + int origSize = size; + const auto ratio = qApp->devicePixelRatio(); + if ( 2 == ratio) { + size += origSize; + } else if (3 == ratio) { + size += origSize; + } + + QPixmap pixmap = icon.pixmap(QSize(size, size)); + + pixmap.setDevicePixelRatio(ratio); + return drawSymbolicColoredPixmap(pixmap, color); +} + QPixmap ImageUtil::drawSymbolicColoredPixmap(const QPixmap &source, const QString& cgColor) { QImage img = source.toImage(); diff --git a/kybackup/component/imageutil.h b/kybackup/component/imageutil.h index e3d4871..e4521c3 100644 --- a/kybackup/component/imageutil.h +++ b/kybackup/component/imageutil.h @@ -3,12 +3,14 @@ #include #include +#include class ImageUtil { public: static const QPixmap loadSvg(const QString &path, const QString &color, int size = 16); static const QPixmap loadSvgTheme(const QString &theme, const QString &color, int size = 16); + static const QPixmap loadPixmap(QIcon &icon, const QString &color, int size = 16); static QPixmap drawSymbolicColoredPixmap(const QPixmap &source, const QString &cgColor); }; diff --git a/kybackup/component/linelabel.cpp b/kybackup/component/linelabel.cpp new file mode 100644 index 0000000..783fcea --- /dev/null +++ b/kybackup/component/linelabel.cpp @@ -0,0 +1,23 @@ +#include "linelabel.h" +#include + +LineLabel::LineLabel(QWidget* parent /*= nullptr*/, QColor color /*= QColor(0xCC, 0xCC, 0xCC)*/, QSize size /*= QSize(150, 24)*/) : + QLabel(parent), + m_color(color) +{ + setFixedSize(size); +} + +LineLabel::~LineLabel() +{} + +void LineLabel::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(m_color); + QRect rect = this->rect(); + painter.drawLine(0, rect.height()/2, rect.width(), rect.height()/2); + + QLabel::paintEvent(event); +} diff --git a/kybackup/component/linelabel.h b/kybackup/component/linelabel.h new file mode 100644 index 0000000..4f2d756 --- /dev/null +++ b/kybackup/component/linelabel.h @@ -0,0 +1,25 @@ +#ifndef LINELABEL_H +#define LINELABEL_H + +#include +#include +#include + +/** + * @brief 目前仅支持横线 + */ +class LineLabel : public QLabel +{ + Q_OBJECT +public: + LineLabel(QWidget* parent = nullptr, QColor color = QColor(0xCC, 0xCC, 0xCC), QSize size = QSize(150, 24)); + virtual ~LineLabel(); + +protected: + virtual void paintEvent(QPaintEvent *); + +private: + QColor m_color; +}; + +#endif // LINELABEL_H diff --git a/kybackup/component/myiconbutton.cpp b/kybackup/component/myiconbutton.cpp index aabc0f2..da9c5c2 100644 --- a/kybackup/component/myiconbutton.cpp +++ b/kybackup/component/myiconbutton.cpp @@ -17,7 +17,7 @@ MyIconButton::MyIconButton(QWidget *parent) : // m_iconButton->setStyleSheet("QPushButton:checked{border: none;}" // "QPushButton:!checked{border: none;}"); - m_textLabel = new QLabel(this); + m_textLabel = new MyLabel(this); QSizePolicy textLabelPolicy = m_textLabel->sizePolicy(); textLabelPolicy.setHorizontalPolicy(QSizePolicy::Fixed); textLabelPolicy.setVerticalPolicy(QSizePolicy::Fixed); @@ -44,39 +44,41 @@ MyIconButton::MyIconButton(QWidget *parent) : MyIconButton::~MyIconButton() {} -void MyIconButton::setThemeIcon(const QString &themeIconName, int size) +void MyIconButton::setThemeIcon(const QString &themeIconName, const QString &defaultIconName, int size) { m_themeIconName = themeIconName; + m_defaultIconName = defaultIconName; - QIcon icon = QIcon::fromTheme(themeIconName); + QIcon icon = QIcon::fromTheme(themeIconName, QIcon(defaultIconName)); m_iconButton->setIcon(icon.pixmap(icon.actualSize(QSize(size, size)))); } void MyIconButton::setDesplayText(const QString &text) { m_originalText = text; - m_textLabel->setFixedWidth(this->width() - 30); - QFontMetrics fontMetrics(m_textLabel->font()); - int fontSize = fontMetrics.width(text); - if (fontSize > m_textLabel->width()) { - m_textLabel->setText(fontMetrics.elidedText(text, Qt::ElideRight, m_textLabel->width())); - } else { - m_textLabel->setText(text); - } + m_textLabel->setDeplayText(text); } void MyIconButton::changePalette(bool checked) { QPalette pal(m_textLabel->palette()); + QIcon icon = QIcon::fromTheme(m_themeIconName, QIcon(m_defaultIconName)); QPixmap pix; if (checked) { pal.setColor(QPalette::ButtonText, pal.color(QPalette::HighlightedText)); - pix = ImageUtil::loadSvgTheme(m_themeIconName, QString("white")); + pix = ImageUtil::loadPixmap(icon, QString("white")); } else { pal.setColor(QPalette::ButtonText, pal.color(QPalette::WindowText)); - pix = ImageUtil::loadSvgTheme(m_themeIconName, QString("default")); + pix = ImageUtil::loadPixmap(icon, QString("default")); } m_textLabel->setPalette(pal); m_iconButton->setIcon(pix); } +void MyIconButton::paintEvent(QPaintEvent *event) +{ + QPushButton::paintEvent(event); + m_textLabel->setFixedWidth(this->width() - 38); + m_textLabel->setDeplayText(m_originalText); +} + diff --git a/kybackup/component/myiconbutton.h b/kybackup/component/myiconbutton.h index d52ecd0..c5566dd 100644 --- a/kybackup/component/myiconbutton.h +++ b/kybackup/component/myiconbutton.h @@ -4,6 +4,7 @@ #include #include #include +#include "mylabel.h" class MyIconButton : public QPushButton { @@ -12,17 +13,21 @@ public: explicit MyIconButton(QWidget *parent = nullptr); ~MyIconButton(); - void setThemeIcon(const QString &themeIconName, int size = 16); + void setThemeIcon(const QString &themeIconName, const QString &defaultIconName = "", int size = 16); void setDesplayText(const QString &text); public slots: void changePalette(bool checked); +protected: + void paintEvent(QPaintEvent *event); + private: QPushButton *m_iconButton; - QLabel *m_textLabel; + MyLabel *m_textLabel; QString m_themeIconName; + QString m_defaultIconName; QString m_originalText; }; diff --git a/kybackup/component/myiconlabel.cpp b/kybackup/component/myiconlabel.cpp index fecc9b2..4f13c54 100644 --- a/kybackup/component/myiconlabel.cpp +++ b/kybackup/component/myiconlabel.cpp @@ -10,8 +10,9 @@ MyIconLabel::MyIconLabel(QWidget *parent /*= nullptr*/) : m_iconLabel = new QLabel(this); // border:1px solid black; // const QString greySheetStyle = "min-width: 36px; min-height: 36px;max-width:36px; max-height: 36px;border-radius: 18px; background:grey"; - const QString greySheetStyle = "min-width: 36px; min-height: 36px;max-width:36px; max-height: 36px;border-radius: 18px"; + const QString greySheetStyle = "min-width: 36px; min-height: 36px;max-width:36px; max-height: 36px;border-radius: 18px; background:#F4F4F4"; m_iconLabel->setStyleSheet(greySheetStyle); + m_iconLabel->setAlignment(Qt::AlignCenter); m_textLabel = new QLabel(this); QSizePolicy textLabelPolicy = m_textLabel->sizePolicy(); @@ -31,11 +32,14 @@ MyIconLabel::MyIconLabel(QWidget *parent /*= nullptr*/) : MyIconLabel::~MyIconLabel() {} -void MyIconLabel::setThemeIcon(const QString &themeIconName) +void MyIconLabel::setThemeIcon(const QString &themeIconName, const QString &defaultIconName) { m_themeIconName = themeIconName; - // m_textLabel->setPixmap(QIcon::fromTheme(themeIconName).pixmap(QSize(24,24))); - m_textLabel->setPixmap(ImageUtil::loadSvgTheme(m_themeIconName, QString("default"))); + m_defaultIconName = defaultIconName; + + QIcon icon = QIcon::fromTheme(themeIconName, QIcon(defaultIconName)); + // m_iconLabel->setPixmap(icon.pixmap(QSize(24,24))); + m_iconLabel->setPixmap(ImageUtil::loadPixmap(icon, QString("default"))); } void MyIconLabel::setDesplayText(const QString &text) @@ -54,13 +58,14 @@ void MyIconLabel::setDesplayText(const QString &text) void MyIconLabel::changePalette(bool dark) { QPalette pal(m_textLabel->palette()); + QIcon icon = QIcon::fromTheme(m_themeIconName, QIcon(m_defaultIconName)); QPixmap pix; if (dark) { pal.setColor(QPalette::WindowText, pal.color(QPalette::HighlightedText)); - pix = ImageUtil::loadSvgTheme(m_themeIconName, QString("white")); + pix = ImageUtil::loadPixmap(icon, QString("white")); } else { pal.setColor(QPalette::WindowText, this->palette().color(QPalette::WindowText)); - pix = ImageUtil::loadSvgTheme(m_themeIconName, QString("default")); + pix = ImageUtil::loadPixmap(icon, QString("default")); } m_textLabel->setPalette(pal); m_iconLabel->setPixmap(pix); diff --git a/kybackup/component/myiconlabel.h b/kybackup/component/myiconlabel.h index c96d34d..ac6444f 100644 --- a/kybackup/component/myiconlabel.h +++ b/kybackup/component/myiconlabel.h @@ -10,7 +10,7 @@ public: explicit MyIconLabel(QWidget *parent = nullptr); virtual ~MyIconLabel(); - void setThemeIcon(const QString &themeIconName); + void setThemeIcon(const QString &themeIconName, const QString &defaultIconName = ""); void setDesplayText(const QString &text); @@ -21,6 +21,7 @@ private: QLabel *m_iconLabel; QLabel *m_textLabel; QString m_themeIconName; + QString m_defaultIconName; QString m_originalText; }; diff --git a/kybackup/component/mylabel.cpp b/kybackup/component/mylabel.cpp new file mode 100644 index 0000000..f5b4aee --- /dev/null +++ b/kybackup/component/mylabel.cpp @@ -0,0 +1,56 @@ +#include "mylabel.h" +#include +#include +#include +#include + +MyLabel::MyLabel(const QString& text, QWidget* parent /*= nullptr*/, QColor color /*= QColor(0xCC, 0xCC, 0xCC)*/) : + QLabel(parent), + m_text(text) +{ + QPalette palette = this->palette(); + palette.setColor(QPalette::WindowText, color); + this->setPalette(palette); + this->setAlignment(Qt::AlignCenter); + this->setScaledContents(true); + this->setText(text); +} + +MyLabel::MyLabel(QWidget* parent) : + QLabel(parent) +{ +} + + +MyLabel::~MyLabel() +{} + +void MyLabel::setFontColor(QColor color) +{ + QPalette palette = this->palette(); + palette.setColor(QPalette::WindowText, color); + this->setPalette(palette); +} + +void MyLabel::setFontSize(int size) +{ + QFont font = this->font(); + font.setPixelSize(size); + // 默认为大字体粗体显示 + if (size > 20) + font.setBold(true); + this->setFont(font); +} + +void MyLabel::paintEvent(QPaintEvent *event) +{ + QFontMetrics fontMetrics(this->font()); + int fontSize = fontMetrics.width(m_text); + if (fontSize > this->width()) { + this->setText(fontMetrics.elidedText(m_text, Qt::ElideRight, this->width())); + } else { + this->setText(m_text); + } + + QLabel::paintEvent(event); +} diff --git a/kybackup/component/mylabel.h b/kybackup/component/mylabel.h new file mode 100644 index 0000000..dc2c48a --- /dev/null +++ b/kybackup/component/mylabel.h @@ -0,0 +1,25 @@ +#ifndef MYLABEL_H +#define MYLABEL_H + +#include + +class MyLabel : public QLabel +{ + Q_OBJECT +public: + MyLabel(const QString& text, QWidget* parent = nullptr, QColor color = QColor(0xCC, 0xCC, 0xCC)); + MyLabel(QWidget* parent = nullptr); + virtual ~MyLabel(); + + void setDeplayText(const QString& text) { m_text = text; QLabel::setText(text);} + void setFontColor(QColor color); + void setFontSize(int size); + +protected: + void paintEvent(QPaintEvent *event); + +private: + QString m_text; +}; + +#endif // MYLABEL_H diff --git a/kybackup/kybackup.pro b/kybackup/kybackup.pro index 92be5bd..48ce219 100644 --- a/kybackup/kybackup.pro +++ b/kybackup/kybackup.pro @@ -33,16 +33,20 @@ HEADERS += \ ../common/mylittleparse.h \ ../common/utils.h \ backup_manager_interface.h \ + component/circlelabel.h \ component/clicklabel.h \ component/hoverwidget.h \ component/imageutil.h \ + component/linelabel.h \ component/myiconbutton.h \ component/myiconlabel.h \ + component/mylabel.h \ functypeconverter.h \ gsettingswrapper.h \ leftsiderbarwidget.h \ maindialog.h \ module/systembackup.h \ + module/udiskdetector.h \ qtsingleapplication/qtlocalpeer.h \ qtsingleapplication/qtlockedfile.h \ qtsingleapplication/qtsingleapplication.h \ @@ -53,17 +57,21 @@ SOURCES += \ ../common/mylittleparse.cpp \ ../common/utils.cpp \ backup_manager_interface.cpp \ + component/circlelabel.cpp \ component/clicklabel.cpp \ component/hoverwidget.cpp \ component/imageutil.cpp \ + component/linelabel.cpp \ component/myiconbutton.cpp \ component/myiconlabel.cpp \ + component/mylabel.cpp \ functypeconverter.cpp \ gsettingswrapper.cpp \ leftsiderbarwidget.cpp \ main.cpp \ maindialog.cpp \ module/systembackup.cpp \ + module/udiskdetector.cpp \ qtsingleapplication/qtlocalpeer.cpp \ qtsingleapplication/qtlockedfile.cpp \ qtsingleapplication/qtlockedfile_unix.cpp \ diff --git a/kybackup/leftsiderbarwidget.cpp b/kybackup/leftsiderbarwidget.cpp index 0d85d32..213515c 100644 --- a/kybackup/leftsiderbarwidget.cpp +++ b/kybackup/leftsiderbarwidget.cpp @@ -21,7 +21,9 @@ LeftsiderbarWidget::LeftsiderbarWidget(QWidget *parent, StartMode mode) QHBoxLayout * titleLayout = new QHBoxLayout(); m_mTitleIcon = new QLabel(); - m_titleLabel = new QLabel(tr("Backup and Restore")); + m_titleLabel = new MyLabel(); + m_titleLabel->setDeplayText(tr("Backup & Restore")); + m_titleLabel->setToolTip(tr("Backup & Restore")); titleWidget->setLayout(titleLayout); titleLayout->addWidget(m_mTitleIcon); titleLayout->addWidget(m_titleLabel); @@ -48,7 +50,10 @@ LeftsiderbarWidget::LeftsiderbarWidget(QWidget *parent, StartMode mode) funcButton->setObjectName(btnName); funcButton->setFixedSize(180, 40); funcButton->setDesplayText(mnamei18nString); - funcButton->setThemeIcon(themeIconName); + QString defaultIconName(":/symbos/"); + defaultIconName += themeIconName; + defaultIconName += ".png"; + funcButton->setThemeIcon(themeIconName, defaultIconName); funcButton->setToolTip(mnamei18nString); funcButton->setCheckable(true); diff --git a/kybackup/leftsiderbarwidget.h b/kybackup/leftsiderbarwidget.h index 2b04049..f959e3f 100644 --- a/kybackup/leftsiderbarwidget.h +++ b/kybackup/leftsiderbarwidget.h @@ -8,7 +8,7 @@ #include #include #include "functypeconverter.h" - +#include "component/mylabel.h" class LeftsiderbarWidget : public QWidget { @@ -27,7 +27,7 @@ private: QVBoxLayout *m_leftSideBarVLayout = nullptr; QLabel *m_mTitleIcon = nullptr; - QLabel *m_titleLabel = nullptr; + MyLabel *m_titleLabel = nullptr; QButtonGroup *m_funcGroup = nullptr; }; diff --git a/kybackup/module/systembackup.cpp b/kybackup/module/systembackup.cpp index 021ad7a..a35072f 100644 --- a/kybackup/module/systembackup.cpp +++ b/kybackup/module/systembackup.cpp @@ -1,18 +1,38 @@ #include "systembackup.h" #include #include +#include +#include -#include "component/myiconlabel.h" +#include "../component/clicklabel.h" +#include "../component/circlelabel.h" +#include "../component/myiconlabel.h" +#include "../component/mylabel.h" +#include "../component/linelabel.h" +#include "../../common/utils.h" SystemBackup::SystemBackup(QWidget *parent /*= nullptr*/) : - QStackedWidget(parent) + QStackedWidget(parent), + m_udector(new UdiskDetector()), + m_isLocal(true), + m_systemBackupState(SystemBackupState::IDEL), + m_movie(nullptr) { + // 界面手写代码创建,作为练手 initFirstWidget(); + initSecondWidget(); + initThirdWidget(); } SystemBackup::~SystemBackup() -{} +{ + delete m_udector; + delete m_movie; +} +/** + * @brief 初始化第一个页面 + */ void SystemBackup::initFirstWidget() { QWidget *first = new QWidget; @@ -23,9 +43,9 @@ void SystemBackup::initFirstWidget() imageBackup_firstPage->setPixmap(pixmap); imageBackup_firstPage->setScaledContents(true); - QLabel *labelBackup_firstPage = new QLabel(tr("System Backup"), first); - // labelBackup_firstPage->setGeometry(40, 120, 300, 48); - labelBackup_firstPage->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + MyLabel *labelBackup_firstPage = new MyLabel(first); + labelBackup_firstPage->setDeplayText(tr("System Backup")); + labelBackup_firstPage->setFixedWidth(500); labelBackup_firstPage->setFixedHeight(48); labelBackup_firstPage->move(41, 120); // 默认水平左对齐,上下居中对齐;故不需要设置 @@ -35,41 +55,42 @@ void SystemBackup::initFirstWidget() font.setBold(true); font.setPixelSize(36); labelBackup_firstPage->setFont(font); + // labelBackup_firstPage->setAttribute(Qt::WA_TranslucentBackground); + labelBackup_firstPage->setScaledContents(true); labelBackup_firstPage->adjustSize(); - labelBackup_firstPage->setAttribute(Qt::WA_TranslucentBackground); - QLabel *labelNote_firstPage = new QLabel(first); - labelNote_firstPage->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + MyLabel *labelNote_firstPage = new MyLabel(first); + labelNote_firstPage->setFixedWidth(700); labelNote_firstPage->setFixedHeight(24); labelNote_firstPage->move(41, 180); - labelNote_firstPage->setText(tr("Can be restored when files are damaged or lost")); + labelNote_firstPage->setDeplayText(tr("Can be restored when files are damaged or lost")); font.setBold(false); font.setPixelSize(18); labelNote_firstPage->setFont(font); + labelNote_firstPage->setScaledContents(true); labelNote_firstPage->adjustSize(); - labelNote_firstPage->setAttribute(Qt::WA_TranslucentBackground); MyIconLabel *iconMultiBackup_firstPage = new MyIconLabel(first); - iconMultiBackup_firstPage->setGeometry(41, 244, 150, 36); - iconMultiBackup_firstPage->setThemeIcon("ukui-bf-many-spot-symbolic"); + 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, 150, 36); - iconSmallSize_firstPage->setThemeIcon("ukui-bf-many-spot-symbolic"); + 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, 150, 36); - iconSecurity_firstPage->setThemeIcon("ukui-bf-many-spot-symbolic"); + 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, 150, 36); - iconSimple_firstPage->setThemeIcon("ukui-bf-many-spot-symbolic"); + 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); @@ -80,6 +101,161 @@ void SystemBackup::initFirstWidget() beginBackup->setAutoRepeat(true); font.setPixelSize(24); beginBackup->setFont(font); + connect(beginBackup, &QPushButton::clicked, this, &SystemBackup::on_next_clicked); + + ClickLabel * backupPointManage = new ClickLabel(tr("Backup Management >>"), first); + backupPointManage->setGeometry(551, 551, 200, 30); + QPalette pal(backupPointManage->palette()); + pal.setColor(QPalette::WindowText, QColor(Qt::blue)); + backupPointManage->setPalette(pal); + backupPointManage->setToolTip(tr("Backup Management >>")); + connect(backupPointManage, &ClickLabel::clicked, this, &SystemBackup::on_systemBackupManage_clicked); addWidget(first); } + +/** + * @brief “上一步”按钮响应槽 + * @param checked + */ +void SystemBackup::on_pre_clicked(bool checked) +{ + Q_UNUSED(checked) + int index = this->currentIndex() - 1; + if (index >= 0) { + this->setCurrentIndex(index); + } +} + +/** + * @brief “开始备份”“下一步”按钮响应槽 + * @param checked + */ +void SystemBackup::on_next_clicked(bool checked) +{ + Q_UNUSED(checked) + int index = this->currentIndex() + 1; + if (index < this->count()) { + this->setCurrentIndex(index); + } +} + +/** + * @brief 系统备份管理响应槽 + */ +void SystemBackup::on_systemBackupManage_clicked() +{ + // TODO:创建系统备份点管理界面 +} + +/** + * @brief 初始化第二个页面 + */ +void SystemBackup::initSecondWidget() +{ + QWidget *second = new QWidget; + + MyLabel* labelSelect = new MyLabel(second); + labelSelect->setDeplayText(tr("Please select backup position")); + labelSelect->setFixedWidth(600); + labelSelect->setFixedHeight(27); + labelSelect->move(41, 41); + QFont font; + font.setBold(true); + font.setPixelSize(18); + labelSelect->setFont(font); + labelSelect->setScaledContents(true); + labelSelect->adjustSize(); + + QComboBox* comboSelect = new QComboBox(second); + comboSelect->setGeometry(41, 84, 680, 36); + // 添加本地默认路径、移动设备目录 + connect(m_udector, &UdiskDetector::udiskListChanged, this, [=](QList diskList) { + comboSelect->clear(); + QString qsLocalDefaultPath = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH; + qsLocalDefaultPath.replace("//", "/"); + QIcon iconFolder = QIcon::fromTheme("insync-folder.png", QIcon(":/images/folder.png")); + comboSelect->addItem(iconFolder, tr("local default path : ") + qsLocalDefaultPath); + + QString qsPreDevPath(tr("removable devices path : ")); + for (QStorageInfo& disk : diskList) { + comboSelect->addItem(iconFolder, qsPreDevPath + disk.rootPath() + BACKUP_SNAPSHOTS_PATH); + } + }); + m_udector->getStorageInfo(); + connect(comboSelect, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { + // 第一个选项是本地系统备份 + m_isLocal = (index == 0); + }); + + QPushButton *preStep = new QPushButton(second); + preStep->setGeometry(271, 176, 97, 36); + preStep->setText(tr("back")); + preStep->setEnabled(true); + preStep->setAutoRepeat(true); + connect(preStep, &QPushButton::clicked, this, &SystemBackup::on_pre_clicked); + + QPushButton *nextStep = new QPushButton(second); + nextStep->setGeometry(389, 176, 97, 36); + nextStep->setText(tr("next")); + nextStep->setEnabled(true); + nextStep->setAutoRepeat(true); + connect(nextStep, &QPushButton::clicked, this, [=](bool checked) { + this->on_next_clicked(checked); + emit this->startCheckEnv(); + }); + + addWidget(second); +} + +/** + * @brief 初始化第三个页面 + */ +void SystemBackup::initThirdWidget() +{ + QWidget *third = new QWidget; + + CircleLable *one = new CircleLable("1", third, 24, QColor(COLOR_BLUE)); + one->move(QPoint(81, 41)); + LineLabel *line1 = new LineLabel(third, QColor(COLOR_BLUE)); + line1->move(QPoint(108, 41)); + CircleLable *two = new CircleLable("2", third); + two->move(QPoint(261, 41)); + LineLabel *line2 = new LineLabel(third); + line2->move(QPoint(288, 41)); + CircleLable *three = new CircleLable("3", third); + three->move(QPoint(441, 41)); + LineLabel *line3 = new LineLabel(third); + line3->move(QPoint(468, 41)); + CircleLable *four = new CircleLable("4", third); + four->move(QPoint(621, 41)); + + MyLabel *label1 = new MyLabel(tr("checking"), third); + label1->setFontColor(QColor(COLOR_BLUE)); + label1->setGeometry(11, 72, 164, 30); + + MyLabel *label2 = new MyLabel(tr("preparing"), third); + label2->setGeometry(191, 72, 164, 30); + + MyLabel *label3 = new MyLabel(tr("backuping"), third); + label3->setGeometry(371, 72, 164, 30); + + MyLabel *label4 = new MyLabel(tr("finished"), third); + label4->setGeometry(551, 72, 164, 30); + + QLabel *loadingGif = new QLabel(third); + QMovie *m_movie = new QMovie(":/images/loading.gif"); + loadingGif->setMovie(m_movie); + loadingGif->setGeometry(180, 180, 20, 20); + m_movie->start(); + + QLabel *bigTitle = new QLabel(third); + QFont font = bigTitle->font(); + font.setBold(true); + font.setPixelSize(24); + bigTitle->setFont(font); + bigTitle->setText(tr("env checking, wait a moment")); + bigTitle->setGeometry(210, 170, 500, 36); + + addWidget(third); +} diff --git a/kybackup/module/systembackup.h b/kybackup/module/systembackup.h index 6ba4bfc..a7ac2e2 100644 --- a/kybackup/module/systembackup.h +++ b/kybackup/module/systembackup.h @@ -2,16 +2,40 @@ #define SYSTEMBACKUP_H #include +#include "udiskdetector.h" class SystemBackup : public QStackedWidget { Q_OBJECT +public: + enum SystemBackupState + { + IDEL = 0, // 空闲 + CHECKING, // 环境校验中 + BACKUPING // 备份中 + }; public: explicit SystemBackup(QWidget *parent = nullptr); ~SystemBackup(); private: void initFirstWidget(); + void initSecondWidget(); + void initThirdWidget(); + +signals: + void startCheckEnv(); + +public slots: + void on_pre_clicked(bool checked = false); + void on_next_clicked(bool checked = false); + void on_systemBackupManage_clicked(); + +private: + UdiskDetector* m_udector; + bool m_isLocal; + int m_systemBackupState; + QMovie *m_movie; }; #endif // SYSTEMBACKUP_H diff --git a/kybackup/module/udiskdetector.cpp b/kybackup/module/udiskdetector.cpp new file mode 100644 index 0000000..91ff088 --- /dev/null +++ b/kybackup/module/udiskdetector.cpp @@ -0,0 +1,60 @@ +#include "udiskdetector.h" +#include +#include + +#include "../../common/utils.h" + +UdiskDetector::UdiskDetector(QObject* parent) + : QObject(parent) +{ + m_udiskList.clear(); + diskRefreshDelay = new QTimer; + connect(diskRefreshDelay, &QTimer::timeout, this, &UdiskDetector::getStorageInfo); + udiskplugwatcher = new QFileSystemWatcher(this); + udiskplugwatcher->addPath("/dev"); + connect(udiskplugwatcher, &QFileSystemWatcher::directoryChanged, this, &UdiskDetector::refreshDiskList); +} + +void UdiskDetector::getStorageInfo() +{ + m_udiskList.clear(); + diskRefreshDelay->stop(); //U盘动态刷新相关 + QHash removableStorages = Utils::getRemovableStorages(); + QList diskList = QStorageInfo::mountedVolumes(); //获取磁盘列表 + for (QStorageInfo& disk : diskList) { + if ("" == disk.displayName()) //名称为空的磁盘不显示 + continue; + if ("/" == disk.displayName()) //系统分区不显示 + continue; + if ("tmpfs" == disk.fileSystemType()) //tmpfs类型的磁盘不显示 + continue; + if ("/boot" == disk.displayName()) //boot分区不显示 + continue; + if (disk.displayName().contains("BACKUP")) //还原分区不显示 + continue; + if (disk.device().contains("/dev/sr0")) //光盘不显示 + continue; + if (disk.device().contains("/dev/sda0")) //内置硬盘不显示 + continue; + if (disk.device().contains("/dev/nvm")) //nvme类型的设备不显示 + continue; + if (!disk.rootPath().startsWith("/media")) + continue; + if (disk.rootPath().contains("loop")) + continue; + if (removableStorages.contains(disk.device())) + m_udiskList.append(disk); + } + + emit udiskListChanged(m_udiskList); +} + +void UdiskDetector::refreshDiskList() +{ + if (diskRefreshDelay->isActive()) { + return; + } + + m_udiskList.clear(); + diskRefreshDelay->start(1000); +} diff --git a/kybackup/module/udiskdetector.h b/kybackup/module/udiskdetector.h new file mode 100644 index 0000000..ede4a4e --- /dev/null +++ b/kybackup/module/udiskdetector.h @@ -0,0 +1,44 @@ +#ifndef UDISKDETECTOR_H +#define UDISKDETECTOR_H + +#include +#include +#include + +class QTimer; +class QFileSystemWatcher; + +class UdiskDetector : public QObject { + Q_OBJECT + Q_PROPERTY(QList udiskList READ getDiskList WRITE setDiskList NOTIFY udiskListChanged) +public: + UdiskDetector(QObject* parent = nullptr); + + void getStorageInfo(); + void refreshDiskList(); + + QList getDiskList() const + { + return m_udiskList; + } + +public slots: + void setDiskList(QList udiskList) + { + if (m_udiskList == udiskList) + return; + + m_udiskList = udiskList; + emit udiskListChanged(m_udiskList); + } + +signals: + void udiskListChanged(QList udiskList); + +private: + QTimer* diskRefreshDelay; + QFileSystemWatcher* udiskplugwatcher; + QList m_udiskList; +}; + +#endif // UDISKDETECTOR_H diff --git a/kybackup/resource/images/folder.png b/kybackup/resource/images/folder.png new file mode 100644 index 0000000..8875427 Binary files /dev/null and b/kybackup/resource/images/folder.png differ diff --git a/kybackup/resource/images/loading.gif b/kybackup/resource/images/loading.gif new file mode 100644 index 0000000..dafb71e Binary files /dev/null and b/kybackup/resource/images/loading.gif differ diff --git a/kybackup/resource/images/system_backup.png b/kybackup/resource/images/system_backup.png deleted file mode 100644 index 1f00087..0000000 Binary files a/kybackup/resource/images/system_backup.png and /dev/null differ diff --git a/kybackup/resource/symbos/dialog-error.png b/kybackup/resource/symbos/dialog-error.png new file mode 100644 index 0000000..e6319da Binary files /dev/null and b/kybackup/resource/symbos/dialog-error.png differ diff --git a/kybackup/resource/symbos/document-properties-symbolic.png b/kybackup/resource/symbos/document-properties-symbolic.png new file mode 100644 index 0000000..f065b46 Binary files /dev/null and b/kybackup/resource/symbos/document-properties-symbolic.png differ diff --git a/kybackup/resource/symbos/list-add-symbolic.png b/kybackup/resource/symbos/list-add-symbolic.png new file mode 100644 index 0000000..250a96c Binary files /dev/null and b/kybackup/resource/symbos/list-add-symbolic.png differ diff --git a/kybackup/resource/symbos/object-rotate-left-symbolic.png b/kybackup/resource/symbos/object-rotate-left-symbolic.png new file mode 100644 index 0000000..5271847 Binary files /dev/null and b/kybackup/resource/symbos/object-rotate-left-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-damage-symbolic.png b/kybackup/resource/symbos/ukui-bf-damage-symbolic.png new file mode 100644 index 0000000..674d2f9 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-damage-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-data-backup-symbolic.png b/kybackup/resource/symbos/ukui-bf-data-backup-symbolic.png new file mode 100644 index 0000000..3ca41fd Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-data-backup-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-data-restore-symbolic.png b/kybackup/resource/symbos/ukui-bf-data-restore-symbolic.png new file mode 100644 index 0000000..a1d9ef3 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-data-restore-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-dataloss-symbolic.png b/kybackup/resource/symbos/ukui-bf-dataloss-symbolic.png new file mode 100644 index 0000000..665551d Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-dataloss-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-fast-symbolic.png b/kybackup/resource/symbos/ukui-bf-fast-symbolic.png new file mode 100644 index 0000000..dd19714 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-fast-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-ghost-mirror-symbolic.png b/kybackup/resource/symbos/ukui-bf-ghost-mirror-symbolic.png new file mode 100644 index 0000000..81b0f5e Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-ghost-mirror-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-many-spot-symbolic.png b/kybackup/resource/symbos/ukui-bf-many-spot-symbolic.png new file mode 100644 index 0000000..5499ce9 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-many-spot-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-operation-log-symbolic.png b/kybackup/resource/symbos/ukui-bf-operation-log-symbolic.png new file mode 100644 index 0000000..b1af452 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-operation-log-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-security-symbolic.png b/kybackup/resource/symbos/ukui-bf-security-symbolic.png new file mode 100644 index 0000000..b57ef4b Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-security-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-simple-symbolic.png b/kybackup/resource/symbos/ukui-bf-simple-symbolic.png new file mode 100644 index 0000000..ed4eb86 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-simple-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-system-backup-symbolic.png b/kybackup/resource/symbos/ukui-bf-system-backup-symbolic.png new file mode 100644 index 0000000..b888d2a Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-system-backup-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-system-restore-symbolic.png b/kybackup/resource/symbos/ukui-bf-system-restore-symbolic.png new file mode 100644 index 0000000..6d79b04 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-system-restore-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-bf-volume-symbolic.png b/kybackup/resource/symbos/ukui-bf-volume-symbolic.png new file mode 100644 index 0000000..1562336 Binary files /dev/null and b/kybackup/resource/symbos/ukui-bf-volume-symbolic.png differ diff --git a/kybackup/resource/symbos/ukui-dialog-success.png b/kybackup/resource/symbos/ukui-dialog-success.png new file mode 100644 index 0000000..f799b78 Binary files /dev/null and b/kybackup/resource/symbos/ukui-dialog-success.png differ