Unified Dialog System¶
A theme-aware dialog system providing message boxes, loading dialogs, input dialogs, and confirmation dialogs with consistent styling and behavior.
Quick Start¶
from src.shared_services.prompt_dialogs.api import (
show_info,
show_warning,
show_error,
ask_question,
LoadingDialog,
ConfirmationDialog,
InputDialog,
)
# Simple message dialogs
show_info(parent, "Success", "File saved successfully.")
show_warning(parent, "Warning", "Unsaved changes detected.")
show_error(parent, "Error", "Failed to connect to server.")
# Question dialog
from PySide6.QtWidgets import QMessageBox
result = ask_question(parent, "Confirm", "Delete this item?")
if result == QMessageBox.StandardButton.Yes:
delete_item()
# Loading dialog with context manager
with LoadingDialog(parent) as loading:
loading.show_loading("Processing files...")
for i, item in enumerate(items):
loading.update_progress(f"Item {i + 1}/{len(items)}", int(100 * i / len(items)))
process_item(item)
# Validated text input
name, ok = InputDialog.get_text(
parent,
title="New Project",
prompt="Project name:",
blacklist=existing_names,
)
if ok:
create_project(name)
# Typed confirmation for destructive actions
if ConfirmationDialog.confirm(
parent,
item_name="important_project.xml",
confirmation_word="Delete",
):
delete_file("important_project.xml")
Components¶
MessageDialog¶
Theme-aware replacement for QMessageBox with static convenience methods:
MessageDialog.info()- Information messagesMessageDialog.warning()- Warning messagesMessageDialog.error()- Error messagesMessageDialog.question()- Yes/No questions
LoadingDialog¶
Modal loading dialog with:
- Animated spinner
- Progress bar with percentage
- Subprocess status tracking
- Message box interception (displays within dialog)
- Fail-safe close button after timeout
- Context manager support
InputDialog¶
Validated text input with:
- Real-time validation feedback
- Blacklist support (existing names)
- Invalid character detection
- Reserved name detection (CON, PRN, etc.)
ConfirmationDialog¶
Typed confirmation for destructive actions:
- User must type a specific word to confirm
- Real-time validation
- Prevents accidental deletion
Message Interception System¶
During loading operations, QMessageBox calls are automatically intercepted and displayed within the loading dialog. This provides seamless user experience and prevents dialog overlap.
All interceptions are logged for developer monitoring:
from src.shared_services.prompt_dialogs.api import get_recent_interceptions
# Review recent interceptions
for entry in get_recent_interceptions(10):
print(f"[{entry.message_type.name}] {entry.title}")
print(f" Source: {entry.source_file}:{entry.source_line}")
Sound Patch¶
Suppresses Windows system sounds for message dialogs:
from src.shared_services.prompt_dialogs.api import apply_sound_patch
# Apply at application startup
apply_sound_patch()
Styling¶
All components use setObjectName() for QSS targeting. Stylesheets are located in:
data/.app_data/stylesheets/dialogs/
main.qss # Common styles
message_dialog.qss # MessageDialog styles
loading_dialog.qss # LoadingDialog styles
confirmation_dialog.qss # ConfirmationDialog styles
input_dialog.qss # InputDialog styles
Module Structure¶
src/shared_services/dialogs/
__init__.py
api.py # Public API exports
README.md
constants/
paths.py # PathDef definitions
base/
theme_aware_dialog.py # Base class with theme support
dialog_registry.py # Active dialog tracking
message_box/
message_dialog.py # Info, warning, error, question
loading/
loading_dialog.py # Main loading dialog
loading_spinner.py # Spinner widget
confirmation/
confirmation_dialog.py # Typed confirmation
input/
input_dialog.py # Validated text input
validators.py # Validation logic
interception/
interceptor.py # MessageBox interception
interception_log.py # Logging for monitoring
sound/
sound_patch.py # Windows sound suppression
Theme Integration¶
All dialogs automatically register with StylesheetManager for theme updates. When the application theme changes, dialogs update their appearance accordingly.
To create a custom theme-aware dialog:
from src.shared_services.prompt_dialogs.base.theme_aware_dialog import ThemeAwareDialog
from src.shared_services.prompt_dialogs.constants.paths import DialogStylesheets
class MyDialog(ThemeAwareDialog):
def __init__(self, parent=None):
super().__init__(
parent=parent,
stylesheets=[DialogStylesheets.Main],
)
self._setup_ui()
def _on_theme_changed(self, theme: str) -> None:
# Handle theme changes (optional)
pass
API Reference¶
src.shared_services.prompt_dialogs.api
¶
Unified Dialog System API.
Provides a clean, theme-aware API for all application dialogs including message boxes, loading dialogs, input dialogs, and confirmation dialogs.
Usage
from src.shared_services.dialogs.api import ( # Dialog classes MessageDialog, LoadingDialog, ConfirmationDialog, InputDialog,
# Convenience functions
show_info,
show_warning,
show_error,
ask_question,
)
Show a simple info message¶
show_info(parent, "Success", "File saved successfully.")
Show a warning with custom buttons¶
result = show_warning( parent, "Unsaved Changes", "You have unsaved changes. Save before closing?", buttons=QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, )
Use loading dialog with context manager¶
with LoadingDialog(parent) as loading: loading.show_loading("Processing files...") loading.update_progress("Step 1/3", 33) do_work()
Get validated text input¶
name, ok = InputDialog.get_text( parent, title="New Project", prompt="Project name:", blacklist=existing_names, ) if ok: create_project(name)
Confirm destructive action¶
if ConfirmationDialog.confirm( parent, item_name="important_project.xml", confirmation_word="Delete", ): delete_file("important_project.xml")
ButtonDef
dataclass
¶
Definition for a button in a MultiButtonDialog.
Attributes:
| Name | Type | Description |
|---|---|---|
text |
str
|
Button label text. |
style |
str
|
Visual style -- "outlined", "filled", or "hold_to_confirm". |
result |
str
|
Identifier string returned when this button is clicked. |
Source code in src\shared_services\prompt_dialogs\multi_button\multi_button_dialog.py
ConfirmationDialog
¶
Bases: ThemeAwareDialog
Confirmation dialog for destructive actions.
When confirmation_word is non-empty the user must type that word
before the hold-to-confirm button becomes active. When it is empty,
the button is active immediately and the text input is hidden.
Signals
confirmed: Emitted when the action is confirmed.
Example
Creating a typed confirmation dialog::
dialog = ConfirmationDialog(
parent=self,
title="Delete Project",
item_name="my_project.xml",
confirmation_word="Delete",
)
if dialog.exec():
delete_project()
Source code in src\shared_services\prompt_dialogs\confirmation\confirmation_dialog.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | |
__init__(parent=None, title='Confirm Action', item_name='', confirmation_word='Delete', warning_message='', show_confirmation_word=True)
¶
Initialize the confirmation dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
None
|
title
|
str
|
Dialog title. |
'Confirm Action'
|
item_name
|
str
|
Name of the item being deleted/modified. |
''
|
confirmation_word
|
str
|
Word the user must type to confirm. Pass empty string for simple hold-to-confirm mode. |
'Delete'
|
warning_message
|
str
|
Optional custom warning message. |
''
|
show_confirmation_word
|
bool
|
If True (default), reveal the word in the instruction label and placeholder. If False, hide it (password-style confirmation). |
True
|
Source code in src\shared_services\prompt_dialogs\confirmation\confirmation_dialog.py
confirm(parent=None, title='Confirm Delete', item_name='', confirmation_word='Delete', warning_message='', show_confirmation_word=True)
staticmethod
¶
Show confirmation dialog and return result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
None
|
title
|
str
|
Dialog title. |
'Confirm Delete'
|
item_name
|
str
|
Name of item being deleted. |
''
|
confirmation_word
|
str
|
Word user must type to confirm. Pass empty string for simple hold-to-confirm mode. |
'Delete'
|
warning_message
|
str
|
Optional custom warning message. |
''
|
show_confirmation_word
|
bool
|
If True (default), reveal the word. If False, hide it (password-style confirmation). |
True
|
Returns:
| Type | Description |
|---|---|
bool
|
True if the user confirmed, False otherwise. |
Example
Typed confirmation::
if ConfirmationDialog.confirm(
self,
item_name="project.xml",
):
delete_file("project.xml")
Simple hold-to-confirm::
if ConfirmationDialog.confirm(
self,
title="Element loeschen",
confirmation_word="",
warning_message="Wirklich loeschen?",
):
delete_element()
Source code in src\shared_services\prompt_dialogs\confirmation\confirmation_dialog.py
is_confirmed()
¶
Check if the action was confirmed.
Returns:
| Type | Description |
|---|---|
bool
|
True if the user confirmed the action. |
DialogRegistry
¶
Singleton registry for tracking active dialogs.
Uses weak references to automatically clean up deleted dialogs. Provides methods for querying active dialogs by type.
The registry is primarily used by the interception system to determine if a loading dialog is active and should intercept message box calls.
Thread-safe singleton implementation using a lock.
Example
Registering a dialog::
registry = DialogRegistry.instance()
registry.register(loading_dialog, "loading")
Checking for active loading::
if registry.is_loading_active():
loading = registry.get_active_loading_dialog()
Source code in src\shared_services\prompt_dialogs\base\dialog_registry.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | |
__init__()
¶
get_active_loading_dialog()
¶
Get the currently active loading dialog.
Returns:
| Type | Description |
|---|---|
Optional[ThemeAwareDialog]
|
The active loading dialog, or None if none is active. |
Source code in src\shared_services\prompt_dialogs\base\dialog_registry.py
get_dialogs_by_type(dialog_type)
¶
Get all registered dialogs of a specific type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dialog_type
|
str
|
Type identifier to filter by. |
required |
Returns:
| Type | Description |
|---|---|
List[ThemeAwareDialog]
|
List of dialogs matching the type. |
Source code in src\shared_services\prompt_dialogs\base\dialog_registry.py
get_registered_count()
¶
Get the number of registered dialogs.
Returns:
| Type | Description |
|---|---|
int
|
Count of registered dialogs. |
instance()
classmethod
¶
Get the singleton instance.
Thread-safe lazy initialization.
Returns:
| Type | Description |
|---|---|
DialogRegistry
|
The shared DialogRegistry instance. |
Source code in src\shared_services\prompt_dialogs\base\dialog_registry.py
is_loading_active()
¶
Check if any loading dialog is currently active.
Returns:
| Type | Description |
|---|---|
bool
|
True if at least one loading dialog is registered and visible. |
Source code in src\shared_services\prompt_dialogs\base\dialog_registry.py
register(dialog, dialog_type)
¶
Register a dialog for tracking.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dialog
|
ThemeAwareDialog
|
The dialog to track. |
required |
dialog_type
|
str
|
Type identifier (e.g., "loading", "message"). |
required |
Source code in src\shared_services\prompt_dialogs\base\dialog_registry.py
reset_instance()
classmethod
¶
unregister(dialog)
¶
Unregister a dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dialog
|
ThemeAwareDialog
|
The dialog to unregister. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the dialog was found and unregistered. |
Source code in src\shared_services\prompt_dialogs\base\dialog_registry.py
DialogStyle
¶
Bases: Enum
Visual style presets for MultiButtonDialog.
Controls the icon and accent color without changing functionality.
Source code in src\shared_services\prompt_dialogs\multi_button\multi_button_dialog.py
InputDialog
¶
Bases: ThemeAwareDialog
Dialog for validated text input.
Provides real-time validation with error feedback. Supports blacklists, invalid character detection, and reserved name checking.
Signals
valid_input_entered: Emitted when valid input is accepted.
Example
Using the dialog::
dialog = InputDialog(
parent=self,
title="Rename File",
prompt="New name:",
blacklist=existing_files,
initial_text="document",
)
if dialog.exec():
new_name = dialog.get_entered_text()
Source code in src\shared_services\prompt_dialogs\input\input_dialog.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | |
__init__(parent=None, title='Enter Name', prompt='Name:', blacklist=None, allow_empty=False, initial_text='', placeholder_text='Enter a valid name...', valid_text='Valid name', error_text='Invalid input.')
¶
Initialize the input dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
None
|
title
|
str
|
Dialog title. |
'Enter Name'
|
prompt
|
str
|
Label text for the input field. |
'Name:'
|
blacklist
|
List[str] | None
|
List of names that are not allowed. |
None
|
allow_empty
|
bool
|
Whether empty input is allowed. |
False
|
initial_text
|
str
|
Initial text in the input field. |
''
|
placeholder_text
|
str
|
Placeholder text shown in the input field. |
'Enter a valid name...'
|
valid_text
|
str
|
Text shown when input is valid. |
'Valid name'
|
error_text
|
str
|
Fallback text shown when input is invalid. |
'Invalid input.'
|
Source code in src\shared_services\prompt_dialogs\input\input_dialog.py
get_entered_text()
¶
Get the entered text after dialog closes.
Returns:
| Type | Description |
|---|---|
str
|
The validated text entered by the user. |
get_text(parent=None, title='Enter Name', prompt='Name:', blacklist=None, allow_empty=False, initial_text='', placeholder_text='Enter a valid name...', valid_text='Valid name', error_text='Invalid input.')
staticmethod
¶
Show input dialog and get validated text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
None
|
title
|
str
|
Dialog title. |
'Enter Name'
|
prompt
|
str
|
Label text for input field. |
'Name:'
|
blacklist
|
List[str] | None
|
List of disallowed names. |
None
|
allow_empty
|
bool
|
Whether empty input is allowed. |
False
|
initial_text
|
str
|
Initial text in the input field. |
''
|
placeholder_text
|
str
|
Placeholder text shown in the input field. |
'Enter a valid name...'
|
valid_text
|
str
|
Text shown when input is valid. |
'Valid name'
|
error_text
|
str
|
Fallback text shown when input is invalid. |
'Invalid input.'
|
Returns:
| Type | Description |
|---|---|
Tuple[str, bool]
|
Tuple of (text, accepted). Text is empty if not accepted. |
Example
Getting a project name::
name, ok = InputDialog.get_text(
self,
title="New Project",
prompt="Project name:",
blacklist=existing_projects,
)
if ok:
create_project(name)
Source code in src\shared_services\prompt_dialogs\input\input_dialog.py
set_text(text)
¶
Set the input field text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to set. |
required |
InputValidator
¶
Validator for text input.
Checks for: - Empty input (if not allowed) - Invalid file name characters - Reserved system names (Windows) - Names ending with period - Blacklisted names (case-insensitive)
Example
Basic validation::
validator = InputValidator(
blacklist=["existing_project"],
allow_empty=False,
)
result = validator.validate("new_project")
if not result.is_valid:
print(result.error_message)
Source code in src\shared_services\prompt_dialogs\input\validators.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | |
__init__(blacklist=None, allow_empty=False, max_length=255, custom_pattern=None, custom_error=None)
¶
Initialize the validator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
blacklist
|
List[str] | None
|
List of names that are not allowed. |
None
|
allow_empty
|
bool
|
Whether empty input is allowed. |
False
|
max_length
|
int
|
Maximum allowed length. |
255
|
custom_pattern
|
str | None
|
Additional regex pattern for invalid characters. |
None
|
custom_error
|
str | None
|
Error message for custom pattern violations. |
None
|
Source code in src\shared_services\prompt_dialogs\input\validators.py
add_to_blacklist(name)
¶
Add a name to the blacklist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name to blacklist. |
required |
clear_blacklist()
¶
remove_from_blacklist(name)
¶
Remove a name from the blacklist.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name to remove. |
required |
validate(text)
¶
Validate the input text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text to validate. |
required |
Returns:
| Type | Description |
|---|---|
ValidationResult
|
ValidationResult with is_valid and optional error_message. |
Source code in src\shared_services\prompt_dialogs\input\validators.py
InterceptionEntry
dataclass
¶
Record of an intercepted message box.
Attributes:
| Name | Type | Description |
|---|---|---|
timestamp |
datetime
|
When the interception occurred. |
message_type |
MessageBoxType
|
Type of message box. |
title |
str
|
Message box title. |
message |
str
|
Message box text content. |
source_file |
Optional[str]
|
File where the message box was triggered. |
source_line |
Optional[int]
|
Line number in the source file. |
call_stack |
str
|
Full call stack at interception time. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
InterceptionLog
¶
Singleton log for tracking intercepted message boxes.
Maintains a circular buffer of recent interceptions with call stack information to help developers identify problematic code.
Example
Logging an interception::
InterceptionLog.log(
message_type=MessageBoxType.WARNING,
title="Error",
message="Failed to save",
)
Reviewing entries::
for entry in InterceptionLog.get_recent_entries():
print(f"[{entry.timestamp}] {entry.title}")
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | |
clear()
classmethod
¶
disable()
classmethod
¶
enable()
classmethod
¶
format_entry(entry)
classmethod
¶
Format an entry for display.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entry
|
InterceptionEntry
|
The entry to format. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Formatted string representation. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
get_all_entries()
classmethod
¶
Get all logged interception entries.
Returns:
| Type | Description |
|---|---|
List[InterceptionEntry]
|
List of all InterceptionEntry objects. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
get_entries_by_source(source_pattern)
classmethod
¶
Get entries filtered by source file pattern.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_pattern
|
str
|
Substring to match in source file path. |
required |
Returns:
| Type | Description |
|---|---|
List[InterceptionEntry]
|
List of matching entries. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
get_entries_by_type(message_type)
classmethod
¶
Get entries filtered by message type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message_type
|
MessageBoxType
|
Type to filter by. |
required |
Returns:
| Type | Description |
|---|---|
List[InterceptionEntry]
|
List of matching entries. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
get_recent_entries(count=10)
classmethod
¶
Get the most recent interception entries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
Maximum number of entries to return. |
10
|
Returns:
| Type | Description |
|---|---|
List[InterceptionEntry]
|
List of recent InterceptionEntry objects. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
is_enabled()
classmethod
¶
Check if logging is enabled.
Returns:
| Type | Description |
|---|---|
bool
|
True if logging is enabled. |
log(message_type, title, message, capture_stack=True)
classmethod
¶
Log an intercepted message box.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message_type
|
MessageBoxType
|
Type of message box. |
required |
title
|
str
|
Message box title. |
required |
message
|
str
|
Message box content. |
required |
capture_stack
|
bool
|
Whether to capture the call stack. |
True
|
Returns:
| Type | Description |
|---|---|
InterceptionEntry
|
The created InterceptionEntry. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
set_max_entries(max_entries)
classmethod
¶
Set the maximum number of entries to keep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_entries
|
int
|
Maximum entry count. |
required |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
InterceptionManager
¶
Bases: QObject
Manages QMessageBox interception during loading operations.
Replaces QMessageBox methods with intercepting versions that route messages through a callback (typically to display within a loading dialog). All interceptions are logged for developer monitoring.
Signals
intercepted: Emitted when a message box is intercepted.
Example
Using with a loading dialog::
def handle_intercept(title, message, icon, buttons):
return loading_dialog.show_embedded_message(
title, message, icon, buttons
)
manager = InterceptionManager(on_intercept=handle_intercept)
manager.start()
# ... loading work ...
manager.stop()
Source code in src\shared_services\prompt_dialogs\interception\interceptor.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | |
__init__(on_intercept=None, parent=None)
¶
Initialize the interception manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
on_intercept
|
Optional[InterceptCallback]
|
Callback to handle intercepted messages. |
None
|
parent
|
Optional[QObject]
|
Parent QObject. |
None
|
Source code in src\shared_services\prompt_dialogs\interception\interceptor.py
is_active()
¶
Check if interception is currently active.
Returns:
| Type | Description |
|---|---|
bool
|
True if intercepting. |
set_callback(callback)
¶
Set the interception callback.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
InterceptCallback
|
Function to handle intercepted messages. |
required |
start()
¶
Start intercepting QMessageBox and QInputDialog calls.
Replaces QMessageBox and QInputDialog static methods with intercepting versions. Safe to call multiple times.
Source code in src\shared_services\prompt_dialogs\interception\interceptor.py
stop()
¶
Stop intercepting QMessageBox and QInputDialog calls.
Restores original QMessageBox and QInputDialog methods. Safe to call multiple times.
Source code in src\shared_services\prompt_dialogs\interception\interceptor.py
LoadingDialog
¶
Bases: ThemeAwareDialog
Modal loading dialog with progress tracking.
Provides a clean, themed loading dialog with: - Animated spinner - Progress bar with percentage - Subprocess status tracking - Message box interception (hides loading, shows MessageDialog) - Fail-safe close button after timeout - Context manager support
Signals
cancelled: Emitted when the user cancels via fail-safe button. progress_updated: Emitted when progress changes (message, percentage). subprocess_changed: Emitted when subprocess name changes.
Example
Using as context manager::
with LoadingDialog(parent) as loading:
loading.show_loading("Uploading...")
for i, item in enumerate(items):
loading.update_progress(f"Item {i+1}/{len(items)}",
int(100 * i / len(items)))
process_item(item)
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 | |
__enter__()
¶
__exit__(exc_type, exc_val, exc_tb)
¶
Exit context manager with cleanup.
__init__(parent=None)
¶
Initialize the loading dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
Optional[QWidget]
|
Parent widget. The dialog will automatically use the top-level window (main window) as its actual parent to ensure stability when views are being loaded/replaced. |
None
|
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
ask_question(title, message)
¶
Ask a yes/no question during loading.
Temporarily hides the loading dialog, shows the question, then restores the loading dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Question title. |
required |
message
|
str
|
Question text. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if user clicked Yes, False otherwise. |
Example
with LoadingDialog(parent) as loading: loading.show_loading("Processing...") if loading.ask_question("Continue?", "Found issues. Proceed anyway?"): # User clicked Yes continue_processing()
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
closeEvent(event)
¶
force_close()
¶
get_input(title, prompt, initial_text='', blacklist=None)
¶
Get text input from the user during loading.
Temporarily hides the loading dialog, shows the input dialog, then restores the loading dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Dialog title. |
required |
prompt
|
str
|
Input prompt text. |
required |
initial_text
|
str
|
Initial text in the input field. |
''
|
blacklist
|
Optional[List[str]]
|
List of disallowed values. |
None
|
Returns:
| Type | Description |
|---|---|
Tuple[str, bool]
|
Tuple of (entered_text, accepted). Text is empty if not accepted. |
Example
with LoadingDialog(parent) as loading: loading.show_loading("Creating project...") # ... do initial work ... name, ok = loading.get_input( "Project Name", "Enter a name for the new project:", initial_text="New Project" ) if ok: finalize_project(name)
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
hide_loading()
¶
Hide the loading dialog.
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
loading_context(message='Please wait...')
¶
Context manager for showing loading dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Loading message to display. |
'Please wait...'
|
Yields:
| Type | Description |
|---|---|
|
Self for progress updates. |
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
set_subprocess(name)
¶
Set the current subprocess name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Subprocess name to display. |
required |
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
show_error(title, message)
¶
Show an error message during loading.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Message title. |
required |
message
|
str
|
Error message text. |
required |
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
show_info(title, message)
¶
Show an info message during loading.
Temporarily hides the loading dialog, shows the message, then restores the loading dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Message title. |
required |
message
|
str
|
Message text. |
required |
Example
with LoadingDialog(parent) as loading: loading.show_loading("Processing...") # ... do work ... loading.show_info("Step Complete", "First phase finished.")
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
show_loading(message='Please wait...')
¶
Show the loading dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Loading message to display. |
'Please wait...'
|
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
show_warning(title, message)
¶
Show a warning message during loading.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Message title. |
required |
message
|
str
|
Warning message text. |
required |
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
update_message(message)
¶
Update the main loading message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
New loading message. |
required |
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
update_progress(message, percentage=-1)
¶
Update progress with message and optional percentage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Progress message. |
required |
percentage
|
int
|
Progress percentage (0-100), or -1 for indeterminate. |
-1
|
Source code in src\shared_services\prompt_dialogs\loading\loading_dialog.py
LoadingDialogInterceptor
¶
Bases: InterceptionManager
Interception manager specifically for LoadingDialog integration.
Wraps InterceptionManager with weak reference to a LoadingDialog for automatic callback routing. When a message is intercepted during loading, the loading dialog is hidden and a proper MessageDialog is shown instead, ensuring the user sees identical dialogs whether intercepted or not.
Example
Using with LoadingDialog::
interceptor = LoadingDialogInterceptor(loading_dialog)
interceptor.start()
# ... loading work ...
interceptor.stop()
Source code in src\shared_services\prompt_dialogs\interception\interceptor.py
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 | |
__init__(loading_dialog, parent=None)
¶
Initialize the loading dialog interceptor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loading_dialog
|
LoadingDialog
|
The loading dialog to route messages to. |
required |
parent
|
Optional[QObject]
|
Parent QObject. |
None
|
Source code in src\shared_services\prompt_dialogs\interception\interceptor.py
LoadingSpinner
¶
Bases: QWidget
Animated loading spinner widget.
Displays a circular spinner animation with customizable colors and animation speed. Integrates with the application theme system.
Signals
started: Emitted when animation starts. stopped: Emitted when animation stops.
Example
Using the spinner::
spinner = LoadingSpinner(parent)
spinner.start()
# ... loading work ...
spinner.stop()
Source code in src\shared_services\prompt_dialogs\loading\loading_spinner.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
__init__(parent=None, size=50, color=None)
¶
Initialize the loading spinner.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
Optional[QWidget]
|
Parent widget. |
None
|
size
|
int
|
Widget size in pixels. |
50
|
color
|
Optional[QColor]
|
Primary spinner color (uses theme highlight if not set). |
None
|
Source code in src\shared_services\prompt_dialogs\loading\loading_spinner.py
is_running()
¶
Check if the spinner is currently animating.
Returns:
| Type | Description |
|---|---|
bool
|
True if the animation is running. |
paintEvent(event)
¶
Paint the spinner.
Source code in src\shared_services\prompt_dialogs\loading\loading_spinner.py
set_color(color)
¶
Set the spinner primary color.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
color
|
QColor
|
New primary color. |
required |
set_lines(count=8, length=10, width=3, inner_radius=12)
¶
Configure spinner line appearance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
Number of lines in the spinner. |
8
|
length
|
int
|
Length of each line. |
10
|
width
|
int
|
Width of each line. |
3
|
inner_radius
|
int
|
Distance from center to line start. |
12
|
Source code in src\shared_services\prompt_dialogs\loading\loading_spinner.py
start(interval_ms=80)
¶
Start the spinner animation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
interval_ms
|
int
|
Animation interval in milliseconds. |
80
|
Source code in src\shared_services\prompt_dialogs\loading\loading_spinner.py
stop()
¶
Stop the spinner animation.
MessageBoxType
¶
Bases: Enum
Type of message box that was intercepted.
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
MessageDialog
¶
Bases: ThemeAwareDialog
Theme-aware message dialog.
Provides a consistent, styled alternative to QMessageBox with automatic theme support.
Signals
button_clicked: Emitted when a button is clicked with the button flag.
Example
Creating a custom message dialog::
dialog = MessageDialog(
parent=self,
message_type=MessageType.WARNING,
title="Confirm",
message="Are you sure?",
buttons=QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
)
result = dialog.exec()
Source code in src\shared_services\prompt_dialogs\message_box\message_dialog.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | |
__init__(parent=None, message_type=MessageType.INFO, title='', message='', buttons=QMessageBox.StandardButton.Ok)
¶
Initialize the message dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
None
|
message_type
|
MessageType
|
Type of message (INFO, WARNING, ERROR, QUESTION). |
INFO
|
title
|
str
|
Dialog title. |
''
|
message
|
str
|
Message to display. |
''
|
buttons
|
StandardButton
|
Standard buttons to show. |
Ok
|
Source code in src\shared_services\prompt_dialogs\message_box\message_dialog.py
error(parent, title, message, buttons=QMessageBox.StandardButton.Ok)
staticmethod
¶
Show an error message dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Error message to display. |
required |
buttons
|
StandardButton
|
Buttons to show. |
Ok
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Source code in src\shared_services\prompt_dialogs\message_box\message_dialog.py
get_result()
¶
Get the result after dialog closes.
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
info(parent, title, message, buttons=QMessageBox.StandardButton.Ok)
staticmethod
¶
Show an info message dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Message to display. |
required |
buttons
|
StandardButton
|
Buttons to show. |
Ok
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Source code in src\shared_services\prompt_dialogs\message_box\message_dialog.py
question(parent, title, message, buttons=QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
staticmethod
¶
Show a question dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Question to display. |
required |
buttons
|
StandardButton
|
Buttons to show (default: Yes/No). |
Yes | No
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Source code in src\shared_services\prompt_dialogs\message_box\message_dialog.py
warning(parent, title, message, buttons=QMessageBox.StandardButton.Ok)
staticmethod
¶
Show a warning message dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Warning message to display. |
required |
buttons
|
StandardButton
|
Buttons to show. |
Ok
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Source code in src\shared_services\prompt_dialogs\message_box\message_dialog.py
MessageType
¶
MultiButtonDialog
¶
Bases: ThemeAwareDialog
Dialog presenting an arbitrary set of styled buttons.
Supports outlined (secondary), filled (primary), and hold-to-confirm button styles. When a hold-to-confirm button arms, the accent header bar transitions to red to reinforce the destructive action.
Source code in src\shared_services\prompt_dialogs\multi_button\multi_button_dialog.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | |
show_dialog(parent, title, message, buttons, icon=None, accent_color=None, dialog_style=None)
staticmethod
¶
Show a multi-button dialog and return the selected result string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
Optional[QWidget]
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Message to display. |
required |
buttons
|
List[ButtonDef]
|
List of ButtonDef defining the buttons. |
required |
icon
|
Optional icon PathDef. Overrides dialog_style icon. |
None
|
|
accent_color
|
Optional[QColor]
|
Optional accent QColor. Overrides dialog_style color. |
None
|
dialog_style
|
Optional[DialogStyle]
|
Optional preset (INFO, WARNING, ERROR) that sets the icon and accent color. Explicit icon/accent_color take precedence over the preset. |
None
|
Returns:
| Type | Description |
|---|---|
Optional[str]
|
The result string of the clicked button, or None if closed. |
Source code in src\shared_services\prompt_dialogs\multi_button\multi_button_dialog.py
SignDialog
¶
Bases: ThemeAwareDialog
Dialog for entering a commit/sign message before releasing.
When allow_cancel is False the dialog cannot be dismissed via
the close button, Escape key, or a cancel button -- the user must
confirm.
Source code in src\shared_services\prompt_dialogs\sign\sign_dialog.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | |
get_commit_message(parent=None, title='Signieren', instruction='Bitte geben Sie eine Beschreibung ein.', placeholder='Unkommentiert', sign_text='Signieren und freigeben', allow_cancel=False, default_message='Unkommentiert', accent_color=None)
staticmethod
¶
Show a sign dialog and return the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
Optional[QWidget]
|
Parent widget. |
None
|
title
|
str
|
Dialog title. |
'Signieren'
|
instruction
|
str
|
Instruction text shown above the text edit. |
'Bitte geben Sie eine Beschreibung ein.'
|
placeholder
|
str
|
Placeholder text in the text edit. |
'Unkommentiert'
|
sign_text
|
str
|
Label for the sign/confirm button. |
'Signieren und freigeben'
|
allow_cancel
|
bool
|
If False, dialog cannot be dismissed without signing. |
False
|
default_message
|
str
|
Message used when text is empty on confirm. |
'Unkommentiert'
|
accent_color
|
Optional[QColor]
|
Optional accent QColor for the header bar. |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
Tuple of (confirmed, message). confirmed is True when the user |
str
|
clicked the sign button. message is the entered text or |
Tuple[bool, str]
|
default_message if empty. |
Source code in src\shared_services\prompt_dialogs\sign\sign_dialog.py
SoundPatch
¶
Monkey patch manager for silent message boxes.
Replaces QMessageBox.setIcon() with a custom implementation that uses setIconPixmap() instead, which does not trigger Windows system sounds. The custom implementation uses SVG icons that match the application theme.
Example
Applying the patch at startup::
from src.shared_services.dialogs.sound.sound_patch import SoundPatch
def main():
app = QApplication(sys.argv)
SoundPatch.apply()
# ... rest of application
Source code in src\shared_services\prompt_dialogs\sound\sound_patch.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | |
apply()
classmethod
¶
Apply the monkey patch to disable QMessageBox sounds globally.
This patches QMessageBox.setIcon() to use setIconPixmap() instead, which displays the icon without triggering Windows system sounds.
Safe to call multiple times - only applies once.
Source code in src\shared_services\prompt_dialogs\sound\sound_patch.py
clear_cache()
classmethod
¶
Clear the icon pixmap cache.
Call this when the theme changes to ensure icons are re-rendered with the correct colors.
is_patched()
classmethod
¶
Check if the patch is currently applied.
Returns:
| Type | Description |
|---|---|
bool
|
True if the patch is active. |
refresh_for_theme()
classmethod
¶
Refresh icons for a theme change.
Clears the cache so icons will be re-rendered with theme-appropriate colors on next use.
Source code in src\shared_services\prompt_dialogs\sound\sound_patch.py
remove()
classmethod
¶
Remove the monkey patch.
Restores the original QMessageBox.setIcon() behavior. Primarily useful for testing purposes.
Source code in src\shared_services\prompt_dialogs\sound\sound_patch.py
ThemeAwareDialog
¶
Bases: QDialog
Base class for theme-aware dialogs.
Automatically registers with StylesheetManager for theme updates. Uses weak references to avoid memory leaks. Handles cleanup on close.
Subclasses should: - Call super().init() with appropriate stylesheets - Set a meaningful object name via setObjectName() - Override _on_theme_changed() if custom theme handling is needed
Attributes:
| Name | Type | Description |
|---|---|---|
dialog_closed |
Signal
|
Signal emitted when the dialog closes. |
Example
Creating a themed dialog::
class InfoDialog(ThemeAwareDialog):
def __init__(self, parent=None):
super().__init__(
parent=parent,
stylesheets=[DialogStylesheets.Main],
)
self.setObjectName("InfoDialog")
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | |
__init__(parent=None, stylesheets=None)
¶
Initialize the theme-aware dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
None
|
stylesheets
|
List[PathDef] | None
|
List of PathDef stylesheet definitions to apply. |
None
|
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
closeEvent(event)
¶
Handle dialog close event.
Unregisters from StylesheetManager and emits dialog_closed signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
QCloseEvent
|
Close event. |
required |
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
get_current_theme()
¶
Get the current theme.
Returns:
| Type | Description |
|---|---|
str
|
Current theme name ("light" or "dark"). |
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
get_theme_color(color_key)
¶
Get a color value for the current theme.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
color_key
|
str
|
Color key from ColorSystem (e.g., 'primary', 'error'). |
required |
Returns:
| Type | Description |
|---|---|
str
|
Color value as hex string. |
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
is_dark_theme()
¶
Check if the current theme is dark.
Returns:
| Type | Description |
|---|---|
bool
|
True if dark theme is active. |
paintEvent(_event)
¶
Draw soft shadow, rounded background, and optional header bar.
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
refresh_style(widget=None)
¶
Refresh the style of a widget after property changes.
Call this after setting dynamic properties to trigger style update.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
widget
|
QWidget | None
|
Widget to refresh. If None, refreshes self. |
None
|
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
show_centered()
¶
Show the dialog centered on the screen or parent.
Positions the dialog in the center of the parent widget if available, otherwise centers on the primary screen.
Source code in src\shared_services\prompt_dialogs\base\theme_aware_dialog.py
UnsavedChangesDialog
¶
Bases: ThemeAwareDialog
Theme-aware dialog for unsaved changes with Save/Discard/Cancel.
Uses the same visual style as MessageDialog (warning accent).
Supports 2-button mode (save/discard) or 3-button mode
(save/discard/cancel) via the show_cancel parameter.
Source code in src\shared_services\prompt_dialogs\unsaved_changes\unsaved_changes_dialog.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
ask(parent, title, message, save_text='Speichern', discard_text='Verwerfen', cancel_text='Abbrechen', show_cancel=True)
staticmethod
¶
Show the dialog and return the user's choice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
Optional[QWidget]
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Message describing the unsaved changes. |
required |
save_text
|
str
|
Label for the save button. |
'Speichern'
|
discard_text
|
str
|
Label for the discard button. |
'Verwerfen'
|
cancel_text
|
str
|
Label for the cancel button. |
'Abbrechen'
|
show_cancel
|
bool
|
Whether to show the cancel button. |
True
|
Returns:
| Type | Description |
|---|---|
UnsavedChangesResult
|
UnsavedChangesResult.SAVE, .DISCARD, or .CANCEL. |
Source code in src\shared_services\prompt_dialogs\unsaved_changes\unsaved_changes_dialog.py
UnsavedChangesResult
¶
ValidationResult
dataclass
¶
Result of input validation.
Attributes:
| Name | Type | Description |
|---|---|---|
is_valid |
bool
|
Whether the input is valid. |
error_message |
Optional[str]
|
Error message if invalid, None if valid. |
Source code in src\shared_services\prompt_dialogs\input\validators.py
apply_sound_patch()
¶
Apply the silent message box patch.
Convenience function for application startup.
ask_question(parent, title, message, buttons=QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
¶
Show a question dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Question to display. |
required |
buttons
|
StandardButton
|
Buttons to show (default: Yes/No). |
Yes | No
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Example
Ask a yes/no question::
result = ask_question(self, "Confirm", "Delete this item?")
if result == QMessageBox.StandardButton.Yes:
delete_item()
Source code in src\shared_services\prompt_dialogs\api.py
ask_unsaved_changes(parent, title, message, save_text='Speichern', discard_text='Verwerfen', cancel_text='Abbrechen', show_cancel=True)
¶
Show a themed unsaved-changes dialog with Save / Discard / Cancel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Message describing the unsaved changes. |
required |
save_text
|
str
|
Label for the save button. |
'Speichern'
|
discard_text
|
str
|
Label for the discard button. |
'Verwerfen'
|
cancel_text
|
str
|
Label for the cancel button. |
'Abbrechen'
|
show_cancel
|
bool
|
Whether to show the cancel button. |
True
|
Returns:
| Type | Description |
|---|---|
UnsavedChangesResult
|
UnsavedChangesResult.SAVE, .DISCARD, or .CANCEL. |
Example
Ask with 3 buttons::
result = ask_unsaved_changes(
self,
"Ungespeicherte Aenderungen",
"Aenderungen speichern?",
save_text="Speichern und Beenden",
discard_text="Verwerfen und Beenden",
)
if result == UnsavedChangesResult.SAVE:
save()
elif result == UnsavedChangesResult.CANCEL:
return
Source code in src\shared_services\prompt_dialogs\api.py
get_recent_interceptions(count=10)
¶
Get recent interception entries.
Convenience function for retrieving entries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
count
|
int
|
Maximum entries to return. |
10
|
Returns:
| Type | Description |
|---|---|
List[InterceptionEntry]
|
List of InterceptionEntry objects. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
log_interception(title, message, message_type=MessageBoxType.UNKNOWN, capture_stack=True)
¶
Log an intercepted message box.
Convenience function for logging interceptions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Message box title. |
required |
message
|
str
|
Message box content. |
required |
message_type
|
MessageBoxType
|
Type of message box. |
UNKNOWN
|
capture_stack
|
bool
|
Whether to capture call stack. |
True
|
Returns:
| Type | Description |
|---|---|
InterceptionEntry
|
The created InterceptionEntry. |
Source code in src\shared_services\prompt_dialogs\interception\interception_log.py
refresh_sound_patch_for_theme()
¶
Refresh the sound patch icons for a theme change.
Call this when the application theme changes.
remove_sound_patch()
¶
Remove the silent message box patch.
Convenience function for testing.
show_error(parent, title, message, buttons=QMessageBox.StandardButton.Ok)
¶
Show an error message dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Error message to display. |
required |
buttons
|
StandardButton
|
Buttons to show. |
Ok
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Example
Show an error message::
show_error(self, "Error", "Failed to save file.")
Source code in src\shared_services\prompt_dialogs\api.py
show_info(parent, title, message, buttons=QMessageBox.StandardButton.Ok)
¶
Show an info message dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Message to display. |
required |
buttons
|
StandardButton
|
Buttons to show. |
Ok
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Example
Show a simple info message::
show_info(self, "Success", "File saved successfully.")
Source code in src\shared_services\prompt_dialogs\api.py
show_warning(parent, title, message, buttons=QMessageBox.StandardButton.Ok)
¶
Show a warning message dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
QWidget | None
|
Parent widget. |
required |
title
|
str
|
Dialog title. |
required |
message
|
str
|
Warning message to display. |
required |
buttons
|
StandardButton
|
Buttons to show. |
Ok
|
Returns:
| Type | Description |
|---|---|
StandardButton
|
The button that was clicked. |
Example
Show a warning with Yes/No buttons::
result = show_warning(
self,
"Warning",
"Are you sure you want to proceed?",
buttons=QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
)
if result == QMessageBox.StandardButton.Yes:
proceed()
Source code in src\shared_services\prompt_dialogs\api.py
validate_file_name(name, blacklist=None)
¶
Validate a file name.
Convenience function for simple file name validation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The file name to validate. |
required |
blacklist
|
List[str] | None
|
Optional list of disallowed names. |
None
|
Returns:
| Type | Description |
|---|---|
Tuple[bool, str]
|
Tuple of (is_valid, error_message). Error message is empty if valid. |