cosmos 3.9.1 → 3.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -3
  3. data/Manifest.txt +7 -0
  4. data/autohotkey/tools/cmd_extractor.ahk +17 -0
  5. data/autohotkey/tools/tlm_extractor.ahk +62 -1
  6. data/bin/cosmos +182 -12
  7. data/data/crc.txt +35 -34
  8. data/demo/config/data/crc.txt +6 -2
  9. data/demo/config/targets/INST/screens/adcs.txt +1 -1
  10. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +1 -1
  11. data/demo/config/tools/example_application.css +58 -0
  12. data/demo/config/tools/launcher/launcher.css +7 -0
  13. data/demo/config/tools/launcher/launcher2.css +10 -0
  14. data/demo/config/tools/test_runner/test_runner.css +45 -0
  15. data/ext/cosmos/ext/packet/packet.c +6 -0
  16. data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +15 -6
  17. data/lib/cosmos/gui/qt_tool.rb +58 -8
  18. data/lib/cosmos/gui/text/ruby_editor.rb +54 -6
  19. data/lib/cosmos/gui/utilities/analyze_log.rb +153 -0
  20. data/lib/cosmos/interfaces/interface.rb +6 -0
  21. data/lib/cosmos/packets/packet_item_limits.rb +14 -2
  22. data/lib/cosmos/packets/structure_item.rb +22 -3
  23. data/lib/cosmos/script/cmd_tlm_server.rb +28 -0
  24. data/lib/cosmos/script/extract.rb +10 -9
  25. data/lib/cosmos/script/tools.rb +10 -4
  26. data/lib/cosmos/system/system.rb +2 -1
  27. data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +12 -0
  28. data/lib/cosmos/tools/cmd_tlm_server/api.rb +84 -0
  29. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +3 -2
  30. data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +9 -0
  31. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +2 -2
  32. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +26 -17
  33. data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +26 -0
  34. data/lib/cosmos/tools/cmd_tlm_server/packet_logging.rb +29 -0
  35. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +33 -0
  36. data/lib/cosmos/tools/data_viewer/data_viewer.rb +1 -1
  37. data/lib/cosmos/tools/launcher/launcher.rb +14 -25
  38. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +3 -7
  39. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +6 -4
  40. data/lib/cosmos/tools/script_runner/script_runner.rb +58 -9
  41. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +45 -19
  42. data/lib/cosmos/tools/table_manager/table_manager.rb +7 -7
  43. data/lib/cosmos/tools/test_runner/test_runner.rb +6 -0
  44. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +145 -8
  45. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +89 -19
  46. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +14 -0
  47. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +1 -1
  48. data/lib/cosmos/tools/tlm_viewer/screen.rb +15 -3
  49. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +23 -12
  50. data/lib/cosmos/version.rb +4 -4
  51. data/spec/packets/packet_item_limits_spec.rb +33 -6
  52. data/spec/packets/packet_item_spec.rb +9 -9
  53. data/spec/packets/packet_spec.rb +18 -6
  54. data/spec/packets/structure_item_spec.rb +22 -4
  55. data/spec/script/cmd_tlm_server_spec.rb +66 -0
  56. data/spec/script/extract_spec.rb +144 -0
  57. data/spec/script/tools_spec.rb +17 -2
  58. data/spec/system/system_spec.rb +1 -1
  59. data/spec/tools/cmd_tlm_server/api_spec.rb +6 -0
  60. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +1 -1
  61. data/spec/tools/table_manager/table_item_parser_spec.rb +61 -0
  62. data/spec/tools/table_manager/table_item_spec.rb +1 -1
  63. metadata +9 -2
@@ -120,6 +120,7 @@ module Cosmos
120
120
  @@limits_sleeper = Sleeper.new
121
121
  @@cancel_output = false
122
122
  @@cancel_limits = false
123
+ @@file_number = 1
123
124
 
124
125
  def initialize(parent, default_tab_text = 'Untitled')
125
126
  super(parent)
@@ -128,6 +129,11 @@ module Cosmos
128
129
  @initialized = false
129
130
  @debug_frame = nil
130
131
 
