cosmos 4.4.0-java → 4.4.1-java

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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.gitignore +1 -0
  4. data/.travis.yml +6 -6
  5. data/Dockerfile +65 -0
  6. data/Manifest.txt +12 -2
  7. data/README.md +5 -0
  8. data/Rakefile +52 -0
  9. data/appveyor.yml +18 -8
  10. data/autohotkey/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
  11. data/autohotkey/lib/cmd_sequence_exporter.rb +52 -0
  12. data/autohotkey/procedures/collect.rb +2 -2
  13. data/autohotkey/procedures/collect_util.rb +1 -1
  14. data/autohotkey/procedures/script_test.rb +1 -1
  15. data/autohotkey/tools/CmdSenderAHK2 +18 -0
  16. data/autohotkey/tools/cmd_sender.ahk +34 -6
  17. data/autohotkey/tools/cmd_sender2.ahk +4 -0
  18. data/autohotkey/tools/cmd_sequence.ahk +21 -8
  19. data/autohotkey/tools/config_editor.ahk +4 -4
  20. data/bin/cstol_converter +1 -1
  21. data/cosmos.gemspec +1 -1
  22. data/data/config/command_modifiers.yaml +16 -1
  23. data/data/config/param_item_modifiers.yaml +5 -0
  24. data/data/config/system.yaml +31 -1
  25. data/data/config/telemetry_modifiers.yaml +16 -1
  26. data/data/crc.txt +415 -410
  27. data/demo/config/dart/Gemfile +1 -6
  28. data/demo/config/data/crc.txt +244 -243
  29. data/demo/config/system/system.txt +3 -0
  30. data/demo/config/system/system2.txt +3 -0
  31. data/demo/config/system/system_alt_ports.txt +3 -0
  32. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +3 -3
  33. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +4 -0
  34. data/demo/config/targets/INST/cmd_tlm/inst_tlm_override.txt +12 -0
  35. data/demo/config/targets/INST/lib/sim_inst.rb +2 -2
  36. data/demo/config/targets/INST/target.txt +1 -0
  37. data/demo/procedures/cosmos_api_test.rb +8 -8
  38. data/install/config/dart/Gemfile +2 -7
  39. data/install/config/data/crc.txt +143 -143
  40. data/install/config/system/system.txt +3 -0
  41. data/lib/cosmos/dart/config/boot.rb +1 -1
  42. data/lib/cosmos/dart/config/database.yml +2 -0
  43. data/lib/cosmos/dart/lib/dart_common.rb +11 -4
  44. data/lib/cosmos/dart/lib/dart_constants.rb +15 -0
  45. data/lib/cosmos/dart/lib/dart_decom_query.rb +5 -6
  46. data/lib/cosmos/dart/lib/dart_decommutator.rb +66 -56
  47. data/lib/cosmos/dart/lib/dart_master_query.rb +71 -0
  48. data/lib/cosmos/dart/lib/dart_reducer_worker_thread.rb +165 -134
  49. data/lib/cosmos/dart/processes/dart.rb +4 -2
  50. data/lib/cosmos/dart/processes/dart_decom_server.rb +2 -2
  51. data/lib/cosmos/dart/processes/dart_ingester.rb +38 -1
  52. data/lib/cosmos/dart/processes/dart_master.rb +44 -0
  53. data/lib/cosmos/dart/processes/dart_util.rb +115 -0
  54. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +21 -2
  55. data/lib/cosmos/interfaces/protocols/length_protocol.rb +5 -0
  56. data/lib/cosmos/io/json_drb.rb +3 -3
  57. data/lib/cosmos/io/posix_serial_driver.rb +1 -1
  58. data/lib/cosmos/io/win32_serial_driver.rb +23 -2
  59. data/lib/cosmos/packet_logs/packet_log_reader.rb +2 -2
  60. data/lib/cosmos/packets/packet.rb +1 -1
  61. data/lib/cosmos/packets/packet_config.rb +26 -8
  62. data/lib/cosmos/packets/structure.rb +17 -0
  63. data/lib/cosmos/packets/structure_item.rb +5 -1
  64. data/lib/cosmos/packets/telemetry.rb +7 -1
  65. data/lib/cosmos/system/system.rb +115 -48
  66. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +360 -0
  67. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +23 -319
  68. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +14 -17
  69. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +43 -331
  70. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +16 -11
  71. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +1 -0
  72. data/lib/cosmos/tools/config_editor/config_editor.rb +33 -2
  73. data/lib/cosmos/tools/config_editor/config_editor_frame.rb +8 -9
  74. data/lib/cosmos/tools/config_editor/system_config_dialog.rb +158 -0
  75. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +2 -2
  76. data/lib/cosmos/tools/test_runner/test.rb +5 -2
  77. data/lib/cosmos/tools/test_runner/test_runner.rb +2 -2
  78. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +17 -13
  79. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +20 -16
  80. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +18 -11
  81. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +16 -5
  82. data/lib/cosmos/utilities/ruby_lex_utils.rb +34 -30
  83. data/lib/cosmos/version.rb +4 -4
  84. data/lib/cosmos/win32/excel.rb +23 -17
  85. data/run_gui_tests.bat +1 -0
  86. data/spec/core_ext/socket_spec.rb +1 -1
  87. data/spec/install/yaml_docs_spec.rb +26 -6
  88. data/spec/interfaces/protocols/length_protocol_spec.rb +39 -0
  89. data/spec/io/json_drb_spec.rb +14 -0
  90. data/spec/io/win32_serial_driver_spec.rb +16 -2
  91. data/spec/packet_logs/packet_log_reader_spec.rb +2 -2
  92. data/spec/packets/structure_spec.rb +52 -2
  93. data/spec/packets/telemetry_spec.rb +29 -1
  94. data/spec/system/system_spec.rb +2 -2
  95. data/spec/utilities/message_log_spec.rb +6 -3
  96. data/tasks/gemfile_stats.rake +22 -13
  97. metadata +15 -5
  98. data/lib/cosmos/dart/Gemfile +0 -69
