From c474ae7b23a45dfbccb4d19a8102b73eb28da1f3 Mon Sep 17 00:00:00 2001 From: donghualin Date: Thu, 27 Oct 2022 07:03:28 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=93=9D=E7=89=99=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E9=80=82=E5=BA=94=E5=BF=AB=E6=8D=B7=E6=8F=92=E4=BB=B6=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 蓝牙插件增加PluginsItemInterface的新增接口,适应快捷面板的功能 Log: Influence: 任务栏-快捷设置-蓝牙 Task: https://pms.uniontech.com/task-view-121387.html Change-Id: I324233d5b2a4dae3b7ede2ad10ccf9afb7cfd401 --- debian/dde-dock.install | 1 + frame/window/quicksettingcontainer.cpp | 24 +- frame/window/quicksettingcontainer.h | 3 +- interfaces/pluginsiteminterface.h | 2 + plugins/bluetooth/CMakeLists.txt | 4 +- plugins/bluetooth/bloothadapterwidget.cpp | 210 ++++++++++++++++++ plugins/bluetooth/bloothadapterwidget.h | 73 ++++++ plugins/bluetooth/bluetooth.json | 1 + plugins/bluetooth/bluetoothitem.cpp | 19 +- plugins/bluetooth/bluetoothitem.h | 4 +- plugins/bluetooth/bluetoothplugin.cpp | 36 ++- plugins/bluetooth/bluetoothplugin.h | 9 + plugins/bluetooth/bluetoothwidget.cpp | 137 ++++++++++++ plugins/bluetooth/bluetoothwidget.h | 62 ++++++ .../bluetooth/componments/adaptersmanager.cpp | 46 ++-- .../bluetooth/componments/adaptersmanager.h | 1 + .../bluetooth/componments/bluetoothapplet.cpp | 9 +- .../bluetooth/componments/bluetoothapplet.h | 4 +- 18 files changed, 600 insertions(+), 45 deletions(-) create mode 100644 plugins/bluetooth/bloothadapterwidget.cpp create mode 100644 plugins/bluetooth/bloothadapterwidget.h create mode 100644 plugins/bluetooth/bluetoothwidget.cpp create mode 100644 plugins/bluetooth/bluetoothwidget.h diff --git a/debian/dde-dock.install b/debian/dde-dock.install index 1091cba33..1de3b1685 100644 --- a/debian/dde-dock.install +++ b/debian/dde-dock.install @@ -7,6 +7,7 @@ usr/lib/dde-dock/plugins/libtrash.so usr/lib/dde-dock/plugins/libtray.so usr/lib/dde-dock/plugins/liboverlay-warning.so usr/lib/dde-dock/plugins/system-trays +usr/lib/dde-dock/plugins/quick-trays usr/lib/dde-dock/plugins/libmultitasking.so usr/lib/dde-dock/plugins/libshow-desktop.so usr/lib/dde-dock/plugins/system-trays/libkeyboard-layout.so diff --git a/frame/window/quicksettingcontainer.cpp b/frame/window/quicksettingcontainer.cpp index 83549ea80..82205c1bd 100644 --- a/frame/window/quicksettingcontainer.cpp +++ b/frame/window/quicksettingcontainer.cpp @@ -158,17 +158,18 @@ void QuickSettingContainer::onItemDetailClick(PluginsItemInterface *pluginInter) if (!quickItemWidget) return; - QWidget *widget = pluginInter->itemWidget(quickItemWidget->itemKey()); + QWidget *widget = pluginInter->itemPopupApplet(QUICK_ITEM_DETAIL_KEY); if (!widget) return; showWidget(widget, pluginInter->pluginDisplayName()); + onResizeView(); } bool QuickSettingContainer::eventFilter(QObject *watched, QEvent *event) { if (watched == m_childPage && event->type() == QEvent::Resize) - resizeView(); + onResizeView(); return QWidget::eventFilter(watched, event); } @@ -184,7 +185,7 @@ void QuickSettingContainer::onPluginInsert(QuickSettingItem *quickItem) { initQuickItem(quickItem); updateItemLayout(); - resizeView(); + onResizeView(); } void QuickSettingContainer::onPluginRemove(QuickSettingItem *quickItem) @@ -196,7 +197,7 @@ void QuickSettingContainer::onPluginRemove(QuickSettingItem *quickItem) //调整子控件的位置 updateItemLayout(); - resizeView(); + onResizeView(); } void QuickSettingContainer::mousePressEvent(QMouseEvent *event) @@ -324,7 +325,7 @@ void QuickSettingContainer::initUi() if (pluginItems.size() > 0) updateItemLayout(); // 设置当前窗口的大小 - resizeView(); + onResizeView(); setFixedWidth(ITEMWIDTH * 4 + (ITEMSPACE * 5)); }, Qt::QueuedConnection); @@ -335,18 +336,18 @@ void QuickSettingContainer::initConnection() { connect(m_pluginLoader, &QuickSettingController::pluginInserted, this, &QuickSettingContainer::onPluginInsert); connect(m_pluginLoader, &QuickSettingController::pluginRemoved, this, &QuickSettingContainer::onPluginRemove); - connect(m_playerWidget, &MediaWidget::visibleChanged, this, [ this ] { resizeView(); }); - connect(m_volumnWidget, &VolumeWidget::visibleChanged, this, [ this ] { resizeView(); }); + connect(m_playerWidget, &MediaWidget::visibleChanged, this, &QuickSettingContainer::onResizeView); + connect(m_volumnWidget, &VolumeWidget::visibleChanged, this, &QuickSettingContainer::onResizeView); connect(m_volumnWidget, &VolumeWidget::rightIconClick, this, [ this ] { showWidget(m_volumeSettingWidget, tr("voice")); - resizeView(); + onResizeView(); }); - connect(m_brihtnessWidget, &BrightnessWidget::visibleChanged, this, [ this ] { resizeView(); }); + connect(m_brihtnessWidget, &BrightnessWidget::visibleChanged, this, &QuickSettingContainer::onResizeView); connect(m_brihtnessWidget->sliderContainer(), &SliderContainer::iconClicked, this, [ this ](const SliderContainer::IconPosition &iconPosition) { if (iconPosition == SliderContainer::RightIcon) { // 点击右侧的按钮,弹出具体的调节的界面 showWidget(m_displaySettingWidget, tr("brightness")); - resizeView(); + onResizeView(); } }); connect(m_childPage, &PluginChildPage::back, this, [ this ] { @@ -358,7 +359,8 @@ void QuickSettingContainer::initConnection() }); } -void QuickSettingContainer::resizeView() +// 调整尺寸 +void QuickSettingContainer::onResizeView() { if (m_switchLayout->currentWidget() == m_mainWidget) { QList pluginItems = m_pluginLoader->settingItems(); diff --git a/frame/window/quicksettingcontainer.h b/frame/window/quicksettingcontainer.h index e0aaf853e..91e077351 100644 --- a/frame/window/quicksettingcontainer.h +++ b/frame/window/quicksettingcontainer.h @@ -70,14 +70,13 @@ private Q_SLOTS: void onPluginRemove(QuickSettingItem *quickItem); void onItemDetailClick(PluginsItemInterface *pluginInter); bool eventFilter(QObject *watched, QEvent *event) override; + void onResizeView(); private: // 加载UI void initUi(); // 初始化槽函数 void initConnection(); - // 调整尺寸 - void resizeView(); // 调整控件位置 void updateItemLayout(); // 初始化控件项目 diff --git a/interfaces/pluginsiteminterface.h b/interfaces/pluginsiteminterface.h index c296829b6..4720dd7f1 100644 --- a/interfaces/pluginsiteminterface.h +++ b/interfaces/pluginsiteminterface.h @@ -34,6 +34,8 @@ enum class DockPart { SystemPanel // 系统插件显示区域 }; +// 快捷面板详情页面的itemWidget对应的itemKey +#define QUICK_ITEM_DETAIL_KEY "quick_item_detail_key" /// /// \brief The PluginsItemInterface class /// the dock plugins item interface, all dock plugins should diff --git a/plugins/bluetooth/CMakeLists.txt b/plugins/bluetooth/CMakeLists.txt index ffe049b77..78185f0d2 100644 --- a/plugins/bluetooth/CMakeLists.txt +++ b/plugins/bluetooth/CMakeLists.txt @@ -30,7 +30,7 @@ pkg_check_modules(QGSettings REQUIRED gsettings-qt) add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN") add_library(${PLUGIN_NAME} SHARED ${SRCS} resources/bluetooth.qrc) -set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../system-trays) +set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../quick-trays) target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS} ${QGSettings_INCLUDE_DIRS} ../../interfaces @@ -48,4 +48,4 @@ target_link_libraries(${PLUGIN_NAME} PRIVATE ${Qt5Svg_LIBRARIES} ) -install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins/system-trays) +install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins/quick-trays) diff --git a/plugins/bluetooth/bloothadapterwidget.cpp b/plugins/bluetooth/bloothadapterwidget.cpp new file mode 100644 index 000000000..f14503510 --- /dev/null +++ b/plugins/bluetooth/bloothadapterwidget.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#include "bloothadapterwidget.h" +#include "adapter.h" +#include "device.h" + +#include +#include + +#define ITEMHEIGHT 45 + +BloothAdapterWidget::BloothAdapterWidget(Adapter *adapter, QWidget *parent) + : QWidget(parent) + , m_adapter(adapter) + , m_myDeviceLabel(new QLabel(tr("my device"), this)) + , m_myDeviceView(new DListView(this)) + , m_otherDeviceLabel(new QLabel(tr("other device"), this)) + , m_otherDeviceView(new DListView(this)) + , m_myDeviceModel(new QStandardItemModel(this)) + , m_otherDeviceModel(new QStandardItemModel(this)) +{ + initUi(); + initConnection(); + initDevice(); +} + +Adapter *BloothAdapterWidget::adapter() +{ + return m_adapter; +} + +void BloothAdapterWidget::onDeviceAdded(const Device *device) +{ + if (device->name().isEmpty()) + return; + + DStandardItem *deviceItem = new DStandardItem; + deviceItem->setData(QVariant::fromValue(const_cast(device)), Dtk::UserRole + 1); + deviceItem->setText(device->name()); + if (device->paired()) { + // 我的设备 + m_myDeviceModel->insertRow(0, deviceItem); + } else { + // 其他设备 + m_otherDeviceModel->insertRow(0, deviceItem); + } + + updateDeviceVisible(); +} + +void BloothAdapterWidget::onDeviceRemoved(const Device *device) +{ + auto removeDeviceItem = [ = ](QStandardItemModel *model) { + for (int i = 0; i < model->rowCount(); i++) { + Device *tmpDevice = model->item(i)->data(Dtk::UserRole + 1).value(); + if (tmpDevice == device) { + model->removeRow(i); + return true; + } + } + + return false; + }; + + if (!removeDeviceItem(m_myDeviceModel)) + removeDeviceItem(m_otherDeviceModel); + + updateDeviceVisible(); +} + +void BloothAdapterWidget::onDeviceNameUpdated(const Device *device) const +{ + auto findDeviceItem = [ = ](QStandardItemModel *model)->DStandardItem * { + for (int i = 0; i < model->rowCount(); i++) { + DStandardItem *item = static_cast(model->item(i)); + Device *tmpDevice = item->data(Dtk::UserRole + 1).value(); + if (tmpDevice == device) { + return item; + } + } + + return nullptr; + }; + DStandardItem *item = findDeviceItem(m_myDeviceModel); + if (!item) + item = findDeviceItem(m_otherDeviceModel); + if (item) + item->setText(device->name()); +} + +void BloothAdapterWidget::onPoweredChanged(const bool powered) +{ + initDevice(); + updateDeviceVisible(); +} + +void BloothAdapterWidget::onOtherClicked(const QModelIndex &index) +{ + Device *device = index.data(Dtk::UserRole + 1).value(); + if (!device || device->state() == Device::State::StateConnected) + return; + + if (device->deviceType() == "audio-card" + && device->state() == Device::State::StateAvailable + && device->deviceType() == "pheadset") { + return; + } + + Q_EMIT requestConnectDevice(device); +} + +void BloothAdapterWidget::initUi() +{ + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + mainLayout->addWidget(m_myDeviceLabel); + mainLayout->addWidget(m_myDeviceView); + mainLayout->addSpacing(20); + mainLayout->addWidget(m_otherDeviceLabel); + mainLayout->addSpacing(6); + mainLayout->addWidget(m_otherDeviceView); + + m_myDeviceLabel->setVisible(false); + m_myDeviceView->setVisible(false); + m_myDeviceView->setModel(m_myDeviceModel); + m_myDeviceView->setFixedHeight(0); + m_myDeviceView->setItemSpacing(5); + + m_otherDeviceLabel->setVisible(false); + m_otherDeviceView->setVisible(false); + m_otherDeviceView->setModel(m_otherDeviceModel); + m_otherDeviceView->setFixedHeight(0); + m_otherDeviceView->setItemSpacing(5); +} + +void BloothAdapterWidget::initConnection() +{ + connect(m_adapter, &Adapter::deviceAdded, this, &BloothAdapterWidget::onDeviceAdded); + connect(m_adapter, &Adapter::deviceRemoved, this, &BloothAdapterWidget::onDeviceRemoved); + connect(m_adapter, &Adapter::deviceNameUpdated, this, &BloothAdapterWidget::onDeviceNameUpdated); + connect(m_adapter, &Adapter::poweredChanged, this, &BloothAdapterWidget::onPoweredChanged); + + connect(m_otherDeviceView, &DListView::clicked, this, &BloothAdapterWidget::onOtherClicked); +} + +void BloothAdapterWidget::initDevice() +{ + m_myDeviceModel->clear(); + m_otherDeviceModel->clear(); + QMap devices = m_adapter->devices(); + for (auto it = devices.begin(); it != devices.end(); it++) + onDeviceAdded(it.value()); +} + +void BloothAdapterWidget::adjustHeight() +{ + int height = m_myDeviceView->height() + 20 + m_otherDeviceView->height() + 5; + + if (m_myDeviceLabel->isVisible()) + height += m_myDeviceLabel->height(); + if (m_otherDeviceLabel->isVisible()) + height += m_otherDeviceLabel->height(); + + setFixedHeight(height); +} + +void BloothAdapterWidget::updateDeviceVisible() +{ + bool powered = m_adapter->powered(); + if (powered) { + m_myDeviceLabel->setVisible(m_myDeviceModel->rowCount() > 0); + m_myDeviceView->setVisible(m_myDeviceModel->rowCount() > 0); + m_myDeviceView->setFixedHeight(std::min(m_myDeviceModel->rowCount(), 10) * ITEMHEIGHT); + + m_otherDeviceLabel->setVisible(m_adapter->powered() && m_otherDeviceModel->rowCount() > 0); + m_otherDeviceView->setVisible(m_adapter->powered() && m_otherDeviceModel->rowCount() > 0); + m_otherDeviceView->setFixedHeight(std::min(m_otherDeviceModel->rowCount(), 10) * ITEMHEIGHT); + } else { + m_myDeviceLabel->setVisible(false); + m_myDeviceView->setVisible(false); + m_myDeviceView->setFixedHeight(0); + + m_otherDeviceLabel->setVisible(false); + m_otherDeviceView->setVisible(false); + m_otherDeviceView->setFixedHeight(0); + } + + adjustHeight(); + Q_EMIT requestUpdate(); + +} diff --git a/plugins/bluetooth/bloothadapterwidget.h b/plugins/bluetooth/bloothadapterwidget.h new file mode 100644 index 000000000..83f47dd85 --- /dev/null +++ b/plugins/bluetooth/bloothadapterwidget.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#ifndef BLOOTHADAPTERWIDGET_H +#define BLOOTHADAPTERWIDGET_H + +#include + +#include + +class Adapter; +class QLabel; +class Device; +class QStandardItemModel; + +using namespace Dtk::Widget; + +class BloothAdapterWidget : public QWidget +{ + Q_OBJECT + +public: + explicit BloothAdapterWidget(Adapter *adapter, QWidget *parent = nullptr); + + Adapter *adapter(); + +Q_SIGNALS: + void requestConnectDevice(Device *device); + void requestUpdate() const; + +protected Q_SLOTS: + void onDeviceAdded(const Device *device); + void onDeviceRemoved(const Device *device); + void onDeviceNameUpdated(const Device *device) const; + void onPoweredChanged(const bool powered); + + void onOtherClicked(const QModelIndex &index); + +private: + void initUi(); + void initConnection(); + void initDevice(); + void adjustHeight(); + void updateDeviceVisible(); + +private: + Adapter *m_adapter; + QLabel *m_myDeviceLabel; + DListView *m_myDeviceView; + QLabel *m_otherDeviceLabel; + DListView *m_otherDeviceView; + QStandardItemModel *m_myDeviceModel; + QStandardItemModel *m_otherDeviceModel; +}; + +#endif // BLOOTHADAPTERWIDGET_H diff --git a/plugins/bluetooth/bluetooth.json b/plugins/bluetooth/bluetooth.json index 8400bab79..936d08d86 100644 --- a/plugins/bluetooth/bluetooth.json +++ b/plugins/bluetooth/bluetooth.json @@ -1,4 +1,5 @@ { "api": "2.0.0", + "primary" : true, "depends-daemon-dbus-service": "org.deepin.daemon.Bluetooth1" } diff --git a/plugins/bluetooth/bluetoothitem.cpp b/plugins/bluetooth/bluetoothitem.cpp index 560fc9921..daf706d0f 100644 --- a/plugins/bluetooth/bluetoothitem.cpp +++ b/plugins/bluetooth/bluetoothitem.cpp @@ -21,6 +21,7 @@ */ #include "bluetoothitem.h" +#include "adaptersmanager.h" #include "constants.h" #include "../widgets/tipswidget.h" #include "../frame/util/imageutil.h" @@ -29,6 +30,7 @@ #include #include #include +#include #include @@ -41,10 +43,10 @@ DGUI_USE_NAMESPACE using namespace Dock; -BluetoothItem::BluetoothItem(QWidget *parent) +BluetoothItem::BluetoothItem(AdaptersManager *adapterManager, QWidget *parent) : QWidget(parent) , m_tipsLabel(new TipsWidget(this)) - , m_applet(new BluetoothApplet(this)) + , m_applet(new BluetoothApplet(adapterManager, this)) , m_devState(Device::State::StateUnavailable) , m_adapterPowered(m_applet->poweredInitState()) { @@ -195,6 +197,19 @@ bool BluetoothItem::hasAdapter() return m_applet->hasAadapter(); } +bool BluetoothItem::isPowered() +{ + if (!m_applet->hasAadapter()) + return false; + + QList adapters = m_applet->adaptersManager()->adapters(); + for (const Adapter *adapter : adapters) { + if (adapter->powered()) + return true; + } + return false; +} + void BluetoothItem::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); diff --git a/plugins/bluetooth/bluetoothitem.h b/plugins/bluetooth/bluetoothitem.h index 3e1c21a3c..89a382f6d 100644 --- a/plugins/bluetooth/bluetoothitem.h +++ b/plugins/bluetooth/bluetoothitem.h @@ -30,6 +30,7 @@ #define BLUETOOTH_KEY "bluetooth-item-key" class BluetoothApplet; +class AdaptersManager; namespace Dock { class TipsWidget; @@ -39,7 +40,7 @@ class BluetoothItem : public QWidget Q_OBJECT public: - explicit BluetoothItem(QWidget *parent = nullptr); + explicit BluetoothItem(AdaptersManager *adapterManager, QWidget *parent = nullptr); QWidget *tipsWidget(); QWidget *popupApplet(); @@ -51,6 +52,7 @@ public: void refreshTips(); bool hasAdapter(); + bool isPowered(); protected: void resizeEvent(QResizeEvent *event); diff --git a/plugins/bluetooth/bluetoothplugin.cpp b/plugins/bluetooth/bluetoothplugin.cpp index e7d29234c..1b9534cf2 100644 --- a/plugins/bluetooth/bluetoothplugin.cpp +++ b/plugins/bluetooth/bluetoothplugin.cpp @@ -21,12 +21,16 @@ */ #include "bluetoothplugin.h" +#include "bluetoothwidget.h" +#include "adaptersmanager.h" #define STATE_KEY "enable" BluetoothPlugin::BluetoothPlugin(QObject *parent) - : QObject(parent), - m_bluetoothItem(nullptr) + : QObject(parent) + , m_adapterManager(new AdaptersManager(this)) + , m_bluetoothItem(nullptr) + , m_bluetoothWidget(new BluetoothWidget(m_adapterManager)) { } @@ -47,7 +51,7 @@ void BluetoothPlugin::init(PluginProxyInterface *proxyInter) if (m_bluetoothItem) return; - m_bluetoothItem.reset(new BluetoothItem); + m_bluetoothItem.reset(new BluetoothItem(m_adapterManager)); connect(m_bluetoothItem.data(), &BluetoothItem::justHasAdapter, [&] { m_enableState = true; @@ -100,6 +104,10 @@ QWidget *BluetoothPlugin::itemPopupApplet(const QString &itemKey) return m_bluetoothItem->popupApplet(); } + if (itemKey == QUICK_ITEM_DETAIL_KEY) { + return m_bluetoothItem->popupApplet(); + } + return nullptr; } @@ -145,6 +153,28 @@ void BluetoothPlugin::pluginSettingsChanged() refreshPluginItemsVisible(); } +QIcon BluetoothPlugin::icon(const DockPart &) +{ + static QIcon icon(":/bluetooth-active-symbolic.svg"); + return icon; +} + +PluginsItemInterface::PluginStatus BluetoothPlugin::status() const +{ + if (m_bluetoothItem.data()->isPowered()) + return PluginStatus::Active; + + return PluginStatus::Deactive; +} + +QString BluetoothPlugin::description() const +{ + if (m_bluetoothItem.data()->isPowered()) + return tr("open"); + + return tr("close"); +} + void BluetoothPlugin::refreshPluginItemsVisible() { if (pluginIsDisable()) diff --git a/plugins/bluetooth/bluetoothplugin.h b/plugins/bluetooth/bluetoothplugin.h index e4db9d83e..094eb4bf4 100644 --- a/plugins/bluetooth/bluetoothplugin.h +++ b/plugins/bluetooth/bluetoothplugin.h @@ -28,6 +28,9 @@ #include +class BluetoothWidget; +class AdaptersManager; + class BluetoothPlugin : public QObject, PluginsItemInterface { Q_OBJECT @@ -53,11 +56,17 @@ public: void refreshIcon(const QString &itemKey) override; void pluginSettingsChanged() override; + QIcon icon(const DockPart &) override; + PluginStatus status() const override; + QString description() const override; + private: void refreshPluginItemsVisible(); private: + AdaptersManager *m_adapterManager; QScopedPointer m_bluetoothItem; + QScopedPointer m_bluetoothWidget; bool m_enableState = true; }; diff --git a/plugins/bluetooth/bluetoothwidget.cpp b/plugins/bluetooth/bluetoothwidget.cpp new file mode 100644 index 000000000..daf3f1408 --- /dev/null +++ b/plugins/bluetooth/bluetoothwidget.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#include "bluetoothwidget.h" +#include "adaptersmanager.h" +#include "bloothadapterwidget.h" +#include "adapter.h" +#include "device.h" + +#include +#include + +#include +#include + +BluetoothWidget::BluetoothWidget(AdaptersManager *adapterManager, QWidget *parent) + : QWidget(parent) + , m_switchButton(new DSwitchButton(this)) + , m_headerWidget(new QWidget(this)) + , m_adapterWidget(new QWidget(this)) + , m_adaptersManager(adapterManager) + , m_adapterLayout(new QVBoxLayout(m_adapterWidget)) +{ + initUi(); + initConnection(); +} + +BluetoothWidget::~BluetoothWidget() +{ +} + +void BluetoothWidget::onAdapterIncreased(Adapter *adapter) +{ + BloothAdapterWidget *adapterWidget = new BloothAdapterWidget(adapter, m_adapterWidget); + m_adapterLayout->addWidget(adapterWidget); + connect(adapterWidget, &BloothAdapterWidget::requestConnectDevice, this, [ this, adapter ](Device *device) { + m_adaptersManager->connectDevice(device, adapter); + }); + connect(adapterWidget, &BloothAdapterWidget::requestUpdate, this, [ this ] { + adjustHeight(); + }); + + updateCheckStatus(); + + QMetaObject::invokeMethod(this, &BluetoothWidget::adjustHeight, Qt::QueuedConnection); +} + +void BluetoothWidget::onAdapterDecreased(Adapter *adapter) +{ + for (int i = 0; i < m_adapterLayout->count(); i++) { + BloothAdapterWidget *adapterWidget = static_cast(m_adapterLayout->itemAt(i)->widget()); + if (adapterWidget && adapterWidget->adapter() == adapter) { + m_adapterLayout->removeWidget(adapterWidget); + + updateCheckStatus(); + QMetaObject::invokeMethod(this, &BluetoothWidget::adjustHeight, Qt::QueuedConnection); + break; + } + } +} + +void BluetoothWidget::onCheckedChanged(bool checked) +{ + QList adapters = m_adaptersManager->adapters(); + for (const Adapter *adapter : adapters) + m_adaptersManager->setAdapterPowered(adapter, checked); +} + +void BluetoothWidget::initUi() +{ + QHBoxLayout *headerLayout = new QHBoxLayout(m_headerWidget); + headerLayout->addStretch(); + headerLayout->addWidget(m_switchButton); + headerLayout->addStretch(); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + mainLayout->addWidget(m_headerWidget); + mainLayout->addSpacing(3); + mainLayout->addWidget(m_adapterWidget); + + m_adapterLayout->setContentsMargins(0, 0, 0, 0); + m_adapterLayout->setSpacing(0); + + QList adapters = m_adaptersManager->adapters(); + for (const Adapter *adapter : adapters) { + onAdapterIncreased(const_cast(adapter)); + } +} + +void BluetoothWidget::initConnection() +{ + connect(m_adaptersManager, &AdaptersManager::adapterIncreased, this, &BluetoothWidget::onAdapterIncreased); + connect(m_adaptersManager, &AdaptersManager::adapterDecreased, this, &BluetoothWidget::onAdapterDecreased); + connect(m_switchButton, &DSwitchButton::checkedChanged, this, &BluetoothWidget::onCheckedChanged); +} + +void BluetoothWidget::updateCheckStatus() +{ + bool checked = false; + QList adapters = m_adaptersManager->adapters(); + for (const Adapter *adapter : adapters) + checked = adapter->powered(); + + m_switchButton->setChecked(checked); +} + +void BluetoothWidget::adjustHeight() +{ + int height = m_switchButton->height() + m_headerWidget->height(); + for (int i = 0; i < m_adapterLayout->count(); i++) { + BloothAdapterWidget *adapterWidget = static_cast(m_adapterLayout->itemAt(i)->widget()); + if (!adapterWidget) + continue; + + height += adapterWidget->height(); + } + + setFixedHeight(height); +} diff --git a/plugins/bluetooth/bluetoothwidget.h b/plugins/bluetooth/bluetoothwidget.h new file mode 100644 index 000000000..109e65c38 --- /dev/null +++ b/plugins/bluetooth/bluetoothwidget.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#ifndef BLUETOOTHWIDGET_H +#define BLUETOOTHWIDGET_H + +#include + +class QLabel; +class AdaptersManager; +class Adapter; +class QVBoxLayout; + +namespace Dtk { namespace Widget { class DListView; class DSwitchButton; } } + +using namespace Dtk::Widget; + +class BluetoothWidget : public QWidget +{ + Q_OBJECT + +public: + explicit BluetoothWidget(AdaptersManager *adapterManager, QWidget *parent = nullptr); + ~BluetoothWidget() override; + +protected Q_SLOTS: + void onAdapterIncreased(Adapter *adapter); + void onAdapterDecreased(Adapter *adapter); + void onCheckedChanged(bool checked); + +private: + void initUi(); + void initConnection(); + void updateCheckStatus(); + void adjustHeight(); + +private: + DSwitchButton *m_switchButton; + QWidget *m_headerWidget; + QWidget *m_adapterWidget; + AdaptersManager *m_adaptersManager; + QVBoxLayout *m_adapterLayout; +}; + +#endif // BLUETOOTHWIDGET_H diff --git a/plugins/bluetooth/componments/adaptersmanager.cpp b/plugins/bluetooth/componments/adaptersmanager.cpp index 59b529fcf..78ee7f631 100644 --- a/plugins/bluetooth/componments/adaptersmanager.cpp +++ b/plugins/bluetooth/componments/adaptersmanager.cpp @@ -227,29 +227,28 @@ void AdaptersManager::adapterAdd(Adapter *adapter, const QJsonObject &adpterObj) QDBusObjectPath dPath(adpterObj["Path"].toString()); QDBusPendingCall call = m_bluetoothInter->GetDevices(dPath); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); - connect(watcher, &QDBusPendingCallWatcher::finished, [this, adapter, call, watcher] { - if (adapter) { - if (!call.isError()) { - QDBusReply reply = call.reply(); - const QString replyStr = reply.value(); - QJsonDocument doc = QJsonDocument::fromJson(replyStr.toUtf8()); - adapter->initDevicesList(doc); - emit this->adapterIncreased(adapter); - } else { - qWarning() << call.error().message(); - } - } - delete watcher; - }); + connect(watcher, &QDBusPendingCallWatcher::finished, watcher, &QDBusPendingCallWatcher::deleteLater); + connect(watcher, &QDBusPendingCallWatcher::finished, [ this, adapter, call ] { + if (!call.isError()) { + QDBusReply reply = call.reply(); + const QString replyStr = reply.value(); + QJsonDocument doc = QJsonDocument::fromJson(replyStr.toUtf8()); + adapter->initDevicesList(doc); - QString id = adapter->id(); - if (!id.isEmpty()) { - if (!m_adapters.contains(id)) { - m_adapters[id] = adapter; - } else if (m_adapters[id] == nullptr) { - m_adapters[id] = adapter; + QString id = adapter->id(); + if (!id.isEmpty()) { + if (!m_adapters.contains(id)) { + m_adapters[id] = adapter; + } else if (!m_adapters[id]) { + m_adapters[id] = adapter; + } + } + + emit this->adapterIncreased(adapter); + } else { + qWarning() << call.error().message(); } - } + }); } void AdaptersManager::inflateAdapter(Adapter *adapter, const QJsonObject &adapterObj) @@ -273,3 +272,8 @@ void AdaptersManager::adapterRefresh(const Adapter *adapter) QDBusObjectPath dPath(adapter->id()); m_bluetoothInter->RequestDiscovery(dPath); } + +QList AdaptersManager::adapters() +{ + return m_adapters.values(); +} diff --git a/plugins/bluetooth/componments/adaptersmanager.h b/plugins/bluetooth/componments/adaptersmanager.h index 50f96a90b..4a997374e 100644 --- a/plugins/bluetooth/componments/adaptersmanager.h +++ b/plugins/bluetooth/componments/adaptersmanager.h @@ -38,6 +38,7 @@ public: void connectDevice(const Device *device, Adapter *adapter); int adaptersCount(); void adapterRefresh(const Adapter *adapter); + QList adapters(); signals: void adapterIncreased(Adapter *adapter); diff --git a/plugins/bluetooth/componments/bluetoothapplet.cpp b/plugins/bluetooth/componments/bluetoothapplet.cpp index 7d684376c..d54a6b501 100644 --- a/plugins/bluetooth/componments/bluetoothapplet.cpp +++ b/plugins/bluetooth/componments/bluetoothapplet.cpp @@ -112,11 +112,11 @@ void SettingLabel::paintEvent(QPaintEvent *event) return QWidget::paintEvent(event); } -BluetoothApplet::BluetoothApplet(QWidget *parent) +BluetoothApplet::BluetoothApplet(AdaptersManager *adapterManager, QWidget *parent) : QWidget(parent) , m_scroarea(nullptr) , m_contentWidget(new QWidget(this)) - , m_adaptersManager(new AdaptersManager(this)) + , m_adaptersManager(adapterManager) , m_settingLabel(new SettingLabel(tr("Bluetooth settings"), this)) , m_mainLayout(new QVBoxLayout(this)) , m_contentLayout(new QVBoxLayout(m_contentWidget)) @@ -178,6 +178,11 @@ QStringList BluetoothApplet::connectedDevicesName() return deviceList; } +AdaptersManager *BluetoothApplet::adaptersManager() +{ + return m_adaptersManager; +} + void BluetoothApplet::onAdapterAdded(Adapter *adapter) { if (!m_adapterItems.size()) { diff --git a/plugins/bluetooth/componments/bluetoothapplet.h b/plugins/bluetooth/componments/bluetoothapplet.h index 442013499..f71e397c6 100644 --- a/plugins/bluetooth/componments/bluetoothapplet.h +++ b/plugins/bluetooth/componments/bluetoothapplet.h @@ -77,7 +77,7 @@ class BluetoothApplet : public QWidget { Q_OBJECT public: - explicit BluetoothApplet(QWidget *parent = nullptr); + explicit BluetoothApplet(AdaptersManager *adapterManager, QWidget *parent = nullptr); bool poweredInitState(); // 当前是否有蓝牙适配器 bool hasAadapter(); @@ -89,6 +89,8 @@ public: QStringList connectedDevicesName(); inline bool airplaneModeEnable() const { return m_airplaneModeEnable;} + // 返回蓝牙适配器 + AdaptersManager *adaptersManager(); signals: void noAdapter();