132
+ # Keep track of a unique file number so we can differentiate untitled tabs
133
+ @file_number = @@file_number
134
+ @@file_number +=1
135
+ @filename = ''
136
+
131
137
  @layout = Qt::VBoxLayout.new
132
138
  @layout.setContentsMargins(0,0,0,0)
133
139
 
@@ -149,6 +155,7 @@ module Cosmos
149
155
 
150
156
  # Add Initial Text Window
151
157
  @script = create_ruby_editor()
158
+ @script.filename = unique_filename()
152
159
  @script.connect(SIGNAL('modificationChanged(bool)')) do |changed|
153
160
  emit modificationChanged(changed)
154
161
  end
@@ -182,7 +189,6 @@ module Cosmos
182
189
 
183
190
  # Configure Variables
184
191
  @line_offset = 0
185
- @filename = ''
186
192
  @output_io = StringIO.new('', 'r+')
187
193
  @output_io_mutex = Mutex.new
188
194
  @change_callback = nil
@@ -210,19 +216,22 @@ module Cosmos
210
216
  @find_dialog = nil
211
217
  @replace_dialog = nil
212
218
 
213
- mark_breakpoints('')
219
+ mark_breakpoints(@script.filename)
220
+ end
221
+
222
+ def unique_filename
223
+ if @filename and !@filename.empty?
224
+ return @filename
225
+ else
226
+ return @default_tab_text.strip + @file_number.to_s
227
+ end
214
228
  end
215
229
 
216
230
  def current_tab_filename
217
231
  if @tab_book_shown
218
- filename = @tab_book.tabText(@tab_book.currentIndex)
219
- if filename == @default_tab_text
220
- return ''
221
- else
222
- return filename.strip
223
- end
232
+ return @tab_book.widget(@tab_book.currentIndex).filename
224
233
  else
225
- return @filename
234
+ return @script.filename
226
235
  end
227
236
  end
228
237
 
@@ -262,7 +271,17 @@ module Cosmos
262
271
  # Stop the message log so a new one will be created with the new filename
263
272
  stop_message_log()
264
273
  @filename = filename
265
- mark_breakpoints(filename)
274
+
275
+ # Deal with breakpoints created under the previous filename.
276
+ bkpt_filename = unique_filename()
277
+ if @@breakpoints[bkpt_filename].nil?
278
+ @@breakpoints[bkpt_filename] = @@breakpoints[@script.filename]
279
+ end
280
+ if bkpt_filename != @script.filename
281
+ @@breakpoints.delete(@script.filename)
282
+ @script.filename = bkpt_filename
283
+ end
284
+ mark_breakpoints(@script.filename)
266
285
  end
267
286
 
268
287
  def modified
@@ -298,6 +317,7 @@ module Cosmos
298
317
  def clear
299
318
  self.set_text('')
300
319
  self.filename = ''
320
+ @script.filename = unique_filename()
301
321
  self.modified = false
302
322
  end
303
323
 
@@ -384,13 +404,15 @@ module Cosmos
384
404
  @script.setPlainText(text)
385
405
  @script.stop_highlight
386
406
  @filename = filename
387
- mark_breakpoints(filename)
407
+ @script.filename = unique_filename()
408
+ mark_breakpoints(@script.filename)
388
409
  end
389
410
  end
390
411
 
391
412
  def set_text_from_file(filename)
392
413
  unless running?()
393
414
  @@file_cache[filename] = nil
415
+ @@breakpoints[filename] = nil
394
416
  load_file_into_script(filename)
395
417
  @filename = filename
396
418
  end
@@ -960,26 +982,27 @@ module Cosmos
960
982
  end
961
983
 
962
984
  def self.set_breakpoint(filename, line_number)
963
- filename = File.basename(filename)
964
985
  @@breakpoints[filename] ||= {}
965
986
  @@breakpoints[filename][line_number] = true
966
987
  end
967
988
 
968
989
  def self.clear_breakpoint(filename, line_number)
969
- filename = File.basename(filename)
970
990
  @@breakpoints[filename] ||= {}
971
991
  @@breakpoints[filename].delete(line_number) if @@breakpoints[filename][line_number]
