314 lines
13 KiB
Python
314 lines
13 KiB
Python
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QListWidget, QListWidgetItem, QFrame, QGridLayout, QSizePolicy
|
|
from PyQt5.QtSvg import QSvgWidget
|
|
from PyQt5.QtCore import Qt, QSize, QMargins
|
|
from PyQt5.QtGui import QPixmap, QIcon, QColor
|
|
import os
|
|
|
|
from src.config import SECONDARY_COLOR, BUTTON_STYLE, UXUI_ASSETS, DongleIconMap
|
|
|
|
def create_device_popup(parent, device_controller):
|
|
"""Create a popup window for device connection management"""
|
|
try:
|
|
# Device connection popup window
|
|
popup = QWidget(parent)
|
|
popup_width = int(parent.width() * 0.67)
|
|
popup_height = int(parent.height() * 0.67)
|
|
popup.setFixedSize(popup_width, popup_height)
|
|
popup.setStyleSheet(f"""
|
|
QWidget {{
|
|
background-color: {SECONDARY_COLOR};
|
|
border-radius: 20px;
|
|
padding: 20px;
|
|
}}
|
|
QLabel {{
|
|
color: white;
|
|
}}
|
|
QListWidget {{
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
border-radius: 10px;
|
|
padding: 5px;
|
|
color: white;
|
|
}}
|
|
QListWidget::item {{
|
|
border-radius: 5px;
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
margin-bottom: 5px;
|
|
}}
|
|
QListWidget::item:selected {{
|
|
background-color: rgba(52, 152, 219, 0.5);
|
|
}}
|
|
QFrame.device-info {{
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
border-radius: 10px;
|
|
padding: 10px;
|
|
margin-top: 15px;
|
|
}}
|
|
""")
|
|
|
|
popup_layout = QVBoxLayout(popup)
|
|
popup_layout.setContentsMargins(20, 20, 20, 20)
|
|
popup_layout.setSpacing(15)
|
|
|
|
# Title row
|
|
title_layout = QHBoxLayout()
|
|
title_layout.setAlignment(Qt.AlignCenter)
|
|
|
|
title_container = QWidget()
|
|
container_layout = QHBoxLayout(title_container)
|
|
container_layout.setSpacing(10)
|
|
|
|
device_icon = QSvgWidget(os.path.join(UXUI_ASSETS, "Assets_svg/ic_window_device.svg"))
|
|
device_icon.setFixedSize(35, 35)
|
|
container_layout.addWidget(device_icon)
|
|
|
|
popup_label = QLabel("Device Connection")
|
|
popup_label.setStyleSheet("color: white; font-size: 32px; font-weight: bold;")
|
|
container_layout.addWidget(popup_label)
|
|
|
|
container_layout.setAlignment(Qt.AlignCenter)
|
|
title_layout.addWidget(title_container)
|
|
popup_layout.addLayout(title_layout)
|
|
|
|
# Device list section - 設置為可捲動
|
|
list_section = QFrame(popup)
|
|
list_section.setStyleSheet("border: none; background: transparent;")
|
|
list_layout = QVBoxLayout(list_section)
|
|
list_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
# Device list - 設置為可捲動的列表
|
|
device_list_widget_popup = QListWidget(popup)
|
|
device_list_widget_popup.setMinimumHeight(250) # 增加整個列表的高度
|
|
# 啟用垂直捲動條
|
|
device_list_widget_popup.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
|
# 設置列表項高度和圖示大小
|
|
device_list_widget_popup.setIconSize(QSize(15, 15)) # 增大圖示
|
|
list_layout.addWidget(device_list_widget_popup)
|
|
|
|
# Store reference to this list widget for later use
|
|
parent.device_list_widget_popup = device_list_widget_popup
|
|
|
|
# Comment out the device details section
|
|
"""
|
|
# Device details section (initially hidden)
|
|
device_details = QFrame(popup)
|
|
device_details.setObjectName("device-details")
|
|
device_details.setProperty("class", "device-info")
|
|
device_details.setVisible(False) # Initially hidden
|
|
|
|
details_layout = QGridLayout(device_details)
|
|
details_layout.setColumnStretch(1, 1)
|
|
# 增加行間距
|
|
details_layout.setVerticalSpacing(2)
|
|
|
|
# Device Type
|
|
device_type_label_title = QLabel("Device Type:")
|
|
device_type_label_title.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(device_type_label_title, 0, 0)
|
|
device_type_label = QLabel("-")
|
|
device_type_label.setObjectName("device-type")
|
|
device_type_label.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(device_type_label, 0, 1)
|
|
|
|
# Port ID
|
|
port_id_label_title = QLabel("Port ID:")
|
|
port_id_label_title.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(port_id_label_title, 1, 0)
|
|
port_id_label = QLabel("-")
|
|
port_id_label.setObjectName("port-id")
|
|
port_id_label.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(port_id_label, 1, 1)
|
|
|
|
# KN Number
|
|
kn_number_label_title = QLabel("KN Number:")
|
|
kn_number_label_title.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(kn_number_label_title, 2, 0)
|
|
kn_number_label = QLabel("-")
|
|
kn_number_label.setObjectName("kn-number")
|
|
kn_number_label.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(kn_number_label, 2, 1)
|
|
|
|
# Status
|
|
status_label_title = QLabel("Status:")
|
|
status_label_title.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(status_label_title, 3, 0)
|
|
status_label = QLabel("-")
|
|
status_label.setObjectName("status")
|
|
status_label.setStyleSheet("font-size: 14px;")
|
|
details_layout.addWidget(status_label, 3, 1)
|
|
|
|
# Store references to labels
|
|
parent.device_detail_labels = {
|
|
"device-type": device_type_label,
|
|
"port-id": port_id_label,
|
|
"kn-number": kn_number_label,
|
|
"status": status_label,
|
|
"frame": device_details
|
|
}
|
|
|
|
# Connect item selection to show details
|
|
device_list_widget_popup.itemClicked.connect(lambda item: show_device_details(parent, item))
|
|
|
|
list_layout.addWidget(device_details)
|
|
"""
|
|
popup_layout.addWidget(list_section)
|
|
|
|
# Button area
|
|
button_layout = QHBoxLayout()
|
|
button_layout.setAlignment(Qt.AlignCenter)
|
|
|
|
refresh_button = QPushButton("Refresh")
|
|
refresh_button.clicked.connect(lambda: refresh_devices(parent, device_controller))
|
|
refresh_button.setFixedSize(150, 45)
|
|
refresh_button.setStyleSheet(BUTTON_STYLE)
|
|
button_layout.addWidget(refresh_button)
|
|
|
|
done_button = QPushButton("Done")
|
|
done_button.setStyleSheet(BUTTON_STYLE)
|
|
done_button.setFixedSize(150, 45)
|
|
done_button.clicked.connect(parent.hide_device_popup)
|
|
button_layout.addWidget(done_button)
|
|
|
|
button_layout.setSpacing(20)
|
|
# 減少底部間距,讓按鈕更靠近底部
|
|
popup_layout.addSpacing(5)
|
|
popup_layout.addLayout(button_layout)
|
|
|
|
return popup
|
|
except Exception as e:
|
|
print(f"Error in create_device_popup: {e}")
|
|
return QWidget(parent)
|
|
|
|
# Also need to comment out the show_device_details function since it's no longer used
|
|
|
|
# def show_device_details(parent, item):
|
|
# """Show details for the selected device"""
|
|
# try:
|
|
# # Get the device data from the item
|
|
# device_data = item.data(Qt.UserRole)
|
|
# print("device_data", device_data)
|
|
# if not device_data:
|
|
# return
|
|
|
|
# # Update the detail labels
|
|
# labels = parent.device_detail_labels
|
|
|
|
# # Set values
|
|
# labels["device-type"].setText(device_data.get("dongle", "-"))
|
|
# labels["port-id"].setText(str(device_data.get("usb_port_id", "-")))
|
|
# labels["kn-number"].setText(str(device_data.get("kn_number", "-")))
|
|
# labels["status"].setText("Connected" if device_data.get("is_connectable", True) else "Not Available")
|
|
|
|
# # Show the details frame
|
|
# labels["frame"].setVisible(True)
|
|
# except Exception as e:
|
|
# print(f"Error showing device details: {e}")
|
|
|
|
|
|
def refresh_devices(parent, device_controller):
|
|
"""Refresh the device list and update the UI"""
|
|
try:
|
|
# Call the refresh method from device controller
|
|
device_controller.refresh_devices()
|
|
|
|
# Clear the list
|
|
parent.device_list_widget_popup.clear()
|
|
|
|
# Comment out the details frame visibility setting
|
|
"""
|
|
# Hide details frame
|
|
if hasattr(parent, "device_detail_labels") and "frame" in parent.device_detail_labels:
|
|
parent.device_detail_labels["frame"].setVisible(False)
|
|
"""
|
|
|
|
# Track unique device models to avoid duplicates
|
|
seen_models = set()
|
|
|
|
# Add devices to the list
|
|
for device in device_controller.connected_devices:
|
|
try:
|
|
item = QListWidgetItem()
|
|
|
|
# Store the device data
|
|
item.setData(Qt.UserRole, device)
|
|
|
|
# 使用自定義 widget 來顯示設備信息
|
|
widget = QWidget()
|
|
widget.setFixedHeight(60) # 固定高度
|
|
|
|
# 使用水平佈局
|
|
main_layout = QHBoxLayout(widget)
|
|
# 減少內邊距保持足夠空間
|
|
main_layout.setContentsMargins(8, 4, 8, 4)
|
|
main_layout.setSpacing(5)
|
|
|
|
# 左側圖示容器(帶有背景色)
|
|
icon_container = QFrame()
|
|
icon_container.setFixedSize(30, 30)
|
|
icon_container.setStyleSheet("background-color: #182D4B; border-radius: 5px;")
|
|
|
|
icon_layout = QVBoxLayout(icon_container)
|
|
icon_layout.setContentsMargins(0, 0, 0, 0)
|
|
icon_layout.setAlignment(Qt.AlignCenter)
|
|
|
|
# 獲取設備圖示
|
|
product_id = hex(device.get("product_id", 0)).strip().lower()
|
|
icon_path = os.path.join(UXUI_ASSETS, "Assets_png", DongleIconMap.get(product_id, "unknown_dongle.png"))
|
|
|
|
if os.path.exists(icon_path):
|
|
icon_label = QLabel()
|
|
pixmap = QPixmap(icon_path)
|
|
# 確保圖標大小適中
|
|
scaled_pixmap = pixmap.scaled(30, 30, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
icon_label.setPixmap(scaled_pixmap)
|
|
icon_layout.addWidget(icon_label)
|
|
|
|
main_layout.addWidget(icon_container)
|
|
|
|
# 右側信息區域
|
|
info_container = QWidget()
|
|
info_layout = QVBoxLayout(info_container)
|
|
info_layout.setContentsMargins(0, 0, 0, 0)
|
|
# info_layout.setSpacing(2)
|
|
|
|
# 設備名稱和型號
|
|
dongle_name = device.get("dongle", "Unknown Device")
|
|
kn_number = device.get("kn_number", "Unknown")
|
|
status = "Connected" if device.get("is_connectable", True) else "Not Available"
|
|
|
|
# 只顯示型號名稱,避免重複
|
|
device_model_key = f"{dongle_name}_{product_id}"
|
|
if device_model_key in seen_models:
|
|
# 只顯示狀態
|
|
device_label_text = ""
|
|
else:
|
|
seen_models.add(device_model_key)
|
|
device_label_text = f"{dongle_name}"
|
|
|
|
device_label = QLabel(device_label_text)
|
|
device_label.setStyleSheet("color: white; font-weight: bold; font-size: 16px;")
|
|
info_layout.addWidget(device_label)
|
|
|
|
# KN 號碼
|
|
kn_label = QLabel(f"KN: {kn_number}")
|
|
kn_label.setStyleSheet("color: white; font-size: 14px;")
|
|
info_layout.addWidget(kn_label)
|
|
|
|
# 將信息容器添加到主佈局
|
|
main_layout.addWidget(info_container, 1) # 設置伸展因子為1
|
|
|
|
# 狀態標籤(右側)
|
|
status_label = QLabel(status)
|
|
status_label.setStyleSheet("color: white; font-size: 12px;")
|
|
main_layout.addWidget(status_label, 0, Qt.AlignRight | Qt.AlignVCenter) # 右對齊
|
|
|
|
# 設置自定義 widget 為列表項的 widget
|
|
parent.device_list_widget_popup.addItem(item)
|
|
parent.device_list_widget_popup.setItemWidget(item, widget)
|
|
|
|
# 設置項目大小
|
|
item.setSizeHint(widget.sizeHint())
|
|
|
|
except Exception as e:
|
|
print(f"Error adding device to list: {e}")
|
|
except Exception as e:
|
|
print(f"Error refreshing devices: {e}") |