lazylabel-gui 1.1.1__py3-none-any.whl → 1.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lazylabel/__init__.py +1 -1
- lazylabel/config/__init__.py +3 -3
- lazylabel/config/hotkeys.py +96 -58
- lazylabel/config/paths.py +8 -9
- lazylabel/config/settings.py +15 -16
- lazylabel/core/__init__.py +3 -3
- lazylabel/core/file_manager.py +49 -33
- lazylabel/core/model_manager.py +9 -11
- lazylabel/core/segment_manager.py +21 -22
- lazylabel/main.py +1 -0
- lazylabel/models/__init__.py +1 -1
- lazylabel/models/sam_model.py +24 -19
- lazylabel/ui/__init__.py +3 -3
- lazylabel/ui/control_panel.py +21 -19
- lazylabel/ui/editable_vertex.py +16 -3
- lazylabel/ui/hotkey_dialog.py +125 -93
- lazylabel/ui/hoverable_polygon_item.py +1 -2
- lazylabel/ui/main_window.py +290 -49
- lazylabel/ui/photo_viewer.py +4 -7
- lazylabel/ui/reorderable_class_table.py +2 -3
- lazylabel/ui/right_panel.py +15 -16
- lazylabel/ui/widgets/__init__.py +1 -1
- lazylabel/ui/widgets/adjustments_widget.py +22 -21
- lazylabel/ui/widgets/model_selection_widget.py +28 -21
- lazylabel/ui/widgets/settings_widget.py +35 -28
- lazylabel/ui/widgets/status_bar.py +2 -2
- lazylabel/utils/__init__.py +2 -2
- lazylabel/utils/custom_file_system_model.py +3 -2
- {lazylabel_gui-1.1.1.dist-info → lazylabel_gui-1.1.3.dist-info}/METADATA +48 -2
- lazylabel_gui-1.1.3.dist-info/RECORD +37 -0
- lazylabel_gui-1.1.1.dist-info/RECORD +0 -37
- {lazylabel_gui-1.1.1.dist-info → lazylabel_gui-1.1.3.dist-info}/WHEEL +0 -0
- {lazylabel_gui-1.1.1.dist-info → lazylabel_gui-1.1.3.dist-info}/entry_points.txt +0 -0
- {lazylabel_gui-1.1.1.dist-info → lazylabel_gui-1.1.3.dist-info}/licenses/LICENSE +0 -0
- {lazylabel_gui-1.1.1.dist-info → lazylabel_gui-1.1.3.dist-info}/top_level.txt +0 -0
lazylabel/ui/hotkey_dialog.py
CHANGED
@@ -1,41 +1,49 @@
|
|
1
1
|
"""Hotkey configuration dialog."""
|
2
2
|
|
3
|
+
from PyQt6.QtCore import Qt, QTimer, pyqtSignal
|
4
|
+
from PyQt6.QtGui import QColor, QFont, QKeySequence
|
3
5
|
from PyQt6.QtWidgets import (
|
4
|
-
QDialog,
|
5
|
-
|
6
|
-
|
6
|
+
QDialog,
|
7
|
+
QHBoxLayout,
|
8
|
+
QHeaderView,
|
9
|
+
QLabel,
|
10
|
+
QLineEdit,
|
11
|
+
QMessageBox,
|
12
|
+
QPushButton,
|
13
|
+
QTableWidget,
|
14
|
+
QTableWidgetItem,
|
15
|
+
QTabWidget,
|
16
|
+
QVBoxLayout,
|
17
|
+
QWidget,
|
7
18
|
)
|
8
|
-
from PyQt6.QtCore import Qt, pyqtSignal, QTimer
|
9
|
-
from PyQt6.QtGui import QKeySequence, QFont, QColor
|
10
|
-
from typing import Dict, List, Optional
|
11
19
|
|
12
|
-
from ..config import
|
20
|
+
from ..config import HotkeyAction, HotkeyManager
|
13
21
|
|
14
22
|
|
15
23
|
class HotkeyLineEdit(QLineEdit):
|
16
24
|
"""Custom line edit that captures key sequences."""
|
17
|
-
|
25
|
+
|
18
26
|
key_captured = pyqtSignal(str)
|
19
|
-
|
27
|
+
|
20
28
|
def __init__(self, parent=None):
|
21
29
|
super().__init__(parent)
|
22
30
|
self.setReadOnly(True)
|
23
31
|
self.setPlaceholderText("Click and press a key (Esc to cancel)")
|
24
32
|
self.capturing = False
|
25
33
|
self.original_style = self.styleSheet()
|
26
|
-
|
34
|
+
|
27
35
|
# Timeout timer to auto-cancel capture
|
28
36
|
self.timeout_timer = QTimer()
|
29
37
|
self.timeout_timer.setSingleShot(True)
|
30
38
|
self.timeout_timer.timeout.connect(self._timeout_capture)
|
31
39
|
self.timeout_duration = 15000 # 15 seconds
|
32
|
-
|
40
|
+
|
33
41
|
def mousePressEvent(self, event):
|
34
42
|
"""Start capturing keys when clicked."""
|
35
43
|
if event.button() == Qt.MouseButton.LeftButton:
|
36
44
|
self.start_capture()
|
37
45
|
super().mousePressEvent(event)
|
38
|
-
|
46
|
+
|
39
47
|
def start_capture(self):
|
40
48
|
"""Start capturing key input."""
|
41
49
|
self.capturing = True
|
@@ -43,52 +51,61 @@ class HotkeyLineEdit(QLineEdit):
|
|
43
51
|
self.setStyleSheet("background-color: #ffeb3b; color: black;")
|
44
52
|
self.setFocus()
|
45
53
|
self.timeout_timer.start(self.timeout_duration)
|
46
|
-
|
54
|
+
|
47
55
|
def stop_capture(self):
|
48
56
|
"""Stop capturing key input."""
|
49
57
|
self.capturing = False
|
50
58
|
self.setStyleSheet(self.original_style)
|
51
59
|
self.clearFocus()
|
52
60
|
self.timeout_timer.stop()
|
53
|
-
|
61
|
+
|
54
62
|
def keyPressEvent(self, event):
|
55
63
|
"""Capture key press events."""
|
56
64
|
if not self.capturing:
|
57
65
|
super().keyPressEvent(event)
|
58
66
|
return
|
59
|
-
|
67
|
+
|
60
68
|
# Handle Escape key to cancel capture
|
61
69
|
if event.key() == Qt.Key.Key_Escape:
|
62
70
|
self.setText("") # Clear the field
|
63
71
|
self.stop_capture()
|
64
72
|
return
|
65
|
-
|
73
|
+
|
66
74
|
# Ignore modifier-only keys and other problematic keys
|
67
75
|
ignored_keys = {
|
68
|
-
Qt.Key.Key_Control,
|
69
|
-
Qt.Key.
|
70
|
-
Qt.Key.
|
76
|
+
Qt.Key.Key_Control,
|
77
|
+
Qt.Key.Key_Shift,
|
78
|
+
Qt.Key.Key_Alt,
|
79
|
+
Qt.Key.Key_Meta,
|
80
|
+
Qt.Key.Key_CapsLock,
|
81
|
+
Qt.Key.Key_NumLock,
|
82
|
+
Qt.Key.Key_ScrollLock,
|
83
|
+
Qt.Key.Key_unknown,
|
84
|
+
Qt.Key.Key_Tab,
|
85
|
+
Qt.Key.Key_Backtab,
|
71
86
|
}
|
72
|
-
|
87
|
+
|
73
88
|
if event.key() in ignored_keys:
|
74
89
|
return
|
75
|
-
|
90
|
+
|
76
91
|
try:
|
77
92
|
# Create key sequence - properly handle modifiers
|
78
93
|
modifiers = event.modifiers()
|
79
94
|
key = event.key()
|
80
|
-
|
95
|
+
|
81
96
|
# Skip invalid keys
|
82
97
|
if key == 0 or key == Qt.Key.Key_unknown:
|
83
98
|
return
|
84
|
-
|
99
|
+
|
85
100
|
# Convert modifiers to int and combine with key
|
86
|
-
modifier_int =
|
101
|
+
modifier_int = (
|
102
|
+
int(modifiers.value) if hasattr(modifiers, "value") else int(modifiers)
|
103
|
+
)
|
87
104
|
key_combination = key | modifier_int
|
88
|
-
|
105
|
+
|
89
106
|
key_sequence = QKeySequence(key_combination)
|
90
107
|
key_string = key_sequence.toString()
|
91
|
-
|
108
|
+
|
92
109
|
# Only accept valid, non-empty key strings
|
93
110
|
if key_string and key_string.strip():
|
94
111
|
self.setText(key_string)
|
@@ -97,13 +114,13 @@ class HotkeyLineEdit(QLineEdit):
|
|
97
114
|
else:
|
98
115
|
# Invalid key combination, just ignore
|
99
116
|
return
|
100
|
-
|
117
|
+
|
101
118
|
except Exception as e:
|
102
119
|
print(f"Error capturing key sequence: {e}")
|
103
120
|
# Cancel capture on any error
|
104
121
|
self.setText("")
|
105
122
|
self.stop_capture()
|
106
|
-
|
123
|
+
|
107
124
|
def focusOutEvent(self, event):
|
108
125
|
"""Stop capturing when focus is lost."""
|
109
126
|
if self.capturing:
|
@@ -111,7 +128,7 @@ class HotkeyLineEdit(QLineEdit):
|
|
111
128
|
if not self.text() or self.text().startswith("Press a key"):
|
112
129
|
self.setText("")
|
113
130
|
super().focusOutEvent(event)
|
114
|
-
|
131
|
+
|
115
132
|
def _timeout_capture(self):
|
116
133
|
"""Handle capture timeout."""
|
117
134
|
if self.capturing:
|
@@ -121,24 +138,24 @@ class HotkeyLineEdit(QLineEdit):
|
|
121
138
|
|
122
139
|
class HotkeyDialog(QDialog):
|
123
140
|
"""Dialog for configuring hotkeys."""
|
124
|
-
|
141
|
+
|
125
142
|
def __init__(self, hotkey_manager: HotkeyManager, parent=None):
|
126
143
|
super().__init__(parent)
|
127
144
|
self.hotkey_manager = hotkey_manager
|
128
145
|
self.modified = False
|
129
146
|
self.key_widgets = {} # Maps (action_name, key_type) to widget
|
130
|
-
|
147
|
+
|
131
148
|
self.setWindowTitle("Hotkey Configuration")
|
132
149
|
self.setModal(True)
|
133
150
|
self.resize(800, 600)
|
134
|
-
|
151
|
+
|
135
152
|
self._setup_ui()
|
136
153
|
self._populate_hotkeys()
|
137
|
-
|
154
|
+
|
138
155
|
def _setup_ui(self):
|
139
156
|
"""Setup the dialog UI."""
|
140
157
|
layout = QVBoxLayout(self)
|
141
|
-
|
158
|
+
|
142
159
|
# Title
|
143
160
|
title = QLabel("Hotkey Configuration")
|
144
161
|
title_font = QFont()
|
@@ -147,7 +164,7 @@ class HotkeyDialog(QDialog):
|
|
147
164
|
title.setFont(title_font)
|
148
165
|
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
149
166
|
layout.addWidget(title)
|
150
|
-
|
167
|
+
|
151
168
|
# Instructions
|
152
169
|
instructions = QLabel(
|
153
170
|
"Click on a hotkey field and press the desired key combination. "
|
@@ -156,68 +173,74 @@ class HotkeyDialog(QDialog):
|
|
156
173
|
instructions.setWordWrap(True)
|
157
174
|
instructions.setStyleSheet("color: #666; margin: 10px;")
|
158
175
|
layout.addWidget(instructions)
|
159
|
-
|
176
|
+
|
160
177
|
# Tab widget for categories
|
161
178
|
self.tab_widget = QTabWidget()
|
162
179
|
layout.addWidget(self.tab_widget)
|
163
|
-
|
180
|
+
|
164
181
|
# Button layout
|
165
182
|
button_layout = QHBoxLayout()
|
166
|
-
|
183
|
+
|
167
184
|
# Save button
|
168
185
|
self.save_button = QPushButton("Save Hotkeys")
|
169
|
-
self.save_button.setToolTip(
|
186
|
+
self.save_button.setToolTip(
|
187
|
+
"Save hotkeys to file for persistence between sessions"
|
188
|
+
)
|
170
189
|
self.save_button.clicked.connect(self._save_hotkeys)
|
171
190
|
button_layout.addWidget(self.save_button)
|
172
|
-
|
191
|
+
|
173
192
|
# Defaults button
|
174
193
|
self.defaults_button = QPushButton("Reset to Defaults")
|
175
194
|
self.defaults_button.setToolTip("Reset all hotkeys to default values")
|
176
195
|
self.defaults_button.clicked.connect(self._reset_to_defaults)
|
177
196
|
button_layout.addWidget(self.defaults_button)
|
178
|
-
|
197
|
+
|
179
198
|
button_layout.addStretch()
|
180
|
-
|
199
|
+
|
181
200
|
# Close button
|
182
201
|
self.close_button = QPushButton("Close")
|
183
202
|
self.close_button.clicked.connect(self.accept)
|
184
203
|
button_layout.addWidget(self.close_button)
|
185
|
-
|
204
|
+
|
186
205
|
layout.addLayout(button_layout)
|
187
|
-
|
188
|
-
def _create_category_tab(
|
206
|
+
|
207
|
+
def _create_category_tab(
|
208
|
+
self, category_name: str, actions: list[HotkeyAction]
|
209
|
+
) -> QWidget:
|
189
210
|
"""Create a tab for a category of hotkeys."""
|
190
211
|
widget = QWidget()
|
191
212
|
layout = QVBoxLayout(widget)
|
192
|
-
|
213
|
+
|
193
214
|
# Create table
|
194
215
|
table = QTableWidget()
|
195
216
|
table.setColumnCount(4)
|
196
|
-
table.setHorizontalHeaderLabels(
|
217
|
+
table.setHorizontalHeaderLabels(
|
218
|
+
["Action", "Description", "Primary Key", "Secondary Key"]
|
219
|
+
)
|
197
220
|
table.setRowCount(len(actions))
|
198
|
-
|
221
|
+
|
199
222
|
# Configure table
|
200
223
|
header = table.horizontalHeader()
|
201
224
|
header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
|
202
225
|
header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
|
203
226
|
header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
|
204
227
|
header.setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
|
205
|
-
|
228
|
+
|
206
229
|
table.setAlternatingRowColors(True)
|
207
230
|
table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
|
208
|
-
|
231
|
+
|
209
232
|
# Populate table
|
210
233
|
for row, action in enumerate(actions):
|
211
234
|
# Action name
|
212
|
-
name_item = QTableWidgetItem(action.name.replace(
|
235
|
+
name_item = QTableWidgetItem(action.name.replace("_", " ").title())
|
213
236
|
name_item.setFlags(name_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
|
214
237
|
table.setItem(row, 0, name_item)
|
215
|
-
|
238
|
+
|
216
239
|
# Description
|
217
240
|
desc_item = QTableWidgetItem(action.description)
|
218
241
|
desc_item.setFlags(desc_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
|
219
242
|
table.setItem(row, 1, desc_item)
|
220
|
-
|
243
|
+
|
221
244
|
# Primary key
|
222
245
|
primary_edit = HotkeyLineEdit()
|
223
246
|
primary_edit.setText(action.primary_key or "")
|
@@ -230,8 +253,8 @@ class HotkeyDialog(QDialog):
|
|
230
253
|
lambda key, name=action.name: self._update_primary_key(name, key)
|
231
254
|
)
|
232
255
|
table.setCellWidget(row, 2, primary_edit)
|
233
|
-
self.key_widgets[(action.name,
|
234
|
-
|
256
|
+
self.key_widgets[(action.name, "primary")] = primary_edit
|
257
|
+
|
235
258
|
# Secondary key
|
236
259
|
secondary_edit = HotkeyLineEdit()
|
237
260
|
secondary_edit.setText(action.secondary_key or "")
|
@@ -244,58 +267,67 @@ class HotkeyDialog(QDialog):
|
|
244
267
|
lambda key, name=action.name: self._update_secondary_key(name, key)
|
245
268
|
)
|
246
269
|
table.setCellWidget(row, 3, secondary_edit)
|
247
|
-
self.key_widgets[(action.name,
|
248
|
-
|
270
|
+
self.key_widgets[(action.name, "secondary")] = secondary_edit
|
271
|
+
|
249
272
|
# Style mouse-related rows
|
250
273
|
if action.mouse_related:
|
251
274
|
for col in range(4):
|
252
275
|
item = table.item(row, col)
|
253
276
|
if item:
|
254
277
|
item.setBackground(QColor("#f8f8f8"))
|
255
|
-
|
278
|
+
|
256
279
|
layout.addWidget(table)
|
257
280
|
return widget
|
258
|
-
|
281
|
+
|
259
282
|
def _populate_hotkeys(self):
|
260
283
|
"""Populate the hotkey tabs."""
|
261
284
|
categories = self.hotkey_manager.get_actions_by_category()
|
262
|
-
|
285
|
+
|
263
286
|
# Define tab order
|
264
|
-
tab_order = [
|
265
|
-
|
287
|
+
tab_order = [
|
288
|
+
"Modes",
|
289
|
+
"Actions",
|
290
|
+
"Navigation",
|
291
|
+
"Segments",
|
292
|
+
"View",
|
293
|
+
"Movement",
|
294
|
+
"Mouse",
|
295
|
+
"General",
|
296
|
+
]
|
297
|
+
|
266
298
|
for category in tab_order:
|
267
299
|
if category in categories:
|
268
300
|
tab_widget = self._create_category_tab(category, categories[category])
|
269
301
|
self.tab_widget.addTab(tab_widget, category)
|
270
|
-
|
302
|
+
|
271
303
|
# Add any remaining categories
|
272
304
|
for category, actions in categories.items():
|
273
305
|
if category not in tab_order:
|
274
306
|
tab_widget = self._create_category_tab(category, actions)
|
275
307
|
self.tab_widget.addTab(tab_widget, category)
|
276
|
-
|
308
|
+
|
277
309
|
def _update_primary_key(self, action_name: str, key: str):
|
278
310
|
"""Update primary key for an action."""
|
279
311
|
# Check for conflicts
|
280
312
|
conflict = self.hotkey_manager.is_key_in_use(key, exclude_action=action_name)
|
281
313
|
if conflict:
|
282
314
|
QMessageBox.warning(
|
283
|
-
self,
|
284
|
-
"Key Conflict",
|
315
|
+
self,
|
316
|
+
"Key Conflict",
|
285
317
|
f"The key '{key}' is already used by '{conflict.replace('_', ' ').title()}'. "
|
286
|
-
"Please choose a different key."
|
318
|
+
"Please choose a different key.",
|
287
319
|
)
|
288
320
|
# Reset the field
|
289
|
-
widget = self.key_widgets.get((action_name,
|
321
|
+
widget = self.key_widgets.get((action_name, "primary"))
|
290
322
|
if widget:
|
291
323
|
action = self.hotkey_manager.get_action(action_name)
|
292
324
|
widget.setText(action.primary_key if action else "")
|
293
325
|
return
|
294
|
-
|
326
|
+
|
295
327
|
# Update the hotkey
|
296
328
|
if self.hotkey_manager.set_primary_key(action_name, key):
|
297
329
|
self.modified = True
|
298
|
-
|
330
|
+
|
299
331
|
def _update_secondary_key(self, action_name: str, key: str):
|
300
332
|
"""Update secondary key for an action."""
|
301
333
|
# Allow empty key for secondary
|
@@ -303,43 +335,41 @@ class HotkeyDialog(QDialog):
|
|
303
335
|
self.hotkey_manager.set_secondary_key(action_name, None)
|
304
336
|
self.modified = True
|
305
337
|
return
|
306
|
-
|
338
|
+
|
307
339
|
# Check for conflicts
|
308
340
|
conflict = self.hotkey_manager.is_key_in_use(key, exclude_action=action_name)
|
309
341
|
if conflict:
|
310
342
|
QMessageBox.warning(
|
311
|
-
self,
|
312
|
-
"Key Conflict",
|
343
|
+
self,
|
344
|
+
"Key Conflict",
|
313
345
|
f"The key '{key}' is already used by '{conflict.replace('_', ' ').title()}'. "
|
314
|
-
"Please choose a different key."
|
346
|
+
"Please choose a different key.",
|
315
347
|
)
|
316
348
|
# Reset the field
|
317
|
-
widget = self.key_widgets.get((action_name,
|
349
|
+
widget = self.key_widgets.get((action_name, "secondary"))
|
318
350
|
if widget:
|
319
351
|
action = self.hotkey_manager.get_action(action_name)
|
320
352
|
widget.setText(action.secondary_key or "")
|
321
353
|
return
|
322
|
-
|
354
|
+
|
323
355
|
# Update the hotkey
|
324
356
|
if self.hotkey_manager.set_secondary_key(action_name, key):
|
325
357
|
self.modified = True
|
326
|
-
|
358
|
+
|
327
359
|
def _save_hotkeys(self):
|
328
360
|
"""Save hotkeys to file."""
|
329
361
|
try:
|
330
362
|
self.hotkey_manager.save_hotkeys()
|
331
363
|
QMessageBox.information(
|
332
|
-
self,
|
333
|
-
"Hotkeys Saved",
|
334
|
-
"Hotkeys have been saved and will persist between sessions."
|
364
|
+
self,
|
365
|
+
"Hotkeys Saved",
|
366
|
+
"Hotkeys have been saved and will persist between sessions.",
|
335
367
|
)
|
336
368
|
except Exception as e:
|
337
369
|
QMessageBox.critical(
|
338
|
-
self,
|
339
|
-
"Save Error",
|
340
|
-
f"Failed to save hotkeys: {str(e)}"
|
370
|
+
self, "Save Error", f"Failed to save hotkeys: {str(e)}"
|
341
371
|
)
|
342
|
-
|
372
|
+
|
343
373
|
def _reset_to_defaults(self):
|
344
374
|
"""Reset all hotkeys to defaults."""
|
345
375
|
reply = QMessageBox.question(
|
@@ -347,22 +377,22 @@ class HotkeyDialog(QDialog):
|
|
347
377
|
"Reset Hotkeys",
|
348
378
|
"Are you sure you want to reset all hotkeys to their default values?",
|
349
379
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
350
|
-
QMessageBox.StandardButton.No
|
380
|
+
QMessageBox.StandardButton.No,
|
351
381
|
)
|
352
|
-
|
382
|
+
|
353
383
|
if reply == QMessageBox.StandardButton.Yes:
|
354
384
|
self.hotkey_manager.reset_to_defaults()
|
355
385
|
self.modified = True
|
356
|
-
|
386
|
+
|
357
387
|
# Update all widgets
|
358
388
|
for (action_name, key_type), widget in self.key_widgets.items():
|
359
389
|
action = self.hotkey_manager.get_action(action_name)
|
360
390
|
if action:
|
361
|
-
if key_type ==
|
391
|
+
if key_type == "primary":
|
362
392
|
widget.setText(action.primary_key or "")
|
363
393
|
else:
|
364
394
|
widget.setText(action.secondary_key or "")
|
365
|
-
|
395
|
+
|
366
396
|
def closeEvent(self, event):
|
367
397
|
"""Handle dialog close."""
|
368
398
|
if self.modified:
|
@@ -370,15 +400,17 @@ class HotkeyDialog(QDialog):
|
|
370
400
|
self,
|
371
401
|
"Unsaved Changes",
|
372
402
|
"You have unsaved hotkey changes. Do you want to apply them for this session?",
|
373
|
-
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No | QMessageBox.StandardButton.Cancel,
|
374
403
|
QMessageBox.StandardButton.Yes
|
404
|
+
| QMessageBox.StandardButton.No
|
405
|
+
| QMessageBox.StandardButton.Cancel,
|
406
|
+
QMessageBox.StandardButton.Yes,
|
375
407
|
)
|
376
|
-
|
408
|
+
|
377
409
|
if reply == QMessageBox.StandardButton.Cancel:
|
378
410
|
event.ignore()
|
379
411
|
return
|
380
412
|
elif reply == QMessageBox.StandardButton.No:
|
381
413
|
# Reload from file to discard changes
|
382
414
|
self.hotkey_manager.load_hotkeys()
|
383
|
-
|
384
|
-
super().closeEvent(event)
|
415
|
+
|
416
|
+
super().closeEvent(event)
|