972
992
  end
973
993
 
974
994
  def self.clear_breakpoints(filename = nil)
975
- filename = File.basename(filename) unless filename.nil?
976
995
  if filename == nil or filename.empty?
977
996
  @@breakpoints = {}
978
997
  else
979
- @@breakpoints[filename] = {}
998
+ @@breakpoints.delete(filename)
980
999
  end
981
1000
  end
982
1001
 
1002
+ def clear_breakpoints
1003
+ ScriptRunnerFrame.clear_breakpoints(unique_filename())
1004
+ end
1005
+
983
1006
  def select_tab_and_destroy_tabs_after_index(index)
984
1007
  Qt.execute_in_main_thread(true) do
985
1008
  if @tab_book_shown
@@ -1352,6 +1375,7 @@ module Cosmos
1352
1375
  else # new file
1353
1376
  # Create new tab
1354
1377
  new_script = create_ruby_editor()
1378
+ new_script.filename = filename
1355
1379
  @tab_book.addTab(new_script, ' ' + File.basename(filename) + ' ')
1356
1380
 
1357
1381
  @call_stack.push(filename.dup)
@@ -1373,9 +1397,12 @@ module Cosmos
1373
1397
  end
1374
1398
 
1375
1399
  def handle_pause(filename, line_number)
1376
- filename = File.basename(filename)
1400
+ bkpt_filename = ''
1401
+ Qt.execute_in_main_thread(true) {bkpt_filename = @active_script.filename}
1377
1402
  breakpoint = false
1378
- breakpoint = true if @@breakpoints[filename] and @@breakpoints[filename][line_number]
1403
+ breakpoint = true if @@breakpoints[bkpt_filename] and @@breakpoints[bkpt_filename][line_number]
1404
+
1405
+ filename = File.basename(filename)
1379
1406
  if @pause
1380
1407
  @pause = false unless @@step_mode
1381
1408
  if breakpoint
@@ -1544,8 +1571,7 @@ module Cosmos
1544
1571
  end
1545
1572
 
1546
1573
  def mark_breakpoints(filename)
1547
- @active_script.clear_breakpoints
1548
- breakpoints = @@breakpoints[File.basename(filename)]
1574
+ breakpoints = @@breakpoints[filename]
1549
1575
  if breakpoints
1550
1576
  breakpoints.each do |line_number, present|
1551
1577
  @active_script.add_breakpoint(line_number) if present
@@ -249,7 +249,7 @@ module Cosmos
249
249
  out.puts line
250
250
  end
251
251
  end
252
- end
252
+ end
253
253
  puts "Created #{filename}"
254
254
  return false
255
255
  end
@@ -358,9 +358,9 @@ module Cosmos
358
358
  @table_commit.statusTip = tr('Incorporate the current table data into a binary file which already contains the table')
359
359
  @table_commit.connect(SIGNAL('triggered()')) { table_commit() }
360
360
 
361
- # @table_update = Qt::Action.new(tr('&Update Definition'), self)
362
- # @table_update.statusTip = tr('Change the defaults in the definition file to the displayed table data')
363
- # @table_update.connect(SIGNAL('triggered()')) { table_update() }
361
+ #@table_update = Qt::Action.new(tr('&Update Definition'), self)
362
+ #@table_update.statusTip = tr('Change the defaults in the definition file to the displayed table data')
363
+ #@table_update.connect(SIGNAL('triggered()')) { table_update() }
364
364
  end
365
365
  end
366
366
 
@@ -385,7 +385,6 @@ module Cosmos
385
385
  file_menu.addAction(@exit_action)
386
386
 
387
387
  unless no_tables
388
- # Table Menu
389
388
  table_menu = menuBar.addMenu(tr('&Table'))
390
389
  table_menu.addAction(@table_check)
391
390
  table_menu.addAction(@table_default)
@@ -393,7 +392,7 @@ module Cosmos
393
392
  table_menu.addSeparator()
394
393
  table_menu.addAction(@table_save)
395
394
  table_menu.addAction(@table_commit)
