Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dss_example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ add_executable(${PROJECT_NAME}
target_include_directories(${PROJECT_NAME} PUBLIC
.
../src
../dss-network-plugin
Dtk6::Widget
Qt6::DBus
Qt6::Network
Expand All @@ -35,5 +36,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
Qt6::Network
Qt6::Widgets
KF6::NetworkManagerQt
dss-network-plugin
dde-network-core6
)
72 changes: 72 additions & 0 deletions dss_example/dssscreenmanager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2011 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "dssscreenmanager.h"

#include "dsstestwidget.h"
#include "networkmodule.h"

Check warning on line 8 in dss_example/dssscreenmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "networkmodule.h" not found.

#include <QGuiApplication>

Check warning on line 10 in dss_example/dssscreenmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QGuiApplication> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QScreen>

Check warning on line 11 in dss_example/dssscreenmanager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QScreen> not found. Please note: Cppcheck does not need standard library headers to get proper results.

DssScreenManager::DssScreenManager(QObject *parent)
: QObject(parent)
, m_netModule(new dde::network::NetworkPlugin(this))
{
m_netModule->init();
initConnection();
initScreen();
}

DssScreenManager::~DssScreenManager()
{
qDeleteAll(m_screenWidget);
m_screenWidget.clear();
}

void DssScreenManager::showWindow()
{
for (auto it = m_screenWidget.constBegin(); it != m_screenWidget.constEnd(); it++) {
showWindow(it.key(), it.value());
}
}

void DssScreenManager::initConnection()
{
connect(qApp, &QGuiApplication::screenAdded, this, &DssScreenManager::onScreenAdded);
connect(qApp, &QGuiApplication::screenRemoved, this, &DssScreenManager::onScreenRemoved);
}

void DssScreenManager::initScreen()
{
QList<QScreen *> screens = QGuiApplication::screens();
for (QScreen *screen : screens) {
DssTestWidget *testWidget = new DssTestWidget(m_netModule);
m_screenWidget[screen] = testWidget;
}
}

void DssScreenManager::showWindow(QScreen *screen, DssTestWidget *testWidget)
{
const QRect screenGeometry = screen->geometry();
testWidget->resize(330, 800);
testWidget->move(screenGeometry.x() + (screenGeometry.width() - testWidget->width()) / 2, (screenGeometry.height() - testWidget->height()) / 2);
testWidget->show();
}

void DssScreenManager::onScreenAdded(QScreen *screen)
{
DssTestWidget *testWidget = new DssTestWidget(m_netModule);
m_screenWidget[screen] = testWidget;
showWindow(screen, testWidget);
}

void DssScreenManager::onScreenRemoved(QScreen *screen)
{
if (m_screenWidget.contains(screen)) {
DssTestWidget *testWidget = m_screenWidget[screen];
m_screenWidget.remove(screen);
testWidget->deleteLater();
}
}
43 changes: 43 additions & 0 deletions dss_example/dssscreenmanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2011 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef DSSSCREENMANAGER_H
#define DSSSCREENMANAGER_H

#include <QMap>

Check warning on line 8 in dss_example/dssscreenmanager.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QMap> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QObject>

Check warning on line 9 in dss_example/dssscreenmanager.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QObject> not found. Please note: Cppcheck does not need standard library headers to get proper results.

class DssTestWidget;
class QScreen;

namespace dde {
namespace network {
class NetworkPlugin;
} // namespace network
} // namespace dde

class DssScreenManager : public QObject
{
Q_OBJECT

public:
explicit DssScreenManager(QObject *parent = nullptr);
~DssScreenManager();
void showWindow();

private:
void initConnection();
void initScreen();
void showWindow(QScreen *screen, DssTestWidget *testWidget);

protected:
void onScreenAdded(QScreen *screen);
void onScreenRemoved(QScreen *screen);

private:
QMap<QScreen *, DssTestWidget *> m_screenWidget;
dde::network::NetworkPlugin *m_netModule;
};

#endif // DSSSCREENMANAGER_H
152 changes: 118 additions & 34 deletions dss_example/dsstestwidget.cpp
Original file line number Diff line number Diff line change
@@ -1,39 +1,62 @@
// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// SPDX-License-Identifier: GPL-3.0-or-later

#include "dsstestwidget.h"
#include <QPushButton>
#include <QLabel>
#include <QMessageBox>

#include "networkmodule.h"

Check warning on line 7 in dss_example/dsstestwidget.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "networkmodule.h" not found.
#include "popupwindow.h"

#include <networkcontroller.h>

Check warning on line 10 in dss_example/dsstestwidget.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <networkcontroller.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <DPalette>

Check warning on line 12 in dss_example/dsstestwidget.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DPalette> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <DFloatingButton>
#include <QMouseEvent>

#include <QHBoxLayout>

Check warning on line 14 in dss_example/dsstestwidget.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QHBoxLayout> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <networkcontroller.h>
#include <QMouseEvent>

Check warning on line 15 in dss_example/dsstestwidget.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QMouseEvent> not found. Please note: Cppcheck does not need standard library headers to get proper results.

using namespace dde::network;
using namespace Dtk::Widget;
DGUI_USE_NAMESPACE

DssTestWidget::DssTestWidget(QWidget *parent)
DssTestWidget::DssTestWidget(dde::network::NetworkPlugin *networkPlugin, QWidget *parent)
: QWidget(parent)
, m_button(nullptr)
, m_pModule(networkPlugin)
, m_container(nullptr)
, m_tipContainer(nullptr)
{
m_button = new Dtk::Widget::DFloatingButton(this);
m_button->setIconSize(QSize(26, 26));
m_button->setFixedSize(QSize(52, 52));
m_button->setAutoExclusive(true);
m_button->setBackgroundRole(DPalette::Button);
m_button->setIcon(QIcon("network-online-symbolic"));
m_button->installEventFilter(this);

// 创建一个简单的布局
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setSpacing(0);
QWidget *iconWidget = new QWidget(this);
m_iconButton = new DFloatingButton(iconWidget);
m_iconButton->setIconSize(QSize(26, 26));
m_iconButton->setFixedSize(QSize(52, 52));
m_iconButton->setAutoExclusive(true);
QPalette palette = m_iconButton->palette();
palette.setColor(QPalette::ColorRole::Window, Qt::transparent);
m_iconButton->setPalette(palette);
m_iconButton->installEventFilter(this);
connect(m_iconButton, &Dtk::Widget::DFloatingButton::clicked, this, &DssTestWidget::onClickButton);

QHBoxLayout *iconLayout = new QHBoxLayout(iconWidget);
iconLayout->setAlignment(Qt::AlignHCenter);
iconLayout->addWidget(m_iconButton);

QPalette paletteSelf = this->palette();
paletteSelf.setColor(QPalette::ColorRole::Window, Qt::darkBlue);
setAutoFillBackground(true);
setPalette(paletteSelf);

QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_button);
layout->addStretch();
layout->addWidget(iconWidget);

QHBoxLayout *iconButtonLayout = new QHBoxLayout(m_iconButton);
QWidget *itemWidget = m_pModule->itemWidget();
itemWidget->setParent(m_iconButton);
iconButtonLayout->addWidget(itemWidget);

installEventFilter(this);
itemWidget->installEventFilter(this);
m_iconButton->installEventFilter(this);
}