@@ -14,7 +14,7 @@ Cosmos.catch_fatal_exception do
14
14
  require 'cosmos/script'
15
15
  require 'cosmos/gui/dialogs/calendar_dialog'
16
16
  require 'cosmos/gui/dialogs/cmd_details_dialog'
17
- require 'cosmos/tools/cmd_sender/cmd_param_table_item_delegate'
17
+ require 'cosmos/tools/cmd_sender/cmd_params'
18
18
  end
19
19
 
20
20
  module Cosmos
@@ -26,36 +26,18 @@ module Cosmos
26
26
  signals 'modified()'
27
27
  MANUALLY = "MANUALLY ENTERED"
28
28
 
29
- # Parse a time and command string into a SequenceItem which is returned
30
- # @param time [String] Time (absolute or relative delay). Supports a single
31
- # float value (relative delay) or a absolute time specified as
32
- # "YYYY/MM/DD HH:MM:SS.MS"
33
- # @param command [String] Command String which should not be
34
- # quoted and is everything inside the quotes of a command.
35
- # For example: TGT PKT with STRING 'HI', VALUE 12. Parse errors are
36
- # raised as execptions which must be handled by higher level code.
37
- # @return [SequenceItem] SequenceItem which the line represents
38
- def self.parse(time, command)
39
- tgt_name, pkt_name, cmd_params = extract_fields_from_cmd_text(command)
40
- packet = System.commands.packet(tgt_name, pkt_name).dup
41
- packet.restore_defaults
42
- cmd_params.each do |param_name, param_value|
43
- packet.write(param_name, param_value)
44
- end
45
- SequenceItem.new(packet, time)
46
- end
47
-
48
29
  # Create a new SequenceItem based on the given command with the given delay
49
- # @param command [Packet] Command packet
50
30
  # @param time [String] Absolute time in YYYY/MM/DD HH:MM:SS format or a
51
31
  # single float value representing the delta delay time
52
- def initialize(command, time = nil)
32
+ def initialize(parent, target_name, packet_name, params = nil, time = nil)
53
33
  super()