396
- # table_menu.addAction(@table_update)
395
+ #table_menu.addAction(@table_update)
397
396
  end
398
397
 
399
398
  # Help Menu
@@ -739,6 +738,7 @@ module Cosmos
739
738
  else
740
739
  table.write(item.name, value)
741
740
  end
741
+ raise "out of range" if item.range && !item.range.include?(table.read(item.name, :RAW))
742
742
 
743
743
  # if we have a problem casting the value it probably means the user put in garbage
744
744
  # in this case force the range check to fail
@@ -1129,4 +1129,4 @@ module Cosmos
1129
1129
  statusBar.showMessage('')
1130
1130
  end
1131
1131
  end
1132
- end # module Cosmos
1132
+ end
@@ -182,10 +182,13 @@ module Cosmos
182
182
  # Check boxes
183
183
  @pause_on_error = Qt::CheckBox.new('Pause on Error')
184
184
  @pause_on_error.setChecked(true)
185
+ @pause_on_error.setObjectName('PauseOnError')
185
186
  @continue_test_case_after_error = Qt::CheckBox.new('Continue Test Case after Error')
186
187
  @continue_test_case_after_error.setChecked(true)
188
+ @continue_test_case_after_error.setObjectName('ContinueTestCaseAfterError')
187
189
  @abort_testing_after_error = Qt::CheckBox.new('Abort Testing after Error')
188
190
  @abort_testing_after_error.setChecked(false)
191
+ @abort_testing_after_error.setObjectName('AbortTestingAfterError')
189
192
 
190
193
  @checkbox_frame = Qt::VBoxLayout.new
191
194
  @checkbox_frame.setContentsMargins(0,0,0,0)
@@ -201,6 +204,7 @@ module Cosmos
201
204
 
202
205
  @manual = Qt::CheckBox.new('Manual')
203
206
  @manual.setChecked(true)
207
+ @manual.setObjectName('Manual')
204
208
  @manual.connect(SIGNAL('stateChanged(int)')) do
205
209
  if @manual.isChecked()
206
210
  $manual = true
@@ -212,6 +216,7 @@ module Cosmos
212
216
  $manual = true
213
217
  @loop_testing = Qt::CheckBox.new('Loop Testing')
214
218
  @loop_testing.setChecked(false)
219
+ @loop_testing.setObjectName('LoopTesting')
215
220
  @loop_testing.connect(SIGNAL('stateChanged(int)')) do
216
221
  if @loop_testing.isChecked()
217
222
  $loop_testing = true
@@ -226,6 +231,7 @@ module Cosmos
226
231
  @break_loop_after_error = Qt::CheckBox.new('Break Loop after Error')
227
232
  @break_loop_after_error.setChecked(false)
228
233
  @break_loop_after_error.setEnabled(false)
234
+ @break_loop_after_error.setObjectName('BreakLoopAfterError')
229
235
 
230
236
  @checkbox_frame = Qt::VBoxLayout.new
231
237
  @checkbox_frame.setContentsMargins(0,0,0,0)
@@ -19,6 +19,7 @@ Cosmos.catch_fatal_exception do
19
19
  require 'cosmos/gui/widgets/packet_log_frame'
20
20
  require 'cosmos/gui/dialogs/progress_dialog'
21
21
  require 'cosmos/gui/widgets/full_text_search_line_edit'
22
+ require 'cosmos/gui/utilities/analyze_log'
22
23
  end
23
24
 
24
25
  module Cosmos
@@ -119,6 +120,10 @@ module Cosmos
119
120
  @file_options.statusTip = tr('Open the options dialog')
120
121
  @file_options.connect(SIGNAL('triggered()')) { handle_options() }
121
122
 
123
+ @analyze_log = Qt::Action.new(tr('&Analyze Logs'), self)
124
+ @analyze_log.statusTip = tr('Analyze log file packet counts')
125
+ @analyze_log.connect(SIGNAL('triggered()')) { analyze_log_files() }
126
+
122
127
  # Mode Menu Actions
123
128
  @fill_down_check = Qt::Action.new(tr('&Fill Down'), self)
