15
15
this program. If not, see <http://www.gnu.org/licenses/>.
16
16
"""
17
17
18
+ import sys
18
19
import time
19
20
import logging
20
21
import pkg_resources
28
29
QMenuBar ,
29
30
QWidget ,
30
31
QFrame ,
31
- QHBoxLayout ,
32
32
QVBoxLayout ,
33
33
QHeaderView ,
34
34
QLabel ,
35
35
QMessageBox ,
36
36
QTreeWidgetItem ,
37
- QSplitter
37
+ QSplitter ,
38
+ QTextBrowser
38
39
)
39
40
from PySide6 .QtGui import QAction
40
41
import pyqtgraph as pg
52
53
Worker ,
53
54
PlaceholderQTreeWidget ,
54
55
BoolTreeWidgetItem ,
56
+ StreamRedirector ,
57
+ QTextBrowserLogger ,
55
58
format_value ,
56
59
display_file_open_dialog ,
57
60
display_file_save_dialog ,
58
61
magnitude_of ,
59
62
check_selected_items ,
63
+ configure_pretty_errors
60
64
)
61
65
62
66
@@ -71,10 +75,8 @@ def __init__(self, app, arguments, logger):
71
75
get_registry ().default_format = ".6f~"
72
76
73
77
self .start_time = time .time ()
74
- if logger is None :
75
- self .logger = logging .getLogger ("tinymovr" )
76
- else :
77
- self .logger = logger
78
+ self .logger = logger if logger is not None else logging .getLogger ("tinymovr" )
79
+ configure_pretty_errors ()
78
80
79
81
self .attr_widgets_by_id = {}
80
82
self .graphs_by_id = {}
@@ -86,6 +88,7 @@ def __init__(self, app, arguments, logger):
86
88
87
89
self .file_menu = QMenu ("File" )
88
90
self .help_menu = QMenu ("Help" )
91
+ self .view_menu = QMenu ("View" )
89
92
90
93
self .export_action = QAction ("Export Config..." , self )
91
94
self .import_action = QAction ("Import Config" , self )
@@ -97,11 +100,19 @@ def __init__(self, app, arguments, logger):
97
100
self .file_menu .addAction (self .import_action )
98
101
self .help_menu .addAction (self .about_action )
99
102
103
+ self .toggle_tree_action = QAction ("Hide Tree" , self ) # Assume tree is visible initially
104
+ self .toggle_tree_action .triggered .connect (self .toggle_tree )
105
+ self .toggle_console_action = QAction ("Hide Console" , self ) # Assume console is visible initially
106
+ self .toggle_console_action .triggered .connect (self .toggle_console )
107
+
108
+ self .view_menu .addAction (self .toggle_tree_action )
109
+ self .view_menu .addAction (self .toggle_console_action )
110
+
100
111
self .menu_bar .addMenu (self .file_menu )
112
+ self .menu_bar .addMenu (self .view_menu )
101
113
self .menu_bar .addMenu (self .help_menu )
102
114
self .setMenuBar (self .menu_bar )
103
115
104
- # Setup the tree widget
105
116
self .tree_widget = PlaceholderQTreeWidget ()
106
117
self .tree_widget .itemChanged .connect (self .item_changed )
107
118
self .tree_widget .itemExpanded .connect (self .update_visible_attrs )
@@ -111,14 +122,13 @@ def __init__(self, app, arguments, logger):
111
122
self .status_label = QLabel ()
112
123
self .status_label .setStyleSheet ("margin: 5px;" )
113
124
114
- # Create splitter and add frames
115
125
self .splitter = QSplitter (QtCore .Qt .Horizontal )
116
126
self .splitter .setHandleWidth (0 )
127
+ self .splitter .splitterMoved .connect (self .check_tree_visibility )
117
128
118
129
self .left_frame = QFrame (self )
119
130
self .left_layout = QVBoxLayout ()
120
131
self .left_layout .addWidget (self .tree_widget )
121
- self .left_layout .addWidget (self .status_label )
122
132
self .left_layout .setSpacing (0 )
123
133
self .left_layout .setContentsMargins (0 , 0 , 0 , 0 )
124
134
self .left_frame .setLayout (self .left_layout )
@@ -135,11 +145,24 @@ def __init__(self, app, arguments, logger):
135
145
self .splitter .addWidget (self .left_frame )
136
146
self .splitter .addWidget (self .right_frame )
137
147
148
+ self .console = QTextBrowser ()
149
+ self .console .setReadOnly (True )
150
+ self .log_handler = QTextBrowserLogger (self .console )
151
+ self .logger .addHandler (self .log_handler )
152
+
153
+ self .main_splitter = QSplitter (QtCore .Qt .Vertical )
154
+ self .main_splitter .setHandleWidth (0 )
155
+ self .main_splitter .showEvent = self .on_show_event
156
+ self .main_splitter .splitterMoved .connect (self .check_console_visibility )
157
+ self .main_splitter .addWidget (self .splitter )
158
+ self .main_splitter .addWidget (self .console )
159
+
138
160
main_layout = QVBoxLayout ()
139
- main_layout .addWidget (self .splitter )
161
+ main_layout .addWidget (self .main_splitter )
162
+ main_layout .addWidget (self .status_label )
140
163
main_layout .setSpacing (0 )
141
164
main_layout .setContentsMargins (0 , 0 , 0 , 0 )
142
-
165
+
143
166
main_widget = QWidget ()
144
167
main_widget .setLayout (main_layout )
145
168
main_widget .setMinimumHeight (600 )
@@ -181,6 +204,18 @@ def __init__(self, app, arguments, logger):
181
204
self .visibility_update_timer .timeout .connect (self .update_visible_attrs )
182
205
self .visibility_update_timer .start (1000 )
183
206
207
+ def on_show_event (self , event ):
208
+ total_height = self .splitter .size ().height ()
209
+ top_percentage = 0.75 # 75% for the top widget
210
+ bottom_percentage = 0.25 # 25% for the bottom widget
211
+
212
+ top_size = int (total_height * top_percentage )
213
+ bottom_size = int (total_height * bottom_percentage )
214
+
215
+ self .main_splitter .setSizes ([top_size , bottom_size ])
216
+
217
+ super (MainWindow , self ).showEvent (event )
218
+
184
219
@QtCore .Slot ()
185
220
def about_to_quit (self ):
186
221
self .visibility_update_timer .stop ()
@@ -361,6 +396,60 @@ def show_about_box(self):
361
396
),
362
397
)
363
398
399
+ def toggle_tree (self ):
400
+ """
401
+ Toggle the visibility of the tree based on actual size.
402
+ """
403
+ tree_size = self .splitter .sizes ()[0 ]
404
+ if tree_size > 0 :
405
+ self .tree_widget .setVisible (False )
406
+ self .splitter .setSizes ([0 , self .splitter .size ().width ()])
407
+ self .toggle_tree_action .setText ("Show Tree" )
408
+ else :
409
+ self .tree_widget .setVisible (True )
410
+ total_size = self .splitter .size ().width ()
411
+ left_size = int (total_size * 0.25 )
412
+ right_size = int (total_size * 0.75 )
413
+ self .splitter .setSizes ([left_size , right_size ])
414
+ self .toggle_tree_action .setText ("Hide Tree" )
415
+
416
+ def toggle_console (self ):
417
+ """
418
+ Toggle the visibility of the console based on actual size.
419
+ """
420
+ console_height = self .main_splitter .sizes ()[- 1 ]
421
+ if console_height > 0 :
422
+ self .console .setVisible (False )
423
+ self .main_splitter .setSizes ([self .main_splitter .size ().height (), 0 ])
424
+ self .toggle_console_action .setText ("Show Console" )
425
+ else :
426
+ self .console .setVisible (True )
427
+ total_height = self .main_splitter .size ().height ()
428
+ top_height = int (total_height * 0.75 )
429
+ bottom_height = int (total_height * 0.25 )
430
+ self .main_splitter .setSizes ([top_height , bottom_height ])
431
+ self .toggle_console_action .setText ("Hide Console" )
432
+
433
+ def check_tree_visibility (self , pos , index ):
434
+ """
435
+ Check tree visibility after splitter is moved and update the action text.
436
+ """
437
+ tree_size = self .splitter .sizes ()[0 ] # Assuming tree is always the first widget in the splitter
438
+ if tree_size == 0 :
439
+ self .toggle_tree_action .setText ("Show Tree" )
440
+ else :
441
+ self .toggle_tree_action .setText ("Hide Tree" )
442
+
443
+ def check_console_visibility (self , pos , index ):
444
+ """
445
+ Check console visibility after splitter is moved and update the action text.
446
+ """
447
+ console_size = self .main_splitter .sizes ()[- 1 ] # Assuming console is always the last widget in the splitter
448
+ if console_size == 0 :
449
+ self .toggle_console_action .setText ("Show Console" )
450
+ else :
451
+ self .toggle_console_action .setText ("Hide Console" )
452
+
364
453
def is_widget_visible (self , widget ):
365
454
"""
366
455
Check if the given widget is visible, i.e., not hidden and all its
0 commit comments