66"""
77
88import sys
9+ import os
10+ import time
11+ import datetime
912from MAVProxy .modules .lib import mp_util
1013from MAVProxy .modules .lib import multiproc
1114from MAVProxy .modules .lib .wx_loader import wx
@@ -23,12 +26,13 @@ class CheckUI():
2326 '''
2427 a checklist UI for MAVProxy
2528 '''
26- def __init__ (self , title = 'MAVProxy: Checklist' , checklist_file = None ):
29+ def __init__ (self , title = 'MAVProxy: Checklist' , checklist_file = None , logdir = None ):
2730 import threading
28- self .title = title
31+ self .title = title
2932 self .menu_callback = None
3033 self .checklist_file = checklist_file
31- self .parent_pipe ,self .child_pipe = multiproc .Pipe ()
34+ self .logdir = logdir
35+ self .parent_pipe , self .child_pipe = multiproc .Pipe ()
3236 self .close_event = multiproc .Event ()
3337 self .close_event .clear ()
3438 self .child = multiproc .Process (target = self .child_task )
@@ -67,6 +71,9 @@ def __init__(self, state, title):
6771 self .state = state
6872 wx .Frame .__init__ (self , None , title = title , size = (600 ,600 ), style = wx .DEFAULT_FRAME_STYLE )
6973
74+ # Track previously checked states to detect changes
75+ self .previous_states = {}
76+
7077 #use tabs for the individual checklists
7178 self .createLists ()
7279 self .panel = wx .Panel (self )
@@ -131,6 +138,19 @@ def createLists(self):
131138 'GCS stable'
132139 ]
133140
141+ def log_check_item (self , item_name , state ):
142+ '''Log a checkbox state change to file'''
143+ if self .state .logdir is not None :
144+ log_path = os .path .join (self .state .logdir , "checklist_log.txt" )
145+ timestamp = datetime .datetime .now ().strftime ("%Y-%m-%d %H:%M:%S" )
146+
147+ statestr = "CHECKED" if state else "UNCHECKED"
148+ try :
149+ with open (log_path , 'a' ) as f :
150+ f .write (f"{ timestamp } : { item_name } - { statestr } \n " )
151+ except Exception as e :
152+ print (f"Error writing to checklist log: { e } " )
153+
134154 # create controls on form - labels, buttons, etc
135155 def createWidgets (self ):
136156 #create the panels for the tabs
@@ -149,8 +169,15 @@ def createWidgets(self):
149169
150170 # Add each checkbox to the scrolled window
151171 for key in self .lists [name ]:
152- CheckBox = wx .CheckBox (scrolled_window , wx .ID_ANY , key )
153- box .Add (CheckBox , 0 , wx .ALL , 5 )
172+ checkbox = wx .CheckBox (scrolled_window , wx .ID_ANY , key )
173+ box .Add (checkbox , 0 , wx .ALL , 5 )
174+
175+ # Setup the event handler for manual checkbox changes
176+ checkbox .Bind (wx .EVT_CHECKBOX , self .on_checkbox_change )
177+
178+ # Initialize previous state tracking
179+ checkbox_id = f"{ name } :{ key } "
180+ self .previous_states [checkbox_id ] = False
154181
155182 # Create a sizer for the panel and add the scrolled window to it
156183 panel_sizer = wx .BoxSizer (wx .VERTICAL )
@@ -160,10 +187,24 @@ def createWidgets(self):
160187 # Add the panel to the notebook
161188 self .nb .AddPage (panel , name )
162189
190+ def on_checkbox_change (self , event ):
191+ '''Handle manual checkbox changes'''
192+ checkbox = event .GetEventObject ()
193+ is_checked = checkbox .GetValue ()
194+ checkbox_text = checkbox .GetLabel ()
195+
196+ # Get current tab name
197+ tab_idx = self .nb .GetSelection ()
198+ tab_name = self .nb .GetPageText (tab_idx )
199+
200+ # Log the check if it's newly checked
201+ self .log_check_item (checkbox_text , is_checked )
202+
163203 #Receive messages from MAVProxy and process them
164204 def on_timer (self , event , notebook ):
165205 state = self .state
166206 page = notebook .GetPage (notebook .GetSelection ())
207+ tab_name = notebook .GetPageText (notebook .GetSelection ())
167208
168209 if state .close_event .wait (0.001 ):
169210 self .timer .Stop ()
@@ -180,15 +221,30 @@ def on_timer(self, event, notebook):
180221 # Go through each item in the current tab and (un)check as needed
181222 for widget in scrolled_window .GetChildren ():
182223 if isinstance (widget , wx .CheckBox ) and widget .GetLabel () == obj .name :
224+ # Check if this is a change from unchecked to checked
225+ checkbox_id = f"{ tab_name } :{ obj .name } "
226+ was_checked = self .previous_states .get (checkbox_id , False )
227+
228+ # Update the checkbox
183229 widget .SetValue (obj .state )
230+
231+ # Update previous state
232+ self .previous_states [checkbox_id ] = obj .state
233+ break
184234 break
185235
186236
187237if __name__ == "__main__" :
188238 # test the console
189239 import time
190-
191- checklist = CheckUI ()
240+
241+ # Create a test log directory if it doesn't exist
242+ test_logdir = os .path .join (os .getcwd (), "checklist_logs" )
243+ if not os .path .exists (test_logdir ):
244+ os .makedirs (test_logdir )
245+
246+ # Initialize with the log directory
247+ checklist = CheckUI (logdir = test_logdir )
192248
193249 #example auto-tick in second tab page
194250 while checklist .is_alive ():
0 commit comments