124
129
  @fill_down_check_keyseq = Qt::KeySequence.new(tr('Ctrl+F'))
@@ -132,10 +137,6 @@ module Cosmos
132
137
  @matlab_header_check.statusTip = tr('Add a Matlab header to the output data')
133
138
  @matlab_header_check.setCheckable(true)
134
139
 
135
- @share_columns_check = Qt::Action.new(tr('&Share Columns'), self)
136
- @share_columns_check.statusTip = tr('Share columns for items with the same name')
137
- @share_columns_check.setCheckable(true)
138
-
139
140
  @unique_only_check = Qt::Action.new(tr('&Unique Only'), self)
140
141
  @unique_only_check_keyseq = Qt::KeySequence.new(tr('Ctrl+U'))
141
142
  @unique_only_check.shortcut = @unique_only_check_keyseq
@@ -149,6 +150,40 @@ module Cosmos
149
150
  @batch_mode_check.setCheckable(true)
150
151
  @batch_mode_check.connect(SIGNAL('triggered()')) { batch_mode_changed() }
151
152
 
153
+ @normal_columns_check = Qt::Action.new(tr('&Normal Columns'), self)
154
+ @normal_columns_check.statusTip = tr('Normal Columns')
155
+ @normal_columns_check.setCheckable(true)
156
+ @normal_columns_check.setChecked(true)
157
+ @normal_columns_check.connect(SIGNAL('triggered()')) { column_mode_changed() }
158
+
159
+ @share_columns_check = Qt::Action.new(tr('Share Columns (&All)'), self)
160
+ @share_columns_check.statusTip = tr('Share columns for all items with the same name')
161
+ @share_columns_check.setCheckable(true)
162
+ @share_columns_check.connect(SIGNAL('triggered()')) { column_mode_changed() }
163
+
164
+ @share_indiv_columns_check = Qt::Action.new(tr('Share Columns (&Selected)'), self)
165
+ @share_indiv_columns_check.statusTip = tr('Share columns for selected items with the same name')
166
+ @share_indiv_columns_check.setCheckable(true)
167
+ @share_indiv_columns_check.connect(SIGNAL('triggered()')) { column_mode_changed() }
168
+
169
+ @full_column_names_check = Qt::Action.new(tr('Full &Column Names'), self)
170
+ @full_column_names_check.statusTip = tr('Use full item names in each column')
171
+ @full_column_names_check.setCheckable(true)
172
+ @full_column_names_check.connect(SIGNAL('triggered()')) { column_mode_changed() }
173
+
174
+ # The column options are mutually exclusive so create an action group
175
+ column_group = Qt::ActionGroup.new(self)
176
+ column_group.addAction(@normal_columns_check)
177
+ column_group.addAction(@share_columns_check)
178
+ column_group.addAction(@share_indiv_columns_check)
179
+ column_group.addAction(@full_column_names_check)
180
+
181
+ @shared_columns = []
182
+ @shared_columns_edit = Qt::Action.new(tr('S&elect Shared Columns'), self)
183
+ @shared_columns_edit.statusTip = tr('Select which columns are shared')
184
+ @shared_columns_edit.setEnabled(false)
185
+ @shared_columns_edit.connect(SIGNAL('triggered()')) { shared_columns_edit() }
186
+
152
187
  # Item Menu Actions
153
188
  @item_edit = Qt::Action.new(tr('&Edit Items'), self)
154
189
  @item_edit_keyseq = Qt::KeySequence.new(tr('Ctrl+E'))
@@ -168,6 +203,7 @@ module Cosmos
168
203
  @file_menu.addAction(@save_config)
169
204
  @file_menu.addSeparator()
170
205
  @file_menu.addAction(@file_options)
206
+ @file_menu.addAction(@analyze_log)
171
207
  @file_menu.addSeparator()
172
208
  @file_menu.addAction(@exit_action)
173
209
 
@@ -175,9 +211,15 @@ module Cosmos
175
211
  @mode_menu = menuBar.addMenu(tr('&Mode'))
176
212
  @mode_menu.addAction(@fill_down_check)
177
213
  @mode_menu.addAction(@matlab_header_check)