54
- @command = command
55
- @table = nil
56
- @param_widgets = []
57
- @show_ignored = false
58
- @states_in_hex = false
34
+ @cmd_params = CmdParams.new
35
+ # Propagate the modified signal up
36
+ @cmd_params.connect(SIGNAL('modified()')) do
37
+ set_cmd_name_info()
38
+ emit modified
39
+ end
40
+ @command = System.commands.packet(target_name, packet_name)
59
41
  @expanded = false
60
42
  @file_dir = System.paths['LOGS']
61
43
 
@@ -66,50 +48,35 @@ module Cosmos
66
48
  top_layout = Qt::VBoxLayout.new
67
49
  top_layout.setContentsMargins(2, 0, 0, 0)
68
50
  setLayout(top_layout)
69
- top_layout.addLayout(create_cmd_layout(command, time))
51
+ top_layout.addLayout(create_cmd_layout(target_name, packet_name, time))
70
52
  top_layout.addWidget(create_parameters())
71
- update_cmd_params()
53
+ add_table(@cmd_params.update_cmd_params(@command, existing: params))
72
54
  set_cmd_name_info()
73
55
  end
74
56
 
75
- # Set or clear read only status on the item
76
- # @param bool [Boolean] Whether to make the item read only
77
- def read_only(bool)
78
- @time.setReadOnly(bool)
57
+ def add_table(table)
58
+ return unless table
59
+ table.setSizePolicy(Qt::SizePolicy.Minimum, Qt::SizePolicy.Minimum)
60
+ table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
61
+ table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
62
+ table.setFixedSize(table.horizontalHeader.length + table.verticalHeader.width,
63
+ 2 + table.verticalHeader.length + table.horizontalHeader.height)
64
+ @table_layout.addWidget(table)
79
65
  end
80
-
81
- # Show or hide ignored parameters
82
- # @param bool [Boolean] Whether to show ignored command items
83
- def show_ignored(bool)
84
- @show_ignored = bool
85
- update_cmd_params(bool)
66
+
67
+ def states_in_hex(checked)
68
+ @cmd_params.states_in_hex(checked)
86
69
  end
87
70
 
88
- # Display state values in hex (or decimal)
89
- # @param bool [Boolean] Whether to display state values in hex
90
- def states_in_hex(bool)
91
- @states_in_hex = bool
92
- @param_widgets.each do |_, _, state_value_item|
93
- next unless state_value_item
94
- text = state_value_item.text
95
- quotes_removed = text.remove_quotes
96
- if text == quotes_removed
97
- if bool
98
- if text.is_int?
99
- @table.blockSignals(true)
100
- state_value_item.text = sprintf("0x%X", text.to_i)
101
- @table.blockSignals(false)
102
- end
103
- else
104
- if text.is_hex?
105
- @table.blockSignals(true)
106
- state_value_item.text = Integer(text).to_s
107
- @table.blockSignals(false)
108
- end
109
- end
110
- end
111
- end
71
+ def show_ignored(checked)
72
+ add_table(@cmd_params.update_cmd_params(@command, show_ignored: checked))
73
+ set_cmd_name_info()
74
+ end
112
75
 
76
+ # Set or clear read only status on the item
77
+ # @param bool [Boolean] Whether to make the item read only
78
+ def read_only(bool)
79
+ @time.setReadOnly(bool)
113
80
  end
114
81
 
115
82
  # Show the command parameters part of the GUI
@@ -124,33 +91,9 @@ module Cosmos
124
91
  @parameters.hide
125
92
  end
126
93
 
