@@ -100,7 +100,11 @@ def __init__(
100100 )
101101
102102 self .__add_entry_box (
103- configuration_frame , title = 'callsigns' , label = 'Callsigns' , width = 55 , columnspan = 3
103+ configuration_frame ,
104+ title = 'callsigns' ,
105+ label = 'Callsigns' ,
106+ width = 55 ,
107+ columnspan = configuration_frame .grid_size ()[0 ],
104108 )
105109 self .__file_selection_option = 'select file...'
106110 self .__add_combo_box (
@@ -110,7 +114,7 @@ def __init__(
110114 options = list (available_serial_ports ()) + [self .__file_selection_option ],
111115 option_select = self .__select_tnc ,
112116 width = 52 ,
113- columnspan = 3 ,
117+ columnspan = configuration_frame . grid_size ()[ 0 ] ,
114118 sticky = 'w' ,
115119 )
116120
@@ -128,20 +132,49 @@ def __init__(
128132 title = 'log_file' ,
129133 file_select = self .__select_log_file ,
130134 label = 'Log' ,
131- width = 55 ,
132- columnspan = 3 ,
135+ width = 52 ,
136+ columnspan = configuration_frame . grid_size ()[ 0 ] ,
133137 sticky = 'w' ,
134138 )
135139 self .__add_file_box (
136140 configuration_frame ,
137141 title = 'output_file' ,
138142 file_select = self .__select_output_file ,
139143 label = 'Output' ,
140- width = 55 ,
141- columnspan = 3 ,
144+ width = 52 ,
145+ columnspan = configuration_frame . grid_size ()[ 0 ] ,
142146 sticky = 'w' ,
143147 )
144148
149+ separator = Separator (configuration_frame , orient = tkinter .HORIZONTAL )
150+ separator .grid (
151+ row = configuration_frame .grid_size ()[1 ],
152+ column = 0 ,
153+ columnspan = configuration_frame .grid_size ()[0 ] + 1 ,
154+ sticky = 'ew' ,
155+ pady = 10 ,
156+ )
157+
158+ plot_label = tkinter .Label (configuration_frame , text = 'Plots' )
159+ plot_label .grid (row = configuration_frame .grid_size ()[1 ], column = 0 , sticky = 'w' )
160+
161+ plot_checkbox_frame = tkinter .Frame (configuration_frame )
162+ plot_checkbox_frame .grid (
163+ row = plot_label .grid_info ()['row' ],
164+ column = 0 ,
165+ columnspan = configuration_frame .grid_size ()[0 ] - 1 ,
166+ )
167+
168+ plot_variables = ['altitude' , 'ascent_rate' , 'ground_speed' ]
169+ self .__plot_toggles = {}
170+ for plot_index , plot in enumerate (plot_variables ):
171+ boolean_var = tkinter .BooleanVar ()
172+ plot_checkbox = tkinter .Checkbutton (
173+ plot_checkbox_frame , text = plot , variable = boolean_var
174+ )
175+ plot_checkbox .grid (row = 0 , column = plot_index , padx = 10 )
176+ self .__plot_toggles [plot ] = boolean_var
177+
145178 separator = Separator (main_window , orient = tkinter .HORIZONTAL )
146179 separator .grid (row = main_window .grid_size ()[1 ], column = 0 , sticky = 'ew' )
147180
@@ -277,7 +310,7 @@ def end_date(self, end_date: datetime):
277310 end_date = f'{ end_date :%Y-%m-%d %H:%M:%S} '
278311 else :
279312 end_date = ''
280- self .replace_text (self .__elements ['start_date ' ], end_date )
313+ self .replace_text (self .__elements ['end_date ' ], end_date )
281314
282315 @property
283316 def log_filename (self ) -> Path :
@@ -320,9 +353,7 @@ def output_filename(self, filename: PathLike):
320353 if not isinstance (filename , Path ):
321354 filename = Path (filename )
322355 if filename .expanduser ().resolve ().is_dir ():
323- filename = (
324- filename / f'packetraven_output_{ datetime .now ():%Y%m%dT%H%M%S} .geojson'
325- )
356+ filename = filename / f'packetraven_output_{ datetime .now ():%Y%m%dT%H%M%S} .txt'
326357 else :
327358 filename = ''
328359 self .replace_text (self .__elements ['output_file' ], filename )
@@ -354,8 +385,12 @@ def __select_output_file(self):
354385 title = 'Create output file...' ,
355386 initialdir = self .output_filename .parent ,
356387 initialfile = self .output_filename .stem ,
357- defaultextension = '.geojson' ,
358- filetypes = [('GeoJSON' , '*.geojson' ), ('Keyhole Markup Language' , '*.kml' )],
388+ defaultextension = '.txt' ,
389+ filetypes = [
390+ ('Text' , '*.txt' ),
391+ ('GeoJSON' , '*.geojson' ),
392+ ('Keyhole Markup Language' , '*.kml' ),
393+ ],
359394 )
360395
361396 def __select_tnc (self , event ):
@@ -384,18 +419,43 @@ def __add_combo_box(
384419 def __add_file_box (
385420 self , frame : tkinter .Frame , title : str , file_select : Callable , ** kwargs
386421 ) -> tkinter .Entry :
387- file_box = self .__add_entry_box (frame , title , ** kwargs )
388- log_file_button = tkinter .Button (frame , text = '...' , command = file_select )
389- log_file_button .grid (
390- row = file_box .grid_info ()['row' ],
391- column = file_box .grid_info ()['column' ] + file_box .grid_info ()['columnspan' ],
422+ if 'row' not in kwargs :
423+ kwargs ['row' ] = frame .grid_size ()[1 ]
424+ if 'column' not in kwargs :
425+ kwargs ['column' ] = 0
426+ file_box_kwargs = {
427+ key : value
428+ for key , value in kwargs .items ()
429+ if key in ['row' , 'column' , 'columnspan' ]
430+ }
431+ if 'columnspan' in file_box_kwargs :
432+ file_box_kwargs ['columnspan' ] -= 1
433+
434+ if 'label' in kwargs :
435+ text_label = tkinter .Label (frame , text = kwargs ['label' ])
436+ text_label .grid (row = kwargs ['row' ], column = kwargs ['column' ], sticky = 'w' )
437+ file_box_kwargs ['column' ] += 1
438+
439+ file_box_frame = tkinter .Frame (frame )
440+ file_box_frame .grid (** file_box_kwargs )
441+
442+ file_box = tkinter .Entry (
443+ file_box_frame , width = kwargs ['width' ] if 'width' in kwargs else None
392444 )
445+ file_button = tkinter .Button (file_box_frame , text = '...' , command = file_select )
446+
447+ file_box .pack (side = 'left' )
448+ file_button .pack (side = 'left' )
449+
450+ self .__elements [title ] = file_box
393451 return file_box
394452
395453 def __add_entry_box (self , frame : tkinter .Frame , title : str , ** kwargs ) -> tkinter .Entry :
396- width = kwargs ['width' ] if 'width' in kwargs else None
397- entry_box = tkinter .Entry (frame , width = width )
398- return self .__add_text_box (frame , title , text_box = entry_box , ** kwargs )
454+ if 'text_box' not in kwargs :
455+ kwargs ['text_box' ] = tkinter .Entry (
456+ frame , width = kwargs ['width' ] if 'width' in kwargs else None
457+ )
458+ return self .__add_text_box (frame , title , ** kwargs )
399459
400460 def __add_text_box (
401461 self ,
@@ -414,6 +474,12 @@ def __add_text_box(
414474 if column is None :
415475 column = 0
416476
477+ if 'columnspan' in kwargs :
478+ if label is not None :
479+ kwargs ['columnspan' ] -= 1
480+ if units is not None :
481+ kwargs ['columnspan' ] -= 1
482+
417483 if label is not None :
418484 text_label = tkinter .Label (frame , text = label )
419485 text_label .grid (row = row , column = column , sticky = 'w' )
@@ -572,6 +638,15 @@ def toggle(self):
572638 if database_password is None or len (database_password ) == 0 :
573639 raise ConnectionError ('missing database password' )
574640 database_kwargs ['password' ] = database_password
641+ if 'table' not in database_kwargs or database_kwargs ['table' ] is None :
642+ database_table = simpledialog .askstring (
643+ 'Database Table' ,
644+ f'enter database table name' ,
645+ parent = self .__windows ['main' ],
646+ )
647+ if database_table is None or len (database_table ) == 0 :
648+ raise ConnectionError ('missing database table name' )
649+ database_kwargs ['table' ] = database_table
575650
576651 self .database = APRSDatabaseTable (
577652 ** database_kwargs , ** ssh_tunnel_kwargs , callsigns = self .callsigns
0 commit comments