/* * iDescriptor: A free and open-source idevice management tool. * * Copyright (C) 2025 Uncore * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "networkdeviceswidget.h" #ifdef __linux__ #include "core/services/avahi/avahi_service.h" #else #include "core/services/dnssd/dnssd_service.h" #endif #include #include #include #include #include NetworkDevicesWidget::NetworkDevicesWidget(QWidget *parent) : Tool(parent) { setWindowTitle("Network Devices - iDescriptor"); setMinimumSize(300, 300); setMaximumSize(500, 500); setupUI(); connect(NetworkDeviceProvider::sharedInstance(), &NetworkDeviceProvider::deviceAdded, this, &NetworkDevicesWidget::onWirelessDeviceAdded); connect(NetworkDeviceProvider::sharedInstance(), &NetworkDeviceProvider::deviceRemoved, this, &NetworkDevicesWidget::onWirelessDeviceRemoved); updateDeviceList(); setMaximumHeight(sizeHint().height()); } NetworkDevicesWidget::~NetworkDevicesWidget() {} void NetworkDevicesWidget::setupUI() { QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(10, 10, 10, 10); mainLayout->setSpacing(10); // Status label m_statusLabel = new QLabel("Scanning for network devices..."); QFont statusFont = m_statusLabel->font(); statusFont.setPointSize(12); statusFont.setWeight(QFont::Medium); m_statusLabel->setFont(statusFont); m_statusLabel->setAlignment(Qt::AlignCenter); mainLayout->addWidget(m_statusLabel); // Device group m_deviceGroup = new QGroupBox("Network Devices"); QFont groupFont = m_deviceGroup->font(); groupFont.setPointSize(14); groupFont.setWeight(QFont::Bold); m_deviceGroup->setFont(groupFont); QVBoxLayout *groupLayout = new QVBoxLayout(m_deviceGroup); groupLayout->setContentsMargins(5, 15, 5, 5); groupLayout->setSpacing(0); // Scroll area m_scrollArea = new QScrollArea(); m_scrollArea->setWidgetResizable(true); m_scrollArea->setMinimumHeight(200); m_scrollArea->setMaximumHeight(400); m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); m_scrollArea->setStyleSheet( "QScrollArea { background: transparent; border: none; }"); // Scroll content m_scrollContent = new QWidget(); m_deviceLayout = new QVBoxLayout(m_scrollContent); m_deviceLayout->setContentsMargins(5, 5, 5, 5); m_deviceLayout->setSpacing(8); m_deviceLayout->addStretch(); m_scrollArea->setWidget(m_scrollContent); groupLayout->addWidget(m_scrollArea); mainLayout->addWidget(m_deviceGroup); mainLayout->addStretch(); } void NetworkDevicesWidget::createDeviceCard(const NetworkDevice &device) { // Main card frame QWidget *card = new QWidget(); QVBoxLayout *cardLayout = new QVBoxLayout(card); cardLayout->setContentsMargins(12, 10, 12, 10); cardLayout->setSpacing(4); // Device name (primary) QLabel *nameLabel = new QLabel(device.name); nameLabel->setWordWrap(true); QFont nameFont = nameLabel->font(); nameFont.setPointSize(13); nameFont.setWeight(QFont::Medium); nameLabel->setFont(nameFont); QPalette namePalette = nameLabel->palette(); namePalette.setColor(QPalette::WindowText, palette().color(QPalette::WindowText)); nameLabel->setPalette(namePalette); // Device info container QWidget *infoContainer = new QWidget(); QHBoxLayout *infoLayout = new QHBoxLayout(infoContainer); infoLayout->setContentsMargins(0, 0, 0, 0); infoLayout->setSpacing(12); // Address info QLabel *addressLabel = new QLabel(QString("IP: %1").arg(device.address)); QFont addressFont = addressLabel->font(); addressFont.setPointSize(11); addressLabel->setFont(addressFont); QPalette addressPalette = addressLabel->palette(); QColor secondaryColor = palette().color(QPalette::WindowText); secondaryColor.setAlpha(180); addressPalette.setColor(QPalette::WindowText, secondaryColor); addressLabel->setPalette(addressPalette); // Port info QLabel *portLabel = new QLabel(QString("Port: %1").arg(device.port)); portLabel->setFont(addressFont); portLabel->setPalette(addressPalette); infoLayout->addWidget(addressLabel); infoLayout->addWidget(portLabel); infoLayout->addStretch(); QLabel *statusIndicator = new QLabel("●"); statusIndicator->setStyleSheet( QString("QLabel { font-size: 14px; color: %1; }") #ifdef WIN32 .arg(COLOR_ACCENT_BLUE.name())); #else .arg(COLOR_GREEN.name())); #endif infoLayout->addWidget(statusIndicator); cardLayout->addWidget(nameLabel); cardLayout->addWidget(infoContainer); // Store the device info as property for later removal card->setProperty("deviceName", device.name); card->setProperty("deviceAddress", device.address); // Insert before the stretch m_deviceLayout->insertWidget(m_deviceLayout->count() - 1, card); m_deviceCards.append(card); } void NetworkDevicesWidget::clearDeviceCards() { for (QWidget *card : m_deviceCards) { card->deleteLater(); } m_deviceCards.clear(); } void NetworkDevicesWidget::updateDeviceList() { clearDeviceCards(); QMap devices = NetworkDeviceProvider::sharedInstance()->getNetworkDevices(); if (devices.isEmpty()) { m_statusLabel->setText("No network devices found"); } else { m_statusLabel->setText( QString("Found %1 network device(s)").arg(devices.count())); for (const NetworkDevice &device : devices) { createDeviceCard(device); } } } void NetworkDevicesWidget::onWirelessDeviceAdded(const NetworkDevice &device) { createDeviceCard(device); // Update status int deviceCount = m_deviceCards.count(); m_statusLabel->setText( QString("Found %1 network device(s)").arg(deviceCount)); } void NetworkDevicesWidget::onWirelessDeviceRemoved(const QString &deviceName) { // Find and remove the corresponding card for (int i = 0; i < m_deviceCards.count(); ++i) { QWidget *card = m_deviceCards[i]; if (card->property("deviceName").toString() == deviceName) { m_deviceCards.removeAt(i); card->deleteLater(); break; } } // Update status int deviceCount = m_deviceCards.count(); if (deviceCount == 0) { m_statusLabel->setText("No network devices found"); } else { m_statusLabel->setText( QString("Found %1 network device(s)").arg(deviceCount)); } }