127
- # @return [Hash] All the parameter item values keyed by their name
128
- def command_params
129
- params = {}
130
- @param_widgets.each do |packet_item, value_item, state_value_item|
131
- text = ''
132
- Qt.execute_in_main_thread do
133
- text = value_item.text
134
- text = state_value_item.text if state_value_item && (text == MANUALLY)
135
- end
136
- quotes_removed = text.remove_quotes
137
- if text == quotes_removed
138
- if (packet_item.data_type == :STRING or packet_item.data_type == :BLOCK) and text.upcase.start_with?("0X")
139
- params[packet_item.name] = text.hex_to_byte_string
140
- else
141
- params[packet_item.name] = text.convert_to_value
142
- end
143
- else
144
- params[packet_item.name] = quotes_removed
145
- end
146
- raise "#{packet_item.name} is required" if quotes_removed == '' && packet_item.required
147
- end
148
- params
149
- end
150
-
151
94
  # @return [String] Command to be executed with no quotes or other decorations
152
95
  def command_string
153
- output_string = System.commands.build_cmd_output_string(@command.target_name, @command.packet_name, command_params(), false)
96
+ output_string = System.commands.build_cmd_output_string(@command.target_name, @command.packet_name, @cmd_params.params_text, false)
154
97
  if output_string =~ /[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F-\xFF]/
155
98
  output_string = output_string.inspect.remove_quotes
156
99
  end
@@ -165,7 +108,7 @@ module Cosmos
165
108
  end
166
109
 
167
110
  def command
168
- System.commands.build_cmd(@command.target_name, @command.packet_name, command_params(), false)
111
+ System.commands.build_cmd(@command.target_name, @command.packet_name, @cmd_params.params_text, false)
169
112
  end
170
113
 
171
114
  # @return [String] Time and command string
@@ -193,12 +136,12 @@ module Cosmos
193
136
  # and the delete button to remove the sequence item.
194
137
  # @param command [Packet] Command packet
195
138
  # @param time [String] Execution delay in absolute or relative time
196
- def create_cmd_layout(command, time)
139
+ def create_cmd_layout(target_name, packet_name, time)
197
140
  cmd_layout = Qt::HBoxLayout.new
198
141
  cmd_layout.setContentsMargins(0, 0, 0, 0)
199
142
  cmd_layout.addWidget(create_time_edit(time))
200
143
 
201
- @cmd_name = Qt::Label.new("#{command.target_name} #{command.packet_name}")
144
+ @cmd_name = Qt::Label.new("#{target_name} #{packet_name}")
202
145
  cmd_layout.addWidget(@cmd_name)
203
146
  @cmd_info = Qt::Label.new("") # Label for the hazardous designation
204
147
  cmd_layout.addWidget(@cmd_info)
@@ -263,252 +206,21 @@ module Cosmos
263
206
  @parameters
264
207
  end
265
208
 