DssTestWidget::~DssTestWidget()
Expand All @@ -42,24 +65,85 @@

bool DssTestWidget::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_button) {
if (watched == m_iconButton) {
// 当鼠标移入的时候显示提示信息
switch (event->type()) {
case QEvent::MouseButtonPress: {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::RightButton) {
QMessageBox::information(this, "DSS Example", "右键点击 - 网络测试程序");
} else if (mouseEvent->button() == Qt::LeftButton) {
QMessageBox::information(this, "DSS Example", "左键点击 - 网络测试程序");
}
case QEvent::Enter: {
if (!m_tipContainer) {
QWidget *tipWidget = m_pModule->itemTipsWidget();
m_tipContainer = new PopupWindow(this);
m_tipContainer->setContent(tipWidget);
m_tipContainer->resizeWithContent();
m_tipContainer->setArrowX(tipWidget->width() / 2);
}
m_tipContainer->raise();
m_tipContainer->show(QPoint(rect().center().x(), m_iconButton->parentWidget()->y()));
} break;
case QEvent::Leave: {
m_tipContainer->hide();
Comment on lines +82 to +83
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Potential null dereference when hiding m_tipContainer on Leave event

In the QEvent::Leave case you call m_tipContainer->hide() even though m_tipContainer is only set up in the Enter path. If Leave occurs before the popup is constructed, this will dereference a null pointer. Add a null check (e.g. if (m_tipContainer) m_tipContainer->hide();) to avoid a crash.

break;
case QEvent::Enter:
break;
case QEvent::Leave:
}
default:
break;
default: break;
}
}

return QWidget::eventFilter(watched, event);
}

