dde-dock/frame/window/systempluginwindow.cpp
donghualin a9987a6c2a fix: 修复时尚模式下无法移除电源插件的问题
原因:在判断该插件是否可移除之前已经将内存中该插件的数据清除,找不到该插件的信息导致无法移除
修改方案:在判断该插件是否可移除之前不清空该插件的内存,等确定该插件可移除后再清空内存,保证插件获取到的数据始终正确

Log: 修复时尚模式下无法移除电源插件的问题
Influence: 任务栏时尚模式下,打开控制中心-个性化-任务栏-插件区域,去掉电源勾选,查看电源按钮是否消失
Task: https://pms.uniontech.com/task-view-121387.html
Change-Id: I0a9f214dab64e6b81b71d8cf50a969979c69c1ac
2022-06-20 15:03:47 +08:00

312 lines
9.2 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.

/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* 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 3 of the License, or
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "systempluginwindow.h"
#include "systemplugincontroller.h"
#include "systempluginitem.h"
#include "dockpluginscontroller.h"
#include "fixedplugincontroller.h"
#include <DListView>
#include <QBoxLayout>
#include <QDir>
#include <QMetaObject>
#include <QGuiApplication>
#define MAXICONSIZE 48
#define MINICONSIZE 24
#define ICONMARGIN 8
SystemPluginWindow::SystemPluginWindow(QWidget *parent)
: QWidget(parent)
, m_pluginController(new FixedPluginController(this))
, m_listView(new DListView(this))
, m_position(Dock::Position::Bottom)
, m_mainLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight, this))
{
initUi();
connect(m_pluginController, &FixedPluginController::pluginItemInserted, this, &SystemPluginWindow::onPluginItemAdded);
connect(m_pluginController, &FixedPluginController::pluginItemRemoved, this, &SystemPluginWindow::onPluginItemRemoved);
connect(m_pluginController, &FixedPluginController::pluginItemUpdated, this, &SystemPluginWindow::onPluginItemUpdated);
}
SystemPluginWindow::~SystemPluginWindow()
{
}
void SystemPluginWindow::setPositon(Position position)
{
if (m_position == position)
return;
m_position = position;
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
m_mainLayout->setDirection(QBoxLayout::Direction::LeftToRight);
else
m_mainLayout->setDirection(QBoxLayout::Direction::TopToBottom);
QObjectList childObjects = children();
for (QObject *childObject : childObjects) {
StretchPluginsItem *item = qobject_cast<StretchPluginsItem *>(childObject);
if (!item)
continue;
item->setPosition(m_position);
}
}
QSize SystemPluginWindow::suitableSize()
{
QObjectList childs = children();
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
int itemWidth = 0;
for (QObject *childObject : childs) {
StretchPluginsItem *childItem = qobject_cast<StretchPluginsItem *>(childObject);
if (!childItem)
continue;
itemWidth += childItem->suitableSize().width();
}
return QSize(itemWidth, QWIDGETSIZE_MAX);
}
int itemHeight = 0;
for (QObject *childObject : childs) {
StretchPluginsItem *item = qobject_cast<StretchPluginsItem *>(childObject);
if (!item)
continue;
itemHeight += item->suitableSize().height();
}
return QSize(QWIDGETSIZE_MAX, itemHeight);
}
void SystemPluginWindow::initUi()
{
m_mainLayout->setContentsMargins(0, 0, 0, 0);
m_mainLayout->setSpacing(0);
}
bool SystemPluginWindow::pluginExist(StretchPluginsItem *pluginItem)
{
for (int i = 0; i < m_mainLayout->count(); i++) {
QLayoutItem *layoutItem = m_mainLayout->itemAt(i);
if (!layoutItem)
continue;
if (layoutItem->widget() == pluginItem)
return true;
}
return false;
}
void SystemPluginWindow::onPluginItemAdded(StretchPluginsItem *pluginItem)
{
if (pluginExist(pluginItem))
return;
pluginItem->setPosition(m_position);
pluginItem->setParent(this);
pluginItem->show();
m_mainLayout->addWidget(pluginItem);
Q_EMIT itemChanged();
}
void SystemPluginWindow::onPluginItemRemoved(StretchPluginsItem *pluginItem)
{
if (!pluginExist(pluginItem))
return;
pluginItem->setParent(nullptr);
pluginItem->hide();
m_mainLayout->removeWidget(pluginItem);
Q_EMIT itemChanged();
}
void SystemPluginWindow::onPluginItemUpdated(StretchPluginsItem *pluginItem)
{
pluginItem->update();
}
#define ICONSIZE 20
#define ICONTEXTSPACE 6
#define PLUGIN_ITEM_DRAG_THRESHOLD 20
StretchPluginsItem::StretchPluginsItem(PluginsItemInterface * const pluginInter, const QString &itemKey, QWidget *parent)
: DockItem(parent)
, m_pluginInter(pluginInter)
, m_itemKey(itemKey)
, m_position(Dock::Position::Bottom)
{
}
StretchPluginsItem::~StretchPluginsItem()
{
}
void StretchPluginsItem::setPosition(Position position)
{
m_position = position;
update();
}
QString StretchPluginsItem::itemKey() const
{
return m_itemKey;
}
PluginsItemInterface *StretchPluginsItem::pluginInter() const
{
return m_pluginInter;
}
void StretchPluginsItem::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
QIcon icon = m_pluginInter->icon(DockPart::SystemPanel);
QRect rctPixmap(rect());
if (needShowText()) {
int textHeight = QFontMetrics(textFont()).height();
// 文本与图标的间距为6
int iconTop = (height() - textHeight - ICONSIZE - ICONTEXTSPACE) / 2;
rctPixmap.setX((width() - ICONSIZE) / 2);
rctPixmap.setY(iconTop);
rctPixmap.setWidth(ICONSIZE);
rctPixmap.setHeight(ICONSIZE);
// 先绘制下面的文本
painter.setFont(textFont());
painter.drawText(QRect(0, iconTop + ICONSIZE + ICONTEXTSPACE, width(), textHeight), Qt::AlignCenter, m_pluginInter->pluginDisplayName());
} else {
rctPixmap.setX((width() - ICONSIZE) / 2);
rctPixmap.setY((height() - ICONSIZE) / 2);
rctPixmap.setWidth(ICONSIZE);
rctPixmap.setHeight(ICONSIZE);
}
// 绘制图标
int iconSize = static_cast<int>(ICONSIZE * (qApp->devicePixelRatio()));
painter.drawPixmap(rctPixmap, icon.pixmap(iconSize, iconSize));
}
QSize StretchPluginsItem::suitableSize() const
{
int iconSize = static_cast<int>(ICONSIZE * (qApp->devicePixelRatio()));
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
int textWidth = QFontMetrics(textFont()).boundingRect(m_pluginInter->pluginDisplayName()).width();
return QSize(qMax(textWidth, iconSize) + 10 * 2, -1);
}
int height = 6; // 图标上边距6
height += iconSize; // 图标尺寸20
height += ICONTEXTSPACE; // 图标与文字间距6
height += QFontMetrics(textFont()).height(); // 文本高度
height += 4; // 下间距4
return QSize(-1, height);
}
QFont StretchPluginsItem::textFont() const
{
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
static QList<QFont> fonts{ DFontSizeManager::instance()->t9(),
DFontSizeManager::instance()->t8(),
DFontSizeManager::instance()->t7(),
DFontSizeManager::instance()->t6() };
#define MINHEIGHT 50
int index = qMin(qMax((height() - MINHEIGHT) / 2, 0), fonts.size() - 1);
return fonts[index];
}
return DFontSizeManager::instance()->t10();
}
bool StretchPluginsItem::needShowText() const
{
// 任务栏在上方或者下方显示的时候根据设计图只有在当前区域高度大于50的时候才同时显示文本和图标
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
return height() >= 50;
return true;
}
const QString StretchPluginsItem::contextMenu() const
{
return m_pluginInter->itemContextMenu(m_itemKey);
}
void StretchPluginsItem::invokedMenuItem(const QString &itemId, const bool checked)
{
m_pluginInter->invokedMenuItem(m_itemKey, itemId, checked);
}
void StretchPluginsItem::mousePressEvent(QMouseEvent *e)
{
m_hover = false;
update();
if (PopupWindow->isVisible())
hideNonModel();
if (e->button() == Qt::LeftButton)
m_mousePressPoint = e->pos();
m_popupTipsDelayTimer->stop();
hideNonModel();
if (e->button() == Qt::RightButton
&& perfectIconRect().contains(e->pos()))
return showContextMenu();
DockItem::mousePressEvent(e);
}
void StretchPluginsItem::mouseReleaseEvent(QMouseEvent *e)
{
DockItem::mouseReleaseEvent(e);
if (e->button() != Qt::LeftButton)
return;
if (checkAndResetTapHoldGestureState() && e->source() == Qt::MouseEventSynthesizedByQt)
return;
const QPoint distance = e->pos() - m_mousePressPoint;
if (distance.manhattanLength() < PLUGIN_ITEM_DRAG_THRESHOLD)
mouseClick();
}
void StretchPluginsItem::mouseClick()
{
const QString command = m_pluginInter->itemCommand(m_itemKey);
if (!command.isEmpty()) {
QProcess::startDetached(command);
return;
}
// request popup applet
if (QWidget *w = m_pluginInter->itemPopupApplet(m_itemKey))
showPopupApplet(w);
}