diff --git a/lib/common-widgets/kiran-collapse/kiran-collapse.cpp b/lib/common-widgets/kiran-collapse/kiran-collapse.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6e9b56a93ee75925d7ceb19f6a7415f6f7c2349 --- /dev/null +++ b/lib/common-widgets/kiran-collapse/kiran-collapse.cpp @@ -0,0 +1,268 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#include "kiran-collapse.h" +#include +#include "ui_kiran-collapse.h" + +#include +#include +#include +#include +#include +#include + +KiranCollapse::KiranCollapse(QWidget *parent) + :KiranCollapse(false, "", nullptr, parent) +{ +} + +KiranCollapse::KiranCollapse(bool defaultIsExpand, const QString &title, + QWidget *expansionSpaceWidget, QWidget *parent) + : QWidget(parent), ui(new Ui::KiranCollapse), + m_isExpanded(defaultIsExpand), m_topBarTitle(title), m_esWidget(expansionSpaceWidget) +{ + init(); +} + +KiranCollapse::~KiranCollapse() +{ + delete ui; +} + +void KiranCollapse::addExpansionSpaceWidget(QWidget *widget) +{ + auto layout = ui->expansionSpaceContainer; + layout->addWidget(widget); +} + +void KiranCollapse::delExpansionSpaceWidget(int index) +{ + if (ui->expansionSpaceContainer->count() == 0) + { + return; + } + auto item = ui->expansionSpaceContainer->takeAt(index); + if (item) + { + QWidget *widget = item->widget(); + delete widget; + delete item; + } +} + +void KiranCollapse::delExpansionSpaceWidget(const QString &widgetName) +{ + // 通过对象名称查找和删除指定的widget + QList widgetsToRemove = ui->expansionSpaceContainer->findChildren(widgetName); + for (QWidget *widget : widgetsToRemove) + { + delExpansionSpaceWidget(ui->expansionSpaceContainer->indexOf(widget)); + } +} + +void KiranCollapse::delAllExpansionSpaceWidget() +{ + while (ui->expansionSpaceContainer->count() != 0) + { + QLayoutItem *item = ui->expansionSpaceContainer->takeAt(0); + if (item) + { + delete item->widget(); + delete item; + } + } +} + +void KiranCollapse::expand() +{ + if (m_isExpanded || m_animationForES->state() == QAbstractAnimation::Running) + { + return; + } + m_animationForES->setEasingCurve(QEasingCurve::OutCubic); + m_animationForES->setStartValue(ui->expansionSpace->height()); + m_animationForES->setEndValue(m_maximumExpansionSpaceHeight); + m_animationForES->start(); + + m_isExpanded = true; + ui->topBar->refreshFlagPixmap(m_isExpanded); + emit expandSpaceExpanded(); +} + +void KiranCollapse::collapse() +{ + if (!m_isExpanded || m_animationForES->state() == QAbstractAnimation::Running) + { + return; + } + m_animationForES->setEasingCurve(QEasingCurve::InCubic); + m_animationForES->setStartValue(m_maximumExpansionSpaceHeight); + m_animationForES->setEndValue(0); + m_animationForES->start(); + m_isExpanded = false; + ui->topBar->refreshFlagPixmap(m_isExpanded); + emit expandSpaceCollapsed(); +} + +void KiranCollapse::changeExpansionState() +{ + if (m_isExpanded) + { + collapse(); + } + else + { + expand(); + } +} + +void KiranCollapse::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + QStyle::State state; + + opt.initFrom(this); + state = opt.state; + + QPainterPath painterPath; + QRectF qRect = opt.rect; + qRect.adjust(0.5, 0.5, -0.5, -0.5); + painterPath.addRoundedRect(qRect, m_radius, m_radius); + + using namespace Kiran; + auto getStateFunc = [this](QStyle::State state) -> StylePalette::ColorState { + if (!(state & QStyle::State_Enabled)) + { + return StylePalette::Disabled; + } + else if (state & QStyle::State_Sunken) + { + return StylePalette::Active; + } + else if ((state & QStyle::State_MouseOver) && testAttribute(Qt::WA_Hover)) + { + return StylePalette::Hover; + } + else + { + return StylePalette::Normal; + } + }; + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + auto kiranPalette = StylePalette::instance(); + if (m_drawBackground) + { + QColor backgroundColor; + backgroundColor = kiranPalette->color(getStateFunc(state), + StylePalette::Widget, + StylePalette::Background); + painter.fillPath(painterPath, backgroundColor); + } + + QWidget::paintEvent(event); +} + +void KiranCollapse::init() +{ + ui->setupUi(this); + ui->expansionSpace->setAttribute(Qt::WA_StyledBackground); + ui->expansionSpaceContainer->setSpacing(12); + + setIsExpand(m_isExpanded); + ui->expansionSpaceContainer->setContentsMargins(m_expansionMarginLeft, + m_expansionMarginTop, + m_expansionMarginRight, + m_expansionMarginBottom); + ui->topBar->setTitle(m_topBarTitle); + // 若为扩展区控件为空,则不添加 + if (m_esWidget) + { + ui->expansionSpaceContainer->addWidget(m_esWidget); + } + m_animationForES = new QPropertyAnimation(ui->expansionSpace, "maximumHeight", this); + m_animationForES->setDuration(200); + connect(ui->topBar, &TopBar::clickedBar, this, &KiranCollapse::changeExpansionState); +} + +bool KiranCollapse::getIsExpand() const +{ + return m_isExpanded; +} + +void KiranCollapse::setIsExpand(bool isExpanded) +{ + m_isExpanded = isExpanded; + // 根据展开/折叠设置最大高度 + ui->expansionSpace->setMaximumHeight(m_isExpanded ? m_maximumExpansionSpaceHeight : 0); + ui->topBar->refreshFlagPixmap(m_isExpanded); +} + +void KiranCollapse::addTopBarWidget(QWidget *widget) +{ + ui->topBar->addWidget(widget); +} + +void KiranCollapse::setTitle(const QString &title) +{ + ui->topBar->setTitle(title); +} + +void KiranCollapse::setTobBarFixedHeight(int height) +{ + ui->topBar->setFixedHeight(height); +} + +void KiranCollapse::setMaximumExpansionHeight(int maxExpandHeight) +{ + m_maximumExpansionSpaceHeight = maxExpandHeight; + // 缓存设置最大高度之前的原始高度 + int curHeight = ui->expansionSpace->height(); + ui->expansionSpace->setMaximumHeight(maxExpandHeight); + // 如果设置最大高度时,处于折叠态则依然保持设置前高度 (防止折叠态是设置该值会导致扩展区展开) + if (!m_isExpanded) + { + ui->expansionSpace->setFixedHeight(curHeight); + } +} +void KiranCollapse::setExpansionMargin(int left, int top, int right, int bottom) +{ + m_expansionMarginLeft = left; + m_expansionMarginTop = top; + m_expansionMarginRight = right; + m_expansionMarginBottom = bottom; + ui->expansionSpaceContainer->setContentsMargins(m_expansionMarginLeft, + m_expansionMarginTop, + m_expansionMarginRight, + m_expansionMarginBottom); +} +void KiranCollapse::setTopBarMargin(int left, int top, int right, int bottom) +{ + ui->topBar->setTopBarMargin(left, top, right, bottom); +} +void KiranCollapse::setTopBarSpacing(int spacing) +{ + ui->topBar->setTopBarSpacing(spacing); +} +void KiranCollapse::setExpand() +{ + expand(); +} +void KiranCollapse::setCollapse() +{ + collapse(); +} diff --git a/lib/common-widgets/kiran-collapse/kiran-collapse.h b/lib/common-widgets/kiran-collapse/kiran-collapse.h new file mode 100644 index 0000000000000000000000000000000000000000..f0edf3605a4575f49e2d4f1eaae56e25d0a1741e --- /dev/null +++ b/lib/common-widgets/kiran-collapse/kiran-collapse.h @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#include + +class QPropertyAnimation; + +namespace Ui +{ +class KiranCollapse; +} + +class KiranCollapse : public QWidget +{ + Q_OBJECT + +public: + explicit KiranCollapse(QWidget* parent = nullptr); + + ~KiranCollapse() override; + + /** + * @brief 通过有参构造实例化 KiranCollapse + * @param 默认是否展开, 文本标题, 扩展区控件, 父控件 + */ + KiranCollapse(bool defaultIsExpand, const QString& title, QWidget* expandSpaceWidget, QWidget* parent = nullptr); + + /** + * @brief 设置 kiran-collapse 的标题 + * @param 标题文本 + */ + void setTitle(const QString& title); + + /** + * @brief 添加一个控件到顶栏 + * @param QWidget控件,加入方式为:每次加入的控件会放在最右边图标的左侧 + */ + void addTopBarWidget(QWidget* widget); + + /** + * @brief 设置顶栏的固定高度 + * @param height 高度(默认为45) + */ + void setTobBarFixedHeight(int height); + + /** + * @brief 设置扩展区内部间距 + * @param left, top, right, bottom + */ + void setExpansionMargin(int left, int top, int right, int bottom); + + /** + * @brief 设置顶栏内部间距 + * @param left, top, right, bottom + */ + void setTopBarMargin(int left, int top, int right, int bottom); + + /** + * @brief 设置顶栏控件间距 + * @param spacing + */ + void setTopBarSpacing(int spacing); + + /** + * @brief 获取 kiran-collapse 是否展开 + * @return bool + */ + bool getIsExpand() const; + + /** + * @brief 设置 kiran-collapse 默认状态是否展开,初始化时使用 + * @param bool + */ + void setIsExpand(bool isExpanded); + + /** + * @brief 设置扩展区最大展开高度 + * @param maxExpandHeight 最大展开高度 (默认为400) + */ + void setMaximumExpansionHeight(int maxExpandHeight); + + /** + * @brief 添加控件到扩展区 + * @param widget - 要加入到扩展区的控件 + */ + void addExpansionSpaceWidget(QWidget* widget); + + /** + * @brief 根据索引删除扩展区的控件 + * @param index - 扩展区内控件从上到下的索引 + */ + void delExpansionSpaceWidget(int index); + + /** + * @brief 根据控件对象名称删除控件 + * @param widgetName + */ + void delExpansionSpaceWidget(const QString& widgetName); + + /** + * @brief 清除扩展区所有控件 + */ + void delAllExpansionSpaceWidget(); + + /** + * @brief 将扩展区展开 + */ + void setExpand(); + + /** + * @brief 将扩展区折叠 + */ + void setCollapse(); + +signals: + void expandSpaceExpanded(); + void expandSpaceCollapsed(); + +protected: + void paintEvent(QPaintEvent* event) override; + +private slots: + void changeExpansionState(); + +private: + void init(); + void expand(); + void collapse(); + +private: + Ui::KiranCollapse* ui; + + // 是否展开 + bool m_isExpanded = false; + // 展开最大高度 + int m_maximumExpansionSpaceHeight = 400; + + // 扩展区内边距 (默认12) + int m_expansionMarginLeft = 12; + int m_expansionMarginTop = 12; + int m_expansionMarginRight = 12; + int m_expansionMarginBottom = 12; + + // 外部圆角 + int m_radius = 6; + bool m_drawBackground = true; + // 扩展区展开搜索动画 + QPropertyAnimation* m_animationForES{}; + + // 顶栏标题 + QString m_topBarTitle; + // 扩展区控件 + QWidget *m_esWidget; +}; diff --git a/lib/common-widgets/kiran-collapse/kiran-collapse.ui b/lib/common-widgets/kiran-collapse/kiran-collapse.ui new file mode 100755 index 0000000000000000000000000000000000000000..36fa6a382e11173650c2561e0bb5c88f6888cd8b --- /dev/null +++ b/lib/common-widgets/kiran-collapse/kiran-collapse.ui @@ -0,0 +1,90 @@ + + + KiranCollapse + + + + 0 + 0 + 700 + 278 + + + + + 0 + 0 + + + + ListExpansionSpace + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + TopBar + QWidget +
kiran-collapse/top-bar.h
+ 1 +
+
+ + +
diff --git a/lib/common-widgets/kiran-collapse/list-expansion-space.cpp b/lib/common-widgets/kiran-collapse/list-expansion-space.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73adedc8bb4348e1e690fe541259c7b3b5299ed2 --- /dev/null +++ b/lib/common-widgets/kiran-collapse/list-expansion-space.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#include "list-expansion-space.h" +#include +#include "logging-category.h" +#include "ui_list-expansion-space.h" + +ListExpansionSpace::ListExpansionSpace(QWidget *parent) : QWidget(parent), + ui(new Ui::ListExpansionSpace) +{ + ui->setupUi(this); + init(); +} + +ListExpansionSpace::~ListExpansionSpace() +{ + delete ui; +} + +void ListExpansionSpace::init() +{ + QPalette qPalette = this->palette(); + qPalette.setBrush(QPalette::Base, QBrush(QColor(255, 255, 255, 0))); + ui->listWidget->setPalette(qPalette); + ui->listWidget->setFrameShape(QListWidget::NoFrame); +} + +void ListExpansionSpace::addListExpansionSpaceItem(QWidget *widget) +{ + auto item = new QListWidgetItem(); + item->setSizeHint(widget->sizeHint()); + ui->listWidget->addItem(item); + ui->listWidget->setItemWidget(item, widget); + emit addedListWidgetItem(); +} + +void ListExpansionSpace::removeListExpansionSpaceCurrentItem() +{ + auto curItem = ui->listWidget->currentItem(); + ui->listWidget->removeItemWidget(curItem); + delete curItem; + + emit removedListWidgetItem(); +} + +void ListExpansionSpace::removeListExpansionSpaceItem(int index) +{ + if (index < 0 || index >= ui->listWidget->count()) + { + KLOG_WARNING(qLcCommonWidget) << "remove ListExpansionSpaceItem Failed, Invalid index value: " << index; + return; + } + QListWidgetItem *pItem = ui->listWidget->item(index); + ui->listWidget->removeItemWidget(pItem); + delete pItem; +} diff --git a/lib/common-widgets/kiran-collapse/list-expansion-space.h b/lib/common-widgets/kiran-collapse/list-expansion-space.h new file mode 100644 index 0000000000000000000000000000000000000000..7664298fe3a28d9ab8e281f3bf56074da7c0dcf4 --- /dev/null +++ b/lib/common-widgets/kiran-collapse/list-expansion-space.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#pragma once +#include + +namespace Ui +{ +class ListExpansionSpace; +} + +class ListExpansionSpace : public QWidget +{ + Q_OBJECT + +public: + explicit ListExpansionSpace(QWidget *parent = nullptr); + ~ListExpansionSpace() override; + +signals: + void addedListWidgetItem(); + void removedListWidgetItem(); + +public slots: + /** + * @brief 添加控件到列表 + * @param widget + */ + void addListExpansionSpaceItem(QWidget *widget); + + /** + * @brief 移除当前选中的列表条目 + */ + void removeListExpansionSpaceCurrentItem(); + + /** + * @brief 根据索引删除列表条目 + * @param index + */ + void removeListExpansionSpaceItem(int index); + +private: + void init(); + +private: + Ui::ListExpansionSpace *ui; +}; diff --git a/lib/common-widgets/kiran-collapse/list-expansion-space.ui b/lib/common-widgets/kiran-collapse/list-expansion-space.ui new file mode 100755 index 0000000000000000000000000000000000000000..65848af682d59492e21552b1773bb37a06480af1 --- /dev/null +++ b/lib/common-widgets/kiran-collapse/list-expansion-space.ui @@ -0,0 +1,50 @@ + + + ListExpansionSpace + + + + 0 + 0 + 243 + 261 + + + + + 0 + 0 + + + + ListExpansionSpace + + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + + + + + + + + + + + diff --git a/lib/common-widgets/kiran-collapse/top-bar-flag-pixmap.cpp b/lib/common-widgets/kiran-collapse/top-bar-flag-pixmap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6429a2b47269ba0a1c3a0e0ed263dde663c1496 --- /dev/null +++ b/lib/common-widgets/kiran-collapse/top-bar-flag-pixmap.cpp @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#include "top-bar-flag-pixmap.h" + +QPixmap FlagPixmap::expansionFlagPixmap() +{ + QImage image(RIGHT_ARROW); + QImage transformedImage = rotateImage(image, 90.0); + return QPixmap::fromImage(transformedImage); +} + +QPixmap FlagPixmap::collapseFlagPixmap() +{ + QImage image(RIGHT_ARROW); + QImage transformedImage = rotateImage(image, -90.0); + return QPixmap::fromImage(transformedImage); +} + +QPixmap FlagPixmap::expansionFlagPixmapDark() +{ + QImage image(RIGHT_ARROW); + QImage transformedImage = rotateImage(image, 90.0); + invertColors(transformedImage); + return QPixmap::fromImage(transformedImage); +} + +QPixmap FlagPixmap::collapseFlagPixmapDark() +{ + QImage image(RIGHT_ARROW); + QImage transformedImage = rotateImage(image, -90.0); + invertColors(transformedImage); + return QPixmap::fromImage(transformedImage); +} + +QImage FlagPixmap::rotateImage(const QImage& image, qreal angle) +{ + QMatrix matrix; + matrix.rotate(angle); + return image.transformed(matrix, Qt::FastTransformation); +} + +void FlagPixmap::invertColors(QImage& image) +{ + for (int y = 0; y < image.height(); ++y) + { + for (int x = 0; x < image.width(); ++x) + { + QColor color = image.pixelColor(x, y); + QColor invertedColor = QColor(255 - color.red(), 255 - color.green(), 255 - color.blue(), color.alpha()); + image.setPixelColor(x, y, invertedColor); + } + } +} \ No newline at end of file diff --git a/lib/common-widgets/kiran-collapse/top-bar-flag-pixmap.h b/lib/common-widgets/kiran-collapse/top-bar-flag-pixmap.h new file mode 100644 index 0000000000000000000000000000000000000000..034f7465a90685fbe022f88d610136367f6e4d1c --- /dev/null +++ b/lib/common-widgets/kiran-collapse/top-bar-flag-pixmap.h @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#pragma once + +#include + +#define RIGHT_ARROW ":/kiran-control-panel/images/arrow.svg" + +class FlagPixmap +{ +public: + // 默认展开图标 + static QPixmap expansionFlagPixmap(); + static QPixmap expansionFlagPixmapDark(); + // 默认折叠图标 + static QPixmap collapseFlagPixmap(); + static QPixmap collapseFlagPixmapDark(); + +private: + static QImage rotateImage(const QImage& image, qreal angle); + static void invertColors(QImage& image); +}; diff --git a/lib/common-widgets/kiran-collapse/top-bar.cpp b/lib/common-widgets/kiran-collapse/top-bar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e45145007e12eab86bf681fd2341188b7385a57f --- /dev/null +++ b/lib/common-widgets/kiran-collapse/top-bar.cpp @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#include "top-bar.h" +#include +#include "logging-category.h" +#include "ui_top-bar.h" + +#include +#include +#include +#include +#include +#include "QtSvg/QSvgRenderer" +#include "top-bar-flag-pixmap.h" + +TopBar::TopBar(QWidget* parent) : QWidget(parent), + ui(new Ui::TopBar) +{ + ui->setupUi(this); + init(); +} + +TopBar::~TopBar() +{ + delete ui; +} + +void TopBar::setTitle(const QString& title) +{ + m_title = title; + ui->title->setText(m_title); +} + +void TopBar::init() +{ + setContentsMargins(m_topBarMarginLeft, + m_topBarMarginTop, + m_topBarMarginRight, + m_topBarMarginBottom); + ui->horizontalLayout->setSpacing(m_spacing); + this->setFixedHeight(m_height); + this->refreshFlagPixmap(true); + + auto stylePalette = Kiran::StylePalette::instance(); + connect(stylePalette, &Kiran::StylePalette::themeChanged, this, [=](Kiran::PaletteType paletteType) { + // 将 QPixmap 转换为 QImage + QImage image = ui->flag->pixmap()->toImage(); + + // 反转颜色 + for (int y = 0; y < image.height(); ++y) + { + for (int x = 0; x < image.width(); ++x) + { + QColor color = image.pixelColor(x, y); + QColor invertedColor = QColor(255 - color.red(), 255 - color.green(), 255 - color.blue(), color.alpha()); + image.setPixelColor(x, y, invertedColor); + } + } + + // 将反转颜色后的 QImage 设置为标志的 pixmap + ui->flag->setPixmap(QPixmap::fromImage(image)); + }); +} + +void TopBar::setFlagPixmap(const QString& flag_url) +{ + if (flag_url.isEmpty()) + { + KLOG_WARNING(qLcCommonWidget) << "flag_url is empty!"; + return; + } + m_flag = QPixmap(flag_url).scaled(ui->flag->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + ui->flag->setPixmap(m_flag); +} + +void TopBar::setFlagPixmap(const QPixmap& pixmap) +{ + m_flag = pixmap; + ui->flag->setPixmap(m_flag); +} + +void TopBar::refreshFlagPixmap(bool isExpanded) +{ + auto stylePalette = Kiran::StylePalette::instance(); + auto styleType = stylePalette->paletteType(); + // clang-format off + if (isExpanded) + { + ui->flag->setPixmap( + (styleType == Kiran::PALETTE_DARK) ? + FlagPixmap::expansionFlagPixmap().scaled(ui->flag->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation) : + FlagPixmap::expansionFlagPixmapDark().scaled(ui->flag->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) + ); + return; + } + ui->flag->setPixmap( + (styleType == Kiran::PALETTE_DARK) ? + FlagPixmap::collapseFlagPixmap().scaled(ui->flag->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) : + FlagPixmap::collapseFlagPixmapDark().scaled(ui->flag->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) + ); + // clang-format on +} + +void TopBar::addWidget(QWidget* widget) +{ + ui->horizontalLayout->insertWidget(ui->horizontalLayout->count() - 1, widget); +} + +void TopBar::mouseReleaseEvent(QMouseEvent* event) +{ + if (this->geometry().contains(this->mapFromGlobal(event->globalPos()))) + { + emit clickedBar(); + } +} + +void TopBar::setTopBarMargin(int left, int top, int right, int bottom) +{ + m_topBarMarginLeft = left; + m_topBarMarginTop = top; + m_topBarMarginRight = right; + m_topBarMarginBottom = bottom; + setContentsMargins(m_topBarMarginLeft, + m_topBarMarginTop, + m_topBarMarginRight, + m_topBarMarginBottom); +} +void TopBar::setTopBarSpacing(int spacing) +{ + m_spacing = spacing; + ui->horizontalLayout->setSpacing(m_spacing); +} diff --git a/lib/common-widgets/kiran-collapse/top-bar.h b/lib/common-widgets/kiran-collapse/top-bar.h new file mode 100644 index 0000000000000000000000000000000000000000..99d8740bd1556057595c81bc31ad57afa90d4f81 --- /dev/null +++ b/lib/common-widgets/kiran-collapse/top-bar.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2020 ~ 2022 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: youzhengcai + */ + +#pragma once + +#include + +namespace Ui +{ +class TopBar; +} + +class TopBar : public QWidget +{ + Q_OBJECT + +public: + explicit TopBar(QWidget* parent = nullptr); + ~TopBar() override; + // 设置标题 + void setTitle(const QString& title); + // 添加控件 + void addWidget(QWidget* widget); + /** + * @brief 设置扩展区内部间距 + * @param left, top, right, bottom + */ + void setTopBarMargin(int left, int top, int right, int bottom); + // 设置控件间距 + void setTopBarSpacing(int spacing); + // 接收图标 URL + void setFlagPixmap(const QString& flag_url); + // 接收 Pixmap 图标 + void setFlagPixmap(const QPixmap& pixmap); + // 刷新 Pixmap 图标 + void refreshFlagPixmap(bool isExpanded); + +protected: + void mouseReleaseEvent(QMouseEvent* event) override; + +signals: + void clickedBar(); + +private: + void init(); + +private: + Ui::TopBar* ui; + + QString m_title; // 顶栏标题 + int m_height = 45; // 顶栏高度, 默认45 + int m_spacing = 12; // 顶栏内部组件间间隔 + int m_topBarMarginLeft = 12; + int m_topBarMarginTop = 5; + int m_topBarMarginRight = 12; + int m_topBarMarginBottom = 5; + + QPixmap m_flag; // 顶栏折叠展开图标 + + QPoint m_mousePos; // 鼠标位置,用于自定义点击事件 +}; diff --git a/lib/common-widgets/kiran-collapse/top-bar.ui b/lib/common-widgets/kiran-collapse/top-bar.ui new file mode 100644 index 0000000000000000000000000000000000000000..3ae384c96130d7e3418ce908bc15be6dc1adb3dc --- /dev/null +++ b/lib/common-widgets/kiran-collapse/top-bar.ui @@ -0,0 +1,88 @@ + + + TopBar + + + + 0 + 0 + 700 + 40 + + + + + 16777215 + 16777215 + + + + ListExpansionSpace + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + TITLE + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + 10 + 10 + + + + + 10 + 10 + + + + FLAG + + + + + + + + + + diff --git a/lib/common-widgets/kiran-slider/kiran-slider.cpp b/lib/common-widgets/kiran-slider/kiran-slider.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6fb7322605ae49297abb720c98ba79a016cc1c57 --- /dev/null +++ b/lib/common-widgets/kiran-slider/kiran-slider.cpp @@ -0,0 +1,436 @@ +/** + * Copyright (c) 2020 ~ 2023 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: liuxinhao + */ +#include "kiran-slider.h" +#include +#include +#include +#include +#include + +using namespace Kiran; + +static const int sliderMargin = 16; + +static const int sliderGrooveHeight = 4; + +static const int sliderHandleHeight = 16; +static const int sliderHandleWidth = 12; + +static const int tickSpace = 2; + +static const int ticknessHeight = 12; +static const int ticknessWedith = 2; + +KiranSlider::MarkPoint::MarkPoint(int value_, QString desc_) +{ + value = value_; + desc = desc_; +} + +bool KiranSlider::UpdateContext::operator==(const UpdateContext& other) const +{ + if (size != other.size || + max != other.max || + min != other.min || + value != other.value) + { + return false; + } + + return true; +} + +KiranSlider::UpdateContext KiranSlider::getCurrentUpdateContext() +{ + KiranSlider::UpdateContext updateCache; + updateCache.min = minimum(); + updateCache.max = maximum(); + updateCache.size = size(); + updateCache.value = value(); + return updateCache; +} + +KiranSlider::KiranSlider(QWidget* parent) + : QAbstractSlider(parent) +{ + connect(this, &QAbstractSlider::valueChanged, this, &KiranSlider::ensureLayoutUpdated); + connect(this, &QAbstractSlider::rangeChanged, this, &KiranSlider::ensureLayoutUpdated); +} + +KiranSlider::~KiranSlider() +{ +} + +QSize KiranSlider::sizeHint() const +{ + const int sliderLength = 160; + + int w = 2 * sliderMargin, h = 2 * sliderMargin; + w += sliderLength; + + h += qMax(sliderGrooveHeight, sliderHandleHeight); + h += 2 * tickSpace; + h += fontMetrics().height(); + + return QSize(w, h); +} + +QSize KiranSlider::minimumSizeHint() const +{ + const int sliderLength = 160; + + int w = 2 * sliderMargin, h = 2 * sliderMargin; + w += sliderLength; + + h += qMax(sliderGrooveHeight, sliderHandleHeight); + h += 2 * tickSpace; + h += fontMetrics().height(); + + return QSize(w, h); +} + +void KiranSlider::addMarks(QList marks) +{ + for (auto markPoint : marks) + { + addMark(markPoint, false); + } + update(); +} + +void KiranSlider::addMark(MarkPoint mark, bool needUpdateUI) +{ + bool inserted = false; + + for (auto markItem = m_markPoints.begin(); + markItem != m_markPoints.end(); + markItem++) + { + if (mark.value < markItem->value) + { + m_markPoints.insert(markItem, mark); + inserted = true; + break; + } + } + + if (!inserted) + { + m_markPoints.append(mark); + } + + if (needUpdateUI) + { + update(); + } +} + +void KiranSlider::deleteMark(int markValue) +{ + for (auto markItem = m_markPoints.begin(); + markItem != m_markPoints.end();) + { + if (markItem->value == markValue) + { + m_markPoints.erase(markItem); + continue; + } + markItem++; + } + + update(); +} + +void KiranSlider::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing); + + drawBackground(painter); + drawSliderGroove(painter); + drawSliderHandle(painter); + drawTickmarks(painter); +} + +void KiranSlider::resizeEvent(QResizeEvent* event) +{ + ensureLayoutUpdated(); + QAbstractSlider::resizeEvent(event); +} + +void KiranSlider::mousePressEvent(QMouseEvent* ev) +{ + if (maximum() == minimum() || (ev->buttons() ^ ev->button())) + { + ev->ignore(); + return; + } + + ev->accept(); + + // 扩大滑动槽触发区域 + auto grooveTriggerRect = m_grooveRect.adjusted(-1,-1,1,1); + + if (m_handleRect.contains(ev->pos())) + { + // 按压滑块 + m_pressedHandle = true; + setSliderDown(true); + } + else if (grooveTriggerRect.contains(ev->pos())) + { + // 按压滑块槽 + int offset = ev->pos().x() - grooveTriggerRect.left(); + int value = sliderValueFromPosition(minimum(), maximum(), offset, grooveTriggerRect.width(), false); + setSliderPosition(value); + } + + return; +} + +void KiranSlider::mouseReleaseEvent(QMouseEvent* ev) +{ + if (ev->buttons() || !m_pressedHandle) + { + ev->ignore(); + return; + } + + setRepeatAction(SliderNoAction); + setSliderDown(false); +} + +void KiranSlider::mouseMoveEvent(QMouseEvent* ev) +{ + if (!m_pressedHandle) + { + ev->ignore(); + return; + } + + ev->accept(); + + // 扩大滑动槽触发区域 + auto grooveTriggerRect = m_grooveRect.adjusted(-1,-1,1,1); + + int offset = ev->pos().x() - grooveTriggerRect.left(); + int value = sliderValueFromPosition(minimum(), maximum(), offset, grooveTriggerRect.width(), false); + + setSliderPosition(value); +} + +void KiranSlider::ensureLayoutUpdated() +{ + // 计算是否需要更新布局 + auto currentContext = getCurrentUpdateContext(); + if (currentContext == m_updateCache) + { + return; + } + + // 更新布局 + auto groove = QRect(sliderMargin, + sliderMargin + (sliderHandleHeight - sliderGrooveHeight) / 2, + width() - (sliderMargin * 2), + sliderGrooveHeight); + + int offset = sliderPositionFromValue(minimum(), maximum(), value(), groove.width(), false); + auto content = groove; + content.setRight(groove.x() + offset); + + auto handle = QRect(0, 0, sliderHandleWidth, sliderHandleHeight); + handle.moveCenter(QPoint(content.right(), content.center().y())); + + m_grooveRect = groove; + m_contentRect = content; + m_handleRect = handle; + + // 缓存当前上下文,避免频繁更新 + m_updateCache = currentContext; +} + +void KiranSlider::drawBackground(QPainter& painter) +{ + QPainterPath backgroundPath; + backgroundPath.addRoundedRect(rect(), 6, 6); + + painter.save(); + + auto backgroundColor = StylePalette::instance()->color(StylePalette::Normal, + StylePalette::Widget, + StylePalette::Background); + painter.fillPath(backgroundPath, backgroundColor); + + painter.restore(); +} + +void KiranSlider::drawSliderGroove(QPainter& painter) +{ + auto backgroundColor = StylePalette::instance()->color(StylePalette::Normal, + StylePalette::Bare, + StylePalette::Background); + + auto foregroundColor = StylePalette::instance()->color(StylePalette::Checked, + StylePalette::Bare, + StylePalette::Foreground); + + painter.save(); + painter.fillRect(m_grooveRect, backgroundColor); + painter.fillRect(m_contentRect, foregroundColor); + painter.restore(); +} + +void KiranSlider::drawTickmarks(QPainter& painter) +{ + for (auto mark : m_markPoints) + { + if (mark.value < minimum()) + { + continue; + } + + if (mark.value > maximum()) + { + return; + } + + drawTickmark(painter, mark); + } +} + +void KiranSlider::drawSliderHandle(QPainter& painter) +{ + auto foregroundColor = StylePalette::instance()->color(StylePalette::Checked, + StylePalette::Bare, + StylePalette::Foreground); + + QRect cricleRect(0, 0, sliderHandleWidth, sliderHandleWidth); + cricleRect.moveCenter(m_handleRect.center()); + cricleRect.moveTop(m_handleRect.top()); + + QPainterPath criclePath; + criclePath.addEllipse(cricleRect); + + QPainterPath trianglePath; + QPointF point1(cricleRect.left(), cricleRect.bottom() - 3); + QPointF point2(cricleRect.right() + 1, cricleRect.bottom() - 3); + QPointF point3(point1.x() + (point2.x() - point1.x()) / 2, m_handleRect.bottom()); + trianglePath.addPolygon(QPolygonF({point1, point2, point3})); + + painter.save(); + painter.fillPath(criclePath, foregroundColor); + painter.fillPath(trianglePath, foregroundColor); + painter.restore(); +} + +void KiranSlider::drawTickmark(QPainter& painter, + const MarkPoint& point) +{ + QFont font("Noto Sans CJK SC regular", 12); + QFontMetrics metrics(font); + + auto backgroundColor = StylePalette::instance()->color(StylePalette::Normal, + StylePalette::Bare, + StylePalette::Background); + + QPen pen = painter.pen(); + pen.setColor(backgroundColor); + + int offset = sliderPositionFromValue(minimum(), + maximum(), + point.value, + m_grooveRect.width(), + false); + + auto ticknessRect = QRect(0, 0, ticknessWedith, ticknessHeight); + + // 计算tickmark位置 + // 标尺移动滑块下tickSpace的位置 + ticknessRect.moveTop(m_grooveRect.bottom() + (sliderHandleHeight - sliderGrooveHeight) / 2 + tickSpace); + // 标尺移动到指定标记位置下 + ticknessRect.moveLeft(m_grooveRect.left() + offset + ticknessRect.width() / 2); + + // 计算tickmark描述位置 + QRect fontRect(0, 0, metrics.width(point.desc), metrics.height()); + fontRect.moveCenter(ticknessRect.center()); + fontRect.moveTop(ticknessRect.bottom() + tickSpace); + + painter.save(); + painter.setPen(pen); + painter.setFont(font); + painter.fillRect(ticknessRect, backgroundColor); + painter.drawText(fontRect, point.desc); + + painter.restore(); +} + +int KiranSlider::sliderPositionFromValue(int min, int max, + int logicalValue, int span, + bool upsideDown) +{ + if (span <= 0 || logicalValue < min || max <= min) + return 0; + if (logicalValue > max) + return upsideDown ? span : min; + + uint range = max - min; + uint p = upsideDown ? max - logicalValue : logicalValue - min; + + if (range > (uint)INT_MAX / 4096) + { + double dpos = (double(p)) / (double(range) / span); + return int(dpos); + } + else if (range > (uint)span) + { + return (2 * p * span + range) / (2 * range); + } + else + { + uint div = span / range; + uint mod = span % range; + return p * div + (2 * p * mod + range) / (2 * range); + } + // equiv. to (p * span) / range + 0.5 + // no overflow because of this implicit assumption: + // span <= 4096 +} + +int KiranSlider::sliderValueFromPosition(int min, int max, + int pos, int span, + bool upsideDown) +{ + if (span <= 0 || pos <= 0) + return upsideDown ? max : min; + if (pos >= span) + return upsideDown ? min : max; + + uint range = max - min; + + if ((uint)span > range) + { + int tmp = (2 * pos * range + span) / (2 * span); + return upsideDown ? max - tmp : tmp + min; + } + else + { + uint div = range / span; + uint mod = range % span; + int tmp = pos * div + (2 * pos * mod + span) / (2 * span); + return upsideDown ? max - tmp : tmp + min; + } + // equiv. to min + (pos*range)/span + 0.5 + // no overflow because of this implicit assumption: + // pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX) +} \ No newline at end of file diff --git a/lib/common-widgets/kiran-slider/kiran-slider.h b/lib/common-widgets/kiran-slider/kiran-slider.h new file mode 100644 index 0000000000000000000000000000000000000000..045d8d7c58a2e7b74b981057fe072fb6b5c3f226 --- /dev/null +++ b/lib/common-widgets/kiran-slider/kiran-slider.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2020 ~ 2023 KylinSec Co., Ltd. + * kiran-control-panel is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * + * Author: liuxinhao + */ + +#pragma once + +#include + +// TOOD:暂时只考虑水平滑块,并且标尺位于下方 +class KiranSlider : public QAbstractSlider +{ + Q_OBJECT +public: + KiranSlider(QWidget* parent = nullptr); + ~KiranSlider(); + + QSize sizeHint() const override; + QSize minimumSizeHint() const override; + + // 不同于QSlider中的标尺功能 + // 使用者根据使用场景,对指定点标记 + struct MarkPoint + { + MarkPoint(int value_, QString desc_); + int value; + QString desc; + }; + void addMarks(QList marks); + void addMark(MarkPoint mark, bool needUpdateUI = true); + void deleteMark(int markValue); + +protected: + void paintEvent(QPaintEvent* event) override; + void resizeEvent(QResizeEvent* event) override; + void mousePressEvent(QMouseEvent* ev) override; + void mouseReleaseEvent(QMouseEvent* ev) override; + void mouseMoveEvent(QMouseEvent* ev) override; + +private slots: + void ensureLayoutUpdated(); + +private: + struct UpdateContext + { + bool operator==(const UpdateContext& other) const; + UpdateContext& operator=(const UpdateContext& other) = default; + QSize size; + int max; + int min; + int value; + }; + UpdateContext getCurrentUpdateContext(); + // 根据具体值获取在滑动条中具体位置 + int sliderPositionFromValue(int min, int max, + int logicalValue, int span, + bool upsideDown); + // 根据传入滑动条位置获取具体值 + int sliderValueFromPosition(int min, int max, + int pos, int span, + bool upsideDown); + void drawBackground(QPainter& painter); + void drawSliderGroove(QPainter& painter); + void drawTickmarks(QPainter& painter); + void drawSliderHandle(QPainter& painter); + void drawTickmark(QPainter& painter, const MarkPoint& point); + +private: + QList m_markPoints; + UpdateContext m_updateCache; + + QRect m_handleRect; + QRect m_grooveRect; + QRect m_contentRect; + + bool m_pressedHandle = false; +}; \ No newline at end of file diff --git a/plugins/appearance/appearance-global-info.cpp b/plugins/appearance/appearance-global-info.cpp index 66661f8d6153b0a7efbb60544b9214ed8539c298..9d0d12c7524ee5c34bcacd989b2b8fdfcdf3800e 100644 --- a/plugins/appearance/appearance-global-info.cpp +++ b/plugins/appearance/appearance-global-info.cpp @@ -254,7 +254,7 @@ bool AppearanceGlobalInfo::getFont(int type, QString &fontName, int &fontSize) KLOG_DEBUG(qLcAppearance) << "get font,font type:" << type << "font info:" << fontValue; #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) - fontInfoList = fontValue.split(" ", QString::SkipEmptyParts); + auto list = fontValue.split(" ", QString::SkipEmptyParts); #else auto list = fontValue.split(" ", Qt::SkipEmptyParts); #endif @@ -272,7 +272,7 @@ bool AppearanceGlobalInfo::getFont(int type, QString &fontName, int &fontSize) return true; } -bool AppearanceGlobalInfo::setFont(int fontType, QString fontInfo) +bool AppearanceGlobalInfo::setFont(int fontType,const QString& fontInfo) { KLOG_DEBUG(qLcAppearance) << "set font,font type:" << fontType << fontInfo; diff --git a/plugins/appearance/appearance-global-info.h b/plugins/appearance/appearance-global-info.h index 24c1d142791e72682a913ed7f49ddb2e1a992806..ac0deb4c83c4225b1b6434069ea800bcb62f810f 100644 --- a/plugins/appearance/appearance-global-info.h +++ b/plugins/appearance/appearance-global-info.h @@ -45,7 +45,7 @@ public: bool setLockScreenBackground(QString); bool getFont(int type,QString& fontName,int& fontSize); - bool setFont(int fontType, QString fontInfo); + bool setFont(int fontType,const QString& fontInfo); signals: void themeChanged(int type, const QString &theme_name); diff --git a/plugins/appearance/pages/font/fonts.cpp b/plugins/appearance/pages/font/fonts.cpp index d4050a88c5aba60ad33f9827a97f01a7d76e5d0a..e722123bdf39234477cb6067af938da9cc3e5c82 100644 --- a/plugins/appearance/pages/font/fonts.cpp +++ b/plugins/appearance/pages/font/fonts.cpp @@ -19,18 +19,23 @@ #include #include #include -#include +#include #include using namespace std; -QStringList Fonts::fontSizes = {"7", "8", "9", "10", "11", "12", "13", "14"}; +#define MIN_FONT_SIZE 7 +#define MAX_FONT_SIZE 14 Fonts::Fonts(QWidget* parent) : QWidget(parent), ui(new Ui::Fonts) { ui->setupUi(this); + m_comboFontTypesMap = { + {ui->combo_system, {APPEARANCE_FONT_TYPE_APPLICATION, APPEARANCE_FONT_TYPE_WINDOW_TITLE}}, + {ui->combo_monospace, {APPEARANCE_FONT_TYPE_MONOSPACE}}}; + initUI(); } @@ -41,148 +46,171 @@ Fonts::~Fonts() bool Fonts::initUI() { + // 初始化字号选择滑动条 + ui->slider->setRange(MIN_FONT_SIZE, MAX_FONT_SIZE); + + QList markPoints; + for (int i = 0; i <= MAX_FONT_SIZE; i++) + { + KiranSlider::MarkPoint markPoint(i, QString::number(i)); + markPoints << markPoint; + } + + ui->slider->addMarks(markPoints); + // 统一QComboBox样式,并初始化可选值列表 QList comboBoxList = this->findChildren(); foreach (QComboBox* comboBox, comboBoxList) { - comboBox->setStyleSheet("QComboBox {combobox-popup: 0;}"); + // comboBox->setStyleSheet("QComboBox {combobox-popup: 0;}"); + + auto complete = new QCompleter(comboBox->model()); + complete->setFilterMode(Qt::MatchContains); + + comboBox->setCompleter(complete); } - m_fontTypeComboBoxMap = { - {APPEARANCE_FONT_TYPE_APPLICATION, {ui->cbox_application_font_name, ui->cbox_application_font_size}}, - {APPEARANCE_FONT_TYPE_WINDOW_TITLE, {ui->cbox_titlebar_font_name, ui->cbox_titlebar_font_size}}, - {APPEARANCE_FONT_TYPE_MONOSPACE, {ui->cbox_monospace_font_name, ui->cbox_monospace_font_size}}}; + // 初始化下拉框字体族列表 + QFontDatabase fontDatabase; + auto fontFamilies = fontDatabase.families(); - QFontDatabase database; - auto fontFamilys = database.families(); - for (auto fontComboBoxs : m_fontTypeComboBoxMap.values()) + QList fillCombos({ui->combo_system, ui->combo_monospace}); + for (auto combo = fillCombos.begin(); + combo != fillCombos.end(); + combo++) { - fontComboBoxs.first->addItems(fontFamilys); - fontComboBoxs.second->addItems(fontSizes); + (*combo)->addItems(fontFamilies); } - for (auto fontType : m_fontTypeComboBoxMap.keys()) + // 读取一个字体类型的字号作为当前字号滑块值 + auto appearanceInterface = AppearanceGlobalInfo::instance(); + QString fontName; + int wordSize = 9; + if (!appearanceInterface->getFont(APPEARANCE_FONT_TYPE_APPLICATION, fontName, wordSize)) + { + KLOG_ERROR(qLcAppearance) << "load current font word size error!"; + } + else { - updateUIFontInfo(fontType); + ui->slider->setValue(wordSize); } - initConnections(); + // 当前相应的字体类型的字体族作为显示 + updateUiCurrentFontFamily(ui->combo_system); + updateUiCurrentFontFamily(ui->combo_monospace); + + m_updateFontSizeTimer.setInterval(200); + m_updateFontSizeTimer.setSingleShot(true); + connect(&m_updateFontSizeTimer, &QTimer::timeout, this, &Fonts::updateAllFontWordSize); + // 初始化连接 + initConnections(); return true; } -void Fonts::updateUIFontInfo(int fontType) +void Fonts::initConnections() { - QStringList fontInfoList; - auto appearanceInterface = AppearanceGlobalInfo::instance(); + connect(AppearanceGlobalInfo::instance(), &AppearanceGlobalInfo::fontChanged, + this, &Fonts::onBackendFontChanged); - QString fontName; - int fontSize; - if (!appearanceInterface->getFont(fontType, fontName, fontSize)) + for (auto fontTypeCombos : m_fontTypeComboBoxMap.values()) { - KLOG_WARNING(qLcAppearance) << "update ui font info failed, type:" << fontType; - return; - } + auto fontNameComboBox = fontTypeCombos.first; + auto fontSizeComboBox = fontTypeCombos.second; - KLOG_DEBUG(qLcAppearance) << "update ui font info,type:" << fontType - << ",name:" << fontName - << ",size:" << fontSize; + connect(fontNameComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &Fonts::onCurrentFontFamilyChanged); + connect(fontSizeComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &Fonts::onCurrentFontFamilyChanged); + } - setUIFontInfo(fontType, fontName, fontSize); + connect(ui->slider, &QSlider::valueChanged, this, &Fonts::onSliderValueChanged); } -void Fonts::setUIFontInfo(int fontType, const QString& name, const int size) +bool Fonts::updateFontToBackend(int fontType, const QString& fontFamily, int fontSize) { - auto fontComboBoxs = m_fontTypeComboBoxMap.find(fontType); - if (fontComboBoxs == m_fontTypeComboBoxMap.end()) - { - KLOG_ERROR(qLcAppearance) << "set ui font info failed,can't find font type:" << fontType; - return; - } - - auto fontNameComboBox = fontComboBoxs.value().first; - auto fontSizeComboBox = fontComboBoxs.value().second; - - int idx = fontNameComboBox->findText(name); - if (idx == -1) + QString fontInfo = QString("%1 %2").arg(fontFamily).arg(fontSize); + bool res = AppearanceGlobalInfo::instance()->setFont(fontType, fontInfo); + if (!res) { - KLOG_ERROR(qLcAppearance) << "can't find font name action" << name << "int combobox"; + KLOG_ERROR(qLcAppearance) << "set font" << fontType << fontInfo << "failed!"; } else { - fontNameComboBox->setCurrentIndex(idx); + KLOG_INFO(qLcAppearance) << "set font" << fontType << fontInfo; } - idx = fontSizeComboBox->findText(QString::number(size)); - if (idx == -1) + return res; +} + +void Fonts::onCurrentFontFamilyChanged() +{ + auto senderComboBox = qobject_cast(sender()); + int currentFontSize = ui->slider->value(); + + if (m_comboFontTypesMap.find(senderComboBox) == m_comboFontTypesMap.end()) { - KLOG_ERROR(qLcAppearance) << "can't find font size action:" << idx << "in combobox"; + return; } - else + + auto fontTypes = m_comboFontTypesMap[senderComboBox]; + for (auto fontType : fontTypes) { - fontSizeComboBox->setCurrentIndex(idx); + updateFontToBackend(fontType, senderComboBox->currentText(), currentFontSize); } } -void Fonts::initConnections() +void Fonts::onSliderValueChanged(int value) { - connect(AppearanceGlobalInfo::instance(), &AppearanceGlobalInfo::fontChanged, this, &Fonts::handleFontChanged); + m_updateFontSizeTimer.start(); +} - for (auto fontTypeCombos : m_fontTypeComboBoxMap.values()) +void Fonts::updateUiCurrentFontFamily(QComboBox* combo) +{ + if (m_comboFontTypesMap.find(combo) == m_comboFontTypesMap.end()) { - auto fontNameComboBox = fontTypeCombos.first; - auto fontSizeComboBox = fontTypeCombos.second; - - connect(fontNameComboBox, QOverload::of(&QComboBox::currentIndexChanged), - this, &Fonts::onComboBoxIdxChanged); - connect(fontSizeComboBox, QOverload::of(&QComboBox::currentIndexChanged), - this, &Fonts::onComboBoxIdxChanged); + KLOG_WARNING(qLcAppearance) << "can not find ComboBox in ComboFontTypesMap"; + ; + return; } -} -void Fonts::onComboBoxIdxChanged(int idx) -{ - auto senderComboBox = qobject_cast(sender()); + QList fontTypes = m_comboFontTypesMap.find(combo).value(); + int fontType = fontTypes.at(0); - int fontType = -1; QString fontName; - int fontSize = 0; - for (auto iter = m_fontTypeComboBoxMap.begin(); - iter != m_fontTypeComboBoxMap.end(); - iter++) + int fontSize; + if (!AppearanceGlobalInfo::instance()->getFont(fontType, fontName, fontSize)) { - auto pair = iter.value(); - if (senderComboBox != pair.first && senderComboBox != pair.second) - { - continue; - } - - fontType = iter.key(); - fontName = pair.first->currentText(); - fontSize = pair.second->currentText().toInt(); + KLOG_ERROR(qLcAppearance, "get font failed,font type:%d", fontType); + return; } - if (fontType == -1) + auto idx = combo->findText(fontName); + if (idx == -1) { - KLOG_ERROR(qLcAppearance) << "current font combobox idx changed,can't find font type!"; + KLOG_ERROR(qLcAppearance) << "can not find" << fontName << "in" << combo->objectName(); return; } - QString fontInfo = QString("%1 %2").arg(fontName).arg(fontSize); - if (!AppearanceGlobalInfo::instance()->setFont(fontType, fontInfo)) + combo->setCurrentText(fontName); +} + +void Fonts::updateAllFontWordSize() +{ + int value = ui->slider->value(); + for (auto combo : m_comboFontTypesMap.keys()) { - KLOG_ERROR(qLcAppearance) << "combobox idx changed,set font" << fontType << fontInfo << "failed!"; - KiranMessageBox::message(nullptr, QObject::tr("Failed"), - QObject::tr("Set font failed!"), - KiranMessageBox::Ok); + auto family = combo->currentText(); + auto wordSize = value; + for (auto fontTypeEnum : m_comboFontTypesMap[combo]) + { + updateFontToBackend(fontTypeEnum, family, wordSize); + } } - - KLOG_INFO(qLcAppearance) << "ui font settings changed,set font" << fontType << fontInfo; } -void Fonts::handleFontChanged(int type, QString fontInfo) +void Fonts::onBackendFontChanged(int type, QString fontInfo) { - updateUIFontInfo(type); } QSize Fonts::sizeHint() const diff --git a/plugins/appearance/pages/font/fonts.h b/plugins/appearance/pages/font/fonts.h index f928134ffb705bc06eebd3fe1a433a622c2fe5cd..b248498bed772e815bb419e93c07f1f9a8fd6f3a 100644 --- a/plugins/appearance/pages/font/fonts.h +++ b/plugins/appearance/pages/font/fonts.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace Ui { @@ -36,17 +37,20 @@ public: private: bool initUI(); - void updateUIFontInfo(int fontType); - void setUIFontInfo(int fontType,const QString& name,const int size); void initConnections(); - bool setFont(int fontType, QString fontInfo); + bool updateFontToBackend(int fontType, const QString& fontFamily,int fontSize); public slots: - void onComboBoxIdxChanged(int idx); - void handleFontChanged(int type, QString fontInfo); + void onCurrentFontFamilyChanged(); + void onSliderValueChanged(int value); + void updateUiCurrentFontFamily(QComboBox* combo); + void updateAllFontWordSize(); + void onBackendFontChanged(int type, QString fontInfo); private: Ui::Fonts *ui; + QMap> m_comboFontTypesMap; + QTimer m_updateFontSizeTimer; // QMap<字体类型, <字体类型名称ComboBox,字体类型字号ComboBox>> QMap> m_fontTypeComboBoxMap; static QStringList fontSizes; diff --git a/plugins/appearance/pages/font/fonts.ui b/plugins/appearance/pages/font/fonts.ui index 58710484c96d78c8272a027b064b528e7ae3e64f..70ecb4d4ad5075d69e1c24720bd2f4dfb18c9668 100644 --- a/plugins/appearance/pages/font/fonts.ui +++ b/plugins/appearance/pages/font/fonts.ui @@ -6,8 +6,8 @@ 0 0 - 683 - 517 + 875 + 713 @@ -15,7 +15,7 @@ - 16 + 0 16 @@ -27,285 +27,168 @@ 16 - 16 + 160 - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 16 - - - - - - 10 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Application Font Settings - - - - - - - 10 - - - - - - 0 - 40 - - - - - 16777215 - 40 - - - - ComboAppFontName - - - 10 - - - QComboBox::AdjustToContents - - - - - - - - 0 - 40 - - - - - 16777215 - 40 - - - - ComboAppFontSize - - - 5 - - - - - - - - - - - - - 10 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Titlebar Font Settings - - - - - - - 10 - - - - - - 0 - 40 - - - - - 16777215 - 40 - - - - ComboTitleFontName - - - - - - - - 0 - 40 - - - - - 16777215 - 40 - - - - ComboTitleFontSize - - - 5 - - - - - - - - - - - - - 10 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Monospace Font Settings - - - - - - - 10 - - - - - - 0 - 40 - - - - - 16777215 - 40 - - - - ComboMonospaceFontName - - - - - - - - 0 - 40 - - - - - 16777215 - 40 - - - - ComboMonospaceFontSize - - - 5 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 212 - - - - - - - + + + Word size + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + + 0 + 0 + + + + + 0 + 80 + + + + + 16777215 + 80 + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 16 + + + + + + + + System font + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 16 + + + + + + + + Monospaced font + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 10 + + + + + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + KiranSlider + QWidget +
kiran-slider/kiran-slider.h
+ 1 +
+
diff --git a/plugins/appearance/pages/theme/icon/icon-theme-page.cpp b/plugins/appearance/pages/theme/icon/icon-theme-page.cpp index a2a87dba166b6f801b5c5a4c0df5a9ff072f96e9..7aaa1429975efc01fd10ad786e173c599bfa0af0 100644 --- a/plugins/appearance/pages/theme/icon/icon-theme-page.cpp +++ b/plugins/appearance/pages/theme/icon/icon-theme-page.cpp @@ -38,14 +38,24 @@ const QStringList IconThemePage::m_fallbackIcons = {"accessories-calculator", "preferences-desktop-wallpaper"}; // 特殊主题展示图标 const QMap IconThemePage::m_specifyIcons = { - {"KiranNew", + {"Spring", {"kc-calculator", "smplayer", - "firefox", - "thunderbird", + "fcitx", + "engrampa", "utilities-terminal", "brasero", - "accessories-text-editor" + "org.gnome.Software" + } + }, + {"Summer", + {"kc-calculator", + "smplayer", + "fcitx", + "engrampa", + "utilities-terminal", + "brasero", + "org.gnome.Software" } }}; // clang-format on @@ -86,7 +96,7 @@ void IconThemePage::loadIconThemes() for (auto theme : themeInfos) { // 过滤非白名单主题 - static const QStringList iconThemeWhiteList = {"Kiran", "Adwaita", "KiranNew"}; + static const QStringList iconThemeWhiteList = {"Kiran", "Adwaita", "Spring","Summer"}; if (!iconThemeWhiteList.contains(theme.name)) { continue; @@ -193,4 +203,4 @@ void IconThemePage::onCurrentItemChanged() { KLOG_INFO(qLcAppearance) << "icon theme updated:" << id; } -} \ No newline at end of file +} diff --git a/plugins/system/pages/system-information/license-agreement.cpp b/plugins/system/pages/system-information/license-agreement.cpp index a8f1542e6826354177adb346edc53b4a58e6562a..66be978bb94dd4b17458a8dbc790dae59a889156 100644 --- a/plugins/system/pages/system-information/license-agreement.cpp +++ b/plugins/system/pages/system-information/license-agreement.cpp @@ -30,11 +30,13 @@ #define EULAFILE "/usr/share/kylin-release" #define LICENSEFILE "/usr/share/doc/kylin-release/LICENSE" +#define PRIVACYFILE "/usr/share/kylin-release/privacy_policy" enum LicenseType { EULA_LICENSE = 0, - VERSION_LICENSE + VERSION_LICENSE, + PRIVACY_POLICY }; using namespace Kiran; @@ -77,8 +79,10 @@ void LicenseAgreement::exportLicense() QString currentHomePath; if (m_licenseType == EULA_LICENSE) currentHomePath = "/" + QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/EULA.pdf"; - else + else if (m_licenseType == VERSION_LICENSE) currentHomePath = "/" + QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/Version-License.pdf"; + else + currentHomePath = "/" + QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/Privacy-Policy.pdf"; QString fileName = QFileDialog::getSaveFileName(this, tr("Save"), @@ -173,6 +177,7 @@ void LicenseAgreement::setEULA() } textStream.setDevice(&file); } + textStream.setCodec("UTF-8"); ui->text_license->setText(textStream.readAll()); file.close(); } @@ -195,6 +200,7 @@ void LicenseAgreement::setVersionLicnese() goto LOAD_VERSION_LICENSE_FROM_RES; } textStream.setDevice(&file); + textStream.setCodec("UTF-8"); ui->text_license->setText(textStream.readAll()); file.close(); return; @@ -239,6 +245,8 @@ LOAD_VERSION_LICENSE_FROM_RES: } QTextStream textStreamTitle(&fileTitle); QTextStream textStreamBody(&fileBody); + textStreamTitle.setCodec("UTF-8"); + textStreamBody.setCodec("UTF-8"); ui->text_license->setAlignment(Qt::AlignHCenter); while (!textStreamTitle.atEnd()) @@ -252,3 +260,34 @@ LOAD_VERSION_LICENSE_FROM_RES: fileBody.close(); fileTitle.close(); } + +void LicenseAgreement::setPrivacyPolicy() +{ + m_licenseType = PRIVACY_POLICY; + ui->text_license->clear(); +#ifdef DISABLE_KIRANWIDGETS + setWindowTitle(LicenseAgreement::tr("Privacy Policy")); +#else + setTitle(LicenseAgreement::tr("Privacy Policy")); +#endif + QFile file(PRIVACYFILE); + QTextStream textStream; + + if (!file.exists()) + { + KLOG_INFO() << PRIVACYFILE << " is not exists "; + ui->text_license->setText(tr("None")); + return; + } + + if (!file.open(QFile::ReadOnly | QFile::Text)) + { + KLOG_INFO() << "Can't open " << PRIVACYFILE; + ui->text_license->setText(tr("None")); + return; + } + textStream.setDevice(&file); + textStream.setCodec("UTF-8"); + ui->text_license->setText(textStream.readAll()); + file.close(); +} diff --git a/plugins/system/pages/system-information/license-agreement.h b/plugins/system/pages/system-information/license-agreement.h index 7a910e7d91bc79c03add4990b789af48f4203a84..100122034e654d9801191b599f0ce05ff4db23c0 100644 --- a/plugins/system/pages/system-information/license-agreement.h +++ b/plugins/system/pages/system-information/license-agreement.h @@ -14,25 +14,25 @@ #ifndef LICENSEAGREEMENT_H #define LICENSEAGREEMENT_H -#include #include +#include namespace Ui { class LicenseAgreement; } - class LicenseAgreement : public KiranTitlebarWindow { Q_OBJECT public: - explicit LicenseAgreement(QWidget *parent, Qt::WindowFlags windowFlags=Qt::Window); + explicit LicenseAgreement(QWidget *parent, Qt::WindowFlags windowFlags = Qt::Window); ~LicenseAgreement(); QString getEulaText(); void setEULA(); void setVersionLicnese(); + void setPrivacyPolicy(); //void setLicenseType(int type); public slots: diff --git a/plugins/system/pages/system-information/system-information.cpp b/plugins/system/pages/system-information/system-information.cpp index 8e85743873c6b77b2f9111e0a1849a8be0d81457..b12cad8d9207799663c79c7dd0eb616046823f2b 100644 --- a/plugins/system/pages/system-information/system-information.cpp +++ b/plugins/system/pages/system-information/system-information.cpp @@ -81,12 +81,22 @@ void SystemInformation::init() licenseAgreement->setVersionLicnese(); licenseAgreement->show(); }); + connect(ui->btn_privacy_policy, &QPushButton::clicked, [this] + { + if (licenseAgreement == nullptr) { + licenseAgreement = new LicenseAgreement(this); + } + licenseAgreement->setPrivacyPolicy(); + licenseAgreement->show(); + }); + // clang-format on connect(ui->btn_change_name, &QPushButton::clicked, this, &SystemInformation::handleChangeHostName); Kiran::StylePropertyHelper::setButtonType(ui->btn_change_name, Kiran::BUTTON_Default); Kiran::StylePropertyHelper::setButtonType(ui->btn_EULA, Kiran::BUTTON_Default); Kiran::StylePropertyHelper::setButtonType(ui->btn_version_license, Kiran::BUTTON_Default); Kiran::StylePropertyHelper::setButtonType(ui->btn_license_show, Kiran::BUTTON_Default); + Kiran::StylePropertyHelper::setButtonType(ui->btn_privacy_policy, Kiran::BUTTON_Default); } bool SystemInformation::initUI() @@ -257,7 +267,7 @@ bool SystemInformation::getLicenseDesc(QString& licenseStatus) } } - licenseStatus = QString("%2").arg(expired?"#ff3838":"#5ab940").arg(statusDesc); + licenseStatus = QString("%2").arg(expired ? "#ff3838" : "#5ab940").arg(statusDesc); return true; } @@ -293,7 +303,7 @@ void SystemInformation::updateHostName(bool isChanged, QString name) void SystemInformation::handleShowLicenseDialog() { - if (!QProcess::startDetached("/usr/bin/ksl-os-gui",QStringList())) + if (!QProcess::startDetached("/usr/bin/ksl-os-gui", QStringList())) { KiranMessageBox::message(this, tr("Error"), tr("Failed to open the license activator"), KiranMessageBox::Ok); } diff --git a/plugins/system/pages/system-information/system-information.ui b/plugins/system/pages/system-information/system-information.ui index 7dd5cddd359cb675b3889b140906a7dd6995f982..d8ee6c4871698fbd620956349fbbb8378c3421a3 100644 --- a/plugins/system/pages/system-information/system-information.ui +++ b/plugins/system/pages/system-information/system-information.ui @@ -129,7 +129,7 @@ - 0 + 6 10 @@ -168,6 +168,12 @@ + + + 0 + 0 + + LabelHostName @@ -178,7 +184,7 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - true + false @@ -229,7 +235,7 @@ - 0 + 6 10 @@ -295,7 +301,7 @@ - 0 + 6 10 @@ -373,7 +379,7 @@ - 0 + 6 10 @@ -439,7 +445,7 @@ - 0 + 6 10 @@ -524,7 +530,7 @@ - 0 + 6 10 @@ -599,7 +605,7 @@ - 0 + 6 10 @@ -658,6 +664,78 @@ + + + + + 0 + 40 + + + + + 16777215 + 40 + + + + + 0 + + + 10 + + + 0 + + + 10 + + + 0 + + + + + Privacy policy: + + + + + + + Qt::Horizontal + + + + 530 + 20 + + + + + + + + + 56 + 28 + + + + + 56 + 28 + + + + Show + + + + + + @@ -682,15 +760,15 @@ - KylinsecLogo + KiranFrame QWidget -
kylinsec-logo.h
+
kiran-frame/kiran-frame.h
1
- KiranFrame + KylinsecLogo QWidget -
kiran-frame/kiran-frame.h
+
kylinsec-logo.h
1
diff --git a/translations/kiran-control-panel.zh_CN.ts b/translations/kiran-control-panel.zh_CN.ts index 846e655310a2b80d97346e6c55b192a8a4101c75..913c84f16453cb8cb0bb7fdd146111d2868cd12c 100644 --- a/translations/kiran-control-panel.zh_CN.ts +++ b/translations/kiran-control-panel.zh_CN.ts @@ -382,6 +382,45 @@ 不支持该程序 + + AutostartPage + + Boot Setup + 开机启动设置 + + + Desktop files(*.desktop) + 桌面类型(*.desktop) + + + select autostart desktop + 选择自启动应用 + + + Select + 选择 + + + Cancel + 取消 + + + Error + 错误 + + + Desktop has existed + 该程序已存在 + + + Desktop cant permit to join + 该程序不允许添加 + + + Desktop dont support + 不支持该程序 + + BatterySettingsPage @@ -980,7 +1019,7 @@ DefaultApp - 默认程序 + 默认程序 @@ -1573,11 +1612,11 @@ ComboAppFontName - + ComboAppFontSize - + Titlebar Font Settings @@ -1585,11 +1624,11 @@ ComboTitleFontName - + ComboTitleFontSize - + Monospace Font Settings @@ -1597,11 +1636,23 @@ ComboMonospaceFontName - + ComboMonospaceFontSize - + + + + Word size + 字号 + + + System font + 系统字体 + + + Monospaced font + 等宽字体 @@ -2605,6 +2656,13 @@ 快速 + + KiranCollapse + + ListExpansionSpace + + + KiranCpanelAppearance @@ -2895,6 +2953,10 @@ p, li { white-space: pre-wrap; } Export EULA failed! 导出最终用户许可协议失败! + + Privacy Policy + 隐私协议 + LicenseInfoWidget @@ -2986,6 +3048,13 @@ p, li { white-space: pre-wrap; } KylinSec.保留所有权利. + + ListExpansionSpace + + ListExpansionSpace + + + Media Key @@ -4132,6 +4201,10 @@ This is line 50 of the test text KylinSec. All rights reserved. KylinSec.保留所有权利. + + Privacy policy: + 隐私协议: + SystemInformationWidget @@ -4389,6 +4462,21 @@ This is line 50 of the test text 重置 + + TopBar + + ListExpansionSpace + + + + TITLE + + + + FLAG + + + TouchPadPage @@ -5515,43 +5603,4 @@ This is line 50 of the test text 系统信息 - - AutostartPage - - Boot Setup - 开机启动设置 - - - Desktop files(*.desktop) - 桌面类型(*.desktop) - - - select autostart desktop - 选择自启动应用 - - - Select - 选择 - - - Cancel - 取消 - - - Error - 错误 - - - Desktop has existed - 该程序已存在 - - - Desktop cant permit to join - 该程序不允许添加 - - - Desktop dont support - 不支持该程序 - -