266
- # Update the command parameters table for the given command
267
- # @param ignored_toggle [Boolean] Whether to display the ignored
268
- # parameters. Pass nil (the default) to keep the existing setting.
269
- def update_cmd_params(ignored_toggle = nil)
270
- old_params = {}
271
- if !ignored_toggle.nil?
272
- # Save parameter values
273
- @param_widgets.each do |packet_item, value_item, state_value_item|
274
- text = value_item.text
275
- if state_value_item
276
- old_params[packet_item.name] = [text, state_value_item.text]
277
- else
278
- old_params[packet_item.name] = text
279
- end
280
- end
281
- end
282
-
283
- target = System.targets[@command.target_name]
284
- packet_items = @command.sorted_items
285
- shown_packet_items = []
286
- packet_items.each do |packet_item|
287
- if target && target.ignored_parameters.include?(packet_item.name) && !@show_ignored
288
- if @param_widgets.empty? # First time rendering the parameters
289
- if packet_item.states
290
- # Skip this if the default matches the saved value
291
- next if @command.read_item(packet_item, :RAW) == packet_item.default
292
- else
293
- # Skip this if the default matches the saved value
294
- next if @command.read_item(packet_item) == packet_item.default
295
- end
296
- else # Check the current values
297
- result = @param_widgets.select {|item,_,_| item == packet_item }
298
- next if result.empty?
299
- _, value_item, state_value_item = result[0]
300
- value = state_value_item ? state_value_item.text : value_item.text
301
- # Skip this if the default matches the current value
302
- next if packet_item.default.to_s == value
303
- end
304
- end
305
- shown_packet_items << packet_item
306
- end
307
-
308
- @table.dispose if @table
309
- @table = nil
310
-
311
- # Update Parameters
312
- @param_widgets = []
313
- drawn_header = false
314
-
315
- row = 0
316
- shown_packet_items.each do |packet_item|
317
- value_item = nil
318
- state_value_item = nil
319
-
320
- unless drawn_header
321
- @table = Qt::TableWidget.new()
322
- @table.setSizePolicy(Qt::SizePolicy::Expanding, Qt::SizePolicy::Expanding)
323
- @table.setWordWrap(true)
324
- @table.setRowCount(shown_packet_items.length)
325
- @table.setColumnCount(5)
326
- @table.setHorizontalHeaderLabels(['Name', ' Value or State ', ' ', 'Units', 'Description'])
327
- @table.verticalHeader.setVisible(false)
328
- @table.setItemDelegate(CmdParamTableItemDelegate.new(@table, @param_widgets))
329
- @table.setEditTriggers(Qt::AbstractItemView::DoubleClicked | Qt::AbstractItemView::SelectedClicked | Qt::AbstractItemView::AnyKeyPressed)
330
- @table.setSelectionMode(Qt::AbstractItemView::NoSelection)
331
- @table.setContextMenuPolicy(Qt::CustomContextMenu)
332
- @table.connect(SIGNAL('customContextMenuRequested(const QPoint&)')) do |point|
333
- context_menu(point)
334
- end
335
- drawn_header = true
336
- end
337
-
338
- # Parameter Name
339
- item = Qt::TableWidgetItem.new("#{packet_item.name}:")
340
- item.setTextAlignment(Qt::AlignRight | Qt::AlignVCenter)
341
- item.setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled)
342
- @table.setItem(row, 0, item)
343
-
344
- if packet_item.states
345
- default = @command.read_item(packet_item, :RAW)
346
- default_state = packet_item.states.key(default)
347
- if old_params[packet_item.name]
348
- value_item = Qt::TableWidgetItem.new(old_params[packet_item.name][0])
349
- else
350
- if default_state
351
- value_item = Qt::TableWidgetItem.new(default_state.to_s)
352
- else
353
- value_item = Qt::TableWidgetItem.new(MANUALLY)
354
- end
355
- end
356
- value_item.setTextAlignment(Qt::AlignRight | Qt::AlignVCenter)
357
- value_item.setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable)
358
- @table.setItem(row, 1, value_item)
359
-
360
- if old_params[packet_item.name]
361
- state_value_item = Qt::TableWidgetItem.new(old_params[packet_item.name][1])
362
- else
363
- if @states_in_hex && packet_item.default.kind_of?(Integer)
364
- state_value_item = Qt::TableWidgetItem.new(sprintf("0x%X", default))
365
- else
366
- default_str = default.to_s
367
- if default_str.is_printable?
368
- state_value_item = Qt::TableWidgetItem.new(default_str)
369
- else
370
- state_value_item = Qt::TableWidgetItem.new("0x" + default_str.simple_formatted)
371
- end
372
- end
373
- end
374
- state_value_item.setTextAlignment(Qt::AlignRight | Qt::AlignVCenter)
375
- state_value_item.setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable)
376
- @table.setItem(row, 2, state_value_item)
377
- else # Parameter Value
378
- if old_params[packet_item.name]
379
- value_item = Qt::TableWidgetItem.new(old_params[packet_item.name])
380
- else
381
- default = @command.read_item(packet_item)
382
- if packet_item.format_string
383
- begin
384
- value_text = sprintf(packet_item.format_string, default)
385
- rescue
386
- # Oh well - Don't use the format string
387
- value_text = default.to_s
388
- end
389
- else
390
- value_text = default.to_s
391
- end
392
- if !value_text.is_printable?
393
- value_text = "0x" + value_text.simple_formatted
394
- end
395
- value_item = Qt::TableWidgetItem.new(value_text)
396
- end
397
- value_item.setTextAlignment(Qt::AlignRight | Qt::AlignVCenter)
398
- value_item.setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable)
399
- @table.setItem(row, 1, value_item)
400
- @table.setSpan(row, 1, 1, 2)
401
- end
402
-
403
- # Units
404
- item = Qt::TableWidgetItem.new(packet_item.units.to_s)
405
- item.setTextAlignment(Qt::AlignRight | Qt::AlignVCenter)
406
- item.setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled)
407
- @table.setItem(row, 3, item)
408
-
409
- # Description
410
- item = Qt::TableWidgetItem.new(packet_item.description.to_s)
411
- item.setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter)
412
- item.setFlags(Qt::NoItemFlags | Qt::ItemIsSelectable | Qt::ItemIsEnabled)
413
- @table.setItem(row, 4, item)
414
-
415
- @param_widgets << [packet_item, value_item, state_value_item]
416
- row += 1
417
- end
418
-
419
- if @table
420
- connect_table_item_changed()
421
- @table.setSizePolicy(Qt::SizePolicy.Minimum, Qt::SizePolicy.Minimum)
422
- @table.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
423
- @table.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
424
- @table.resizeColumnsToContents()
425
- @table.resizeRowsToContents()
426
- @table.setFixedSize(@table.horizontalHeader.length + @table.verticalHeader.width,
427
- 2 + @table.verticalHeader.length + @table.horizontalHeader.height)
428
- @table_layout.addWidget(@table)
429
- end
430
- end
431
-
432
209
  # Sets the @cmd_name label to the command that will be sent. Also udpates