178
- @mode_menu.addAction(@share_columns_check)
179
214
  @mode_menu.addAction(@unique_only_check)
180
215
  @mode_menu.addAction(@batch_mode_check)
216
+ @mode_menu.addSeparator();
217
+ @mode_menu.addAction(@normal_columns_check)
218
+ @mode_menu.addAction(@share_columns_check)
219
+ @mode_menu.addAction(@share_indiv_columns_check)
220
+ @mode_menu.addAction(@full_column_names_check)
221
+ @mode_menu.addSeparator();
222
+ @mode_menu.addAction(@shared_columns_edit)
181
223
 
182
224
  # Item Menu
183
225
  @item_menu = menuBar.addMenu(tr('&Item'))
@@ -361,7 +403,6 @@ module Cosmos
361
403
 
362
404
  # Process and Open Buttons
363
405
  @button_layout = Qt::HBoxLayout.new
364
-
365
406
  @process_button = Qt::PushButton.new('&Process Files')
366
407
  @process_button.connect(SIGNAL('clicked()')) { process_log_files() }
367
408
  @button_layout.addWidget(@process_button)
@@ -451,7 +492,22 @@ module Cosmos
451
492
  def sync_gui_to_config
452
493
  @tlm_extractor_config.matlab_header = @matlab_header_check.checked?
453
494
  @tlm_extractor_config.fill_down = @fill_down_check.checked?
454
- @tlm_extractor_config.share_columns = @share_columns_check.checked?
495
+ if @share_columns_check.checked?
496
+ @tlm_extractor_config.set_column_mode(:SHARE_ALL_COLUMNS)
497
+ elsif @share_indiv_columns_check.checked?
498
+ @tlm_extractor_config.set_column_mode(:SHARE_INDIV_COLUMNS)
499
+ @tlm_extractor_config.clear_shared_columns
500
+ @shared_columns.each do |item|
501
+ split_item = item.scan ConfigParser::PARSING_REGEX
502
+ item_name = split_item[0]
503
+ value_type = split_item[1].to_sym
504
+ @tlm_extractor_config.add_shared_column(item_name, value_type)
505
+ end
506
+ elsif @full_column_names_check.checked?
507
+ @tlm_extractor_config.set_column_mode(:FULL_COLUMN_NAMES)
508
+ else
509
+ @tlm_extractor_config.set_column_mode(:NORMAL)
510
+ end
455
511
  @tlm_extractor_config.unique_only = @unique_only_check.checked?
456
512
  @tlm_extractor_config.downsample_seconds = @downsample_entry.value
457
513
  @tlm_extractor_config.output_filename = @packet_log_frame.output_filename
@@ -480,7 +536,21 @@ module Cosmos
480
536
  def sync_config_to_gui
481
537
  @matlab_header_check.setChecked(@tlm_extractor_config.matlab_header)
482
538
  @fill_down_check.setChecked(@tlm_extractor_config.fill_down)
483
- @share_columns_check.setChecked(@tlm_extractor_config.share_columns)
539
+ case @tlm_extractor_config.column_mode
540
+ when :SHARE_ALL_COLUMNS
541
+ @share_columns_check.setChecked(true)
542
+ when :SHARE_INDIV_COLUMNS
543
+ @share_indiv_columns_check.setChecked(true)
544
+ @shared_columns = []
545
+ @tlm_extractor_config.shared_indiv_columns.each do |shared_column|
546
+ @shared_columns << shared_column
547
+ end
548
+ when :FULL_COLUMN_NAMES
549
+ @full_column_names_check.setChecked(true)
550
+ else
551
+ @normal_columns_check.setChecked(true)
552
+ end
553
+ column_mode_changed()
484
554
  @unique_only_check.setChecked(@tlm_extractor_config.unique_only)
485
555
  @downsample_entry.value = @tlm_extractor_config.downsample_seconds
486
556
 
@@ -502,6 +572,10 @@ module Cosmos
502
572
  # File Menu Handlers
503
573
  ###############################################################################
504
574
 
575
+ def analyze_log_files
576
+ AnalyzeLog.execute(self, @packet_log_frame)
577
+ end
578
+
505
579
  # Handles processing log files
