ukui-control-center/shell/homepagewidget.cpp

426 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

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

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "homepagewidget.h"
#include "ui_homepagewidget.h"
#include <QLabel>
#include <QSignalMapper>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QListWidget>
#include <QDBusInterface>
#include <QDebug>
#include <QScrollBar>
#include <QStringList>
#include <QSvgRenderer>
#include "mainwindow.h"
#include "utils/functionselect.h"
#include "interface/ukcccommon.h"
using namespace ukcc;
#include "flowlayout.h"
#include "utils/modulefactory.h"
#define STYLE_FONT_SCHEMA "org.ukui.style"
const QStringList KexcludeModule{"update","security","application","search_f"};
HomePageWidget::HomePageWidget(QWidget *parent, QMap<QString, QGSettings *> map) :
QWidget(parent),
vecGsettins(map),
ui(new Ui::HomePageWidget)
{
qApp->installEventFilter(this);
ui->setupUi(this);
// 获取主窗口
this->setParent(parent);
pmainWindow = (MainWindow *)parentWidget();
// 初始化首页
initUI();
ui->scrollArea->viewport()->setAttribute(Qt::WA_TranslucentBackground);
ui->scrollArea->setStyleSheet("QScrollArea{background-color: transparent;}");
ui->scrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
ui->scrollArea->verticalScrollBar()->setVisible(false);
}
HomePageWidget::~HomePageWidget()
{
delete ui;
ui = nullptr;
}
void HomePageWidget::initUI() {
FlowLayout * flowLayout = new FlowLayout(ui->widget_2, true, 0);
flowLayout->setContentsMargins(70, 0, 70, 0);
mModuleMap = UkccCommon::getModuleHideStatus();
QSignalMapper * moduleSignalMapper = new QSignalMapper(this);
int totalModule = ModulesFactory::size();
for(int index = 0; index < totalModule; index++) {
ModuleInfo *curModuleInfo = ModulesFactory::getModuleInfoByIndex(index);
if (curModuleInfo == nullptr) {
continue;
}
//获取当前模块名
const QString locale = QLocale::system().name();
QString modulenamei18nString = curModuleInfo->getModuleNameLocale(locale);
QString modulenameString = curModuleInfo->moduleName;
if ((mModuleMap.keys().contains(modulenameString) && !mModuleMap[modulenameString].toBool())
|| (UkccCommon::isTablet() && KexcludeModule.contains(modulenameString))) {
continue;
}
// pangw无安全模块-不显示 社区无更新和安全-不显示
if ((modulenameString == "security" || modulenameString == "update") && UkccCommon::isCommunity()) {
continue;
}
//三权分立下非root用户不可设置网络、时间语言、更新
#ifdef WITHKYSEC
if (!kysec_is_disabled() && kysec_get_3adm_status() && (getuid() || geteuid())){
if (modulenameString == "network" || modulenameString == "datetime" || modulenameString == "update") {
continue;
}
}
#endif
//构建首页10个模块
//基础Widget
QWidget * baseWidget = new QWidget();
baseWidget->setAttribute(Qt::WA_DeleteOnClose);
baseWidget->setObjectName("itemBaseWidget");
//baseWidget 的顶级布局
QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget);
baseVerLayout->setMargin(0);
baseVerLayout->setSpacing(0);
//包含显示内容的布局
QBoxLayout * majorHorLayout = new QHBoxLayout();
majorHorLayout->setMargin(0);
majorHorLayout->setSpacing(0);
//内容Widget的构建
QPushButton * widget = new QPushButton();
QString picModuleName = modulenameString;
widget->setMinimumWidth(300);
widget->setMinimumHeight(97);
widget->setAttribute(Qt::WA_DeleteOnClose);
widget->setProperty("useButtonPalette", true);
if (picModuleName == "search_f") {
picModuleName = "search";
}
widget->setObjectName("itemWidget");
widget->setFlat(true);
QHBoxLayout * mainHorLayout = new QHBoxLayout(widget);
mainHorLayout->setMargin(16);
mainHorLayout->setSpacing(16);
QLabel * logoLabel = new QLabel(widget);
logoLabel->setFixedSize(48, 48);
logoLabel->setObjectName("logoLabel");
logoLabel->setScaledContents(true);
QString themeIconName = curModuleInfo->themeIconName;
QString localIconName = curModuleInfo->localIconName;
logoLabel->setPixmap(QIcon::fromTheme(themeIconName,QIcon(localIconName))
.pixmap(logoLabel->size()));
const QByteArray settingId(STYLE_FONT_SCHEMA);
if (QGSettings::isSchemaInstalled(settingId)) {
QGSettings *mQtSettings = new QGSettings(settingId, QByteArray(), this);
connect(mQtSettings, &QGSettings::changed, this, [=](QString key) {
if (key == "iconThemeName") {
logoLabel->setPixmap(QIcon::fromTheme(themeIconName,QIcon(localIconName))
.pixmap(logoLabel->size()));
}
});
}
QVBoxLayout * rightVerLayout = new QVBoxLayout();
rightVerLayout->setContentsMargins(0, 2, 0, 0);
rightVerLayout->setSpacing(8);
QLabel * titleLabel = new QLabel(widget);
titleLabel->setObjectName("mptitleLabel");
titleLabel->setText(modulenamei18nString);
QHBoxLayout * funcHorLayout = new QHBoxLayout();
funcHorLayout->setSpacing(8);
uint AllWidth = 0;
QList<TristateLabel *> Labels;
QList<PluginInfo> tmpList = curModuleInfo->pluginInfoList;
int showModuleCount = 0;
for (int funcIndex = 0; funcIndex < tmpList.size(); funcIndex++){
PluginInfo single = tmpList.at(funcIndex);
//跳过不在首页显示的功能
if (!single.mainShow)
continue;
if (mModuleMap.keys().contains(single.nameString.toLower())) {
if (!mModuleMap[single.nameString.toLower()].toBool()) {
continue;
}
}
QObject* pluginObj = ModulesFactory::getPluginObjectByName(single.namei18nString);
if (pluginObj == nullptr) {
continue;
}
QString textName = single.namei18nString;
TristateLabel *label = new TristateLabel(textName, widget);
if (single.isEnable) {
Labels.append(label);
AllWidth += label->width() + funcHorLayout->spacing();
}
// 显示后总label宽度大导致显示不全隐藏后加载显示的label
if (!single.isEnable || AllWidth > 198) {
label->setVisible(false);
}
// 监听该插件是否启用
if (vecGsettins.contains(single.oriNameString)) {
// 插件未启用直接隐藏该label
if (!vecGsettins[single.oriNameString]->get(SHOW_KEY).toBool())
label->setVisible(false);
connect(vecGsettins[single.oriNameString], &QGSettings::changed,[=](QString key){
if (key == SHOW_KEY) {
CommonInterface* pluginInstance = qobject_cast<CommonInterface*>(pluginObj);
bool isShow = pluginInstance->isEnable() && vecGsettins[single.oriNameString]->get(SHOW_KEY).toBool();
// 动态调整在首页显示的插件池
if (isShow) {
if (!mLabels[index].contains(label)) {
mLabels[index].insert(funcIndex, label);
}
int MWidth = 0;
for (TristateLabel * label : mLabels[index]) {
if ((MWidth += label->width() + funcHorLayout->spacing()) < 198) {
label->setVisible(true);
} else {
label->setVisible(false);
}
}
} else {
if (mLabels[index].contains(label)) {
mLabels[index].removeOne(label);
}
label->setVisible(false);
}
}
});
}
connect(label, SIGNAL(clicked()), moduleSignalMapper, SLOT(map()));
moduleSignalMapper->setMapping(label, pluginObj);
funcHorLayout->addWidget(label);
++showModuleCount;
}
mLabels.append(Labels);
funcHorLayout->addStretch();
// 下属无插件,不显示
if (curModuleInfo->pluginInfoList.size() == 0 || showModuleCount == 0) {
widget->setVisible(false);
continue;
}
const QByteArray styleID(STYLE_FONT_SCHEMA);
QGSettings *stylesettings = new QGSettings(styleID, QByteArray(), this);
connect(stylesettings,&QGSettings::changed, [=](QString key) {
if ("systemFont" == key || "systemFontSize" == key) {
int MWidth = 0;
for (TristateLabel * label : Labels) {
QFontMetrics fontMetrics(this->font());
int fontSize = fontMetrics.width(label->text());
label->setFixedWidth(fontSize);
if ((MWidth += label->width() + funcHorLayout->spacing()) < 198) {
label->setVisible(true);
} else {
label->setVisible(false);
}
}
}
});
connect(widget, &QPushButton::clicked, [=]() {
//获取模块的第一项跳转
QString firstFunc;
QList<PluginInfo> tmpList = curModuleInfo->pluginInfoList;
for (PluginInfo tmpStruct : tmpList) {
bool isIntel = UkccCommon::isTablet();
if ((isIntel && tmpStruct.namei18nString == "User Info")
|| (!isIntel && tmpStruct.namei18nString == "User Info Intel")) {
continue;
}
if (!tmpStruct.isEnable) {
continue;
}
QObject* pluginObj = ModulesFactory::getPluginObjectByName(tmpStruct.namei18nString);
if (pluginObj == nullptr) {
continue;
}
// 若该插件不启用,跳转为下一项
if (vecGsettins.contains(tmpStruct.nameString)) {
QGSettings *msettings = vecGsettins[tmpStruct.nameString];
if (msettings) {
if (!msettings->get(SHOW_KEY).toBool()) {
continue;
}
}
}
if (mModuleMap.isEmpty() || !mModuleMap.contains(tmpStruct.nameString.toLower()) || mModuleMap[tmpStruct.nameString.toLower()].toBool()) {
firstFunc = tmpStruct.namei18nString;
UkccCommon::buriedSettings(tmpStruct.nameString, nullptr, "home clicked");
//跳转
pmainWindow->functionBtnClicked(pluginObj);
break;
}
}
});
rightVerLayout->addStretch();
rightVerLayout->addWidget(titleLabel);
rightVerLayout->addLayout(funcHorLayout);
rightVerLayout->addStretch();
mainHorLayout->addWidget(logoLabel);
mainHorLayout->addLayout(rightVerLayout);
mainHorLayout->addStretch();
widget->setLayout(mainHorLayout);
majorHorLayout->addWidget(widget);
majorHorLayout->addStretch();
baseVerLayout->addLayout(majorHorLayout);
baseVerLayout->addStretch();
baseWidget->setLayout(baseVerLayout);
flowLayout->addWidget(baseWidget);
}
connect(moduleSignalMapper, SIGNAL(mapped(QObject*)), pmainWindow, SLOT(pluginBtnClicked(QObject*)));
}
QGSettings *HomePageWidget::setGsettingsPath(QList<char *> list , QString name)
{
// 为每个插件创建动态QGSettings对象用于监听插件是否隐藏
QByteArray ba;
char *path;
ba = (QString("%1%2").arg(name).arg("/")).toUtf8();
path = ba.data();
const QByteArray id(PLUGINS_SCHEMA);
if (!QGSettings::isSchemaInstalled(id)) {
return nullptr;
}
QGSettings *settings = nullptr;
QString plugin = QString("%1%2%3").arg(PLUGINS_PATH).arg(name).arg("/");
settings = new QGSettings(id, plugin.toUtf8().data(), this);
//判断是否已存在该路径,不存在则赋初值
for (int j = 0; j < list.count(); j++) {
if (!qstrcmp(path, list.at(j))){
return settings;
}
}
settings->set(PLUGIN_NAME , name);
settings->set(SHOW_KEY , true);
return settings;
}
const QPixmap HomePageWidget::loadSvg(const QString &fileName, COLOR color)
{
int size = 48;
const auto ratio = qApp->devicePixelRatio();
if ( 2 == ratio) {
size = 96;
} else if (3 == ratio) {
size = 144;
}
QPixmap pixmap(size, size);
QSvgRenderer renderer(fileName);
pixmap.fill(Qt::transparent);
QPainter painter;
painter.begin(&pixmap);
renderer.render(&painter);
painter.end();
pixmap.setDevicePixelRatio(ratio);
return drawSymbolicColoredPixmap(pixmap, color);
}
QPixmap HomePageWidget::drawSymbolicColoredPixmap(const QPixmap &source, COLOR cgColor)
{
QImage img = source.toImage();
for (int x = 0; x < img.width(); x++) {
for (int y = 0; y < img.height(); y++) {
auto color = img.pixelColor(x, y);
if (color.alpha() > 0) {
if ( WHITE == cgColor) {
color.setRed(255);
color.setGreen(255);
color.setBlue(255);
img.setPixelColor(x, y, color);
} else if( BLACK == cgColor) {
color.setRed(0);
color.setGreen(0);
color.setBlue(0);
img.setPixelColor(x, y, color);
} else if (GRAY == cgColor) {
color.setRed(152);
color.setGreen(163);
color.setBlue(164);
img.setPixelColor(x, y, color);
} else if(HIGHLIGHT == cgColor){
QColor highLightColor = palette().color(QPalette::Highlight);
color.setRed(highLightColor.red());
color.setGreen(highLightColor.green());
color.setBlue(highLightColor.blue());
img.setPixelColor(x, y, color);
}
else {
return source;
}
}
}
}
return QPixmap::fromImage(img);
}
bool HomePageWidget::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::MouseMove) {
if (ui->scrollArea->geometry().contains(this->mapFromGlobal(QCursor::pos()))) {
ui->scrollArea->verticalScrollBar()->setVisible(true);
} else {
ui->scrollArea->verticalScrollBar()->setVisible(false);
}
}
return QObject::eventFilter(watched, event);
}