433
210
  # the @cmd_info with whether this command is hazardous or not.
434
211
  def set_cmd_name_info
435
- @cmd_name.text = command_string
436
- hazardous, _ = System.commands.cmd_hazardous?(@command.target_name, @command.packet_name, command_params())
437
- if hazardous
438
- @cmd_info.text = "(Hazardous)"
439
- else
440
- @cmd_info.text = ""
212
+ Qt.execute_in_main_thread do
213
+ @cmd_name.text = command_string
214
+ hazardous, _ = System.commands.cmd_hazardous?(@command.target_name, @command.packet_name, @cmd_params.params_text)
215
+ if hazardous
216
+ @cmd_info.text = "(Hazardous)"
217
+ else
218
+ @cmd_info.text = ""
219
+ end
441
220
  end
442
221
  rescue => error
443
222
  @cmd_info.text = "(Error)"
444
- Qt::MessageBox.warning(self, 'Error', error.message)
445
- end
446
-
447
- # If the user right clicks over a table item, this method displays a context
448
- # menu with various options.
449
- # @param point [Qt::Point] Point to display the context menu
450
- def context_menu(point)
451
- target_name = @command.target_name
452
- packet_name = @command.packet_name
453
- item = @table.itemAt(point)
454
- if item
455
- item_name = @table.item(item.row, 0).text[0..-2] # Remove :
456
- if target_name.length > 0 && packet_name.length > 0 && item_name.length > 0
457
- menu = Qt::Menu.new()
458
-
459
- details_action = Qt::Action.new("Details #{target_name} #{packet_name} #{item_name}", self)
460
- details_action.statusTip = "Popup details about #{target_name} #{packet_name} #{item_name}"
461
- details_action.connect(SIGNAL('triggered()')) do
462
- CmdDetailsDialog.new(nil, target_name, packet_name, item_name)
463
- end
464
- menu.addAction(details_action)
465
-
466
- file_chooser_action = Qt::Action.new("Insert Filename", self)
467
- file_chooser_action.statusTip = "Select a file and place its name into this parameter"
468
- file_chooser_action.connect(SIGNAL('triggered()')) do
469
- filename = Qt::FileDialog::getOpenFileName(self, "Insert Filename:", @file_dir, "All Files (*)")
470
- if filename && !filename.empty?
471
- @file_dir = File.dirname(filename)
472
- _, value_item, state_value_item = @param_widgets[item.row]
473
- if state_value_item
474
- state_value_item.setText(filename)
475
- elsif value_item
476
- value_item.setText(filename)
477
- end
478
- end
479
- end
480
- menu.addAction(file_chooser_action)
481
-
482
- menu.exec(@table.mapToGlobal(point))
483
- menu.dispose
484
- end
485
- end # if item
486
- end
487
-
488
- # Connect the itemChanged signal to the table so we can handle user edits
489
- # of the table parameters. This method emits the modified signal.
490
- def connect_table_item_changed
491
- @table.connect(SIGNAL('itemChanged(QTableWidgetItem*)')) do |item|
492
- packet_item, value_item, state_value_item = @param_widgets[item.row]
493
- if item.column == 1
494
- if packet_item.states
495
- value = packet_item.states[value_item.text]
496
- @table.blockSignals(true)
497
- if @states_in_hex && value.kind_of?(Integer)
498
- state_value_item.setText(sprintf("0x%X", value))
499
- else
500
- state_value_item.setText(value.to_s)
501
- end
502
- @table.blockSignals(false)
503
- end
504
- elsif item.column == 2
505
- @table.blockSignals(true)
506
- @table.item(item.row, 1).setText(MANUALLY)
507
- @table.blockSignals(false)
508
- end
509
- set_cmd_name_info()
510
- emit modified # Tell the higher level that something changed
511
- end
223
+ Qt::MessageBox.warning(self, 'Error', "Error parsing #{@command.target_name} #{@command.packet_name} due to #{error.message}")
512
224
  end
