mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-03 00:15:21 +00:00
feat: 加载插件流程移动到插件里单独加载
将加载插件的流程和快捷面板的功能移动到单独的插件中,精简任务栏的代码 Log: Influence: 加载插件 Task: https://pms.uniontech.com/task-view-222353.html Change-Id: I9b2fbe4f32c852f6a3535daab87c63741bd8914a
This commit is contained in:
parent
978d7fe738
commit
4a2847f03f
1
debian/dde-dock.install
vendored
1
debian/dde-dock.install
vendored
@ -1,6 +1,7 @@
|
|||||||
usr/share
|
usr/share
|
||||||
usr/bin
|
usr/bin
|
||||||
etc/dde-dock
|
etc/dde-dock
|
||||||
|
usr/lib/dde-dock/plugins/loader/libpluginmanager.so
|
||||||
usr/lib/dde-dock/plugins/libshutdown.so
|
usr/lib/dde-dock/plugins/libshutdown.so
|
||||||
usr/lib/dde-dock/plugins/libtrash.so
|
usr/lib/dde-dock/plugins/libtrash.so
|
||||||
usr/lib/dde-dock/plugins/liboverlay-warning.so
|
usr/lib/dde-dock/plugins/liboverlay-warning.so
|
||||||
|
@ -12,7 +12,7 @@ endif()
|
|||||||
generation_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/dbusinterface/xml ${CMAKE_CURRENT_SOURCE_DIR}/dbusinterface/generation_dbus_interface)
|
generation_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/dbusinterface/xml ${CMAKE_CURRENT_SOURCE_DIR}/dbusinterface/generation_dbus_interface)
|
||||||
|
|
||||||
# Sources files
|
# Sources files
|
||||||
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../widgets/*.h" "../widgets/*.cpp")
|
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../widgets/*.h" "../widgets/*.cpp" "../interfaces/*.h")
|
||||||
|
|
||||||
# Find the library
|
# Find the library
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
44
interfaces/pluginmanagerinterface.h
Normal file
44
interfaces/pluginmanagerinterface.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 ~ 2023 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef PLUGINMANAGERINTERFACE_H
|
||||||
|
#define PLUGINMANAGERINTERFACE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
class PluginsItemInterface;
|
||||||
|
|
||||||
|
class PluginManagerInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual QList<PluginsItemInterface *> plugins() const = 0;
|
||||||
|
virtual QList<PluginsItemInterface *> pluginsInSetting() const = 0;
|
||||||
|
virtual QList<PluginsItemInterface *> currentPlugins() const = 0;
|
||||||
|
virtual QString itemKey(PluginsItemInterface *itemInter) const = 0;
|
||||||
|
virtual QJsonObject metaData(PluginsItemInterface *itemInter) const = 0;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void pluginLoadFinished();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLUGINMANAGERINTERFACE_H
|
@ -4,7 +4,7 @@ add_subdirectory("power")
|
|||||||
add_subdirectory("sound")
|
add_subdirectory("sound")
|
||||||
add_subdirectory("display")
|
add_subdirectory("display")
|
||||||
add_subdirectory("media")
|
add_subdirectory("media")
|
||||||
#add_subdirectory("tray")
|
add_subdirectory("pluginmanager")
|
||||||
add_subdirectory("trash")
|
add_subdirectory("trash")
|
||||||
add_subdirectory("keyboard-layout")
|
add_subdirectory("keyboard-layout")
|
||||||
add_subdirectory("onboard")
|
add_subdirectory("onboard")
|
||||||
|
45
plugins/pluginmanager/CMakeLists.txt
Normal file
45
plugins/pluginmanager/CMakeLists.txt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
set(PLUGIN_NAME "pluginmanager")
|
||||||
|
|
||||||
|
project(${PLUGIN_NAME})
|
||||||
|
|
||||||
|
# Sources files
|
||||||
|
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "*.qrc" "../../frame/drag/quickdragcore.h" "../../frame/drag/quickdragcore.cpp"
|
||||||
|
"../../frame/util/settingconfig.h" "../../frame/util/settingconfig.cpp"
|
||||||
|
"../../frame/util/pluginloader.h" "../../frame/util/pluginloader.cpp"
|
||||||
|
"../../frame/dbus/dockinterface.h" "../../frame/dbus/dockinterface.cpp"
|
||||||
|
"../../frame/dbusinterface/generation_dbus_interface/org_deepin_dde_daemon_dock1.h"
|
||||||
|
"../../frame/dbusinterface/generation_dbus_interface/org_deepin_dde_daemon_dock1.cpp"
|
||||||
|
"../../frame/dbusinterface/types/dockrect.h"
|
||||||
|
"../../frame/dbusinterface/types/dockrect.cpp"
|
||||||
|
"../../interfaces/pluginmanagerinterface.h"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
find_package(Qt5Widgets REQUIRED)
|
||||||
|
find_package(Qt5Svg REQUIRED)
|
||||||
|
find_package(Qt5DBus REQUIRED)
|
||||||
|
find_package(DtkWidget REQUIRED)
|
||||||
|
pkg_check_modules(QGSettings REQUIRED gsettings-qt)
|
||||||
|
|
||||||
|
add_library(${PLUGIN_NAME} SHARED ${SRCS})
|
||||||
|
set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../loader/)
|
||||||
|
target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
|
||||||
|
${Qt5DBus_INCLUDE_DIRS}
|
||||||
|
${QGSettings_INCLUDE_DIRS}
|
||||||
|
./pluginadapter
|
||||||
|
../../frame/drag
|
||||||
|
../../frame/dbusinterface
|
||||||
|
../../frame/dbusinterface/generation_dbus_interface/
|
||||||
|
../../interfaces
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PLUGIN_NAME} PRIVATE
|
||||||
|
${DtkWidget_LIBRARIES}
|
||||||
|
${Qt5Widgets_LIBRARIES}
|
||||||
|
${Qt5Svg_LIBRARIES}
|
||||||
|
${Qt5DBus_LIBRARIES}
|
||||||
|
${QGSettings_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins/loader)
|
704
plugins/pluginmanager/dockplugincontroller.cpp
Normal file
704
plugins/pluginmanager/dockplugincontroller.cpp
Normal file
@ -0,0 +1,704 @@
|
|||||||
|
/*
|
||||||
|
* 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 "dockplugincontroller.h"
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
#include "pluginsiteminterface_v20.h"
|
||||||
|
#include "pluginadapter.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "settingconfig.h"
|
||||||
|
|
||||||
|
#include <DNotifySender>
|
||||||
|
#include <DSysInfo>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QMapIterator>
|
||||||
|
#include <QPluginLoader>
|
||||||
|
|
||||||
|
#define PLUGININFO "pluginInfo"
|
||||||
|
#define DOCK_QUICK_PLUGINS "Dock_Quick_Plugins"
|
||||||
|
|
||||||
|
static const QStringList CompatiblePluginApiList {
|
||||||
|
"1.1.1",
|
||||||
|
"1.2",
|
||||||
|
"1.2.1",
|
||||||
|
"1.2.2",
|
||||||
|
DOCK_PLUGIN_API_VERSION
|
||||||
|
};
|
||||||
|
|
||||||
|
class PluginInfo : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PluginInfo() : QObject(nullptr), m_loaded(false), m_visible(false) {}
|
||||||
|
bool m_loaded;
|
||||||
|
bool m_visible;
|
||||||
|
QString m_itemKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
DockPluginController::DockPluginController(PluginProxyInterface *proxyInter, QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_dbusDaemonInterface(QDBusConnection::sessionBus().interface())
|
||||||
|
, m_dockDaemonInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
|
||||||
|
, m_proxyInter(proxyInter)
|
||||||
|
{
|
||||||
|
qApp->installEventFilter(this);
|
||||||
|
|
||||||
|
refreshPluginSettings();
|
||||||
|
|
||||||
|
connect(SETTINGCONFIG, &SettingConfig::valueChanged, this, &DockPluginController::onConfigChanged);
|
||||||
|
connect(m_dockDaemonInter, &DockInter::PluginSettingsSynced, this, &DockPluginController::refreshPluginSettings, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
DockPluginController::~DockPluginController()
|
||||||
|
{
|
||||||
|
for (auto inter : m_pluginsMap.keys()) {
|
||||||
|
delete m_pluginsMap.value(inter).value("pluginloader");
|
||||||
|
m_pluginsMap[inter]["pluginloader"] = nullptr;
|
||||||
|
if (m_pluginsMap[inter].contains(PLUGININFO))
|
||||||
|
m_pluginsMap[inter][PLUGININFO]->deleteLater();
|
||||||
|
m_pluginsMap.remove(inter);
|
||||||
|
delete inter;
|
||||||
|
inter = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PluginsItemInterface *> DockPluginController::plugins() const
|
||||||
|
{
|
||||||
|
return m_pluginsMap.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PluginsItemInterface *> DockPluginController::pluginsInSetting() const
|
||||||
|
{
|
||||||
|
// 插件有三种状态
|
||||||
|
// 1、所有的插件,不管这个插件是否调用itemAdded方法,只要是通过dock加载的插件(换句话说,也就是在/lib/dde-dock/plugins目录下的插件)
|
||||||
|
// 2、在1的基础上,插件自身调用了itemAdded方法的插件,例如机器上没有蓝牙设备,那么蓝牙插件就不会调用itemAdded方法,这时候就不算
|
||||||
|
// 3、在2的基础上,由控制中心来决定那些插件是否在任务栏显示的插件
|
||||||
|
// 此处返回的是第二种插件
|
||||||
|
QList<PluginsItemInterface *> settingPlugins;
|
||||||
|
QMap<PluginsItemInterface *, int> pluginSort;
|
||||||
|
for (auto it = m_pluginsMap.begin(); it != m_pluginsMap.end(); it++) {
|
||||||
|
PluginsItemInterface *plugin = it.key();
|
||||||
|
qInfo() << plugin->pluginName();
|
||||||
|
if (plugin->pluginDisplayName().isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QMap<QString, QObject *> pluginMap = it.value();
|
||||||
|
// 如果不包含PLUGININFO这个key值,肯定是未加载
|
||||||
|
if (!pluginMap.contains(PLUGININFO))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PluginInfo *pluginInfo = static_cast<PluginInfo *>(pluginMap[PLUGININFO]);
|
||||||
|
if (!pluginInfo->m_loaded)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// 这里只需要返回插件为可以在控制中心设置的插件
|
||||||
|
if (!(plugin->flags() & PluginFlag::Attribute_CanSetting))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
settingPlugins << plugin;
|
||||||
|
pluginSort[plugin] = plugin->itemSortKey(pluginInfo->m_itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(settingPlugins.begin(), settingPlugins.end(), [ pluginSort ](PluginsItemInterface *plugin1, PluginsItemInterface *plugin2) {
|
||||||
|
return pluginSort[plugin1] < pluginSort[plugin2];
|
||||||
|
});
|
||||||
|
|
||||||
|
return settingPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PluginsItemInterface *> DockPluginController::currentPlugins() const
|
||||||
|
{
|
||||||
|
QList<PluginsItemInterface *> loadedPlugins;
|
||||||
|
|
||||||
|
QMap<PluginsItemInterface *, int> pluginSortMap;
|
||||||
|
for (auto it = m_pluginsMap.begin(); it != m_pluginsMap.end(); it++) {
|
||||||
|
QMap<QString, QObject *> objectMap = it.value();
|
||||||
|
if (!objectMap.contains(PLUGININFO))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PluginInfo *pluginInfo = static_cast<PluginInfo *>(objectMap[PLUGININFO]);
|
||||||
|
if (!pluginInfo->m_loaded)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PluginsItemInterface *plugin = it.key();
|
||||||
|
loadedPlugins << plugin;
|
||||||
|
pluginSortMap[plugin] = plugin->itemSortKey(pluginInfo->m_itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(loadedPlugins.begin(), loadedPlugins.end(), [ pluginSortMap ](PluginsItemInterface *pluginItem1, PluginsItemInterface *pluginItem2) {
|
||||||
|
return pluginSortMap.value(pluginItem1) < pluginSortMap.value(pluginItem2);
|
||||||
|
});
|
||||||
|
return loadedPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value)
|
||||||
|
{
|
||||||
|
savePluginValue(getPluginInterface(itemInter), key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVariant DockPluginController::getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &fallback)
|
||||||
|
{
|
||||||
|
return getPluginValue(getPluginInterface(itemInter), key, fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::removeValue(PluginsItemInterface *const itemInter, const QStringList &keyList)
|
||||||
|
{
|
||||||
|
removePluginValue(getPluginInterface(itemInter), keyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||||
|
{
|
||||||
|
PluginsItemInterface *pluginItem = getPluginInterface(itemInter);
|
||||||
|
|
||||||
|
PluginAdapter *pluginAdapter = dynamic_cast<PluginAdapter *>(pluginItem);
|
||||||
|
if (pluginAdapter) {
|
||||||
|
// 如果该插件可以正常转换为PluginAdapter插件,表示当前插件是v20插件,为了兼容v20插件
|
||||||
|
// 中获取ICON,因此,使用调用插件的itemWidget来截图的方式返回QIcon,所以此处传入itemKey
|
||||||
|
pluginAdapter->setItemKey(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是通过插件来调用m_proxyInter的
|
||||||
|
PluginInfo *pluginInfo = nullptr;
|
||||||
|
QMap<QString, QObject *> &interfaceData = m_pluginsMap[pluginItem];
|
||||||
|
if (interfaceData.contains(PLUGININFO)) {
|
||||||
|
pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||||
|
// 如果插件已经加载,则无需再次加载(此处保证插件出现重复调用itemAdded的情况)
|
||||||
|
if (pluginInfo->m_loaded)
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
pluginInfo = new PluginInfo;
|
||||||
|
interfaceData[PLUGININFO] = pluginInfo;
|
||||||
|
}
|
||||||
|
pluginInfo->m_itemKey = itemKey;
|
||||||
|
pluginInfo->m_loaded = true;
|
||||||
|
|
||||||
|
if (pluginCanDock(pluginItem))
|
||||||
|
addPluginItem(pluginItem, itemKey);
|
||||||
|
|
||||||
|
Q_EMIT pluginInserted(pluginItem, itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||||
|
{
|
||||||
|
m_proxyInter->itemUpdate(getPluginInterface(itemInter), itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||||
|
{
|
||||||
|
PluginsItemInterface *pluginInter = getPluginInterface(itemInter);
|
||||||
|
// 更新字段中的isLoaded字段,表示当前没有加载
|
||||||
|
QMap<QString, QObject *> &interfaceData = m_pluginsMap[pluginInter];
|
||||||
|
if (interfaceData.contains(PLUGININFO)) {
|
||||||
|
PluginInfo *pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||||
|
// 将是否加载的标记修改为未加载
|
||||||
|
pluginInfo->m_loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
removePluginItem(pluginInter, itemKey);
|
||||||
|
Q_EMIT pluginRemoved(pluginInter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
|
||||||
|
{
|
||||||
|
m_proxyInter->requestWindowAutoHide(getPluginInterface(itemInter), itemKey, autoHide);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||||
|
{
|
||||||
|
m_proxyInter->requestRefreshWindowVisible(getPluginInterface(itemInter), itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求页面显示或者隐藏,由插件内部来调用,例如在移除蓝牙插件后,如果已经弹出了蓝牙插件的面板,则隐藏面板
|
||||||
|
void DockPluginController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
|
||||||
|
{
|
||||||
|
PluginsItemInterface *pluginInter = getPluginInterface(itemInter);
|
||||||
|
Q_EMIT requestAppletVisible(pluginInter, itemKey, visible);
|
||||||
|
m_proxyInter->requestSetAppletVisible(pluginInter, itemKey, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface *DockPluginController::getPluginInterface(PluginsItemInterface * const itemInter)
|
||||||
|
{
|
||||||
|
// 先从事先定义好的map中查找,如果没有找到,就是v23插件,直接返回当前插件的指针
|
||||||
|
qulonglong pluginAddr = (qulonglong)itemInter;
|
||||||
|
if (m_pluginAdapterMap.contains(pluginAddr))
|
||||||
|
return m_pluginAdapterMap[pluginAddr];
|
||||||
|
|
||||||
|
return itemInter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::addPluginItem(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||||
|
{
|
||||||
|
// 如果这个插件都没有加载,那么此处肯定是无需新增
|
||||||
|
if (!m_pluginsMap.contains(itemInter))
|
||||||
|
return;
|
||||||
|
|
||||||
|
PluginInfo *pluginInfo = nullptr;
|
||||||
|
QMap<QString, QObject *> &interfaceData = m_pluginsMap[itemInter];
|
||||||
|
// 此处的PLUGININFO的数据已经在前面调用的地方给填充了数据,如果没有获取到这个数据,则无需新增
|
||||||
|
if (!interfaceData.contains(PLUGININFO))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||||
|
pluginInfo->m_visible = true;
|
||||||
|
|
||||||
|
m_proxyInter->itemAdded(itemInter, itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::removePluginItem(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||||
|
{
|
||||||
|
if (!m_pluginsMap.contains(itemInter))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 更新字段中的isLoaded字段,表示当前没有加载
|
||||||
|
QMap<QString, QObject *> &interfaceData = m_pluginsMap[itemInter];
|
||||||
|
if (!interfaceData.contains(PLUGININFO))
|
||||||
|
return;
|
||||||
|
|
||||||
|
PluginInfo *pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||||
|
// 将是否在任务栏显示的标记改为不显示
|
||||||
|
pluginInfo->m_visible = false;
|
||||||
|
m_proxyInter->itemRemoved(itemInter, itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DockPluginController::itemKey(PluginsItemInterface *itemInter) const
|
||||||
|
{
|
||||||
|
if (!m_pluginsMap.contains(itemInter))
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
QMap<QString, QObject *> interfaceData = m_pluginsMap[itemInter];
|
||||||
|
if (!interfaceData.contains(PLUGININFO))
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
PluginInfo *pluginInfo = static_cast<PluginInfo *>(interfaceData[PLUGININFO]);
|
||||||
|
return pluginInfo->m_itemKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject DockPluginController::metaData(PluginsItemInterface *pluginItem)
|
||||||
|
{
|
||||||
|
if (!m_pluginsMap.contains(pluginItem))
|
||||||
|
return QJsonObject();
|
||||||
|
|
||||||
|
QPluginLoader *pluginLoader = qobject_cast<QPluginLoader *>(m_pluginsMap[pluginItem].value("pluginloader"));
|
||||||
|
|
||||||
|
if (!pluginLoader)
|
||||||
|
return QJsonObject();
|
||||||
|
|
||||||
|
return pluginLoader->metaData().value("MetaData").toObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::savePluginValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &value)
|
||||||
|
{
|
||||||
|
// is it necessary?
|
||||||
|
// refreshPluginSettings();
|
||||||
|
|
||||||
|
// save to local cache
|
||||||
|
QJsonObject localObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
|
||||||
|
localObject.insert(key, QJsonValue::fromVariant(value)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||||
|
|
||||||
|
// save to daemon
|
||||||
|
QJsonObject remoteObject, remoteObjectInter;
|
||||||
|
remoteObjectInter.insert(key, QJsonValue::fromVariant(value)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||||
|
remoteObject.insert(itemInter->pluginName(), remoteObjectInter);
|
||||||
|
|
||||||
|
if (itemInter->type() == PluginsItemInterface::Fixed && key == "enable" && !value.toBool()) {
|
||||||
|
int fixedPluginCount = 0;
|
||||||
|
// 遍历FixPlugin插件个数
|
||||||
|
for (auto it(m_pluginsMap.begin()); it != m_pluginsMap.end();) {
|
||||||
|
if (it.key()->type() == PluginsItemInterface::Fixed) {
|
||||||
|
fixedPluginCount++;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
// 修改插件的order值,位置为队尾
|
||||||
|
QString name = localObject.keys().last();
|
||||||
|
// 此次做一下判断,有可能初始数据不存在pos_*字段,会导致enable字段被修改。或者此处可以循环所有字段是否存在pos_开头的字段?
|
||||||
|
if (name != key) {
|
||||||
|
localObject.insert(name, QJsonValue::fromVariant(fixedPluginCount)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||||
|
// daemon中同样修改
|
||||||
|
remoteObjectInter.insert(name, QJsonValue::fromVariant(fixedPluginCount)); //Note: QVariant::toJsonValue() not work in Qt 5.7
|
||||||
|
remoteObject.insert(itemInter->pluginName(), remoteObjectInter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pluginSettingsObject.insert(itemInter->pluginName(), localObject);
|
||||||
|
m_dockDaemonInter->MergePluginSettings(QJsonDocument(remoteObject).toJson(QJsonDocument::JsonFormat::Compact));
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVariant DockPluginController::getPluginValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &fallback)
|
||||||
|
{
|
||||||
|
// load from local cache
|
||||||
|
QVariant v = m_pluginSettingsObject.value(itemInter->pluginName()).toObject().value(key).toVariant();
|
||||||
|
if (v.isNull() || !v.isValid()) {
|
||||||
|
v = fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::removePluginValue(PluginsItemInterface * const itemInter, const QStringList &keyList)
|
||||||
|
{
|
||||||
|
if (keyList.isEmpty()) {
|
||||||
|
m_pluginSettingsObject.remove(itemInter->pluginName());
|
||||||
|
} else {
|
||||||
|
QJsonObject localObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
|
||||||
|
for (auto key : keyList) {
|
||||||
|
localObject.remove(key);
|
||||||
|
}
|
||||||
|
m_pluginSettingsObject.insert(itemInter->pluginName(), localObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dockDaemonInter->RemovePluginSettings(itemInter->pluginName(), keyList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::startLoadPlugin(const QStringList &dirs)
|
||||||
|
{
|
||||||
|
QDir dir;
|
||||||
|
for (const QString &path : dirs) {
|
||||||
|
if (!dir.exists(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
startLoader(new PluginLoader(path, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DockPluginController::isPluginLoaded(PluginsItemInterface *itemInter)
|
||||||
|
{
|
||||||
|
if (!m_pluginsMap.contains(itemInter))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QMap<QString, QObject *> pluginObject = m_pluginsMap.value(itemInter);
|
||||||
|
if (!pluginObject.contains(PLUGININFO))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
PluginInfo *pluginInfo = static_cast<PluginInfo *>(pluginObject.value(PLUGININFO));
|
||||||
|
return pluginInfo->m_visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *DockPluginController::pluginItemAt(PluginsItemInterface *const itemInter, const QString &itemKey) const
|
||||||
|
{
|
||||||
|
if (!m_pluginsMap.contains(itemInter))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_pluginsMap[itemInter][itemKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface *DockPluginController::pluginInterAt(const QString &itemKey)
|
||||||
|
{
|
||||||
|
QMapIterator<PluginsItemInterface *, QMap<QString, QObject *>> it(m_pluginsMap);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
if (it.value().keys().contains(itemKey)) {
|
||||||
|
return it.key();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface *DockPluginController::pluginInterAt(QObject *destItem)
|
||||||
|
{
|
||||||
|
QMapIterator<PluginsItemInterface *, QMap<QString, QObject *>> it(m_pluginsMap);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
if (it.value().values().contains(destItem)) {
|
||||||
|
return it.key();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::startLoader(PluginLoader *loader)
|
||||||
|
{
|
||||||
|
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
|
||||||
|
connect(loader, &PluginLoader::pluginFounded, this, [ = ](const QString &pluginFile) {
|
||||||
|
QPair<QString, PluginsItemInterface *> pair;
|
||||||
|
pair.first = pluginFile;
|
||||||
|
pair.second = nullptr;
|
||||||
|
m_pluginLoadMap.insert(pair, false);
|
||||||
|
});
|
||||||
|
connect(loader, &PluginLoader::pluginFounded, this, &DockPluginController::loadPlugin, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
int delay = Utils::SettingValue("com.deepin.dde.dock", "/com/deepin/dde/dock/", "delay-plugins-time", 0).toInt();
|
||||||
|
QTimer::singleShot(delay, loader, [ = ] { loader->start(QThread::LowestPriority); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::displayModeChanged()
|
||||||
|
{
|
||||||
|
const Dock::DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
|
||||||
|
const auto inters = m_pluginsMap.keys();
|
||||||
|
|
||||||
|
for (auto inter : inters)
|
||||||
|
inter->displayModeChanged(displayMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::positionChanged()
|
||||||
|
{
|
||||||
|
const Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
|
||||||
|
const auto inters = m_pluginsMap.keys();
|
||||||
|
|
||||||
|
for (auto inter : inters)
|
||||||
|
inter->positionChanged(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::loadPlugin(const QString &pluginFile)
|
||||||
|
{
|
||||||
|
QPluginLoader *pluginLoader = new QPluginLoader(pluginFile, this);
|
||||||
|
const QJsonObject &meta = pluginLoader->metaData().value("MetaData").toObject();
|
||||||
|
const QString &pluginApi = meta.value("api").toString();
|
||||||
|
bool pluginIsValid = true;
|
||||||
|
if (pluginApi.isEmpty() || !CompatiblePluginApiList.contains(pluginApi)) {
|
||||||
|
qDebug() << objectName()
|
||||||
|
<< "plugin api version not matched! expect versions:" << CompatiblePluginApiList
|
||||||
|
<< ", got version:" << pluginApi
|
||||||
|
<< ", the plugin file is:" << pluginFile;
|
||||||
|
|
||||||
|
pluginIsValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface *interface = qobject_cast<PluginsItemInterface *>(pluginLoader->instance());
|
||||||
|
if (!interface) {
|
||||||
|
// 如果识别当前插件失败,就认为这个插件是v20的插件,将其转换为v20插件接口
|
||||||
|
PluginsItemInterface_V20 *interface_v20 = qobject_cast<PluginsItemInterface_V20 *>(pluginLoader->instance());
|
||||||
|
if (interface_v20) {
|
||||||
|
// 将v20插件接口通过适配器转换成v23的接口,方便在后面识别
|
||||||
|
PluginAdapter *pluginAdapter = new PluginAdapter(interface_v20, pluginLoader);
|
||||||
|
// 将适配器的地址保存到map列表中,因为适配器自己会调用itemAdded方法,转换成PluginsItemInterface类,但是实际上它
|
||||||
|
// 对应的是PluginAdapter类,因此,这个map用于在后面的itemAdded方法中用来查找
|
||||||
|
m_pluginAdapterMap[(qulonglong)(interface_v20)] = pluginAdapter;
|
||||||
|
interface = pluginAdapter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interface) {
|
||||||
|
qDebug() << objectName() << "load plugin failed!!!" << pluginLoader->errorString() << pluginFile;
|
||||||
|
|
||||||
|
pluginLoader->unload();
|
||||||
|
pluginLoader->deleteLater();
|
||||||
|
|
||||||
|
pluginIsValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pluginIsValid) {
|
||||||
|
for (auto &pair : m_pluginLoadMap.keys()) {
|
||||||
|
if (pair.first == pluginFile) {
|
||||||
|
m_pluginLoadMap.remove(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString notifyMessage(tr("The plugin %1 is not compatible with the system."));
|
||||||
|
Dtk::Core::DUtil::DNotifySender(notifyMessage.arg(QFileInfo(pluginFile).fileName())).appIcon("dialog-warning").call();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interface->pluginName() == "multitasking" && (Utils::IS_WAYLAND_DISPLAY || Dtk::Core::DSysInfo::deepinType() == Dtk::Core::DSysInfo::DeepinServer)) {
|
||||||
|
for (auto &pair : m_pluginLoadMap.keys()) {
|
||||||
|
if (pair.first == pluginFile) {
|
||||||
|
m_pluginLoadMap.remove(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMapIterator<QPair<QString, PluginsItemInterface *>, bool> it(m_pluginLoadMap);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
if (it.key().first == pluginFile) {
|
||||||
|
m_pluginLoadMap.remove(it.key());
|
||||||
|
QPair<QString, PluginsItemInterface *> newPair;
|
||||||
|
newPair.first = pluginFile;
|
||||||
|
newPair.second = interface;
|
||||||
|
m_pluginLoadMap.insert(newPair, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存 PluginLoader 对象指针
|
||||||
|
QMap<QString, QObject *> interfaceData;
|
||||||
|
interfaceData["pluginloader"] = pluginLoader;
|
||||||
|
m_pluginsMap.insert(interface, interfaceData);
|
||||||
|
QString dbusService = meta.value("depends-daemon-dbus-service").toString();
|
||||||
|
if (!dbusService.isEmpty() && !m_dbusDaemonInterface->isServiceRegistered(dbusService).value()) {
|
||||||
|
qDebug() << objectName() << dbusService << "daemon has not started, waiting for signal";
|
||||||
|
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
|
||||||
|
[ = ](const QString & name, const QString & oldOwner, const QString & newOwner) {
|
||||||
|
Q_UNUSED(oldOwner);
|
||||||
|
if (name == dbusService && !newOwner.isEmpty()) {
|
||||||
|
qDebug() << objectName() << dbusService << "daemon started, init plugin and disconnect";
|
||||||
|
initPlugin(interface);
|
||||||
|
disconnect(m_dbusDaemonInterface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(justforlxz): 插件的所有初始化工作都在init函数中进行,
|
||||||
|
// loadPlugin函数是按队列执行的,initPlugin函数会有可能导致
|
||||||
|
// 函数执行被阻塞。
|
||||||
|
QTimer::singleShot(1, this, [ = ] {
|
||||||
|
initPlugin(interface);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::initPlugin(PluginsItemInterface *interface)
|
||||||
|
{
|
||||||
|
if (!interface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qDebug() << objectName() << "init plugin: " << interface->pluginName();
|
||||||
|
interface->init(this);
|
||||||
|
|
||||||
|
for (const auto &pair : m_pluginLoadMap.keys()) {
|
||||||
|
if (pair.second == interface)
|
||||||
|
m_pluginLoadMap.insert(pair, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loaded = true;
|
||||||
|
for (int i = 0; i < m_pluginLoadMap.keys().size(); ++i) {
|
||||||
|
if (!m_pluginLoadMap.values()[i]) {
|
||||||
|
loaded = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插件全部加载完成
|
||||||
|
if (loaded) {
|
||||||
|
emit pluginLoadFinished();
|
||||||
|
}
|
||||||
|
qDebug() << objectName() << "init plugin finished: " << interface->pluginName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::refreshPluginSettings()
|
||||||
|
{
|
||||||
|
const QString &pluginSettings = m_dockDaemonInter->GetPluginSettings().value();
|
||||||
|
if (pluginSettings.isEmpty()) {
|
||||||
|
qDebug() << "Error! get plugin settings from dbus failed!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QJsonObject &pluginSettingsObject = QJsonDocument::fromJson(pluginSettings.toLocal8Bit()).object();
|
||||||
|
if (pluginSettingsObject.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing changed
|
||||||
|
if (pluginSettingsObject == m_pluginSettingsObject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto pluginsIt = pluginSettingsObject.constBegin(); pluginsIt != pluginSettingsObject.constEnd(); ++pluginsIt) {
|
||||||
|
const QString &pluginName = pluginsIt.key();
|
||||||
|
const QJsonObject &settingsObject = pluginsIt.value().toObject();
|
||||||
|
QJsonObject newSettingsObject = m_pluginSettingsObject.value(pluginName).toObject();
|
||||||
|
for (auto settingsIt = settingsObject.constBegin(); settingsIt != settingsObject.constEnd(); ++settingsIt) {
|
||||||
|
newSettingsObject.insert(settingsIt.key(), settingsIt.value());
|
||||||
|
}
|
||||||
|
// TODO: remove not exists key-values
|
||||||
|
m_pluginSettingsObject.insert(pluginName, newSettingsObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// not notify plugins to refresh settings if this update is not emit by dock daemon
|
||||||
|
if (sender() != m_dockDaemonInter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify all plugins to reload plugin settings
|
||||||
|
for (PluginsItemInterface *pluginInter : m_pluginsMap.keys()) {
|
||||||
|
pluginInter->pluginSettingsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// reload all plugin items for sort order or container
|
||||||
|
QMap<PluginsItemInterface *, QMap<QString, QObject *>> pluginsMapTemp = m_pluginsMap;
|
||||||
|
for (auto it = pluginsMapTemp.constBegin(); it != pluginsMapTemp.constEnd(); ++it) {
|
||||||
|
const QList<QString> &itemKeyList = it.value().keys();
|
||||||
|
for (auto key : itemKeyList) {
|
||||||
|
if (key != "pluginloader") {
|
||||||
|
itemRemoved(it.key(), key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto key : itemKeyList) {
|
||||||
|
if (key != "pluginloader") {
|
||||||
|
itemAdded(it.key(), key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DockPluginController::eventFilter(QObject *object, QEvent *event)
|
||||||
|
{
|
||||||
|
if (object != qApp || event->type() != QEvent::DynamicPropertyChange)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QDynamicPropertyChangeEvent *const dpce = static_cast<QDynamicPropertyChangeEvent *>(event);
|
||||||
|
const QString propertyName = dpce->propertyName();
|
||||||
|
|
||||||
|
if (propertyName == PROP_POSITION)
|
||||||
|
positionChanged();
|
||||||
|
else if (propertyName == PROP_DISPLAY_MODE)
|
||||||
|
displayModeChanged();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DockPluginController::pluginCanDock(PluginsItemInterface *plugin) const
|
||||||
|
{
|
||||||
|
// 观察插件是否已经驻留在任务栏上,如果已经驻留在任务栏,则始终显示
|
||||||
|
if (plugin->flags() & PluginFlag::Attribute_ForceDock)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const QStringList configPlugins = SETTINGCONFIG->value(DOCK_QUICK_PLUGINS).toStringList();
|
||||||
|
return configPlugins.contains(plugin->pluginName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part)
|
||||||
|
{
|
||||||
|
m_proxyInter->updateDockInfo(itemInter, part);
|
||||||
|
Q_EMIT pluginUpdated(itemInter, part);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPluginController::onConfigChanged(const QString &key, const QVariant &value)
|
||||||
|
{
|
||||||
|
if (key != DOCK_QUICK_PLUGINS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStringList pluginNames = value.toStringList();
|
||||||
|
// 这里只处理工具插件(回收站)和系统插件(电源插件)
|
||||||
|
for (PluginsItemInterface *plugin : plugins()) {
|
||||||
|
QString itemKey = this->itemKey(plugin);
|
||||||
|
if (!pluginNames.contains(plugin->pluginName()) && isPluginLoaded(plugin)) {
|
||||||
|
// 如果当前配置中不包含当前插件,但是当前插件已经加载,那么就移除该插件
|
||||||
|
removePluginItem(plugin, itemKey);
|
||||||
|
QWidget *itemWidget = plugin->itemWidget(itemKey);
|
||||||
|
if (itemWidget)
|
||||||
|
itemWidget->setVisible(false);
|
||||||
|
} else if (pluginNames.contains(plugin->pluginName()) && !isPluginLoaded(plugin)) {
|
||||||
|
// 如果当前配置中包含当前插件,但是当前插件并未加载,那么就加载该插件
|
||||||
|
addPluginItem(plugin, itemKey);
|
||||||
|
// 只有工具插件是通过QWidget的方式进行显示的,因此,这里只处理工具插件
|
||||||
|
if (plugin->flags() & PluginFlag::Type_Tool) {
|
||||||
|
QWidget *itemWidget = plugin->itemWidget(itemKey);
|
||||||
|
if (itemWidget)
|
||||||
|
itemWidget->setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
plugins/pluginmanager/dockplugincontroller.h
Normal file
116
plugins/pluginmanager/dockplugincontroller.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DOCKPLUGINCONTROLLER_H
|
||||||
|
#define DOCKPLUGINCONTROLLER_H
|
||||||
|
|
||||||
|
#include "pluginproxyinterface.h"
|
||||||
|
#include "pluginloader.h"
|
||||||
|
#include "dbusutil.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QDBusConnectionInterface>
|
||||||
|
|
||||||
|
class PluginsItemInterface;
|
||||||
|
class PluginAdapter;
|
||||||
|
|
||||||
|
class DockPluginController : public QObject, protected PluginProxyInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DockPluginController(PluginProxyInterface *proxyInter, QObject *parent = Q_NULLPTR);
|
||||||
|
~ DockPluginController() override;
|
||||||
|
|
||||||
|
QList<PluginsItemInterface *> plugins() const; // 所有的插件
|
||||||
|
QList<PluginsItemInterface *> pluginsInSetting() const; // 控制中心用于可以设置是否显示或隐藏的插件
|
||||||
|
QList<PluginsItemInterface *> currentPlugins() const; // 当前使用的插件
|
||||||
|
|
||||||
|
QString itemKey(PluginsItemInterface *itemInter) const;
|
||||||
|
QJsonObject metaData(PluginsItemInterface *pluginItem);
|
||||||
|
|
||||||
|
virtual void savePluginValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value);
|
||||||
|
virtual const QVariant getPluginValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant());
|
||||||
|
virtual void removePluginValue(PluginsItemInterface * const itemInter, const QStringList &keyList);
|
||||||
|
void startLoadPlugin(const QStringList &dirs);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void pluginLoadFinished();
|
||||||
|
void pluginInserted(PluginsItemInterface *itemInter, QString);
|
||||||
|
void pluginRemoved(PluginsItemInterface *itemInter);
|
||||||
|
void pluginUpdated(PluginsItemInterface *, const DockPart);
|
||||||
|
void requestAppletVisible(PluginsItemInterface *, const QString &, bool);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isPluginLoaded(PluginsItemInterface *itemInter);
|
||||||
|
|
||||||
|
QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;
|
||||||
|
PluginsItemInterface *pluginInterAt(const QString &itemKey);
|
||||||
|
PluginsItemInterface *pluginInterAt(QObject *destItem);
|
||||||
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
|
||||||
|
bool pluginCanDock(PluginsItemInterface *plugin) const;
|
||||||
|
void updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// implements PluginProxyInterface
|
||||||
|
void saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) override;
|
||||||
|
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) override;
|
||||||
|
void removeValue(PluginsItemInterface * const itemInter, const QStringList &keyList) override;
|
||||||
|
|
||||||
|
void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override;
|
||||||
|
void itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey) override;
|
||||||
|
void itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) override;
|
||||||
|
void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override;
|
||||||
|
void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override;
|
||||||
|
void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override;
|
||||||
|
PluginsItemInterface *getPluginInterface(PluginsItemInterface * const itemInter);
|
||||||
|
|
||||||
|
void addPluginItem(PluginsItemInterface * const itemInter, const QString &itemKey);
|
||||||
|
void removePluginItem(PluginsItemInterface * const itemInter, const QString &itemKey);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void startLoader(PluginLoader *loader);
|
||||||
|
void displayModeChanged();
|
||||||
|
void positionChanged();
|
||||||
|
void loadPlugin(const QString &pluginFile);
|
||||||
|
void initPlugin(PluginsItemInterface *interface);
|
||||||
|
void refreshPluginSettings();
|
||||||
|
void onConfigChanged(const QString &key, const QVariant &value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDBusConnectionInterface *m_dbusDaemonInterface;
|
||||||
|
DockInter *m_dockDaemonInter;
|
||||||
|
|
||||||
|
// interface, "pluginloader", PluginLoader指针对象
|
||||||
|
QMap<PluginsItemInterface *, QMap<QString, QObject *>> m_pluginsMap;
|
||||||
|
|
||||||
|
// filepath, interface, loaded
|
||||||
|
QMap<QPair<QString, PluginsItemInterface *>, bool> m_pluginLoadMap;
|
||||||
|
|
||||||
|
QJsonObject m_pluginSettingsObject;
|
||||||
|
QMap<qulonglong, PluginAdapter *> m_pluginAdapterMap;
|
||||||
|
|
||||||
|
PluginProxyInterface *m_proxyInter;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ABSTRACTPLUGINSCONTROLLER_H
|
122
plugins/pluginmanager/iconmanager.cpp
Normal file
122
plugins/pluginmanager/iconmanager.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 ~ 2023 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 "iconmanager.h"
|
||||||
|
#include "dockplugincontroller.h"
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
|
||||||
|
#include <DDciIcon>
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
|
#define ITEMSPACE 6
|
||||||
|
#define ITEMHEIGHT 16
|
||||||
|
#define ITEMWIDTH 18
|
||||||
|
static QStringList pluginNames = {"power", "sound", "network"};
|
||||||
|
|
||||||
|
DGUI_USE_NAMESPACE
|
||||||
|
|
||||||
|
IconManager::IconManager(DockPluginController *pluginController, QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
, m_pluginController(pluginController)
|
||||||
|
, m_size(QSize(ITEMWIDTH, ITEMHEIGHT))
|
||||||
|
, m_position(Dock::Position::Bottom)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconManager::updateSize(QSize size)
|
||||||
|
{
|
||||||
|
m_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconManager::setPosition(Dock::Position position)
|
||||||
|
{
|
||||||
|
m_position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap IconManager::pixmap() const
|
||||||
|
{
|
||||||
|
QList<PluginsItemInterface *> plugins;
|
||||||
|
for (const QString &pluginName : pluginNames) {
|
||||||
|
PluginsItemInterface *plugin = findPlugin(pluginName);
|
||||||
|
if (plugin)
|
||||||
|
plugins << plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugins.size() < 2) {
|
||||||
|
// 缺省图标
|
||||||
|
DDciIcon::Theme theme = DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? DDciIcon::Light : DDciIcon::Dark;
|
||||||
|
DDciIcon dciIcon(QString(":/resources/dock_control.dci"));
|
||||||
|
return dciIcon.pixmap(QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1 : qApp->devicePixelRatio(), ITEMHEIGHT, theme, DDciIcon::Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组合图标
|
||||||
|
QPixmap pixmap;
|
||||||
|
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
|
||||||
|
pixmap = QPixmap(ITEMWIDTH * plugins.size() + ITEMSPACE * (plugins.size() + 1), m_size.height() - 8);
|
||||||
|
} else {
|
||||||
|
pixmap = QPixmap(m_size.width() - 8, ITEMWIDTH * plugins.size() + ITEMSPACE * (plugins.size() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
QPainter painter(&pixmap);
|
||||||
|
painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
|
||||||
|
QColor backColor = DGuiApplicationHelper::ColorType::DarkType == DGuiApplicationHelper::instance()->themeType() ? QColor(20, 20, 20) : Qt::white;
|
||||||
|
backColor.setAlphaF(0.2);
|
||||||
|
QPainterPath path;
|
||||||
|
path.addRoundedRect(pixmap.rect(), 5, 5);
|
||||||
|
painter.fillPath(path, backColor);
|
||||||
|
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
|
||||||
|
QPoint pointPixmap(ITEMSPACE, (pixmap.height() - ITEMHEIGHT) / 2);
|
||||||
|
for (PluginsItemInterface *plugin : plugins) {
|
||||||
|
QIcon icon = plugin->icon(DockPart::QuickShow);
|
||||||
|
QPixmap pixmapDraw = icon.pixmap(ITEMHEIGHT, ITEMHEIGHT);
|
||||||
|
painter.drawPixmap(pointPixmap, pixmapDraw);
|
||||||
|
pointPixmap.setX(pointPixmap.x() + ITEMWIDTH + ITEMSPACE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QPoint pointPixmap((pixmap.width() - ITEMWIDTH) / 2, ITEMSPACE);
|
||||||
|
for (PluginsItemInterface *plugin : plugins) {
|
||||||
|
QIcon icon = plugin->icon(DockPart::QuickShow);
|
||||||
|
QPixmap pixmapDraw = icon.pixmap(ITEMHEIGHT, ITEMHEIGHT);
|
||||||
|
painter.drawPixmap(pointPixmap, pixmapDraw);
|
||||||
|
pointPixmap.setY(pointPixmap.y() + ITEMWIDTH + ITEMSPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
painter.end();
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IconManager::isFixedPlugin(PluginsItemInterface *plugin) const
|
||||||
|
{
|
||||||
|
return pluginNames.contains(plugin->pluginName());
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface *IconManager::findPlugin(const QString &pluginName) const
|
||||||
|
{
|
||||||
|
QList<PluginsItemInterface *> plugins = m_pluginController->currentPlugins();
|
||||||
|
for (PluginsItemInterface *plugin : plugins) {
|
||||||
|
if (plugin->pluginName() == pluginName)
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
52
plugins/pluginmanager/iconmanager.h
Normal file
52
plugins/pluginmanager/iconmanager.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 ~ 2023 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef ICONMANAGER_H
|
||||||
|
#define ICONMANAGER_H
|
||||||
|
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPixmap>
|
||||||
|
|
||||||
|
class DockPluginController;
|
||||||
|
class PluginsItemInterface;
|
||||||
|
|
||||||
|
class IconManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IconManager(DockPluginController *pluginController, QObject *parent = nullptr);
|
||||||
|
void updateSize(QSize size);
|
||||||
|
void setPosition(Dock::Position position);
|
||||||
|
QPixmap pixmap() const;
|
||||||
|
bool isFixedPlugin(PluginsItemInterface *plugin) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginsItemInterface *findPlugin(const QString &pluginName) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DockPluginController *m_pluginController;
|
||||||
|
QSize m_size;
|
||||||
|
Dock::Position m_position;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ICONMANAGER_H
|
313
plugins/pluginmanager/largerquickitem.cpp
Normal file
313
plugins/pluginmanager/largerquickitem.cpp
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* 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 "largerquickitem.h"
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
|
||||||
|
#include <DFontSizeManager>
|
||||||
|
#include <DGuiApplicationHelper>
|
||||||
|
#include <DPaletteHelper>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#define BGSIZE 36
|
||||||
|
#define ICONWIDTH 24
|
||||||
|
#define ICONHEIGHT 24
|
||||||
|
|
||||||
|
DWIDGET_USE_NAMESPACE
|
||||||
|
|
||||||
|
static QSize expandSize = QSize(20, 20);
|
||||||
|
|
||||||
|
LargerQuickItem::LargerQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||||
|
: QuickSettingItem(pluginInter, itemKey, parent)
|
||||||
|
, m_iconWidget(nullptr)
|
||||||
|
, m_nameLabel(nullptr)
|
||||||
|
, m_stateLabel(nullptr)
|
||||||
|
, m_itemWidgetParent(nullptr)
|
||||||
|
{
|
||||||
|
initUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
LargerQuickItem::~LargerQuickItem()
|
||||||
|
{
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (itemWidget)
|
||||||
|
itemWidget->setParent(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LargerQuickItem::doUpdate()
|
||||||
|
{
|
||||||
|
if (m_iconWidget && m_nameLabel && m_stateLabel) {
|
||||||
|
m_iconWidget->update();
|
||||||
|
m_nameLabel->setText(QFontMetrics(m_nameLabel->font()).elidedText(pluginItem()->pluginDisplayName(), Qt::TextElideMode::ElideRight, m_nameLabel->width()));
|
||||||
|
m_stateLabel->setText(QFontMetrics(m_stateLabel->font()).elidedText(pluginItem()->description(), Qt::TextElideMode::ElideRight, m_stateLabel->width()));
|
||||||
|
} else {
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (itemWidget) {
|
||||||
|
// 如果插件没有返回图标的显示,则获取插件的itemWidget
|
||||||
|
itemWidget->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LargerQuickItem::detachPlugin()
|
||||||
|
{
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (itemWidget && itemWidget->parentWidget() == this)
|
||||||
|
itemWidget->setParent(m_itemWidgetParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickSettingItem::QuickItemStyle LargerQuickItem::type() const
|
||||||
|
{
|
||||||
|
return QuickSettingItem::QuickItemStyle::Larger;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LargerQuickItem::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (!m_iconWidget)
|
||||||
|
return QuickSettingItem::eventFilter(obj, event);
|
||||||
|
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::MouseButtonRelease: {
|
||||||
|
if (obj->objectName() == "expandLabel") {
|
||||||
|
// 如果是鼠标的按下事件
|
||||||
|
QWidget *widget = pluginItem()->itemPopupApplet(QUICK_ITEM_KEY);
|
||||||
|
if (widget)
|
||||||
|
Q_EMIT requestShowChildWidget(widget);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (obj == this) {
|
||||||
|
QStringList commandArgumend = pluginItem()->itemCommand(itemKey()).split(" ");
|
||||||
|
if (commandArgumend.size() == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
QString command = commandArgumend.first();
|
||||||
|
commandArgumend.removeFirst();
|
||||||
|
QProcess::startDetached(command, commandArgumend);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::Resize: {
|
||||||
|
QLabel *labelWidget = qobject_cast<QLabel *>(obj);
|
||||||
|
if (!labelWidget)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (labelWidget == m_nameLabel) {
|
||||||
|
labelWidget->setText(QFontMetrics(labelWidget->font()).elidedText(pluginItem()->pluginDisplayName(), Qt::TextElideMode::ElideRight, labelWidget->width()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (labelWidget == m_stateLabel) {
|
||||||
|
labelWidget->setText(QFontMetrics(labelWidget->font()).elidedText(pluginItem()->description(), Qt::TextElideMode::ElideRight, labelWidget->width()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QuickSettingItem::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LargerQuickItem::showEvent(QShowEvent *event)
|
||||||
|
{
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (pluginItem()->icon(DockPart::QuickPanel).isNull() && itemWidget) {
|
||||||
|
itemWidget->setParent(this);
|
||||||
|
itemWidget->setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LargerQuickItem::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (pluginItem()->icon(DockPart::QuickPanel).isNull() && itemWidget) {
|
||||||
|
itemWidget->setFixedSize(size());
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickSettingItem::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LargerQuickItem::initUi()
|
||||||
|
{
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (pluginItem()->icon(DockPart::QuickPanel).isNull() && itemWidget) {
|
||||||
|
m_itemWidgetParent = itemWidget->parentWidget();
|
||||||
|
// 如果插件没有返回图标的显示,则获取插件的itemWidget
|
||||||
|
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||||
|
itemWidget->setParent(this);
|
||||||
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
mainLayout->addWidget(itemWidget);
|
||||||
|
itemWidget->setVisible(true);
|
||||||
|
} else {
|
||||||
|
// 如果插件获取到插件区域的图标,则让其按照图标来组合显示
|
||||||
|
// 如果是占用两排的插件,则用横向Layout
|
||||||
|
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||||
|
mainLayout->setContentsMargins(10, 0, 10, 0);
|
||||||
|
mainLayout->setSpacing(0);
|
||||||
|
mainLayout->addStretch(10);
|
||||||
|
mainLayout->setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
|
// 添加图标
|
||||||
|
QWidget *iconWidgetParent = new QWidget(this);
|
||||||
|
QVBoxLayout *iconLayout = new QVBoxLayout(iconWidgetParent);
|
||||||
|
iconLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
iconLayout->setSpacing(0);
|
||||||
|
iconLayout->setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
|
m_iconWidget = new QuickIconWidget(pluginItem(), itemKey(), iconWidgetParent);
|
||||||
|
m_iconWidget->setFixedSize(BGSIZE, BGSIZE);
|
||||||
|
iconLayout->addWidget(m_iconWidget);
|
||||||
|
mainLayout->addWidget(iconWidgetParent);
|
||||||
|
mainLayout->addSpacing(10);
|
||||||
|
|
||||||
|
// 添加中间的名称部分
|
||||||
|
QWidget *textWidget = new QWidget(this);
|
||||||
|
m_nameLabel = new QLabel(textWidget);
|
||||||
|
m_stateLabel = new QLabel(textWidget);
|
||||||
|
m_nameLabel->setObjectName("nameLabel");
|
||||||
|
m_stateLabel->setObjectName("stateLabel");
|
||||||
|
|
||||||
|
// 设置图标和文字的属性
|
||||||
|
QFont nameFont = DFontSizeManager::instance()->t6();
|
||||||
|
nameFont.setBold(true);
|
||||||
|
QPalette pe;
|
||||||
|
pe.setColor(QPalette::WindowText, Qt::black);
|
||||||
|
m_nameLabel->setPalette(pe);
|
||||||
|
m_stateLabel->setPalette(pe);
|
||||||
|
m_nameLabel->setFont(nameFont);
|
||||||
|
m_stateLabel->setFont(DFontSizeManager::instance()->t10());
|
||||||
|
m_nameLabel->setText(pluginItem()->pluginDisplayName());
|
||||||
|
m_stateLabel->setText(pluginItem()->description());
|
||||||
|
m_nameLabel->installEventFilter(this);
|
||||||
|
m_stateLabel->installEventFilter(this);
|
||||||
|
|
||||||
|
QVBoxLayout *textLayout = new QVBoxLayout(textWidget);
|
||||||
|
textLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
textLayout->setSpacing(0);
|
||||||
|
textLayout->addWidget(m_nameLabel);
|
||||||
|
textLayout->addWidget(m_stateLabel);
|
||||||
|
textLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
mainLayout->addWidget(textWidget);
|
||||||
|
|
||||||
|
// 添加右侧的展开按钮
|
||||||
|
QWidget *expandWidgetParent = new QWidget(this);
|
||||||
|
QVBoxLayout *expandLayout = new QVBoxLayout(expandWidgetParent);
|
||||||
|
expandLayout->setSpacing(0);
|
||||||
|
QLabel *expandLabel = new QLabel(expandWidgetParent);
|
||||||
|
expandLabel->setObjectName("expandLabel");
|
||||||
|
expandLabel->setPixmap(QPixmap(expandFileName()));
|
||||||
|
expandLabel->setFixedSize(expandSize);
|
||||||
|
expandLabel->setAutoFillBackground(true);
|
||||||
|
expandLabel->installEventFilter(this);
|
||||||
|
expandLayout->addWidget(expandLabel);
|
||||||
|
pe.setBrush(QPalette::Window, Qt::transparent);
|
||||||
|
expandLabel->setPalette(pe);
|
||||||
|
mainLayout->addWidget(expandWidgetParent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LargerQuickItem::expandFileName() const
|
||||||
|
{
|
||||||
|
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
||||||
|
return QString(":/icons/resources/arrow-right-dark.svg");
|
||||||
|
|
||||||
|
return QString(":/icons/resources/arrow-right.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QuickIconWidget::QuickIconWidget
|
||||||
|
* @param pluginInter
|
||||||
|
* @param parent
|
||||||
|
* 图标的widget
|
||||||
|
*/
|
||||||
|
QuickIconWidget::QuickIconWidget(PluginsItemInterface *pluginInter, const QString &itemKey, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_pluginInter(pluginInter)
|
||||||
|
, m_itemKey(itemKey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickIconWidget::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
QPixmap pixmapIcon = pluginIcon();
|
||||||
|
if (pixmapIcon.isNull())
|
||||||
|
return QWidget::paintEvent(event);
|
||||||
|
|
||||||
|
pixmapIcon = pluginIcon(true);
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
|
||||||
|
painter.setPen(foregroundColor());
|
||||||
|
|
||||||
|
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||||
|
QPainter pa(&pixmapIcon);
|
||||||
|
pa.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||||
|
pa.fillRect(pixmapIcon.rect(), painter.pen().brush());
|
||||||
|
// 如果是主图标,则显示阴影背景
|
||||||
|
painter.save();
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.setBrush(dpa.brush(DPalette::ColorRole::Midlight));
|
||||||
|
painter.drawEllipse(rect());
|
||||||
|
painter.restore();
|
||||||
|
QRect rctIcon((rect().width() - pixmapIcon.width()) / 2, (rect().height() - pixmapIcon.height()) / 2, pixmapIcon.width(), pixmapIcon.height());
|
||||||
|
painter.drawPixmap(rctIcon, pixmapIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor QuickIconWidget::foregroundColor() const
|
||||||
|
{
|
||||||
|
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||||
|
// TODO 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色
|
||||||
|
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Active)
|
||||||
|
return dpa.color(DPalette::ColorGroup::Active, DPalette::ColorRole::Text);
|
||||||
|
|
||||||
|
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Deactive)
|
||||||
|
return dpa.color(DPalette::ColorGroup::Disabled, DPalette::ColorRole::Text);
|
||||||
|
|
||||||
|
return dpa.color(DPalette::ColorGroup::Normal, DPalette::ColorRole::Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap QuickIconWidget::pluginIcon(bool contailGrab) const
|
||||||
|
{
|
||||||
|
QIcon icon = m_pluginInter->icon(DockPart::QuickPanel);
|
||||||
|
if (icon.isNull() && contailGrab) {
|
||||||
|
// 如果图标为空,就使用itemWidget的截图作为它的图标,这种一般是适用于老版本插件或者没有实现v23接口的插件
|
||||||
|
QWidget *itemWidget = m_pluginInter->itemWidget(m_itemKey);
|
||||||
|
if (itemWidget) {
|
||||||
|
itemWidget->setFixedSize(ICONWIDTH, ICONHEIGHT);
|
||||||
|
return itemWidget->grab();
|
||||||
|
}
|
||||||
|
return QPixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取icon接口返回的图标
|
||||||
|
int pixmapWidth = width();
|
||||||
|
int pixmapHeight = height();
|
||||||
|
QList<QSize> iconSizes = icon.availableSizes();
|
||||||
|
if (iconSizes.size() > 0) {
|
||||||
|
QSize size = iconSizes[0];
|
||||||
|
if (size.isValid() && !size.isEmpty() && !size.isNull()) {
|
||||||
|
pixmapWidth = size.width();
|
||||||
|
pixmapHeight = size.height();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return icon.pixmap(pixmapWidth, pixmapHeight);
|
||||||
|
}
|
82
plugins/pluginmanager/largerquickitem.h
Normal file
82
plugins/pluginmanager/largerquickitem.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef LARGERQUICKITEM_H
|
||||||
|
#define LARGERQUICKITEM_H
|
||||||
|
|
||||||
|
#include <quicksettingitem.h>
|
||||||
|
|
||||||
|
class QuickIconWidget;
|
||||||
|
class QWidget;
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
|
// 插件在快捷面板中的展示样式,这个为大图标,展示为两列的那种,例如网络和蓝牙
|
||||||
|
class LargerQuickItem : public QuickSettingItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
LargerQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||||
|
~LargerQuickItem() override;
|
||||||
|
void doUpdate() override;
|
||||||
|
void detachPlugin() override;
|
||||||
|
|
||||||
|
QuickItemStyle type() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
void showEvent(QShowEvent *event) override;
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initUi();
|
||||||
|
QString expandFileName() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QuickIconWidget *m_iconWidget;
|
||||||
|
QLabel *m_nameLabel;
|
||||||
|
QLabel *m_stateLabel;
|
||||||
|
QWidget *m_itemWidgetParent;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The QuickIconWidget class
|
||||||
|
* 图标的Widget
|
||||||
|
*/
|
||||||
|
class QuickIconWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QuickIconWidget(PluginsItemInterface *pluginInter, const QString &itemKey, QWidget *parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QColor foregroundColor() const;
|
||||||
|
QPixmap pluginIcon(bool contailGrab = false) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginsItemInterface *m_pluginInter;
|
||||||
|
QString m_itemKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MULTIQUICKITEM_H
|
105
plugins/pluginmanager/linequickitem.cpp
Normal file
105
plugins/pluginmanager/linequickitem.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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 "linequickitem.h"
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
|
||||||
|
#include <DBlurEffectWidget>
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
DWIDGET_USE_NAMESPACE
|
||||||
|
|
||||||
|
LineQuickItem::LineQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||||
|
: QuickSettingItem(pluginInter, itemKey, parent)
|
||||||
|
, m_centerWidget(pluginInter->itemWidget(QUICK_ITEM_KEY))
|
||||||
|
, m_centerParentWidget(nullptr)
|
||||||
|
, m_effectWidget(new DBlurEffectWidget(this))
|
||||||
|
{
|
||||||
|
initUi();
|
||||||
|
QMetaObject::invokeMethod(this, &LineQuickItem::resizeSelf, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
LineQuickItem::~LineQuickItem()
|
||||||
|
{
|
||||||
|
if (m_centerWidget)
|
||||||
|
m_centerWidget->setParent(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineQuickItem::doUpdate()
|
||||||
|
{
|
||||||
|
if (m_centerWidget)
|
||||||
|
m_centerWidget->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineQuickItem::detachPlugin()
|
||||||
|
{
|
||||||
|
if (m_centerWidget)
|
||||||
|
m_centerWidget->setParent(m_centerParentWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickSettingItem::QuickItemStyle LineQuickItem::type() const
|
||||||
|
{
|
||||||
|
return QuickSettingItem::QuickItemStyle::Line;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LineQuickItem::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (obj == m_centerWidget && event->type() == QEvent::Resize)
|
||||||
|
resizeSelf();
|
||||||
|
|
||||||
|
return QuickSettingItem::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineQuickItem::initUi()
|
||||||
|
{
|
||||||
|
QColor maskColor(Qt::white);
|
||||||
|
maskColor.setAlphaF(0.8);
|
||||||
|
m_effectWidget->setMaskColor(maskColor);
|
||||||
|
m_effectWidget->setBlurRectXRadius(8);
|
||||||
|
m_effectWidget->setBlurRectYRadius(8);
|
||||||
|
|
||||||
|
// 如果图标不为空
|
||||||
|
if (!m_centerWidget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_centerWidget->setVisible(true);
|
||||||
|
m_centerParentWidget = m_centerWidget->parentWidget();
|
||||||
|
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout(m_effectWidget);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setAlignment(Qt::AlignHCenter);
|
||||||
|
layout->addWidget(m_centerWidget);
|
||||||
|
|
||||||
|
QHBoxLayout *mainLayout = new QHBoxLayout(this);
|
||||||
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
mainLayout->addWidget(m_effectWidget);
|
||||||
|
|
||||||
|
m_centerWidget->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineQuickItem::resizeSelf()
|
||||||
|
{
|
||||||
|
if (!m_centerWidget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_effectWidget->setFixedHeight(m_centerWidget->height());
|
||||||
|
setFixedHeight(m_centerWidget->height());
|
||||||
|
}
|
58
plugins/pluginmanager/linequickitem.h
Normal file
58
plugins/pluginmanager/linequickitem.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef LINEQUICKITEM_H
|
||||||
|
#define LINEQUICKITEM_H
|
||||||
|
|
||||||
|
#include "quicksettingitem.h"
|
||||||
|
|
||||||
|
namespace Dtk {
|
||||||
|
namespace Widget {
|
||||||
|
class DBlurEffectWidget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插件在快捷面板中的展示的样式,这个为整行显示的插件,例如声音,亮度调整和音乐播放等
|
||||||
|
class LineQuickItem : public QuickSettingItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
LineQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||||
|
~LineQuickItem() override;
|
||||||
|
void doUpdate() override;
|
||||||
|
void detachPlugin() override;
|
||||||
|
|
||||||
|
QuickItemStyle type() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initUi();
|
||||||
|
void resizeSelf();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *m_centerWidget;
|
||||||
|
QWidget *m_centerParentWidget;
|
||||||
|
Dtk::Widget::DBlurEffectWidget *m_effectWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FULLQUICKITEM_H
|
209
plugins/pluginmanager/pluginadapter/pluginadapter.cpp
Normal file
209
plugins/pluginmanager/pluginadapter/pluginadapter.cpp
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* 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 "pluginadapter.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#define ICONWIDTH 24
|
||||||
|
#define ICONHEIGHT 24
|
||||||
|
|
||||||
|
PluginAdapter::PluginAdapter(PluginsItemInterface_V20 *pluginInter, QPluginLoader *pluginLoader)
|
||||||
|
: m_pluginInter(pluginInter)
|
||||||
|
, m_pluginLoader(pluginLoader)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginAdapter::~PluginAdapter()
|
||||||
|
{
|
||||||
|
delete m_pluginInter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString PluginAdapter::pluginName() const
|
||||||
|
{
|
||||||
|
return m_pluginInter->pluginName();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString PluginAdapter::pluginDisplayName() const
|
||||||
|
{
|
||||||
|
return m_pluginInter->pluginDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::init(PluginProxyInterface *proxyInter)
|
||||||
|
{
|
||||||
|
m_pluginInter->init(proxyInter);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *PluginAdapter::itemWidget(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemWidget(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *PluginAdapter::itemTipsWidget(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemTipsWidget(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *PluginAdapter::itemPopupApplet(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemPopupApplet(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString PluginAdapter::itemCommand(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemCommand(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString PluginAdapter::itemContextMenu(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemContextMenu(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked)
|
||||||
|
{
|
||||||
|
m_pluginInter->invokedMenuItem(itemKey, menuId, checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PluginAdapter::itemSortKey(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemSortKey(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::setSortKey(const QString &itemKey, const int order)
|
||||||
|
{
|
||||||
|
m_pluginInter->setSortKey(itemKey, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginAdapter::itemAllowContainer(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemAllowContainer(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginAdapter::itemIsInContainer(const QString &itemKey)
|
||||||
|
{
|
||||||
|
return m_pluginInter->itemIsInContainer(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::setItemIsInContainer(const QString &itemKey, const bool container)
|
||||||
|
{
|
||||||
|
m_pluginInter->setItemIsInContainer(itemKey, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginAdapter::pluginIsAllowDisable()
|
||||||
|
{
|
||||||
|
return m_pluginInter->pluginIsAllowDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginAdapter::pluginIsDisable()
|
||||||
|
{
|
||||||
|
return m_pluginInter->pluginIsDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::pluginStateSwitched()
|
||||||
|
{
|
||||||
|
m_pluginInter->pluginStateSwitched();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::displayModeChanged(const Dock::DisplayMode displayMode)
|
||||||
|
{
|
||||||
|
m_pluginInter->displayModeChanged(displayMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::positionChanged(const Dock::Position position)
|
||||||
|
{
|
||||||
|
m_pluginInter->positionChanged(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::refreshIcon(const QString &itemKey)
|
||||||
|
{
|
||||||
|
m_pluginInter->refreshIcon(itemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::pluginSettingsChanged()
|
||||||
|
{
|
||||||
|
m_pluginInter->pluginSettingsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface::PluginType PluginAdapter::type()
|
||||||
|
{
|
||||||
|
switch (m_pluginInter->type()) {
|
||||||
|
case PluginsItemInterface_V20::PluginType::Fixed:
|
||||||
|
return PluginsItemInterface::PluginType::Fixed;
|
||||||
|
case PluginsItemInterface_V20::PluginType::Normal:
|
||||||
|
return PluginsItemInterface::PluginType::Normal;
|
||||||
|
}
|
||||||
|
return PluginsItemInterface::PluginType::Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface::PluginSizePolicy PluginAdapter::pluginSizePolicy() const
|
||||||
|
{
|
||||||
|
switch (m_pluginInter->pluginSizePolicy()) {
|
||||||
|
case PluginsItemInterface_V20::PluginSizePolicy::Custom:
|
||||||
|
return PluginsItemInterface::PluginSizePolicy::Custom;
|
||||||
|
case PluginsItemInterface_V20::PluginSizePolicy::System:
|
||||||
|
return PluginsItemInterface::PluginSizePolicy::System;
|
||||||
|
}
|
||||||
|
return PluginsItemInterface::PluginSizePolicy::Custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon PluginAdapter::icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType)
|
||||||
|
{
|
||||||
|
QWidget *itemWidget = m_pluginInter->itemWidget(m_itemKey);
|
||||||
|
if (!itemWidget)
|
||||||
|
return QIcon();
|
||||||
|
|
||||||
|
switch (dockPart) {
|
||||||
|
case DockPart::QuickPanel:
|
||||||
|
case DockPart::SystemPanel: {
|
||||||
|
// 如果图标为空,就使用itemWidget的截图作为它的图标,这种一般是适用于老版本插件或者没有实现v23接口的插件
|
||||||
|
QSize oldSize = itemWidget->size();
|
||||||
|
itemWidget->setFixedSize(ICONWIDTH, ICONHEIGHT);
|
||||||
|
QPixmap pixmap = itemWidget->grab();
|
||||||
|
itemWidget->setFixedSize(oldSize);
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface::PluginMode PluginAdapter::status() const
|
||||||
|
{
|
||||||
|
return PluginMode::Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PluginAdapter::description() const
|
||||||
|
{
|
||||||
|
return m_pluginInter->pluginDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginFlags PluginAdapter::flags() const
|
||||||
|
{
|
||||||
|
if (m_pluginLoader->fileName().contains(TRAY_PATH))
|
||||||
|
return PluginFlag::Type_Tray | PluginFlag::Attribute_CanDrag | PluginFlag::Attribute_CanInsert;
|
||||||
|
|
||||||
|
return PluginsItemInterface::flags();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginAdapter::setItemKey(const QString &itemKey)
|
||||||
|
{
|
||||||
|
m_itemKey = itemKey;
|
||||||
|
}
|
81
plugins/pluginmanager/pluginadapter/pluginadapter.h
Normal file
81
plugins/pluginmanager/pluginadapter/pluginadapter.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef PLUGINADAPTER_H
|
||||||
|
#define PLUGINADAPTER_H
|
||||||
|
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
#include "pluginsiteminterface_v20.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
/** 适配器,当加载到v20插件的时候,通过该接口来转成v23接口的插件
|
||||||
|
* @brief The PluginAdapter class
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PluginAdapter : public QObject, public PluginsItemInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(PluginsItemInterface)
|
||||||
|
|
||||||
|
public:
|
||||||
|
PluginAdapter(PluginsItemInterface_V20 *pluginInter, QPluginLoader *pluginLoader);
|
||||||
|
~PluginAdapter();
|
||||||
|
|
||||||
|
const QString pluginName() const override;
|
||||||
|
const QString pluginDisplayName() const override;
|
||||||
|
void init(PluginProxyInterface *proxyInter) override;
|
||||||
|
QWidget *itemWidget(const QString &itemKey) override;
|
||||||
|
|
||||||
|
QWidget *itemTipsWidget(const QString &itemKey) override;
|
||||||
|
QWidget *itemPopupApplet(const QString &itemKey) override;
|
||||||
|
const QString itemCommand(const QString &itemKey) override;
|
||||||
|
const QString itemContextMenu(const QString &itemKey) override;
|
||||||
|
void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) override;
|
||||||
|
int itemSortKey(const QString &itemKey) override;
|
||||||
|
void setSortKey(const QString &itemKey, const int order) override;
|
||||||
|
bool itemAllowContainer(const QString &itemKey) override;
|
||||||
|
bool itemIsInContainer(const QString &itemKey) override;
|
||||||
|
void setItemIsInContainer(const QString &itemKey, const bool container) override;
|
||||||
|
|
||||||
|
bool pluginIsAllowDisable() override;
|
||||||
|
bool pluginIsDisable() override;
|
||||||
|
void pluginStateSwitched() override;
|
||||||
|
void displayModeChanged(const Dock::DisplayMode displayMode) override;
|
||||||
|
void positionChanged(const Dock::Position position) override;
|
||||||
|
void refreshIcon(const QString &itemKey) override;
|
||||||
|
void pluginSettingsChanged() override;
|
||||||
|
PluginType type() override;
|
||||||
|
PluginSizePolicy pluginSizePolicy() const override;
|
||||||
|
|
||||||
|
QIcon icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType()) override;
|
||||||
|
PluginMode status() const override;
|
||||||
|
QString description() const override;
|
||||||
|
PluginFlags flags() const override;
|
||||||
|
|
||||||
|
void setItemKey(const QString &itemKey);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginsItemInterface_V20 *m_pluginInter;
|
||||||
|
QString m_itemKey;
|
||||||
|
QPluginLoader *m_pluginLoader;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLUGINADAPTER_H
|
261
plugins/pluginmanager/pluginadapter/pluginsiteminterface_v20.h
Normal file
261
plugins/pluginmanager/pluginadapter/pluginsiteminterface_v20.h
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 ~ 2018 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PLUGINSITEMINTERFACE_V20_H
|
||||||
|
#define PLUGINSITEMINTERFACE_V20_H
|
||||||
|
|
||||||
|
#include "pluginproxyinterface.h"
|
||||||
|
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief The PluginsItemInterface_V20 class
|
||||||
|
/// the dock plugins item interface, all dock plugins should
|
||||||
|
/// inheirt this class and override all pure virtual function.
|
||||||
|
///
|
||||||
|
class PluginsItemInterface_V20
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum PluginType {
|
||||||
|
Normal,
|
||||||
|
Fixed
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Plugin size policy
|
||||||
|
*/
|
||||||
|
enum PluginSizePolicy {
|
||||||
|
System = 1 << 0, // Follow the system
|
||||||
|
Custom = 1 << 1 // The custom
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief ~PluginsItemInterface_V20
|
||||||
|
/// DON'T try to delete m_proxyInter.
|
||||||
|
///
|
||||||
|
virtual ~PluginsItemInterface_V20() {}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief pluginName
|
||||||
|
/// tell dock the unique plugin id
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual const QString pluginName() const = 0;
|
||||||
|
virtual const QString pluginDisplayName() const { return QString(); }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief init
|
||||||
|
/// init your plugins, you need to save proxyInter to m_proxyInter
|
||||||
|
/// member variable. but you shouldn't free this pointer.
|
||||||
|
/// \param proxyInter
|
||||||
|
/// DON'T try to delete this pointer.
|
||||||
|
///
|
||||||
|
virtual void init(PluginProxyInterface *proxyInter) = 0;
|
||||||
|
///
|
||||||
|
/// \brief itemWidget
|
||||||
|
/// your plugin item widget, each item should have a unique key.
|
||||||
|
/// \param itemKey
|
||||||
|
/// your widget' unqiue key.
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual QWidget *itemWidget(const QString &itemKey) = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief itemTipsWidget
|
||||||
|
/// override this function if your item want to have a tips.
|
||||||
|
/// the tips will shown when user hover your item.
|
||||||
|
/// nullptr will be ignored.
|
||||||
|
/// \param itemKey
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual QWidget *itemTipsWidget(const QString &itemKey) {Q_UNUSED(itemKey); return nullptr;}
|
||||||
|
///
|
||||||
|
/// \brief itemPopupApplet
|
||||||
|
/// override this function if your item wants to have an popup applet.
|
||||||
|
/// the popup applet will shown when user click your item.
|
||||||
|
///
|
||||||
|
/// Tips:
|
||||||
|
/// dock should receive mouse press/release event to check user mouse operate,
|
||||||
|
/// if your item filter mouse event, this function will not be called.
|
||||||
|
/// so if you override mouse event and want to use popup applet, you
|
||||||
|
/// should pass event to your parent use QWidget::someEvent(e);
|
||||||
|
/// \param itemKey
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual QWidget *itemPopupApplet(const QString &itemKey) {Q_UNUSED(itemKey); return nullptr;}
|
||||||
|
///
|
||||||
|
/// \brief itemCommand
|
||||||
|
/// execute spec command when user clicked your item.
|
||||||
|
/// ensure your command do not get user input.
|
||||||
|
///
|
||||||
|
/// empty string will be ignored.
|
||||||
|
/// \param itemKey
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual const QString itemCommand(const QString &itemKey) {Q_UNUSED(itemKey); return QString();}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief itemContextMenu
|
||||||
|
/// context menu is shown when RequestPopupMenu called.
|
||||||
|
/// \param itemKey
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual const QString itemContextMenu(const QString &itemKey) {Q_UNUSED(itemKey); return QString();}
|
||||||
|
///
|
||||||
|
/// \brief invokedMenuItem
|
||||||
|
/// call if context menu item is clicked
|
||||||
|
/// \param itemKey
|
||||||
|
/// \param itemId
|
||||||
|
/// menu item id
|
||||||
|
/// \param checked
|
||||||
|
///
|
||||||
|
virtual void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) {Q_UNUSED(itemKey); Q_UNUSED(menuId); Q_UNUSED(checked);}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief itemSortKey
|
||||||
|
/// tell dock where your item wants to put on.
|
||||||
|
///
|
||||||
|
/// this index is start from 1 and
|
||||||
|
/// 0 for left side
|
||||||
|
/// -1 for right side
|
||||||
|
/// \param itemKey
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual int itemSortKey(const QString &itemKey) {Q_UNUSED(itemKey); return 1;}
|
||||||
|
///
|
||||||
|
/// \brief setSortKey
|
||||||
|
/// save your item new position
|
||||||
|
/// sort key will be changed when plugins order
|
||||||
|
/// changed(by user drag-drop)
|
||||||
|
/// \param itemKey
|
||||||
|
/// \param order
|
||||||
|
///
|
||||||
|
virtual void setSortKey(const QString &itemKey, const int order) {Q_UNUSED(itemKey); Q_UNUSED(order);}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief itemAllowContainer
|
||||||
|
/// tell dock is your item allow to move into container
|
||||||
|
///
|
||||||
|
/// if your item placed into container, popup tips and popup
|
||||||
|
/// applet will be disabled.
|
||||||
|
/// \param itemKey
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual bool itemAllowContainer(const QString &itemKey) {Q_UNUSED(itemKey); return false;}
|
||||||
|
///
|
||||||
|
/// \brief itemIsInContainer
|
||||||
|
/// tell dock your item is in container, this function
|
||||||
|
/// called at item init and if your item enable container.
|
||||||
|
/// \param itemKey
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
virtual bool itemIsInContainer(const QString &itemKey) {Q_UNUSED(itemKey); return false;}
|
||||||
|
///
|
||||||
|
/// \brief setItemIsInContainer
|
||||||
|
/// save your item new state.
|
||||||
|
/// this function called when user drag out your item from
|
||||||
|
/// container or user drop item into container(if your item
|
||||||
|
/// allow drop into container).
|
||||||
|
/// \param itemKey
|
||||||
|
/// \param container
|
||||||
|
///
|
||||||
|
virtual void setItemIsInContainer(const QString &itemKey, const bool container) {Q_UNUSED(itemKey); Q_UNUSED(container);}
|
||||||
|
|
||||||
|
virtual bool pluginIsAllowDisable() { return false; }
|
||||||
|
virtual bool pluginIsDisable() { return false; }
|
||||||
|
virtual void pluginStateSwitched() {}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief displayModeChanged
|
||||||
|
/// override this function to receive display mode changed signal
|
||||||
|
/// \param displayMode
|
||||||
|
///
|
||||||
|
virtual void displayModeChanged(const Dock::DisplayMode displayMode) {Q_UNUSED(displayMode);}
|
||||||
|
///
|
||||||
|
/// \brief positionChanged
|
||||||
|
/// override this function to receive dock position changed signal
|
||||||
|
/// \param position
|
||||||
|
///
|
||||||
|
virtual void positionChanged(const Dock::Position position) {Q_UNUSED(position);}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief refreshIcon
|
||||||
|
/// refresh item icon, its triggered when system icon theme changed.
|
||||||
|
/// \param itemKey
|
||||||
|
/// item key
|
||||||
|
///
|
||||||
|
virtual void refreshIcon(const QString &itemKey) { Q_UNUSED(itemKey); }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief displayMode
|
||||||
|
/// get current dock display mode
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
inline Dock::DisplayMode displayMode() const
|
||||||
|
{
|
||||||
|
return qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief position
|
||||||
|
/// get current dock position
|
||||||
|
/// \return
|
||||||
|
///
|
||||||
|
inline Dock::Position position() const
|
||||||
|
{
|
||||||
|
return qApp->property(PROP_POSITION).value<Dock::Position>();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief settingsChanged
|
||||||
|
/// override this function to receive plugin settings changed signal(DeepinSync)
|
||||||
|
///
|
||||||
|
virtual void pluginSettingsChanged() {}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief type
|
||||||
|
/// default plugin add dock right,fixed plugin add to dock fixed area
|
||||||
|
///
|
||||||
|
virtual PluginType type() { return Normal; }
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief plugin size policy
|
||||||
|
/// default plugin size policy
|
||||||
|
///
|
||||||
|
virtual PluginSizePolicy pluginSizePolicy() const { return System; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///
|
||||||
|
/// \brief m_proxyInter
|
||||||
|
/// NEVER delete this object.
|
||||||
|
///
|
||||||
|
PluginProxyInterface *m_proxyInter = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
#define ModuleInterfaceV20_iid "com.deepin.dock.PluginsItemInterface"
|
||||||
|
|
||||||
|
Q_DECLARE_INTERFACE(PluginsItemInterface_V20, ModuleInterfaceV20_iid)
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // PLUGINSITEMINTERFACE_H
|
146
plugins/pluginmanager/pluginchildpage.cpp
Normal file
146
plugins/pluginmanager/pluginchildpage.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* 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 "pluginchildpage.h"
|
||||||
|
|
||||||
|
#include <DStyle>
|
||||||
|
#include <DGuiApplicationHelper>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QPainterPath>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
DWIDGET_USE_NAMESPACE
|
||||||
|
DGUI_USE_NAMESPACE
|
||||||
|
|
||||||
|
PluginChildPage::PluginChildPage(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_headerWidget(new QWidget(this))
|
||||||
|
, m_back(new QPushButton(m_headerWidget))
|
||||||
|
, m_title(new QLabel(m_headerWidget))
|
||||||
|
, m_container(new QWidget(this))
|
||||||
|
, m_topWidget(nullptr)
|
||||||
|
, m_containerLayout(new QVBoxLayout(m_container))
|
||||||
|
{
|
||||||
|
initUi();
|
||||||
|
initConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginChildPage::~PluginChildPage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginChildPage::pushWidget(QWidget *widget)
|
||||||
|
{
|
||||||
|
// 首先将界面其他的窗体移除
|
||||||
|
for (int i = m_containerLayout->count() - 1; i >= 0; i--) {
|
||||||
|
QLayoutItem *item = m_containerLayout->itemAt(i);
|
||||||
|
item->widget()->removeEventFilter(this);
|
||||||
|
item->widget()->hide();
|
||||||
|
m_containerLayout->removeItem(item);
|
||||||
|
}
|
||||||
|
m_topWidget = widget;
|
||||||
|
if (widget) {
|
||||||
|
widget->installEventFilter(this);
|
||||||
|
m_containerLayout->addWidget(widget);
|
||||||
|
widget->show();
|
||||||
|
}
|
||||||
|
QMetaObject::invokeMethod(this, &PluginChildPage::resetHeight, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginChildPage::setTitle(const QString &text)
|
||||||
|
{
|
||||||
|
m_title->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginChildPage::initUi()
|
||||||
|
{
|
||||||
|
m_back->setIcon(backPixmap());
|
||||||
|
m_back->setFixedWidth(24);
|
||||||
|
m_back->setFlat(true);
|
||||||
|
m_title->setAlignment(Qt::AlignCenter);
|
||||||
|
QHBoxLayout *headerLayout = new QHBoxLayout(m_headerWidget);
|
||||||
|
headerLayout->setContentsMargins(11, 12, 24 + 11, 12);
|
||||||
|
headerLayout->setSpacing(0);
|
||||||
|
headerLayout->addWidget(m_back);
|
||||||
|
headerLayout->addWidget(m_title);
|
||||||
|
m_headerWidget->setFixedHeight(48);
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||||
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
mainLayout->setSpacing(0);
|
||||||
|
|
||||||
|
mainLayout->addWidget(m_headerWidget);
|
||||||
|
mainLayout->addWidget(m_container);
|
||||||
|
m_containerLayout->setContentsMargins(11, 0, 11, 0);
|
||||||
|
m_containerLayout->setSpacing(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginChildPage::initConnection()
|
||||||
|
{
|
||||||
|
connect(m_back, &QPushButton::clicked, this, &PluginChildPage::back);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginChildPage::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
if (watched == m_topWidget && event->type() == QEvent::Resize) {
|
||||||
|
resetHeight();
|
||||||
|
}
|
||||||
|
return QWidget::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginChildPage::resetHeight()
|
||||||
|
{
|
||||||
|
QMargins m = m_containerLayout->contentsMargins();
|
||||||
|
m_container->setFixedHeight(m.top() + m.bottom() + (m_topWidget ? m_topWidget->height() : 0));
|
||||||
|
setFixedHeight(m_headerWidget->height() + m_container->height());
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap PluginChildPage::backPixmap() const
|
||||||
|
{
|
||||||
|
QPixmap pixmap(16, 16);
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
// 设置背景色
|
||||||
|
QColor backColor;
|
||||||
|
if (DGuiApplicationHelper::ColorType::DarkType == DGuiApplicationHelper::instance()->themeType()) {
|
||||||
|
backColor = Qt::black;
|
||||||
|
backColor.setAlphaF(0.05);
|
||||||
|
} else {
|
||||||
|
backColor = Qt::white;
|
||||||
|
backColor.setAlphaF(0.2);
|
||||||
|
}
|
||||||
|
QPainter painter(&pixmap);
|
||||||
|
painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
QPainterPath path;
|
||||||
|
path.addEllipse(pixmap.rect());
|
||||||
|
painter.fillPath(path, backColor);
|
||||||
|
QSize arrowSize(10, 10);
|
||||||
|
QPixmap arrowPixmap = DStyle::standardIcon(style(), DStyle::SP_ArrowLeave).pixmap(arrowSize);
|
||||||
|
// 让其居中显示
|
||||||
|
QSize backSize = pixmap.size();
|
||||||
|
painter.drawPixmap((backSize.width() - arrowSize.width()) / 2, (backSize.height() - arrowSize.height()) / 2,
|
||||||
|
arrowSize.width(), arrowSize.height(), arrowPixmap);
|
||||||
|
painter.end();
|
||||||
|
return pixmap;
|
||||||
|
}
|
61
plugins/pluginmanager/pluginchildpage.h
Normal file
61
plugins/pluginmanager/pluginchildpage.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef PLUGINCHILDPAGE_H
|
||||||
|
#define PLUGINCHILDPAGE_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
|
class QLabel;
|
||||||
|
class QVBoxLayout;
|
||||||
|
|
||||||
|
class PluginChildPage : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PluginChildPage(QWidget *parent);
|
||||||
|
~PluginChildPage() override;
|
||||||
|
void pushWidget(QWidget *widget);
|
||||||
|
void setTitle(const QString &text);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void back();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initUi();
|
||||||
|
void initConnection();
|
||||||
|
void resetHeight();
|
||||||
|
QPixmap backPixmap() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *m_headerWidget;
|
||||||
|
QPushButton *m_back;
|
||||||
|
QLabel *m_title;
|
||||||
|
QWidget *m_container;
|
||||||
|
QWidget *m_topWidget;
|
||||||
|
QVBoxLayout *m_containerLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLUGINCHILDPAGE_H
|
195
plugins/pluginmanager/pluginmanager.cpp
Normal file
195
plugins/pluginmanager/pluginmanager.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 ~ 2023 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 "pluginmanager.h"
|
||||||
|
#include "dockplugincontroller.h"
|
||||||
|
#include "quicksettingcontainer.h"
|
||||||
|
#include "iconmanager.h"
|
||||||
|
|
||||||
|
#include <QResizeEvent>
|
||||||
|
|
||||||
|
PluginManager::PluginManager(QObject *parent)
|
||||||
|
: m_dockController(nullptr)
|
||||||
|
, m_iconManager(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString PluginManager::pluginName() const
|
||||||
|
{
|
||||||
|
return "pluginManager";
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString PluginManager::pluginDisplayName() const
|
||||||
|
{
|
||||||
|
return "pluginManager";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginManager::init(PluginProxyInterface *proxyInter)
|
||||||
|
{
|
||||||
|
if (m_proxyInter == proxyInter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_proxyInter = proxyInter;
|
||||||
|
|
||||||
|
m_dockController.reset(new DockPluginController(proxyInter));
|
||||||
|
m_quickContainer.reset(new QuickSettingContainer(m_dockController.data()));
|
||||||
|
m_iconManager.reset(new IconManager(m_dockController.data()));
|
||||||
|
m_iconManager->setPosition(position());
|
||||||
|
|
||||||
|
connect(m_dockController.data(), &DockPluginController::pluginInserted, this, [ this ](PluginsItemInterface *itemInter) {
|
||||||
|
if (m_iconManager->isFixedPlugin(itemInter)) {
|
||||||
|
m_proxyInter->itemUpdate(this, pluginName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_dockController.data(), &DockPluginController::pluginUpdated, this, [ this ](PluginsItemInterface *itemInter) {
|
||||||
|
if (m_iconManager->isFixedPlugin(itemInter)) {
|
||||||
|
m_proxyInter->itemUpdate(this, pluginName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_dockController.data(), &DockPluginController::pluginRemoved, this, [ this ](PluginsItemInterface *itemInter) {
|
||||||
|
if (m_iconManager->isFixedPlugin(itemInter)) {
|
||||||
|
m_proxyInter->itemUpdate(this, pluginName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_dockController.data(), &DockPluginController::requestAppletVisible, this, [ this ](PluginsItemInterface *itemInter, const QString &itemKey, bool visible) {
|
||||||
|
if (visible) {
|
||||||
|
QWidget *appletWidget = itemInter->itemPopupApplet(itemKey);
|
||||||
|
if (appletWidget)
|
||||||
|
m_quickContainer->showPage(appletWidget, itemInter);
|
||||||
|
} else {
|
||||||
|
// 显示主面板
|
||||||
|
m_quickContainer->topLevelWidget()->hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_dockController.data(), &DockPluginController::pluginLoadFinished, this, &PluginManager::pluginLoadFinished);
|
||||||
|
|
||||||
|
// 开始加载插件
|
||||||
|
m_dockController->startLoadPlugin(getPluginPaths());
|
||||||
|
|
||||||
|
m_proxyInter->itemAdded(this, pluginName());
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *PluginManager::itemWidget(const QString &itemKey)
|
||||||
|
{
|
||||||
|
Q_UNUSED(itemKey);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *PluginManager::itemPopupApplet(const QString &itemKey)
|
||||||
|
{
|
||||||
|
if (itemKey == QUICK_ITEM_KEY) {
|
||||||
|
// 返回快捷面板
|
||||||
|
return m_quickContainer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon PluginManager::icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType)
|
||||||
|
{
|
||||||
|
if (dockPart == DockPart::QuickShow) {
|
||||||
|
return m_iconManager->pixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginFlags PluginManager::flags() const
|
||||||
|
{
|
||||||
|
// 当前快捷插件组合区域只支持在快捷区域显示
|
||||||
|
return PluginFlag::Type_Common | PluginFlag::Attribute_ForceDock;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface::PluginSizePolicy PluginManager::pluginSizePolicy() const
|
||||||
|
{
|
||||||
|
return PluginSizePolicy::Custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginManager::eventHandler(QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::Resize) {
|
||||||
|
QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
|
||||||
|
m_iconManager->updateSize(resizeEvent->size());
|
||||||
|
}
|
||||||
|
return PluginsItemInterface::eventHandler(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginManager::positionChanged(const Dock::Position position)
|
||||||
|
{
|
||||||
|
m_iconManager->setPosition(position);
|
||||||
|
m_proxyInter->itemUpdate(this, pluginName());
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PluginsItemInterface *> PluginManager::plugins() const
|
||||||
|
{
|
||||||
|
return m_dockController->plugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PluginsItemInterface *> PluginManager::pluginsInSetting() const
|
||||||
|
{
|
||||||
|
return m_dockController->pluginsInSetting();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PluginsItemInterface *> PluginManager::currentPlugins() const
|
||||||
|
{
|
||||||
|
return m_dockController->currentPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PluginManager::itemKey(PluginsItemInterface *itemInter) const
|
||||||
|
{
|
||||||
|
return m_dockController->itemKey(itemInter);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject PluginManager::metaData(PluginsItemInterface *itemInter) const
|
||||||
|
{
|
||||||
|
return m_dockController->metaData(itemInter);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_DEBUG
|
||||||
|
static QStringList getPathFromConf(const QString &key) {
|
||||||
|
QSettings set("/etc/deepin/dde-dock.conf", QSettings::IniFormat);
|
||||||
|
auto value = set.value(key).toString();
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
return value.split(':');
|
||||||
|
}
|
||||||
|
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QStringList PluginManager::getPluginPaths() const
|
||||||
|
{
|
||||||
|
QStringList pluginPaths;
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
pluginPaths << QString("%1/..%2").arg(qApp->applicationDirPath()).arg(QUICK_PATH)
|
||||||
|
<< QString("%1/..%2").arg(qApp->applicationDirPath()).arg(PLUGIN_PATH)
|
||||||
|
<< QString("%1/..%2").arg(qApp->applicationDirPath()).arg(TRAY_PATH);
|
||||||
|
#else
|
||||||
|
pluginPaths << QString("/usr/lib/dde-dock%1").arg(QUICK_PATH)
|
||||||
|
<< QString("/usr/lib/dde-dock%1").arg(PLUGIN_PATH)
|
||||||
|
<< QString("/usr/lib/dde-dock%1").arg(TRAY_PATH);
|
||||||
|
|
||||||
|
const QStringList pluginsDirs = (getPathFromConf("PATH") << getPathFromConf("SYSTEM_TRAY_PATH"));
|
||||||
|
if (!pluginsDirs.isEmpty())
|
||||||
|
pluginPaths << pluginsDirs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pluginPaths;
|
||||||
|
}
|
72
plugins/pluginmanager/pluginmanager.h
Normal file
72
plugins/pluginmanager/pluginmanager.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 ~ 2023 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef PLUGINMANAGER_H
|
||||||
|
#define PLUGINMANAGER_H
|
||||||
|
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
#include "pluginmanagerinterface.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class DockPluginController;
|
||||||
|
class QuickSettingContainer;
|
||||||
|
class IconManager;
|
||||||
|
|
||||||
|
class PluginManager : public PluginManagerInterface, public PluginsItemInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(PluginsItemInterface)
|
||||||
|
Q_PLUGIN_METADATA(IID "com.deepin.dock.PluginsItemInterface" FILE "pluginmanager.json")
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PluginManager(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
const QString pluginName() const override;
|
||||||
|
const QString pluginDisplayName() const override;
|
||||||
|
void init(PluginProxyInterface *proxyInter) override;
|
||||||
|
QWidget *itemWidget(const QString &itemKey) override;
|
||||||
|
QWidget *itemPopupApplet(const QString &itemKey) override;
|
||||||
|
QIcon icon(const DockPart &dockPart, DGuiApplicationHelper::ColorType themeType) override;
|
||||||
|
PluginFlags flags() const override;
|
||||||
|
PluginSizePolicy pluginSizePolicy() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventHandler(QEvent *event) override;
|
||||||
|
void positionChanged(const Dock::Position position) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// 实现PluginManagerInterface接口,用于向dock提供所有已经加载的插件
|
||||||
|
QList<PluginsItemInterface *> plugins() const override;
|
||||||
|
QList<PluginsItemInterface *> pluginsInSetting() const override;
|
||||||
|
QList<PluginsItemInterface *> currentPlugins() const override;
|
||||||
|
QString itemKey(PluginsItemInterface *itemInter) const override;
|
||||||
|
QJsonObject metaData(PluginsItemInterface *itemInter) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList getPluginPaths() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<DockPluginController> m_dockController;
|
||||||
|
QSharedPointer<QuickSettingContainer> m_quickContainer;
|
||||||
|
QSharedPointer<IconManager> m_iconManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLUGINMANAGER_H
|
4
plugins/pluginmanager/pluginmanager.json
Normal file
4
plugins/pluginmanager/pluginmanager.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"api": "2.0.0",
|
||||||
|
"order":0
|
||||||
|
}
|
5
plugins/pluginmanager/pluginmanager.qrc
Normal file
5
plugins/pluginmanager/pluginmanager.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>resources/dock_control.dci</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
415
plugins/pluginmanager/quicksettingcontainer.cpp
Normal file
415
plugins/pluginmanager/quicksettingcontainer.cpp
Normal file
@ -0,0 +1,415 @@
|
|||||||
|
/*
|
||||||
|
* 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 "quicksettingcontainer.h"
|
||||||
|
#include "dockplugincontroller.h"
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
#include "quicksettingitem.h"
|
||||||
|
#include "pluginchildpage.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "quickdragcore.h"
|
||||||
|
|
||||||
|
#include <DListView>
|
||||||
|
#include <DStyle>
|
||||||
|
|
||||||
|
#include <QDrag>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <QStackedLayout>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QBitmap>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
|
DWIDGET_USE_NAMESPACE
|
||||||
|
|
||||||
|
struct QuickDragInfo {
|
||||||
|
QPoint dragPosition;
|
||||||
|
QWidget *dragItem = nullptr;
|
||||||
|
PluginsItemInterface *pluginInter = nullptr;
|
||||||
|
void reset() {
|
||||||
|
dragPosition.setX(0);
|
||||||
|
dragPosition.setY(0);
|
||||||
|
dragItem = nullptr;
|
||||||
|
pluginInter = nullptr;
|
||||||
|
}
|
||||||
|
bool isNull() {
|
||||||
|
return !dragItem;
|
||||||
|
}
|
||||||
|
} QuickDragInfo;
|
||||||
|
|
||||||
|
#define ITEMWIDTH 70
|
||||||
|
#define ITEMHEIGHT 60
|
||||||
|
#define ITEMSPACE 10
|
||||||
|
#define COLUMNCOUNT 4
|
||||||
|
|
||||||
|
QuickSettingContainer::QuickSettingContainer(DockPluginController *pluginController, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_switchLayout(new QStackedLayout(this))
|
||||||
|
, m_mainWidget(new QWidget(this))
|
||||||
|
, m_pluginWidget(new QWidget(m_mainWidget))
|
||||||
|
, m_pluginLayout(new QGridLayout(m_pluginWidget))
|
||||||
|
, m_componentWidget(new QWidget(m_mainWidget))
|
||||||
|
, m_mainlayout(new QVBoxLayout(m_mainWidget))
|
||||||
|
, m_pluginController(pluginController)
|
||||||
|
, m_childPage(new PluginChildPage(this))
|
||||||
|
, m_dragInfo(new struct QuickDragInfo)
|
||||||
|
, m_childShowPlugin(nullptr)
|
||||||
|
{
|
||||||
|
initUi();
|
||||||
|
initConnection();
|
||||||
|
m_childPage->installEventFilter(this);
|
||||||
|
setMouseTracking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickSettingContainer::~QuickSettingContainer()
|
||||||
|
{
|
||||||
|
delete m_dragInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::showPage(QWidget *widget, PluginsItemInterface *pluginInter)
|
||||||
|
{
|
||||||
|
if (widget && pluginInter && widget != m_mainWidget) {
|
||||||
|
m_childShowPlugin = pluginInter;
|
||||||
|
m_childPage->setTitle(pluginInter->pluginDisplayName());
|
||||||
|
m_childPage->pushWidget(widget);
|
||||||
|
m_switchLayout->setCurrentWidget(m_childPage);
|
||||||
|
} else {
|
||||||
|
m_childShowPlugin = nullptr;
|
||||||
|
m_switchLayout->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
onResizeView();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuickSettingContainer::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::Resize: {
|
||||||
|
onResizeView();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::MouseButtonPress: {
|
||||||
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
|
QuickSettingItem *item = qobject_cast<QuickSettingItem *>(watched);
|
||||||
|
if (item) {
|
||||||
|
m_dragInfo->dragPosition = mouseEvent->pos();
|
||||||
|
m_dragInfo->dragItem = item;
|
||||||
|
m_dragInfo->pluginInter = item->pluginItem();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::MouseButtonRelease: {
|
||||||
|
m_dragInfo->reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::showEvent(QShowEvent *event)
|
||||||
|
{
|
||||||
|
// 当面板显示的时候,直接默认显示快捷面板的窗口
|
||||||
|
QWidget::showEvent(event);
|
||||||
|
if (m_switchLayout->currentWidget() != m_mainWidget) {
|
||||||
|
m_childPage->pushWidget(nullptr);
|
||||||
|
m_switchLayout->setCurrentWidget(m_mainWidget);
|
||||||
|
onResizeView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::appendPlugin(PluginsItemInterface *itemInter, QString itemKey, bool needLayout)
|
||||||
|
{
|
||||||
|
QuickSettingItem *quickItem = QuickSettingFactory::createQuickWidget(itemInter, itemKey);
|
||||||
|
if (!quickItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
quickItem->setParent(m_pluginWidget);
|
||||||
|
quickItem->setMouseTracking(true);
|
||||||
|
quickItem->installEventFilter(this);
|
||||||
|
connect(quickItem, &QuickSettingItem::requestShowChildWidget, this, &QuickSettingContainer::onShowChildWidget);
|
||||||
|
m_quickSettings << quickItem;
|
||||||
|
if (quickItem->type() == QuickSettingItem::QuickItemStyle::Line) {
|
||||||
|
// 插件位置占据整行,例如声音、亮度和音乐等
|
||||||
|
m_componentWidget->layout()->addWidget(quickItem);
|
||||||
|
updateFullItemLayout();
|
||||||
|
} else if (needLayout) {
|
||||||
|
// 插件占据两行或者一行
|
||||||
|
updateItemLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
onResizeView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::onPluginRemove(PluginsItemInterface *itemInter)
|
||||||
|
{
|
||||||
|
QList<QuickSettingItem *>::Iterator removeItemIter = std::find_if(m_quickSettings.begin(), m_quickSettings.end(), [ = ](QuickSettingItem *item)->bool {
|
||||||
|
return item->pluginItem() == itemInter;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (removeItemIter == m_quickSettings.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QuickSettingItem *removeItem = *removeItemIter;
|
||||||
|
removeItem->detachPlugin();
|
||||||
|
|
||||||
|
if (removeItem->type() == QuickSettingItem::QuickItemStyle::Line)
|
||||||
|
m_componentWidget->layout()->removeWidget(removeItem);
|
||||||
|
else
|
||||||
|
m_pluginLayout->removeWidget(removeItem);
|
||||||
|
|
||||||
|
m_quickSettings.removeOne(removeItem);
|
||||||
|
removeItem->deleteLater();
|
||||||
|
if (m_childShowPlugin == itemInter)
|
||||||
|
showPage(nullptr);
|
||||||
|
|
||||||
|
updateItemLayout();
|
||||||
|
updateFullItemLayout();
|
||||||
|
onResizeView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::onShowChildWidget(QWidget *childWidget)
|
||||||
|
{
|
||||||
|
QuickSettingItem *quickWidget = qobject_cast<QuickSettingItem *>(sender());
|
||||||
|
if (!quickWidget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
showPage(childWidget, quickWidget->pluginItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (m_dragInfo->isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QPoint pointCurrent = event->pos();
|
||||||
|
if (qAbs(m_dragInfo->dragPosition.x() - pointCurrent.x()) > 5
|
||||||
|
|| qAbs(m_dragInfo->dragPosition.y() - pointCurrent.y()) > 5) {
|
||||||
|
QuickSettingItem *moveItem = qobject_cast<QuickSettingItem *>(m_dragInfo->dragItem);
|
||||||
|
QuickIconDrag *drag = new QuickIconDrag(this, moveItem->dragPixmap());
|
||||||
|
QuickPluginMimeData *mimedata = new QuickPluginMimeData(m_dragInfo->pluginInter, drag);
|
||||||
|
drag->setMimeData(mimedata);
|
||||||
|
drag->setDragHotPot(m_dragInfo->dragPosition);
|
||||||
|
|
||||||
|
m_dragInfo->reset();
|
||||||
|
drag->exec(Qt::CopyAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::updateItemLayout()
|
||||||
|
{
|
||||||
|
// 清空之前的控件,重新添加
|
||||||
|
while (m_pluginLayout->count() > 0)
|
||||||
|
m_pluginLayout->takeAt(0);
|
||||||
|
|
||||||
|
// 将插件按照两列和一列的顺序来进行排序
|
||||||
|
QMap<QuickSettingItem::QuickItemStyle, QList<QuickSettingItem *>> quickSettings;
|
||||||
|
QMap<QuickSettingItem::QuickItemStyle, QMap<QuickSettingItem *, int>> orderQuickSettings;
|
||||||
|
for (QuickSettingItem *item : m_quickSettings) {
|
||||||
|
QuickSettingItem::QuickItemStyle type = item->type();
|
||||||
|
if (type == QuickSettingItem::QuickItemStyle::Line)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QJsonObject metaData = m_pluginController->metaData(item->pluginItem());
|
||||||
|
if (metaData.contains("order"))
|
||||||
|
orderQuickSettings[type][item] = metaData.value("order").toInt();
|
||||||
|
else
|
||||||
|
quickSettings[type] << item;
|
||||||
|
}
|
||||||
|
// 将需要排序的插件按照顺序插入到原来的数组中
|
||||||
|
for (auto itQuick = orderQuickSettings.begin(); itQuick != orderQuickSettings.end(); itQuick++) {
|
||||||
|
QuickSettingItem::QuickItemStyle type = itQuick.key();
|
||||||
|
QMap<QuickSettingItem *, int> &orderQuicks = itQuick.value();
|
||||||
|
for (auto it = orderQuicks.begin(); it != orderQuicks.end(); it++) {
|
||||||
|
int index = it.value();
|
||||||
|
if (index >= 0 && index < quickSettings[type].size())
|
||||||
|
quickSettings[type][index] = it.key();
|
||||||
|
else
|
||||||
|
quickSettings[type] << it.key();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto insertQuickSetting = [ quickSettings, this ](QuickSettingItem::QuickItemStyle type, int &row, int &column) {
|
||||||
|
if (!quickSettings.contains(type))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int usedColumn = (type == QuickSettingItem::QuickItemStyle::Larger ? 2 : 1);
|
||||||
|
QList<QuickSettingItem *> quickPlugins = quickSettings[type];
|
||||||
|
for (QuickSettingItem *quickItem : quickPlugins) {
|
||||||
|
quickItem->setVisible(true);
|
||||||
|
m_pluginLayout->addWidget(quickItem, row, column, 1, usedColumn);
|
||||||
|
column += usedColumn;
|
||||||
|
if (column >= COLUMNCOUNT) {
|
||||||
|
row++;
|
||||||
|
column = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
int column = 0;
|
||||||
|
insertQuickSetting(QuickSettingItem::QuickItemStyle::Larger, row, column);
|
||||||
|
insertQuickSetting(QuickSettingItem::QuickItemStyle::Standard, row, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::updateFullItemLayout()
|
||||||
|
{
|
||||||
|
while (m_componentWidget->layout()->count() > 0)
|
||||||
|
m_componentWidget->layout()->takeAt(0);
|
||||||
|
|
||||||
|
QList<QuickSettingItem *> fullItems;
|
||||||
|
QMap<QuickSettingItem *, int> fullItemOrder;
|
||||||
|
for (QuickSettingItem *item : m_quickSettings) {
|
||||||
|
if (item->type() != QuickSettingItem::QuickItemStyle::Line)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fullItems << item;
|
||||||
|
int order = -1;
|
||||||
|
QJsonObject metaData = m_pluginController->metaData(item->pluginItem());
|
||||||
|
if (metaData.contains("order"))
|
||||||
|
order = metaData.value("order").toInt();
|
||||||
|
|
||||||
|
fullItemOrder[item] = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(fullItems.begin(), fullItems.end(), [ fullItemOrder, fullItems ](QuickSettingItem *item1, QuickSettingItem *item2) {
|
||||||
|
int order1 = fullItemOrder.value(item1, -1);
|
||||||
|
int order2 = fullItemOrder.value(item2, -1);
|
||||||
|
if (order1 == order2) {
|
||||||
|
// 如果两个值相等,就根据他们的加载顺序进行排序
|
||||||
|
return fullItems.indexOf(item1) < fullItems.indexOf(item2);
|
||||||
|
}
|
||||||
|
if (order1 == -1)
|
||||||
|
return false;
|
||||||
|
if (order2 == -1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return order1 < order2;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (QuickSettingItem *item : fullItems) {
|
||||||
|
item->setVisible(true);
|
||||||
|
m_componentWidget->layout()->addWidget(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::initUi()
|
||||||
|
{
|
||||||
|
m_mainlayout->setSpacing(ITEMSPACE);
|
||||||
|
m_mainlayout->setContentsMargins(ITEMSPACE, ITEMSPACE, ITEMSPACE, ITEMSPACE);
|
||||||
|
|
||||||
|
m_pluginLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
m_pluginLayout->setSpacing(ITEMSPACE);
|
||||||
|
m_pluginLayout->setAlignment(Qt::AlignLeft);
|
||||||
|
for (int i = 0; i < COLUMNCOUNT; i++)
|
||||||
|
m_pluginLayout->setColumnMinimumWidth(i, ITEMWIDTH);
|
||||||
|
|
||||||
|
m_pluginWidget->setLayout(m_pluginLayout);
|
||||||
|
m_mainlayout->addWidget(m_pluginWidget);
|
||||||
|
|
||||||
|
QVBoxLayout *ctrlLayout = new QVBoxLayout(m_componentWidget);
|
||||||
|
ctrlLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
ctrlLayout->setSpacing(ITEMSPACE);
|
||||||
|
ctrlLayout->setDirection(QBoxLayout::BottomToTop);
|
||||||
|
|
||||||
|
m_mainlayout->addWidget(m_componentWidget);
|
||||||
|
// 加载所有的可以在快捷面板显示的插件
|
||||||
|
QList<PluginsItemInterface *> plugins = m_pluginController->currentPlugins();
|
||||||
|
for (PluginsItemInterface *plugin : plugins) {
|
||||||
|
appendPlugin(plugin, m_pluginController->itemKey(plugin), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_switchLayout->addWidget(m_mainWidget);
|
||||||
|
m_switchLayout->addWidget(m_childPage);
|
||||||
|
|
||||||
|
setMouseTracking(true);
|
||||||
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(this, [ = ] {
|
||||||
|
if (plugins.size() > 0) {
|
||||||
|
updateItemLayout();
|
||||||
|
updateFullItemLayout();
|
||||||
|
}
|
||||||
|
// 设置当前窗口的大小
|
||||||
|
onResizeView();
|
||||||
|
setFixedWidth(ITEMWIDTH * 4 + (ITEMSPACE * 5));
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::initConnection()
|
||||||
|
{
|
||||||
|
connect(m_pluginController, &DockPluginController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, QString itemKey) {
|
||||||
|
appendPlugin(itemInter, itemKey);
|
||||||
|
});
|
||||||
|
connect(m_pluginController, &DockPluginController::pluginRemoved, this, &QuickSettingContainer::onPluginRemove);
|
||||||
|
connect(m_pluginController, &DockPluginController::pluginUpdated, this, &QuickSettingContainer::onPluginUpdated);
|
||||||
|
|
||||||
|
connect(m_childPage, &PluginChildPage::back, this, [ this ] {
|
||||||
|
showPage(m_mainWidget);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调整尺寸
|
||||||
|
void QuickSettingContainer::onResizeView()
|
||||||
|
{
|
||||||
|
if (m_switchLayout->currentWidget() == m_mainWidget) {
|
||||||
|
int selfPluginCount = 0;
|
||||||
|
int fullItemHeight = 0;
|
||||||
|
int widgetCount = 0;
|
||||||
|
for (QuickSettingItem *item : m_quickSettings) {
|
||||||
|
item->setFixedHeight(ITEMHEIGHT);
|
||||||
|
if (item->type() == QuickSettingItem::QuickItemStyle::Line) {
|
||||||
|
fullItemHeight += item->height();
|
||||||
|
widgetCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 如果是置顶的插件,则认为它占用两个普通插件的位置
|
||||||
|
int increCount = (item->type() == QuickSettingItem::QuickItemStyle::Larger ? 2 : 1);
|
||||||
|
selfPluginCount += increCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rowCount = selfPluginCount / COLUMNCOUNT;
|
||||||
|
if (selfPluginCount % COLUMNCOUNT > 0)
|
||||||
|
rowCount++;
|
||||||
|
|
||||||
|
m_pluginWidget->setFixedHeight(ITEMHEIGHT * rowCount + ITEMSPACE * (rowCount - 1));
|
||||||
|
m_componentWidget->setFixedHeight(fullItemHeight + (widgetCount - 1) * ITEMSPACE);
|
||||||
|
|
||||||
|
setFixedHeight(ITEMSPACE * 3 + m_pluginWidget->height() + m_componentWidget->height());
|
||||||
|
} else if (m_switchLayout->currentWidget() == m_childPage) {
|
||||||
|
setFixedHeight(m_childPage->height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingContainer::onPluginUpdated(PluginsItemInterface *itemInter, const DockPart dockPart)
|
||||||
|
{
|
||||||
|
if (dockPart != DockPart::QuickPanel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (QuickSettingItem *settingItem : m_quickSettings) {
|
||||||
|
if (settingItem->pluginItem() != itemInter)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
settingItem->doUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
94
plugins/pluginmanager/quicksettingcontainer.h
Normal file
94
plugins/pluginmanager/quicksettingcontainer.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef QUICKSETTINGCONTAINER_H
|
||||||
|
#define QUICKSETTINGCONTAINER_H
|
||||||
|
|
||||||
|
#include "pluginproxyinterface.h"
|
||||||
|
|
||||||
|
#include "dtkwidget_global.h"
|
||||||
|
|
||||||
|
#include <DListView>
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class DockItem;
|
||||||
|
class QVBoxLayout;
|
||||||
|
class DockPluginController;
|
||||||
|
class BrightnessModel;
|
||||||
|
class BrightnessWidget;
|
||||||
|
class QuickSettingItem;
|
||||||
|
class QStackedLayout;
|
||||||
|
class VolumeDevicesWidget;
|
||||||
|
class QLabel;
|
||||||
|
class PluginChildPage;
|
||||||
|
class QGridLayout;
|
||||||
|
class DisplaySettingWidget;
|
||||||
|
struct QuickDragInfo;
|
||||||
|
|
||||||
|
DWIDGET_USE_NAMESPACE
|
||||||
|
|
||||||
|
class QuickSettingContainer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
void showPage(QWidget *widget, PluginsItemInterface *pluginInter = nullptr);
|
||||||
|
explicit QuickSettingContainer(DockPluginController *pluginController, QWidget *parent = nullptr);
|
||||||
|
~QuickSettingContainer() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
void showEvent(QShowEvent *event) override;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onPluginRemove(PluginsItemInterface *itemInter);
|
||||||
|
void onShowChildWidget(QWidget *childWidget);
|
||||||
|
void onResizeView();
|
||||||
|
void onPluginUpdated(PluginsItemInterface *itemInter, const DockPart dockPart);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 加载UI
|
||||||
|
void initUi();
|
||||||
|
// 初始化槽函数
|
||||||
|
void initConnection();
|
||||||
|
// 调整控件位置
|
||||||
|
void updateItemLayout();
|
||||||
|
// 调整全列插件的位置
|
||||||
|
void updateFullItemLayout();
|
||||||
|
// 插入插件
|
||||||
|
void appendPlugin(PluginsItemInterface *itemInter, QString itemKey, bool needLayout = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStackedLayout *m_switchLayout;
|
||||||
|
QWidget *m_mainWidget;
|
||||||
|
QWidget *m_pluginWidget;
|
||||||
|
QGridLayout *m_pluginLayout;
|
||||||
|
QWidget *m_componentWidget;
|
||||||
|
QVBoxLayout *m_mainlayout;
|
||||||
|
DockPluginController *m_pluginController;
|
||||||
|
PluginChildPage *m_childPage;
|
||||||
|
QuickDragInfo *m_dragInfo;
|
||||||
|
QList<QuickSettingItem *> m_quickSettings;
|
||||||
|
PluginsItemInterface *m_childShowPlugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLUGINCONTAINER_H
|
148
plugins/pluginmanager/quicksettingitem.cpp
Normal file
148
plugins/pluginmanager/quicksettingitem.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* 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 "quicksettingitem.h"
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
#include "imageutil.h"
|
||||||
|
#include "largerquickitem.h"
|
||||||
|
#include "standardquickitem.h"
|
||||||
|
#include "linequickitem.h"
|
||||||
|
|
||||||
|
#include <DGuiApplicationHelper>
|
||||||
|
#include <DFontSizeManager>
|
||||||
|
#include <DPaletteHelper>
|
||||||
|
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QPainterPath>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#define ICONWIDTH 24
|
||||||
|
#define ICONHEIGHT 24
|
||||||
|
#define ICONSPACE 10
|
||||||
|
#define RADIUS 8
|
||||||
|
#define FONTSIZE 10
|
||||||
|
|
||||||
|
#define BGWIDTH 128
|
||||||
|
#define BGSIZE 36
|
||||||
|
#define MARGINLEFTSPACE 10
|
||||||
|
#define OPENICONSIZE 12
|
||||||
|
#define MARGINRIGHTSPACE 9
|
||||||
|
|
||||||
|
DWIDGET_USE_NAMESPACE
|
||||||
|
|
||||||
|
QuickSettingItem::QuickSettingItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_pluginInter(pluginInter)
|
||||||
|
, m_itemKey(itemKey)
|
||||||
|
{
|
||||||
|
setAcceptDrops(true);
|
||||||
|
this->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickSettingItem::~QuickSettingItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginsItemInterface *QuickSettingItem::pluginItem() const
|
||||||
|
{
|
||||||
|
return m_pluginInter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QPixmap QuickSettingItem::dragPixmap()
|
||||||
|
{
|
||||||
|
QPixmap pluginPixmap = m_pluginInter->icon(DockPart::QuickPanel, DGuiApplicationHelper::instance()->themeType()).pixmap(ICONWIDTH, ICONHEIGHT);
|
||||||
|
|
||||||
|
QPainter foregroundPainter(&pluginPixmap);
|
||||||
|
foregroundPainter.setPen(foregroundColor());
|
||||||
|
foregroundPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||||
|
foregroundPainter.fillRect(pluginPixmap.rect(), foregroundColor());
|
||||||
|
|
||||||
|
QPixmap pixmapDrag(ICONWIDTH + ICONSPACE + FONTSIZE * 2, ICONHEIGHT + ICONSPACE + FONTSIZE * 2);
|
||||||
|
pixmapDrag.fill(Qt::transparent);
|
||||||
|
QPainter painter(&pixmapDrag);
|
||||||
|
painter.drawPixmap(QPoint((ICONSPACE + FONTSIZE * 2) / 2, 0), pluginPixmap);
|
||||||
|
painter.setPen(foregroundPainter.pen());
|
||||||
|
|
||||||
|
QFont font;
|
||||||
|
font.setPixelSize(FONTSIZE);
|
||||||
|
painter.setFont(font);
|
||||||
|
QTextOption option;
|
||||||
|
option.setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
||||||
|
painter.drawText(QRect(QPoint(0, ICONHEIGHT + ICONSPACE),
|
||||||
|
QPoint(pixmapDrag.width(), pixmapDrag.height())), m_pluginInter->pluginDisplayName(), option);
|
||||||
|
return pixmapDrag;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString QuickSettingItem::itemKey() const
|
||||||
|
{
|
||||||
|
return m_itemKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickSettingItem::paintEvent(QPaintEvent *e)
|
||||||
|
{
|
||||||
|
QWidget::paintEvent(e);
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter::RenderHint::Antialiasing);
|
||||||
|
painter.setPen(foregroundColor());
|
||||||
|
QPainterPath path;
|
||||||
|
path.addRoundedRect(rect(), RADIUS, RADIUS);
|
||||||
|
painter.setClipPath(path);
|
||||||
|
// 绘制背景色
|
||||||
|
QColor backColor(Qt::white);
|
||||||
|
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::DarkType) {
|
||||||
|
backColor = Qt::black;
|
||||||
|
backColor.setAlphaF(0.5);
|
||||||
|
}
|
||||||
|
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||||
|
painter.fillRect(rect(), backColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor QuickSettingItem::foregroundColor() const
|
||||||
|
{
|
||||||
|
DPalette dpa = DPaletteHelper::instance()->palette(this);
|
||||||
|
// TODO: 此处的颜色是临时获取的,后期需要和设计师确认,改成正规的颜色
|
||||||
|
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Active)
|
||||||
|
return dpa.color(DPalette::ColorGroup::Active, DPalette::ColorRole::Text);
|
||||||
|
|
||||||
|
if (m_pluginInter->status() == PluginsItemInterface::PluginMode::Deactive)
|
||||||
|
return dpa.color(DPalette::ColorGroup::Disabled, DPalette::ColorRole::Text);
|
||||||
|
|
||||||
|
return dpa.color(DPalette::ColorGroup::Normal, DPalette::ColorRole::Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickSettingItem *QuickSettingFactory::createQuickWidget(PluginsItemInterface * const pluginInter, const QString &itemKey)
|
||||||
|
{
|
||||||
|
// 如果显示在面板的图标或者Widget为空,则不让显示(例如电池插件)
|
||||||
|
if (!(pluginInter->flags() & PluginFlag::Type_Common))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (pluginInter->flags() & PluginFlag::Quick_Multi)
|
||||||
|
return new LargerQuickItem(pluginInter, itemKey);
|
||||||
|
|
||||||
|
if (pluginInter->flags() & PluginFlag::Quick_Full)
|
||||||
|
return new LineQuickItem(pluginInter, itemKey);
|
||||||
|
|
||||||
|
if (pluginInter->flags() & PluginFlag::Quick_Single)
|
||||||
|
return new StandardQuickItem(pluginInter, itemKey);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
69
plugins/pluginmanager/quicksettingitem.h
Normal file
69
plugins/pluginmanager/quicksettingitem.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef QUICKSETTINGITEM_H
|
||||||
|
#define QUICKSETTINGITEM_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class PluginsItemInterface;
|
||||||
|
class QuickIconWidget;
|
||||||
|
|
||||||
|
class QuickSettingItem : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class QuickItemStyle {
|
||||||
|
Standard = 1, // 插件的UI显示单列
|
||||||
|
Larger, // 插件的UI显示双列,例如网络和蓝牙等
|
||||||
|
Line // 插件的UI整行显示,例如声音,亮度、音乐播放等
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
QuickSettingItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||||
|
~QuickSettingItem() override;
|
||||||
|
PluginsItemInterface *pluginItem() const;
|
||||||
|
virtual const QPixmap dragPixmap();
|
||||||
|
virtual void doUpdate() {}
|
||||||
|
virtual void detachPlugin() {}
|
||||||
|
const QString itemKey() const;
|
||||||
|
|
||||||
|
virtual QuickItemStyle type() const = 0;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void requestShowChildWidget(QWidget *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
QColor foregroundColor() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginsItemInterface *m_pluginInter;
|
||||||
|
QString m_itemKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QuickSettingFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static QuickSettingItem *createQuickWidget(PluginsItemInterface *const pluginInter, const QString &itemKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QUICKSETTINGITEM_H
|
BIN
plugins/pluginmanager/resources/dock_control.dci
Normal file
BIN
plugins/pluginmanager/resources/dock_control.dci
Normal file
Binary file not shown.
200
plugins/pluginmanager/standardquickitem.cpp
Normal file
200
plugins/pluginmanager/standardquickitem.cpp
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* 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 "standardquickitem.h"
|
||||||
|
#include "pluginsiteminterface.h"
|
||||||
|
|
||||||
|
#include <DFontSizeManager>
|
||||||
|
#include <DGuiApplicationHelper>
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
#define ICONHEIGHT 24
|
||||||
|
#define ICONWIDTH 24
|
||||||
|
#define TEXTHEIGHT 11
|
||||||
|
|
||||||
|
DWIDGET_USE_NAMESPACE
|
||||||
|
|
||||||
|
StandardQuickItem::StandardQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent)
|
||||||
|
: QuickSettingItem(pluginInter, itemKey, parent)
|
||||||
|
, m_itemParentWidget(nullptr)
|
||||||
|
, m_needPaint(true)
|
||||||
|
{
|
||||||
|
initUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardQuickItem::~StandardQuickItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickSettingItem::QuickItemStyle StandardQuickItem::type() const
|
||||||
|
{
|
||||||
|
return QuickSettingItem::QuickItemStyle::Standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardQuickItem::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event);
|
||||||
|
QStringList commandArgument = pluginItem()->itemCommand(itemKey()).split(" ");
|
||||||
|
if (commandArgument.size() > 0) {
|
||||||
|
QString command = commandArgument.first();
|
||||||
|
commandArgument.removeFirst();
|
||||||
|
QProcess::startDetached(command, commandArgument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardQuickItem::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
doUpdate();
|
||||||
|
QuickSettingItem::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardQuickItem::initUi()
|
||||||
|
{
|
||||||
|
QWidget *topWidget = iconWidget(this);
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->addWidget(topWidget);
|
||||||
|
installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *StandardQuickItem::iconWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
// 显示图标的窗体
|
||||||
|
QWidget *widget = new QWidget(parent);
|
||||||
|
m_needPaint = true;
|
||||||
|
QIcon icon = pluginItem()->icon(DockPart::QuickPanel);
|
||||||
|
if (icon.isNull()) {
|
||||||
|
// 如果图标为空,则将获取itemWidget作为它的显示
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (itemWidget) {
|
||||||
|
m_itemParentWidget = itemWidget->parentWidget();
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout(widget);
|
||||||
|
layout->setContentsMargins(0, 0, 0 ,0);
|
||||||
|
itemWidget->setParent(widget);
|
||||||
|
layout->addWidget(itemWidget);
|
||||||
|
itemWidget->setVisible(true);
|
||||||
|
m_needPaint = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_needPaint) {
|
||||||
|
// 如果没有子窗体,则需要添加下方的文字
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(widget);
|
||||||
|
layout->setAlignment(Qt::AlignVCenter);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
QLabel *imageLabel = new QLabel(widget);
|
||||||
|
imageLabel->setObjectName("imageLabel");
|
||||||
|
imageLabel->setFixedHeight(ICONHEIGHT);
|
||||||
|
imageLabel->setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
|
QLabel *labelText = new QLabel(widget);
|
||||||
|
labelText->setObjectName("textLabel");
|
||||||
|
labelText->setFixedHeight(TEXTHEIGHT);
|
||||||
|
updatePluginName(labelText);
|
||||||
|
labelText->setAlignment(Qt::AlignCenter);
|
||||||
|
labelText->setFont(DFontSizeManager::instance()->t10());
|
||||||
|
layout->addWidget(imageLabel);
|
||||||
|
layout->addSpacing(7);
|
||||||
|
layout->addWidget(labelText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap StandardQuickItem::pixmap() const
|
||||||
|
{
|
||||||
|
// 如果快捷面板区域的图标为空,那么就获取itemWidget的截图
|
||||||
|
QIcon icon = pluginItem()->icon(DockPart::QuickPanel);
|
||||||
|
if (icon.isNull())
|
||||||
|
return QPixmap();
|
||||||
|
|
||||||
|
int pixmapWidth = ICONWIDTH;
|
||||||
|
int pixmapHeight = ICONHEIGHT;
|
||||||
|
QList<QSize> iconSizes = icon.availableSizes();
|
||||||
|
if (iconSizes.size() > 0) {
|
||||||
|
QSize size = iconSizes[0];
|
||||||
|
if (size.isValid() && !size.isEmpty() && !size.isNull()) {
|
||||||
|
pixmapWidth = size.width();
|
||||||
|
pixmapHeight = size.height();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return icon.pixmap(pixmapWidth / qApp->devicePixelRatio(), pixmapHeight / qApp->devicePixelRatio());
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel *StandardQuickItem::findChildLabel(QWidget *parent, const QString &childObjectName) const
|
||||||
|
{
|
||||||
|
QList<QObject *> childrends = parent->children();
|
||||||
|
for (QObject *child : childrends) {
|
||||||
|
QWidget *widget = qobject_cast<QWidget *>(child);
|
||||||
|
if (!widget)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QLabel *label = qobject_cast<QLabel *>(child);
|
||||||
|
if (label && widget->objectName() == childObjectName)
|
||||||
|
return label;
|
||||||
|
|
||||||
|
label = findChildLabel(widget, childObjectName);
|
||||||
|
if (label)
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardQuickItem::updatePluginName(QLabel *textLabel)
|
||||||
|
{
|
||||||
|
if (!textLabel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString text = pluginItem()->description();
|
||||||
|
if (text.isEmpty())
|
||||||
|
text = pluginItem()->pluginDisplayName();
|
||||||
|
QFontMetrics ftm(textLabel->font());
|
||||||
|
text = ftm.elidedText(text, Qt::TextElideMode::ElideRight, textLabel->width());
|
||||||
|
textLabel->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardQuickItem::doUpdate()
|
||||||
|
{
|
||||||
|
if (m_needPaint) {
|
||||||
|
QLabel *imageLabel = findChildLabel(this, "imageLabel");
|
||||||
|
if (imageLabel) {
|
||||||
|
// 更新图像
|
||||||
|
imageLabel->setPixmap(pixmap());
|
||||||
|
}
|
||||||
|
updatePluginName(findChildLabel(this, "textLabel"));
|
||||||
|
} else {
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (itemWidget)
|
||||||
|
itemWidget->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StandardQuickItem::detachPlugin()
|
||||||
|
{
|
||||||
|
QWidget *itemWidget = pluginItem()->itemWidget(QUICK_ITEM_KEY);
|
||||||
|
if (itemWidget && !m_needPaint)
|
||||||
|
itemWidget->setParent(m_itemParentWidget);
|
||||||
|
}
|
57
plugins/pluginmanager/standardquickitem.h
Normal file
57
plugins/pluginmanager/standardquickitem.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#ifndef STANDARDQUICKITEM_H
|
||||||
|
#define STANDARDQUICKITEM_H
|
||||||
|
|
||||||
|
#include "quicksettingitem.h"
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
|
// 插件在快捷面板中展示的样式,这个为默认,展示一行一列的那种
|
||||||
|
class StandardQuickItem : public QuickSettingItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
StandardQuickItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = nullptr);
|
||||||
|
~StandardQuickItem() override;
|
||||||
|
|
||||||
|
QuickItemStyle type() const override;
|
||||||
|
void doUpdate() override;
|
||||||
|
void detachPlugin() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initUi();
|
||||||
|
QWidget *iconWidget(QWidget *parent);
|
||||||
|
QPixmap pixmap() const;
|
||||||
|
QLabel *findChildLabel(QWidget *parent, const QString &childObjectName) const;
|
||||||
|
void updatePluginName(QLabel *textLabel);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *m_itemParentWidget;
|
||||||
|
bool m_needPaint;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SINGLEQUICKITEM_H
|
Loading…
x
Reference in New Issue
Block a user