Mon, 22 Apr 2024 18:23:20 +0200
Changed the source code and the source code documentation to improve the indication of unused method/function arguments.
9857 | 1 | # -*- coding: utf-8 -*- |
2 | ||
10439
21c28b0f9e41
Updated copyright for 2024.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10090
diff
changeset
|
3 | # Copyright (c) 2023 - 2024 Detlev Offenbach <detlev@die-offenbachs.de> |
9857 | 4 | # |
5 | ||
6 | """ | |
7 | Module implementing a dialog to scan for Bluetooth devices. | |
8 | """ | |
9 | ||
10 | from PyQt6.QtCore import Qt, pyqtSlot | |
11 | from PyQt6.QtWidgets import QHeaderView, QTreeWidgetItem, QWidget | |
12 | ||
13 | from eric7.EricGui.EricOverrideCursor import EricOverrideCursor | |
14 | from eric7.EricWidgets import EricMessageBox | |
15 | ||
16 | from .Ui_BluetoothScanWindow import Ui_BluetoothScanWindow | |
17 | ||
18 | ||
19 | class BluetoothScanWindow(QWidget, Ui_BluetoothScanWindow): | |
20 | """ | |
21 | Class implementing a dialog to scan for Bluetooth devices. | |
22 | """ | |
23 | ||
24 | def __init__(self, device, parent=None): | |
25 | """ | |
26 | Constructor | |
27 | ||
28 | @param device reference to the connected device | |
29 | @type BaseDevice | |
30 | @param parent reference to the parent widget (defaults to None) | |
31 | @type QWidget (optional) | |
32 | """ | |
33 | super().__init__(parent) | |
34 | self.setupUi(self) | |
35 | ||
36 | windowFlags = self.windowFlags() | |
37 | windowFlags |= Qt.WindowType.Window | |
38 | windowFlags |= Qt.WindowType.WindowContextHelpButtonHint | |
39 | self.setWindowFlags(windowFlags) | |
40 | ||
41 | self.__device = device | |
42 | ||
43 | self.devicesList.setColumnCount(4) | |
44 | self.devicesList.headerItem().setText(3, "") | |
45 | ||
46 | self.scanButton.clicked.connect(self.scanDevices) | |
47 | ||
48 | self.devicesList.sortByColumn(0, Qt.SortOrder.AscendingOrder) | |
49 | ||
50 | @pyqtSlot() | |
51 | def scanDevices(self): | |
52 | """ | |
53 | Public slot to ask the device for a Bluetooth scan and display the result. | |
54 | """ | |
55 | self.devicesList.clear() | |
56 | self.statusLabel.clear() | |
57 | ||
58 | self.scanButton.setEnabled(False) | |
59 | with EricOverrideCursor(): | |
60 | scanResults, error = self.__device.getDeviceScan( | |
61 | timeout=self.durationSpinBox.value() | |
62 | ) | |
63 | self.scanButton.setEnabled(True) | |
64 | ||
65 | if error: | |
66 | EricMessageBox.warning( | |
67 | self, | |
68 | self.tr("Bluetooth Scan"), | |
69 | self.tr( | |
70 | """<p>The scan for available devices failed.</p>""" | |
71 | """<p>Reason: {0}</p>""" | |
72 | ).format(error), | |
73 | ) | |
74 | ||
75 | else: | |
9859 | 76 | self.statusLabel.setText( |
77 | self.tr("<p>Detected <b>%n</b> device(s).</p>", "", len(scanResults)) | |
78 | ) | |
9857 | 79 | for res in scanResults.values(): |
80 | name = res.name | |
81 | if not name: | |
82 | name = self.tr("N/A") | |
83 | itm = QTreeWidgetItem( | |
84 | self.devicesList, [name, res.address, str(res.rssi)] | |
85 | ) | |
86 | itm.setTextAlignment(1, Qt.AlignmentFlag.AlignHCenter) | |
87 | itm.setTextAlignment(2, Qt.AlignmentFlag.AlignHCenter) | |
88 | ||
10090 | 89 | for serviceID, serviceName, isComplete in res.services: |
90 | if len(serviceID) == 6: | |
9857 | 91 | bits = 16 |
10090 | 92 | elif len(serviceID) == 10: |
9857 | 93 | bits = 32 |
94 | else: | |
95 | bits = 128 | |
96 | template = ( | |
10090 | 97 | self.tr("Complete {0}-bit Service UUID: {1}{2}") |
9857 | 98 | if isComplete |
10090 | 99 | else self.tr("Incomplete {0}-bit Service UUID: {1}{2}") |
9857 | 100 | ) |
10090 | 101 | citm = QTreeWidgetItem( |
102 | itm, | |
103 | [ | |
104 | template.format( | |
105 | bits, | |
106 | serviceID, | |
10621
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
107 | ( |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
108 | self.tr(" - {0}").format(serviceName) |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
109 | if serviceName |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
110 | else "" |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
111 | ), |
10090 | 112 | ) |
113 | ], | |
114 | ) | |
9859 | 115 | citm.setFirstColumnSpanned(True) |
9857 | 116 | |
9859 | 117 | seenMIds = [] |
9857 | 118 | for mid, _, mname in res.manufacturer(withName=True): |
9859 | 119 | if mid not in seenMIds: |
120 | citm = QTreeWidgetItem( | |
121 | itm, | |
122 | [ | |
10621
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
123 | ( |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
124 | self.tr("Manufacturer ID: 0x{0:x} - {1}").format( |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
125 | mid, mname |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
126 | ) |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
127 | if bool(mname) |
f5631f40c4d9
Corrected some code formatting issues.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
10439
diff
changeset
|
128 | else self.tr("Manufacturer ID: 0x{0:x}").format(mid) |
9859 | 129 | ) |
130 | ], | |
131 | ) | |
132 | citm.setFirstColumnSpanned(True) | |
133 | seenMIds.append(mid) | |
134 | ||
135 | txPower = res.txPower | |
136 | if txPower: | |
137 | citm = QTreeWidgetItem( | |
138 | itm, [self.tr("Tx Power Level [dBm]: {0}").format(txPower)] | |
9857 | 139 | ) |
9859 | 140 | citm.setFirstColumnSpanned(True) |
9857 | 141 | |
142 | self.__resizeColumns() | |
143 | self.__resort() | |
144 | ||
145 | def __resort(self): | |
146 | """ | |
147 | Private method to resort the devices list. | |
148 | """ | |
149 | self.devicesList.sortItems( | |
150 | self.devicesList.sortColumn(), | |
151 | self.devicesList.header().sortIndicatorOrder(), | |
152 | ) | |
153 | ||
154 | def __resizeColumns(self): | |
155 | """ | |
156 | Private method to resize the columns of the result list. | |
157 | """ | |
158 | self.devicesList.header().resizeSections( | |
159 | QHeaderView.ResizeMode.ResizeToContents | |
160 | ) | |
161 | self.devicesList.header().setStretchLastSection(True) |