513
225
  end
514
226
  end
@@ -19,8 +19,9 @@ module Cosmos
19
19
  signals 'modified()'
20
20
 
21
21
  # Create the SequenceList
22
- def initialize
22
+ def initialize(parent)
23
23
  super()
24
+ @parent = parent
24
25
  @modified = false
25
26
  layout = Qt::VBoxLayout.new()
26
27
  layout.setContentsMargins(0, 0, 0, 0)
@@ -45,7 +46,8 @@ module Cosmos
45
46
  usage = "#{keyword} <Delay Time> <Command>"
46
47
  parser.verify_num_parameters(2, 2, usage)
47
48
  begin
48
- item = SequenceItem.parse(params[0], params[1])
49
+ tgt_name, pkt_name, cmd_params = extract_fields_from_cmd_text(params[1])
50
+ item = SequenceItem.new(@parent, tgt_name, pkt_name, cmd_params, params[0])
49
51
  # Connect the SequenceItems modified signal to propagate it
50
52
  # forward by emitting our own modified signal
51
53
  item.connect(SIGNAL("modified()")) do
@@ -63,12 +65,13 @@ module Cosmos
63
65
  @modified = false # Initially we're not modified
64
66
  end
65
67
 
66
- # Add a new SequenceItem to the list.
67
- # @param command [Packet] Command packet to base the SequenceItem on
68
+ # Add a new SequenceItem to the list based on the given target and packet
69
+ # @param target_name [String] target name containing the command
70
+ # @param packet_name [String] packet name containing the command
68
71
  # @return [SequenceItem] The item added
69
- def add(command)
72
+ def add(target_name, packet_name)
70
73
  @modified = true
71
- item = SequenceItem.new(command)
74
+ item = SequenceItem.new(@parent, target_name, packet_name)
72
75
  # Connect the SequenceItems modified signal to propagate it
73
76
  # forward by emitting our own modified signal
74
77
  item.connect(SIGNAL("modified()")) do
@@ -118,11 +121,13 @@ module Cosmos
118
121
  # application.
119
122
  # @param filename [String] Filename to open and write the sequence
120
123
  def save(filename)
121
- @modified = false
122
- File.open(filename, "w") do |file|
123
- # Each SequenceItem's save method returns the save string
124
- file.write(collect {|item| item.save }.join("\n"))
125
- file.write("\n") # final newline
124
+ begin
125
+ sequence = collect {|item| item.save }.join("\n") + "\n"
126
+ @modified = false
127
+ File.open(filename, "w") {|file| file.write(sequence) }
128
+ rescue Exception => err
129
+ message = "Error saving due to #{err}"
130
+ Qt::MessageBox.critical(self, 'Error', message)
126
131
  end
127
132
  end
128
133