506
580
  def process_log_files
507
581
  @cancel = false
@@ -656,6 +730,15 @@ module Cosmos
656
730
  box.dispose
657
731
  end
658
732
 
733
+ def column_mode_changed()
734
+ if @share_indiv_columns_check.checked?
735
+ @shared_columns_edit.setEnabled(true)
736
+ else
737
+ @shared_columns_edit.setEnabled(false)
738
+ @shared_columns = []
739
+ end
740
+ end
741
+
659
742
  def batch_mode_changed
660
743
  if @batch_mode_check.checked?
661
744
  @config_box.hide
@@ -665,6 +748,7 @@ module Cosmos
665
748
  @fill_down_check.setEnabled(false)
666
749
  @matlab_header_check.setEnabled(false)
667
750
  @share_columns_check.setEnabled(false)
751
+ @full_column_names_check.setEnabled(false)
668
752
  @unique_only_check.setEnabled(false)
669
753
  @open_config.setEnabled(false)
670
754
  @save_config.setEnabled(false)
@@ -679,6 +763,7 @@ module Cosmos
679
763
  @fill_down_check.setEnabled(true)
680
764
  @matlab_header_check.setEnabled(true)
681
765
  @share_columns_check.setEnabled(true)
766
+ @full_column_names_check.setEnabled(true)
682
767
  @unique_only_check.setEnabled(true)
683
768
  @open_config.setEnabled(true)
684
769
  @save_config.setEnabled(true)
@@ -836,6 +921,58 @@ module Cosmos
836
921
  end
837
922
  end
838
923
 
924
+ def shared_columns_edit
925
+
926
+ # Get the list of "common" items in the config item list.
927
+ item_list = []
928
+ @config_item_list.each do |item|
929
+ split_item = item.text.scan ConfigParser::PARSING_REGEX
930
+ item_type = split_item[0]
931
+ item_name = split_item[3]
932
+ value_type = split_item[4]
933
+ if value_type
934
+ value_type = value_type.upcase.intern
935
+ else
936
+ value_type = :CONVERTED
937
+ end
938
+ if item_type == 'ITEM'
939
+ item_list << item_name + ' ' + value_type.to_s
940
+ end
941
+ end
942
+ shared_column_list = item_list.select {|item| item_list.count(item) > 1}
943
+ shared_column_list.uniq!
944
+
945
+ dialog = Qt::Dialog.new(self)
946
+ dialog.setWindowTitle("Select Common Items to Share Columns")
947
+ layout = Qt::VBoxLayout.new
948
+
949
+ list_layout = Qt::BoxLayout.new(Qt::Horizontal)
950
+ list = MyListWidget.new(self)
951
+ list.setSelectionMode(Qt::AbstractItemView::MultiSelection)
952
+ list.setMinimumHeight(150)
953
+ list.setMinimumWidth(400)
954
+ shared_column_list.each {|item| list.addItem(item)}
955
+ list_layout.addWidget(list)
956
+ layout.addLayout(list_layout)
957
+ list.each {|item| item.setSelected(true) if @shared_columns.include?(item.text)}
958
+
959
+ button_layout = Qt::BoxLayout.new(Qt::Horizontal)
960
+ cancel = Qt::PushButton.new("Cancel")
961
+ connect(cancel, SIGNAL('clicked()'), dialog, SLOT('reject()'))
962
+ button_layout.addWidget(cancel)
963
+ ok = Qt::PushButton.new("Save")
964
+ connect(ok, SIGNAL('clicked()'), dialog, SLOT('accept()'))
965
+ button_layout.addWidget(ok)
966
+ layout.addLayout(button_layout)
967
+
968
+ dialog.setLayout(layout)
969
+ if dialog.exec == Qt::Dialog::Accepted
970
+ @shared_columns = []
971
+ list.each {|item| @shared_columns << item.text if item.isSelected()}
972
+ end
973
+ dialog.dispose
974
+ end
975
+
839
976
  def open_button
840
977
  Cosmos.open_in_text_editor(@packet_log_frame.output_filename)
841
978
  end