Coverage for main/components/collapsible_info_frame.py: 94%
33 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-03 15:51 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-03 15:51 +0000
1from PyQt6.QtCore import QCoreApplication
2from PyQt6.QtWidgets import QFrame, QVBoxLayout, QPushButton, QLabel
5class CollapsibleInfoFrame(QFrame):
6 """
7 A collapsible information panel displaying contextual help or configuration instructions.
9 This widget provides a styled information box with a toggle button that expands
10 or collapses its content. It’s particularly useful for showing optional user
11 guidance (e.g., color-coding legends, usage tips, or data selection rules).
13 ---
14 **Features**
15 - Collapsible/expandable content area
16 - Styled using Qt stylesheets for a clean look
17 - Supports dynamic translation through Qt's `QCoreApplication.translate`
18 - Automatically reacts to external language change signals (if provided in `context`)
19 ---
21 **Parameters**
22 - `context (dict | None)`: Optional application context dictionary.
23 If it includes a `"language_changed"` signal, the frame will update its text automatically when the language changes.
25 **Example**
26 ```python
27 frame = CollapsibleInfoFrame(context)
28 frame.show()
29 ```
30 """
32 def __init__(self, context):
33 """
34 Initialize the collapsible information frame.
36 Args:
37 context (dict | None): Optional dictionary providing signal connections
38 for language translation updates.
39 """
40 super().__init__()
42 # --- Frame styling ---
43 self.setObjectName("info_frame")
44 self.setStyleSheet("""
45 QFrame#info_frame {
46 background-color: #e3f2fd; /* Soft blue background */
47 border: 1px solid #2196f3; /* Blue border */
48 border-radius: 6px;
49 margin: 6px 0;
50 }
51 """)
53 # --- Main layout configuration ---
54 self.layout = QVBoxLayout(self)
55 self.layout.setContentsMargins(8, 6, 8, 6)
56 self.layout.setSpacing(4)
58 # --- Toggle button ---
59 self.toggle_button = QPushButton("Configuration Instructions")
60 self.toggle_button.setStyleSheet("""
61 QPushButton {
62 font-size: 14px;
63 font-weight: bold;
64 color: #1976d2;
65 background: none;
66 border: none;
67 text-align: left;
68 padding: 4px 8px;
69 }
70 QPushButton:hover {
71 background-color: #bbdefb; /* Hover highlight */
72 border-radius: 4px;
73 }
74 """)
75 self.toggle_button.clicked.connect(self.toggle_content)
76 self.layout.addWidget(self.toggle_button)
78 # --- Content area ---
79 self.content_frame = QFrame()
80 self.content_layout = QVBoxLayout(self.content_frame)
81 self.content_layout.setContentsMargins(8, 4, 8, 4)
82 self.content_layout.setSpacing(4)
84 # --- Informational text ---
85 self.info_text = QLabel("""
86 <style>
87 .info-list { margin: 0; padding-left: 1rem; }
88 .info-list li { margin-bottom: 0.3rem; line-height: 1.3; }
89 </style>
90 <ul class="info-list" role="list">
91 <li><strong>Yellow frames</strong> indicate patients with <strong>multiple files</strong>.
92 <br> Requires <strong>medical review</strong> and manual selection.</li>
93 <li><strong>White frames</strong> show patients with auto-selected files.</li>
94 </ul>
95 """)
96 self.info_text.setStyleSheet("""
97 color: #000000;
98 font-size: 12px;
99 line-height: 1.4;
100 padding: 2px 0;
101 """)
102 self.info_text.setWordWrap(True)
104 self.content_layout.addWidget(self.info_text)
105 self.layout.addWidget(self.content_frame)
107 # --- Internal state ---
108 self.is_collapsed = False # Whether the content is hidden
110 # --- Language translation support ---
111 self._translate_ui()
112 if context and "language_changed" in context:
113 context["language_changed"].connect(self._translate_ui)
115 # -------------------------------------------------------------------------
117 def toggle_content(self):
118 """
119 Toggle the visibility of the content section.
121 This method inverts the current state of the frame (expanded ↔ collapsed).
122 It is connected to the toggle button’s `clicked` signal.
123 """
124 self.is_collapsed = not self.is_collapsed
125 self.content_frame.setVisible(not self.is_collapsed)
127 # -------------------------------------------------------------------------
129 def _translate_ui(self):
130 """
131 Update the text of the UI elements for the current language.
133 This method is automatically called during initialization and whenever
134 the `"language_changed"` signal is emitted from the application context.
135 """
136 self.toggle_button.setText(QCoreApplication.translate("Components", "Configuration Instructions"))
137 self.info_text.setText(QCoreApplication.translate("Components", """
138 <style>
139 .info-list { margin: 0; padding-left: 1rem; }
140 .info-list li { margin-bottom: 0.3rem; line-height: 1.3; }
141 </style>
142 <ul class="info-list" role="list">
143 <li><strong>Yellow frames</strong> indicate patients with <strong>multiple files</strong>.
144 <br> Requires <strong>medical review</strong> and manual selection.</li>
145 <li><strong>White frames</strong> show patients with auto-selected files.</li>
146 </ul>
147 """))