void DssTestWidget::resizeEvent(QResizeEvent *event)
{
if (m_container && m_container->isVisible()) {
m_container->resizeWithContent();
m_container->show(QPoint(rect().width() / 2, m_iconButton->parentWidget()->y()));
}
QWidget::resizeEvent(event);
}

void DssTestWidget::mousePressEvent(QMouseEvent *event)
{
if (m_tipContainer && m_tipContainer->isVisible())
m_tipContainer->hide();
if (m_container && m_container->isVisible())
m_container->hide();

QWidget::mousePressEvent(event);
}

void DssTestWidget::onClickButton()
{
if (!m_pModule->content())
return;

// 左键弹出菜单
if (!m_container) {
m_container = new PopupWindow(this);
connect(m_container, &PopupWindow::contentDetach, this, [ this ] {
m_container->setContent(nullptr);
m_container->hide();
});
}
static QWidget *netlistWidget = nullptr;
if (!netlistWidget) {
netlistWidget = m_pModule->content();
}
netlistWidget->setParent(m_container);
netlistWidget->adjustSize();
m_container->setContent(netlistWidget);
m_container->resizeWithContent();
m_container->setArrowX(m_container->width() / 2);

if (m_container->isVisible()) {
m_container->hide();
if (m_tipContainer) {
m_tipContainer->toggle();
}
} else {
if (m_tipContainer) {
m_tipContainer->hide();
}
QWidget *content = m_container->getContent();
content->adjustSize();
m_container->resizeWithContent();
m_container->show(QPoint(rect().width() / 2, m_iconButton->parentWidget()->y()));
}
}
35 changes: 24 additions & 11 deletions dss_example/dsstestwidget.h
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef DSSTESTWIDGET_H
#define DSSTESTWIDGET_H

#include <DFloatingButton>

#include <QWidget>

namespace Dtk {
namespace Widget {
class DFloatingButton;
}
}
class PopupWindow;

namespace dde {
namespace network {
class NetworkPlugin;
} // namespace network
} // namespace dde

class QPushButton;
using namespace Dtk::Widget;

class DssTestWidget : public QWidget
{
Q_OBJECT

public:
DssTestWidget(QWidget *parent = Q_NULLPTR);
~DssTestWidget();
explicit DssTestWidget(dde::network::NetworkPlugin *networkPlugin, QWidget *parent = Q_NULLPTR);
~DssTestWidget() override;

private:
bool eventFilter(QObject *watched, QEvent *event);
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;

protected slots:
void onClickButton();

private:
Dtk::Widget::DFloatingButton *m_button;
dde::network::NetworkPlugin *m_pModule;
DFloatingButton *m_iconButton;
PopupWindow *m_container;
PopupWindow *m_tipContainer;
};

#endif // DSSTESTWIDGET_H
Loading