cosmos 4.2.4-java → 4.5.0-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 (458) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +30 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  5. data/.github/ISSUE_TEMPLATE/help---usage---general-question.md +12 -0
  6. data/.gitignore +2 -0
  7. data/.travis.yml +6 -6
  8. data/Dockerfile +69 -0
  9. data/Gemfile +1 -1
  10. data/Manifest.txt +130 -46
  11. data/README.md +9 -0
  12. data/Rakefile +57 -0
  13. data/appveyor.yml +18 -7
  14. data/autohotkey/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -1
  15. data/autohotkey/config/targets/INST/cmd_tlm/inst_tlm.txt +5 -5
  16. data/autohotkey/config/targets/INST/lib/sim_inst.rb +3 -1
  17. data/autohotkey/config/tools/cmd_sequence/cmd_sequence.txt +2 -0
  18. data/autohotkey/config/tools/handbook_creator/assets/css/bootstrap-theme.css +397 -0
  19. data/autohotkey/config/tools/handbook_creator/assets/css/bootstrap-theme.min.css +7 -0
  20. data/autohotkey/config/tools/handbook_creator/assets/css/bootstrap.css +7118 -0
  21. data/autohotkey/config/tools/handbook_creator/assets/css/bootstrap.min.css +7 -0
  22. data/autohotkey/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  23. data/autohotkey/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  24. data/autohotkey/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  25. data/autohotkey/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  26. data/autohotkey/config/tools/handbook_creator/assets/js/bootstrap.js +2006 -0
  27. data/autohotkey/config/tools/handbook_creator/assets/js/bootstrap.min.js +7 -0
  28. data/autohotkey/config/tools/table_manager/ConfigTables_def.txt +2 -4
  29. data/autohotkey/config/tools/table_manager/SubTables/OneDimensionalSubTable_def.txt +31 -0
  30. data/autohotkey/config/tools/table_manager/SubTables/TwoDimensionalSubTable_def.txt +28 -0
  31. data/autohotkey/config/tools/test_runner/test_runner.txt +1 -1
  32. data/autohotkey/config/tools/test_runner/test_runner2.txt +1 -1
  33. data/autohotkey/config/tools/test_runner/test_runner3.txt +1 -1
  34. data/autohotkey/config/tools/test_runner/test_runner4.txt +1 -1
  35. data/autohotkey/lib/cmd_sequence_exporter.rb +52 -0
  36. data/autohotkey/procedures/collect.rb +2 -2
  37. data/autohotkey/procedures/collect_util.rb +1 -1
  38. data/autohotkey/procedures/script_test.rb +1 -1
  39. data/autohotkey/tools/CmdSenderAHK2 +18 -0
  40. data/autohotkey/tools/cmd_sender.ahk +34 -6
  41. data/autohotkey/tools/cmd_sender2.ahk +4 -0
  42. data/autohotkey/tools/cmd_sequence.ahk +36 -22
  43. data/autohotkey/tools/cmd_sequence2.ahk +1 -1
  44. data/autohotkey/tools/config_editor.ahk +5 -5
  45. data/autohotkey/tools/launcher.ahk +1 -0
  46. data/autohotkey/tools/limits_monitor.ahk +1 -1
  47. data/autohotkey/tools/packet_viewer.ahk +7 -6
  48. data/autohotkey/tools/script_runner.ahk +16 -4
  49. data/autohotkey/tools/test_runner.ahk +8 -8
  50. data/bin/cosmos +38 -1
  51. data/bin/cstol_converter +1 -1
  52. data/bin/dart_util +0 -0
  53. data/bin/rubysloc +73 -28
  54. data/bin/xtce_converter +1 -1
  55. data/cosmos.gemspec +7 -9
  56. data/data/config/_interfaces.yaml +4 -0
  57. data/data/config/cmd_sequence.yaml +14 -0
  58. data/data/config/command_modifiers.yaml +16 -1
  59. data/data/config/housekeeping_params.yaml +14 -0
  60. data/data/config/interface_modifiers.yaml +14 -2
  61. data/data/config/item_modifiers.yaml +11 -1
  62. data/data/config/launcher.yaml +12 -2
  63. data/data/config/param_item_modifiers.yaml +7 -2
  64. data/data/config/parameter_modifiers.yaml +20 -0
  65. data/data/config/screen.yaml +2 -0
  66. data/data/config/script_runner.yaml +9 -0
  67. data/data/config/system.yaml +152 -28
  68. data/data/config/table_manager.yaml +7 -0
  69. data/data/config/target.yaml +12 -0
  70. data/data/config/telemetry_modifiers.yaml +19 -2
  71. data/data/config/test_runner.yaml +10 -9
  72. data/data/config/widgets.yaml +174 -11
  73. data/data/crc.txt +428 -415
  74. data/demo/Gemfile +1 -1
  75. data/demo/Launcher.bat +1 -9
  76. data/demo/Launcher2.bat +1 -0
  77. data/demo/LauncherMini.bat +1 -0
  78. data/demo/Rakefile +2 -0
  79. data/demo/config/dart/Gemfile +2 -7
  80. data/demo/config/data/crc.txt +243 -219
  81. data/demo/config/system/system.txt +42 -3
  82. data/demo/config/system/system2.txt +34 -5
  83. data/demo/config/system/system_alt_ports.txt +80 -0
  84. data/demo/config/targets/EXAMPLE/cmd_tlm_server.txt +1 -0
  85. data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +5 -4
  86. data/demo/config/targets/INST/cmd_tlm/inst_tlm.txt +12 -7
  87. data/demo/config/targets/INST/cmd_tlm/inst_tlm_override.txt +12 -0
  88. data/demo/config/targets/INST/cmd_tlm_server.txt +2 -0
  89. data/demo/config/targets/INST/lib/sim_inst.rb +15 -3
  90. data/demo/config/targets/INST/screens/adcs.txt +2 -2
  91. data/demo/config/targets/INST/screens/block.txt +1 -1
  92. data/demo/config/targets/INST/screens/commanding.txt +1 -1
  93. data/demo/config/targets/INST/screens/ground.txt +27 -5
  94. data/demo/config/targets/INST/screens/ground_error.gif +0 -0
  95. data/demo/config/{data/groundoff.gif → targets/INST/screens/ground_off.gif} +0 -0
  96. data/demo/config/{data/groundon.gif → targets/INST/screens/ground_on.gif} +0 -0
  97. data/demo/config/targets/INST/screens/limits.txt +69 -31
  98. data/demo/config/targets/INST/screens/other.txt +13 -3
  99. data/demo/config/targets/INST/screens/params.txt +54 -0
  100. data/demo/config/targets/INST/screens/satellite.gif +0 -0
  101. data/demo/config/targets/INST/target.txt +1 -0
  102. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server_chain.txt +18 -0
  103. data/demo/config/tools/data_viewer/data_viewer.txt +3 -0
  104. data/demo/config/tools/handbook_creator/assets/css/bootstrap-theme.css +397 -0
  105. data/demo/config/tools/handbook_creator/assets/css/bootstrap-theme.min.css +7 -0
  106. data/demo/config/tools/handbook_creator/assets/css/bootstrap.css +7118 -0
  107. data/demo/config/tools/handbook_creator/assets/css/bootstrap.min.css +7 -0
  108. data/demo/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  109. data/demo/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  110. data/demo/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  111. data/demo/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  112. data/demo/config/tools/handbook_creator/assets/img/ball_logo.bmp +0 -0
  113. data/demo/config/tools/handbook_creator/assets/img/ball_logo.gif +0 -0
  114. data/demo/config/tools/handbook_creator/assets/img/ball_logo.jpg +0 -0
  115. data/demo/config/tools/handbook_creator/assets/js/bootstrap.js +2006 -0
  116. data/demo/config/tools/handbook_creator/assets/js/bootstrap.min.js +7 -0
  117. data/demo/config/tools/handbook_creator/assets/js/html5shiv.js +8 -0
  118. data/demo/config/tools/handbook_creator/assets/js/jquery-1.10.2.min.js +6 -0
  119. data/demo/config/tools/handbook_creator/assets/js/respond.min.js +6 -0
  120. data/demo/config/tools/handbook_creator/default_toc.xsl +59 -59
  121. data/demo/config/tools/script_runner/script_runner.txt +1 -2
  122. data/demo/config/tools/test_runner/test_runner.txt +3 -1
  123. data/demo/lib/example_background_task.rb +1 -0
  124. data/demo/procedures/cosmos_api_test.rb +26 -22
  125. data/demo/procedures/interactive.rb +22 -0
  126. data/demo/procedures/local_screen_example.rb +51 -0
  127. data/ext/cosmos/ext/cosmos_io/cosmos_io.c +32 -4
  128. data/ext/cosmos/ext/packet/packet.c +6 -77
  129. data/ext/mkrf_conf.rb +2 -2
  130. data/extensions/vscode/.gitignore +4 -0
  131. data/extensions/vscode/.vscode/launch.json +32 -0
  132. data/extensions/vscode/.vscode/settings.json +13 -0
  133. data/extensions/vscode/.vscode/tasks.json +79 -0
  134. data/extensions/vscode/License.txt +879 -0
  135. data/extensions/vscode/README.md +9 -0
  136. data/extensions/vscode/client/License.txt +879 -0
  137. data/extensions/vscode/client/README.md +39 -0
  138. data/extensions/vscode/client/cosmos.configuration.json +23 -0
  139. data/extensions/vscode/client/images/icon.png +0 -0
  140. data/extensions/vscode/client/package-lock.json +414 -0
  141. data/extensions/vscode/client/package.json +105 -0
  142. data/extensions/vscode/client/src/extension.ts +132 -0
  143. data/extensions/vscode/client/src/screen_preview.rb +25 -0
  144. data/extensions/vscode/client/syntaxes/cosmos.tmLanguage.json +219 -0
  145. data/extensions/vscode/client/tsconfig.json +17 -0
  146. data/extensions/vscode/package-lock.json +26 -0
  147. data/extensions/vscode/package.json +35 -0
  148. data/extensions/vscode/server/License.txt +879 -0
  149. data/extensions/vscode/server/package-lock.json +236 -0
  150. data/extensions/vscode/server/package.json +29 -0
  151. data/extensions/vscode/server/src/server.ts +59 -0
  152. data/extensions/vscode/server/tsconfig.json +16 -0
  153. data/install/Gemfile +1 -1
  154. data/install/Launcher.bat +1 -9
  155. data/install/config/dart/Gemfile +3 -8
  156. data/install/config/data/crc.txt +148 -132
  157. data/install/config/system/system.txt +36 -3
  158. data/install/config/tools/handbook_creator/assets/css/bootstrap-theme.css +397 -0
  159. data/install/config/tools/handbook_creator/assets/css/bootstrap-theme.min.css +7 -0
  160. data/install/config/tools/handbook_creator/assets/css/bootstrap.css +7118 -0
  161. data/install/config/tools/handbook_creator/assets/css/bootstrap.min.css +7 -0
  162. data/install/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  163. data/install/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  164. data/install/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  165. data/install/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  166. data/install/config/tools/handbook_creator/assets/img/ball_logo.bmp +0 -0
  167. data/install/config/tools/handbook_creator/assets/img/ball_logo.gif +0 -0
  168. data/install/config/tools/handbook_creator/assets/img/ball_logo.jpg +0 -0
  169. data/install/config/tools/handbook_creator/assets/js/bootstrap.js +2006 -0
  170. data/install/config/tools/handbook_creator/assets/js/bootstrap.min.js +7 -0
  171. data/install/config/tools/handbook_creator/assets/js/html5shiv.js +8 -0
  172. data/install/config/tools/handbook_creator/assets/js/jquery-1.10.2.min.js +6 -0
  173. data/install/config/tools/handbook_creator/assets/js/respond.min.js +6 -0
  174. data/install/config/tools/handbook_creator/default_toc.xsl +59 -59
  175. data/lib/cosmos/config/config_parser.rb +4 -5
  176. data/lib/cosmos/conversions.rb +2 -0
  177. data/lib/cosmos/conversions/packet_time_formatted_conversion.rb +38 -0
  178. data/lib/cosmos/conversions/packet_time_seconds_conversion.rb +38 -0
  179. data/lib/cosmos/core_ext/cosmos_io.rb +2 -1
  180. data/lib/cosmos/core_ext/time.rb +3 -1
  181. data/lib/cosmos/dart/config/boot.rb +1 -1
  182. data/lib/cosmos/dart/config/database.yml +2 -0
  183. data/lib/cosmos/dart/examples/dart_decom_client.rb +1 -1
  184. data/lib/cosmos/dart/examples/dart_stream_client.rb +6 -2
  185. data/lib/cosmos/dart/lib/dart_common.rb +13 -6
  186. data/lib/cosmos/dart/lib/dart_constants.rb +15 -0
  187. data/lib/cosmos/dart/lib/dart_database_cleaner.rb +2 -2
  188. data/lib/cosmos/dart/lib/dart_decom_query.rb +5 -6
  189. data/lib/cosmos/dart/lib/dart_decommutator.rb +64 -54
  190. data/lib/cosmos/dart/lib/dart_importer.rb +3 -3
  191. data/lib/cosmos/dart/lib/dart_master_query.rb +71 -0
  192. data/lib/cosmos/dart/lib/dart_packet_log_writer.rb +2 -2
  193. data/lib/cosmos/dart/lib/dart_reducer_worker_thread.rb +165 -134
  194. data/lib/cosmos/dart/processes/dart.rb +4 -2
  195. data/lib/cosmos/dart/processes/dart_decom_server.rb +3 -3
  196. data/lib/cosmos/dart/processes/dart_ingester.rb +40 -1
  197. data/lib/cosmos/dart/processes/dart_master.rb +44 -0
  198. data/lib/cosmos/dart/processes/dart_util.rb +119 -4
  199. data/lib/cosmos/dart/spec/dart/dart_reducer_manager_spec.rb +3 -3
  200. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +9 -5
  201. data/lib/cosmos/gui/dialogs/details_dialog.rb +44 -29
  202. data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +1 -1
  203. data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +3 -3
  204. data/lib/cosmos/gui/dialogs/interface_raw_dialog.rb +2 -2
  205. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +1 -1
  206. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +11 -10
  207. data/lib/cosmos/gui/dialogs/tlm_graph_dialog.rb +4 -2
  208. data/lib/cosmos/gui/opengl/earth_model.rb +1 -1
  209. data/lib/cosmos/gui/qt.rb +13 -2
  210. data/lib/cosmos/gui/qt_tool.rb +71 -43
  211. data/lib/cosmos/gui/text/ruby_editor.rb +91 -49
  212. data/lib/cosmos/gui/utilities/classification_banner.rb +60 -0
  213. data/lib/cosmos/gui/utilities/screenshot.rb +1 -1
  214. data/lib/cosmos/gui/utilities/script_module_gui.rb +117 -91
  215. data/lib/cosmos/gui/widgets/dart_meta_frame.rb +22 -3
  216. data/lib/cosmos/interfaces.rb +2 -0
  217. data/lib/cosmos/interfaces/dart_status_interface.rb +1 -1
  218. data/lib/cosmos/interfaces/interface.rb +9 -1
  219. data/lib/cosmos/interfaces/linc_interface.rb +3 -3
  220. data/lib/cosmos/interfaces/protocols/burst_protocol.rb +1 -1
  221. data/lib/cosmos/interfaces/protocols/crc_protocol.rb +1 -1
  222. data/lib/cosmos/interfaces/protocols/fixed_protocol.rb +40 -18
  223. data/lib/cosmos/interfaces/protocols/ignore_packet_protocol.rb +46 -0
  224. data/lib/cosmos/interfaces/protocols/length_protocol.rb +5 -0
  225. data/lib/cosmos/interfaces/protocols/preidentified_protocol.rb +68 -23
  226. data/lib/cosmos/interfaces/protocols/template_protocol.rb +9 -4
  227. data/lib/cosmos/interfaces/serial_interface.rb +7 -1
  228. data/lib/cosmos/interfaces/simulated_target_interface.rb +14 -5
  229. data/lib/cosmos/interfaces/stream_interface.rb +1 -1
  230. data/lib/cosmos/interfaces/tcpip_server_interface.rb +13 -13
  231. data/lib/cosmos/io/json_drb.rb +16 -12
  232. data/lib/cosmos/io/json_drb_object.rb +7 -2
  233. data/lib/cosmos/io/json_drb_rack.rb +25 -5
  234. data/lib/cosmos/io/json_rpc.rb +1 -1
  235. data/lib/cosmos/io/posix_serial_driver.rb +60 -22
  236. data/lib/cosmos/io/serial_driver.rb +11 -8
  237. data/lib/cosmos/io/win32_serial_driver.rb +31 -3
  238. data/lib/cosmos/packet_logs/packet_log_reader.rb +71 -28
  239. data/lib/cosmos/packet_logs/packet_log_writer.rb +13 -1
  240. data/lib/cosmos/packets/commands.rb +30 -9
  241. data/lib/cosmos/packets/packet.rb +105 -34
  242. data/lib/cosmos/packets/packet_config.rb +60 -10
  243. data/lib/cosmos/packets/parsers/format_string_parser.rb +0 -1
  244. data/lib/cosmos/packets/parsers/state_parser.rb +0 -1
  245. data/lib/cosmos/packets/parsers/xtce_converter.rb +2 -0
  246. data/lib/cosmos/packets/parsers/xtce_parser.rb +5 -4
  247. data/lib/cosmos/packets/structure.rb +32 -4
  248. data/lib/cosmos/packets/structure_item.rb +5 -1
  249. data/lib/cosmos/packets/telemetry.rb +30 -4
  250. data/lib/cosmos/script/api_shared.rb +22 -10
  251. data/lib/cosmos/script/extract.rb +1 -1
  252. data/lib/cosmos/script/limits.rb +4 -0
  253. data/lib/cosmos/script/script.rb +29 -20
  254. data/lib/cosmos/script/scripting.rb +16 -14
  255. data/lib/cosmos/script/telemetry.rb +3 -1
  256. data/lib/cosmos/script/tools.rb +18 -8
  257. data/lib/cosmos/streams/serial_stream.rb +11 -6
  258. data/lib/cosmos/system/system.rb +214 -76
  259. data/lib/cosmos/system/target.rb +39 -9
  260. data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +116 -55
  261. data/lib/cosmos/tools/cmd_sender/cmd_param_table_item_delegate.rb +15 -0
  262. data/lib/cosmos/tools/cmd_sender/cmd_params.rb +382 -0
  263. data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +54 -340
  264. data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +74 -52
  265. data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +40 -333
  266. data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +16 -11
  267. data/lib/cosmos/tools/cmd_tlm_server/api.rb +13 -0
  268. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +2 -0
  269. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +44 -15
  270. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +8 -1
  271. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +18 -20
  272. data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +13 -2
  273. data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +2 -2
  274. data/lib/cosmos/tools/cmd_tlm_server/gui/logging_tab.rb +13 -13
  275. data/lib/cosmos/tools/cmd_tlm_server/gui/packets_tab.rb +9 -6
  276. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +8 -8
  277. data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +5 -5
  278. data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +35 -20
  279. data/lib/cosmos/tools/cmd_tlm_server/replay_backend.rb +15 -11
  280. data/lib/cosmos/tools/cmd_tlm_server/router_thread.rb +5 -0
  281. data/lib/cosmos/tools/cmd_tlm_server/routers.rb +2 -0
  282. data/lib/cosmos/tools/config_editor/config_editor.rb +181 -94
  283. data/lib/cosmos/tools/config_editor/config_editor_frame.rb +10 -9
  284. data/lib/cosmos/tools/config_editor/system_config_dialog.rb +158 -0
  285. data/lib/cosmos/tools/data_viewer/data_viewer.rb +57 -47
  286. data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +1 -0
  287. data/lib/cosmos/tools/data_viewer/dump_component.rb +3 -9
  288. data/lib/cosmos/tools/data_viewer/text_component.rb +77 -0
  289. data/lib/cosmos/tools/handbook_creator/handbook_creator.rb +68 -42
  290. data/lib/cosmos/tools/handbook_creator/handbook_creator_config.rb +1 -1
  291. data/lib/cosmos/tools/launcher/launcher.rb +2 -1
  292. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +59 -41
  293. data/lib/cosmos/tools/opengl_builder/opengl_builder.rb +42 -42
  294. data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +64 -59
  295. data/lib/cosmos/tools/script_runner/script_runner.rb +198 -123
  296. data/lib/cosmos/tools/script_runner/script_runner_config.rb +14 -0
  297. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +87 -35
  298. data/lib/cosmos/tools/table_manager/table_config.rb +5 -3
  299. data/lib/cosmos/tools/table_manager/table_manager.rb +48 -45
  300. data/lib/cosmos/tools/test_runner/test.rb +5 -2
  301. data/lib/cosmos/tools/test_runner/test_runner.rb +61 -38
  302. data/lib/cosmos/tools/test_runner/test_runner_chooser.rb +24 -12
  303. data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +48 -48
  304. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +5 -8
  305. data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +20 -16
  306. data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +3 -3
  307. data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +7 -7
  308. data/lib/cosmos/tools/tlm_grapher/data_object_editors/xy_data_object_editor.rb +10 -10
  309. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +10 -3
  310. data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +6 -6
  311. data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +14 -14
  312. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_dart_thread.rb +21 -17
  313. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +5 -8
  314. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +94 -91
  315. data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +27 -26
  316. data/lib/cosmos/tools/tlm_viewer/screen.rb +76 -14
  317. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +51 -34
  318. data/lib/cosmos/tools/tlm_viewer/widgets.rb +3 -0
  319. data/lib/cosmos/tools/tlm_viewer/widgets/aging_widget.rb +4 -5
  320. data/lib/cosmos/tools/tlm_viewer/widgets/array_widget.rb +3 -4
  321. data/lib/cosmos/tools/tlm_viewer/widgets/block_widget.rb +4 -5
  322. data/lib/cosmos/tools/tlm_viewer/widgets/canvas_clickable.rb +16 -2
  323. data/lib/cosmos/tools/tlm_viewer/widgets/canvas_widget.rb +17 -3
  324. data/lib/cosmos/tools/tlm_viewer/widgets/canvasdot_widget.rb +1 -2
  325. data/lib/cosmos/tools/tlm_viewer/widgets/canvasellipse_widget.rb +40 -0
  326. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimage_widget.rb +12 -7
  327. data/lib/cosmos/tools/tlm_viewer/widgets/canvasimagevalue_widget.rb +79 -29
  328. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabel_widget.rb +1 -0
  329. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslabelvalue_widget.rb +2 -1
  330. data/lib/cosmos/tools/tlm_viewer/widgets/canvasline_widget.rb +2 -0
  331. data/lib/cosmos/tools/tlm_viewer/widgets/canvaslinevalue_widget.rb +4 -0
  332. data/lib/cosmos/tools/tlm_viewer/widgets/canvasvalue_widget.rb +33 -25
  333. data/lib/cosmos/tools/tlm_viewer/widgets/checkbutton_widget.rb +5 -3
  334. data/lib/cosmos/tools/tlm_viewer/widgets/combobox_widget.rb +5 -3
  335. data/lib/cosmos/tools/tlm_viewer/widgets/formatfontvalue_widget.rb +1 -1
  336. data/lib/cosmos/tools/tlm_viewer/widgets/formatvalue_widget.rb +4 -7
  337. data/lib/cosmos/tools/tlm_viewer/widgets/horizontal_widget.rb +5 -5
  338. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalbox_widget.rb +6 -7
  339. data/lib/cosmos/tools/tlm_viewer/widgets/horizontalline_widget.rb +2 -4
  340. data/lib/cosmos/tools/tlm_viewer/widgets/label_widget.rb +10 -8
  341. data/lib/cosmos/tools/tlm_viewer/widgets/labelformatvalue_widget.rb +2 -3
  342. data/lib/cosmos/tools/tlm_viewer/widgets/labelled_widget.rb +58 -0
  343. data/lib/cosmos/tools/tlm_viewer/widgets/labelprogressbar_widget.rb +3 -4
  344. data/lib/cosmos/tools/tlm_viewer/widgets/labeltrendlimitsbar_widget.rb +2 -4
  345. data/lib/cosmos/tools/tlm_viewer/widgets/labelvalue_widget.rb +2 -1
  346. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluedesc_widget.rb +3 -5
  347. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluelimitsbar_widget.rb +2 -3
  348. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluelimitscolumn_widget.rb +2 -3
  349. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluerangebar_widget.rb +2 -3
  350. data/lib/cosmos/tools/tlm_viewer/widgets/labelvaluerangecolumn_widget.rb +2 -3
  351. data/lib/cosmos/tools/tlm_viewer/widgets/layout_widget.rb +3 -5
  352. data/lib/cosmos/tools/tlm_viewer/widgets/led_widget.rb +108 -0
  353. data/lib/cosmos/tools/tlm_viewer/widgets/limits_widget.rb +60 -10
  354. data/lib/cosmos/tools/tlm_viewer/widgets/limitsbar_widget.rb +22 -8
  355. data/lib/cosmos/tools/tlm_viewer/widgets/limitscolor_widget.rb +19 -13
  356. data/lib/cosmos/tools/tlm_viewer/widgets/limitscolumn_widget.rb +22 -8
  357. data/lib/cosmos/tools/tlm_viewer/widgets/linegraph_widget.rb +2 -3
  358. data/lib/cosmos/tools/tlm_viewer/widgets/matrixbycolumns_widget.rb +4 -3
  359. data/lib/cosmos/tools/tlm_viewer/widgets/multi_widget.rb +1 -3
  360. data/lib/cosmos/tools/tlm_viewer/widgets/progressbar_widget.rb +10 -5
  361. data/lib/cosmos/tools/tlm_viewer/widgets/radiobutton_widget.rb +7 -4
  362. data/lib/cosmos/tools/tlm_viewer/widgets/rangebar_widget.rb +4 -6
  363. data/lib/cosmos/tools/tlm_viewer/widgets/rangecolumn_widget.rb +3 -5
  364. data/lib/cosmos/tools/tlm_viewer/widgets/screenshotbutton_widget.rb +4 -3
  365. data/lib/cosmos/tools/tlm_viewer/widgets/scrollwindow_widget.rb +2 -3
  366. data/lib/cosmos/tools/tlm_viewer/widgets/sectionheader_widget.rb +2 -3
  367. data/lib/cosmos/tools/tlm_viewer/widgets/spacer_widget.rb +4 -6
  368. data/lib/cosmos/tools/tlm_viewer/widgets/tabbook_widget.rb +2 -3
  369. data/lib/cosmos/tools/tlm_viewer/widgets/tabitem_widget.rb +2 -3
  370. data/lib/cosmos/tools/tlm_viewer/widgets/textbox_widget.rb +13 -4
  371. data/lib/cosmos/tools/tlm_viewer/widgets/textfield_widget.rb +3 -4
  372. data/lib/cosmos/tools/tlm_viewer/widgets/timegraph_widget.rb +3 -8
  373. data/lib/cosmos/tools/tlm_viewer/widgets/title_widget.rb +6 -12
  374. data/lib/cosmos/tools/tlm_viewer/widgets/trendbar_widget.rb +5 -10
  375. data/lib/cosmos/tools/tlm_viewer/widgets/trendlimitsbar_widget.rb +5 -3
  376. data/lib/cosmos/tools/tlm_viewer/widgets/value_widget.rb +4 -4
  377. data/lib/cosmos/tools/tlm_viewer/widgets/valuelimitsbar_widget.rb +2 -3
  378. data/lib/cosmos/tools/tlm_viewer/widgets/valuelimitscolumn_widget.rb +2 -3
  379. data/lib/cosmos/tools/tlm_viewer/widgets/valuerangebar_widget.rb +3 -4
  380. data/lib/cosmos/tools/tlm_viewer/widgets/valuerangecolumn_widget.rb +2 -3
  381. data/lib/cosmos/tools/tlm_viewer/widgets/vertical_widget.rb +8 -7
  382. data/lib/cosmos/tools/tlm_viewer/widgets/verticalbox_widget.rb +9 -7
  383. data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +60 -47
  384. data/lib/cosmos/top_level.rb +37 -13
  385. data/lib/cosmos/utilities/ruby_lex_utils.rb +34 -30
  386. data/lib/cosmos/version.rb +5 -5
  387. data/lib/cosmos/win32/excel.rb +81 -24
  388. data/make_gems.sh +10 -0
  389. data/run_gui_tests.bat +1 -0
  390. data/spec/conversions/packet_time_formatted_conversion_spec.rb +58 -0
  391. data/spec/conversions/packet_time_seconds_conversion_spec.rb +60 -0
  392. data/spec/core_ext/socket_spec.rb +1 -1
  393. data/spec/core_ext/time_spec.rb +4 -0
  394. data/spec/gui/utilities/script_module_gui_spec.rb +44 -63
  395. data/spec/install/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -1
  396. data/spec/install/config/targets/INST/cmd_tlm/inst_tlm.txt +5 -5
  397. data/spec/install/yaml_docs_spec.rb +132 -0
  398. data/spec/interfaces/linc_interface_spec.rb +1 -1
  399. data/spec/interfaces/protocols/fixed_protocol_spec.rb +20 -9
  400. data/spec/interfaces/protocols/ignore_packet_protocol_spec.rb +243 -0
  401. data/spec/interfaces/protocols/length_protocol_spec.rb +39 -0
  402. data/spec/interfaces/protocols/preidentified_protocol_spec.rb +227 -4
  403. data/spec/interfaces/protocols/template_protocol_spec.rb +78 -25
  404. data/spec/io/json_drb_rack_spec.rb +166 -0
  405. data/spec/io/json_drb_spec.rb +14 -0
  406. data/spec/io/json_rpc_spec.rb +4 -5
  407. data/spec/io/posix_serial_driver_spec.rb +81 -0
  408. data/spec/io/serial_driver_spec.rb +15 -13
  409. data/spec/io/win32_serial_driver_spec.rb +33 -3
  410. data/spec/packet_logs/packet_log_reader_spec.rb +106 -52
  411. data/spec/packets/commands_spec.rb +22 -0
  412. data/spec/packets/packet_config_spec.rb +29 -16
  413. data/spec/packets/packet_item_spec.rb +2 -2
  414. data/spec/packets/packet_spec.rb +39 -6
  415. data/spec/packets/parsers/format_string_parser_spec.rb +0 -11
  416. data/spec/packets/parsers/macro_parser_spec.rb +36 -36
  417. data/spec/packets/parsers/state_parser_spec.rb +69 -11
  418. data/spec/packets/structure_spec.rb +93 -2
  419. data/spec/packets/telemetry_spec.rb +63 -10
  420. data/spec/script/extract_spec.rb +4 -1
  421. data/spec/script/script_spec.rb +2 -3
  422. data/spec/script/scripting_spec.rb +2 -1
  423. data/spec/script/tools_spec.rb +0 -1
  424. data/spec/streams/tcpip_socket_stream_spec.rb +32 -27
  425. data/spec/system/system_spec.rb +187 -4
  426. data/spec/system/target_spec.rb +62 -1
  427. data/spec/tools/cmd_tlm_server/api_spec.rb +29 -21
  428. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +15 -7
  429. data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +33 -0
  430. data/spec/tools/cmd_tlm_server/commanding_spec.rb +25 -1
  431. data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +15 -0
  432. data/spec/tools/cmd_tlm_server/router_thread_spec.rb +2 -3
  433. data/spec/top_level/top_level_spec.rb +29 -5
  434. data/spec/utilities/message_log_spec.rb +6 -3
  435. data/tasks/gemfile_stats.rake +38 -14
  436. data/test/performance/config/system/system.txt +0 -0
  437. data/test/performance/config/targets/PACKET/cmd_tlm/packet_tlm.txt +5 -5
  438. data/test/performance/config/tools/handbook_creator/assets/css/bootstrap-theme.css +397 -0
  439. data/test/performance/config/tools/handbook_creator/assets/css/bootstrap-theme.min.css +7 -0
  440. data/test/performance/config/tools/handbook_creator/assets/css/bootstrap.css +7118 -0
  441. data/test/performance/config/tools/handbook_creator/assets/css/bootstrap.min.css +7 -0
  442. data/test/performance/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  443. data/test/performance/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  444. data/test/performance/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  445. data/test/performance/config/tools/handbook_creator/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  446. data/test/performance/config/tools/handbook_creator/assets/img/ball_logo.bmp +0 -0
  447. data/test/performance/config/tools/handbook_creator/assets/img/ball_logo.gif +0 -0
  448. data/test/performance/config/tools/handbook_creator/assets/img/ball_logo.jpg +0 -0
  449. data/test/performance/config/tools/handbook_creator/assets/js/bootstrap.js +2006 -0
  450. data/test/performance/config/tools/handbook_creator/assets/js/bootstrap.min.js +7 -0
  451. data/test/performance/config/tools/handbook_creator/assets/js/html5shiv.js +8 -0
  452. data/test/performance/config/tools/handbook_creator/assets/js/jquery-1.10.2.min.js +6 -0
  453. data/test/performance/config/tools/handbook_creator/assets/js/respond.min.js +6 -0
  454. data/test/performance/config/tools/test_runner/test_runner.txt +1 -1
  455. data/test/performance/procedures/cosmos_api_test.rb +1 -1
  456. data/test/performance/tools/identify_performance.rb +82 -0
  457. metadata +146 -62
  458. data/lib/cosmos/dart/Gemfile +0 -69
@@ -18,9 +18,10 @@ module Cosmos
18
18
  COMMANDS = "Commands"
19
19
  TELEMETRY = "Telemetry"
20
20
 
21
- def initialize(server_gui, name, tab_widget)
21
+ def initialize(server_gui, name, tab_widget, replay = false)
22
22
  @server_gui = server_gui
23
23
  @name = name
24
+ @replay = replay
24
25
  @widget = nil
25
26
  reset()
26
27
  @scroll = Qt::ScrollArea.new
@@ -116,11 +117,11 @@ module Cosmos
116
117
  packets.sort.each do |packet_name, packet|
117
118
  packet.received_count ||= 0
118
119
  next if packet.hidden
119
- target_name_widget = Qt::TableWidgetItem.new(Qt::Object.tr(target_name))
120
+ target_name_widget = Qt::TableWidgetItem.new(target_name)
120
121
  target_name_widget.setTextAlignment(Qt::AlignRight | Qt::AlignVCenter)
121
122
  table.setItem(row, 0, target_name_widget)
122
- table.setItem(row, 1, Qt::TableWidgetItem.new(Qt::Object.tr(packet_name)))
123
- packet_count = Qt::TableWidgetItem.new(Qt::Object.tr(packet.received_count.to_s))
123
+ table.setItem(row, 1, Qt::TableWidgetItem.new(packet_name))
124
+ packet_count = Qt::TableWidgetItem.new(packet.received_count.to_s)
124
125
  packet_count.setTextAlignment(Qt::AlignCenter)
125
126
  table.setItem(row, 2, packet_count)
126
127
  view_raw = Qt::PushButton.new("View Raw")
@@ -147,11 +148,13 @@ module Cosmos
147
148
  view_pv = Qt::PushButton.new("View in #{tool_name}")
148
149
  view_pv.connect(SIGNAL('clicked()')) do
149
150
  tool_name = tool_name.split.join.gsub("Command","Cmd") # remove space and convert name
150
- Cosmos.run_cosmos_tool(tool_name, "-p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}")
151
+ options = "-p \"#{target_name} #{packet_name}\" --system #{File.basename(System.initial_filename)}"
152
+ options += " --replay" if @replay && @name == TELEMETRY
153
+ Cosmos.run_cosmos_tool(tool_name, options)
151
154
  end
152
155
  table.setCellWidget(row, 4, view_pv)
153
156
  else
154
- table_widget = Qt::TableWidgetItem.new(Qt::Object.tr('N/A'))
157
+ table_widget = Qt::TableWidgetItem.new('N/A')
155
158
  table_widget.setTextAlignment(Qt::AlignCenter)
156
159
  table.setItem(row, 4, table_widget)
157
160
  end
@@ -53,7 +53,7 @@ module Cosmos
53
53
  private
54
54
 
55
55
  def populate_limits_status(layout)
56
- limits = Qt::GroupBox.new(Qt::Object.tr("Limits Status"))
56
+ limits = Qt::GroupBox.new("Limits Status")
57
57
  limits_layout = Qt::FormLayout.new(limits)
58
58
  current_limits_set = System.limits_set.to_s
59
59
 
@@ -88,7 +88,7 @@ module Cosmos
88
88
  @previous_request_count = 0
89
89
  end
90
90
 
91
- api = Qt::GroupBox.new(Qt::Object.tr("API Status"))
91
+ api = Qt::GroupBox.new("API Status")
92
92
  api_layout = Qt::VBoxLayout.new(api)
93
93
  @api_table = Qt::TableWidget.new()
94
94
  @api_table.verticalHeader.hide()
@@ -97,14 +97,14 @@ module Cosmos
97
97
  @api_table.setHorizontalHeaderLabels(["Port", "Num Clients", "Requests", "Requests/Sec", "Avg Request Time", "Estimated Utilization"])
98
98
 
99
99
  if CmdTlmServer.mode == :CMD_TLM_SERVER
100
- @api_table.setItem(0, 0, Qt::TableWidgetItem.new(Qt::Object.tr(System.ports['CTS_API'].to_s)))
100
+ @api_table.setItem(0, 0, Qt::TableWidgetItem.new(System.ports['CTS_API'].to_s))
101
101
  else
102
- @api_table.setItem(0, 0, Qt::TableWidgetItem.new(Qt::Object.tr(System.ports['REPLAY_API'].to_s)))
102
+ @api_table.setItem(0, 0, Qt::TableWidgetItem.new(System.ports['REPLAY_API'].to_s))
103
103
  end
104
- item0 = Qt::TableWidgetItem.new(Qt::Object.tr(CmdTlmServer.json_drb.num_clients.to_s))
104
+ item0 = Qt::TableWidgetItem.new(CmdTlmServer.json_drb.num_clients.to_s)
105
105
  item0.setTextAlignment(Qt::AlignCenter)
106
106
  @api_table.setItem(0, 1, item0)
107
- item = Qt::TableWidgetItem.new(Qt::Object.tr(@previous_request_count.to_s))
107
+ item = Qt::TableWidgetItem.new(@previous_request_count.to_s)
108
108
  item.setTextAlignment(Qt::AlignCenter)
109
109
  @api_table.setItem(0, 2, item)
110
110
  item2 = Qt::TableWidgetItem.new("0.0")
@@ -122,7 +122,7 @@ module Cosmos
122
122
  end
123
123
 
124
124
  def populate_system_status(layout)
125
- system = Qt::GroupBox.new(Qt::Object.tr("System Status"))
125
+ system = Qt::GroupBox.new("System Status")
126
126
  system_layout = Qt::VBoxLayout.new(system)
127
127
  @system_table = Qt::TableWidget.new()
128
128
  @system_table.verticalHeader.hide()
@@ -148,7 +148,7 @@ module Cosmos
148
148
  end
149
149
 
150
150
  def populate_background_status(layout)
151
- background_tasks_groupbox = Qt::GroupBox.new(Qt::Object.tr("Background Tasks"))
151
+ background_tasks_groupbox = Qt::GroupBox.new("Background Tasks")
152
152
  background_tasks_layout = Qt::VBoxLayout.new(background_tasks_groupbox)
153
153
  @background_tasks_table = Qt::TableWidget.new()
154
154
  @background_tasks_table.verticalHeader.hide()
@@ -68,21 +68,21 @@ module Cosmos
68
68
  def populate_targets_table
69
69
  row = 0
70
70
  System.targets.sort.each do |target_name, target|
71
- target_name_widget = Qt::TableWidgetItem.new(Qt::Object.tr(target_name))
71
+ target_name_widget = Qt::TableWidgetItem.new(target_name)
72
72
  target_name_widget.setTextAlignment(Qt::AlignCenter)
73
73
  @targets_table.setItem(row, 0, target_name_widget)
74
74
  if target.interface
75
- interface_name_widget = Qt::TableWidgetItem.new(Qt::Object.tr(target.interface.name.to_s))
75
+ interface_name_widget = Qt::TableWidgetItem.new(target.interface.name.to_s)
76
76
  else
77
- interface_name_widget = Qt::TableWidgetItem.new(Qt::Object.tr(''))
77
+ interface_name_widget = Qt::TableWidgetItem.new('')
78
78
  end
79
79
  interface_name_widget.setTextAlignment(Qt::AlignCenter)
80
80
  @targets_table.setItem(row, 1, interface_name_widget)
81
- cmd_cnt = Qt::TableWidgetItem.new(Qt::Object.tr(target.cmd_cnt.to_s))
81
+ cmd_cnt = Qt::TableWidgetItem.new(target.cmd_cnt.to_s)
82
82
  cmd_cnt.setTextAlignment(Qt::AlignCenter)
83
83
  @targets_table.setItem(row, 2, cmd_cnt)
84
84
 
85
- tlm_cnt = Qt::TableWidgetItem.new(Qt::Object.tr(target.tlm_cnt.to_s))
85
+ tlm_cnt = Qt::TableWidgetItem.new(target.tlm_cnt.to_s)
86
86
  tlm_cnt.setTextAlignment(Qt::AlignCenter)
87
87
  @targets_table.setItem(row, 3, tlm_cnt)
88
88
 
@@ -140,34 +140,43 @@ module Cosmos
140
140
  protected
141
141
 
142
142
  def handle_packet(packet)
143
- # Identify and update packet
144
- if packet.identified?
145
- begin
146
- # Preidentifed packet - place it into the current value table
147
- identified_packet = System.telemetry.update!(packet.target_name,
148
- packet.packet_name,
149
- packet.buffer)
150
- rescue RuntimeError
151
- # Packet identified but we don't know about it
152
- # Clear packet_name and target_name and try to identify
153
- Logger.warn "Received unknown identified telemetry: #{packet.target_name} #{packet.packet_name}"
154
- packet.target_name = nil
155
- packet.packet_name = nil
143
+ if packet.stored
144
+ # Stored telemetry does not update the current value table
145
+ identified_packet = System.telemetry.identify_and_define_packet(packet, @interface.target_names)
146
+ else
147
+ # Identify and update packet
148
+ if packet.identified?
149
+ begin
150
+ # Preidentifed packet - place it into the current value table
151
+ identified_packet = System.telemetry.update!(packet.target_name,
152
+ packet.packet_name,
153
+ packet.buffer)
154
+ rescue RuntimeError
155
+ # Packet identified but we don't know about it
156
+ # Clear packet_name and target_name and try to identify
157
+ Logger.warn "Received unknown identified telemetry: #{packet.target_name} #{packet.packet_name}"
158
+ packet.target_name = nil
159
+ packet.packet_name = nil
160
+ identified_packet = System.telemetry.identify!(packet.buffer,
161
+ @interface.target_names)
162
+ end
163
+ else
164
+ # Packet needs to be identified
156
165
  identified_packet = System.telemetry.identify!(packet.buffer,
157
166
  @interface.target_names)
158
167
  end
159
- else
160
- # Packet needs to be identified
161
- identified_packet = System.telemetry.identify!(packet.buffer,
162
- @interface.target_names)
163
168
  end
164
169
 
165
170
  if identified_packet
166
171
  identified_packet.received_time = packet.received_time
172
+ identified_packet.stored = packet.stored
173
+ identified_packet.extra = packet.extra
167
174
  packet = identified_packet
168
175
  else
169
176
  unknown_packet = System.telemetry.update!('UNKNOWN', 'UNKNOWN', packet.buffer)
170
177
  unknown_packet.received_time = packet.received_time
178
+ unknown_packet.stored = packet.stored
179
+ unknown_packet.extra = packet.extra
171
180
  packet = unknown_packet
172
181
  data_length = packet.length
173
182
  string = "#{@interface.name} - Unknown #{data_length} byte packet starting: "
@@ -194,9 +203,15 @@ module Cosmos
194
203
  end
195
204
 
196
205
  # Write to packet log writers
197
- @interface.packet_log_writer_pairs.each do |packet_log_writer_pair|
198
- # Write errors are handled by the log writer
199
- packet_log_writer_pair.tlm_log_writer.write(packet)
206
+ if packet.stored and !@interface.stored_packet_log_writer_pairs.empty?
207
+ @interface.stored_packet_log_writer_pairs.each do |packet_log_writer_pair|
208
+ packet_log_writer_pair.tlm_log_writer.write(packet)
209
+ end
210
+ else
211
+ @interface.packet_log_writer_pairs.each do |packet_log_writer_pair|
212
+ # Write errors are handled by the log writer
213
+ packet_log_writer_pair.tlm_log_writer.write(packet)
214
+ end
200
215
  end
201
216
  end
202
217
 
@@ -118,9 +118,9 @@ module Cosmos
118
118
  @end_time = ''
119
119
  else
120
120
  packet = read_at_index(@packet_offsets.length - 1, :FORWARD)
121
- @end_time = packet.received_time.formatted(true, 3, true) if packet and packet.received_time
121
+ @end_time = packet.packet_time.formatted(true, 3, true) if packet and packet.packet_time
122
122
  packet = read_at_index(0, :FORWARD)
123
- @start_time = packet.received_time.formatted(true, 3, true) if packet and packet.received_time
123
+ @start_time = packet.packet_time.formatted(true, 3, true) if packet and packet.packet_time
124
124
  end
125
125
  rescue Exception => error
126
126
  Logger.error "Error in Analysis Thread\n#{error.formatted}"
@@ -261,7 +261,7 @@ module Cosmos
261
261
  @current_time_object = @start_time_object.dup
262
262
  else
263
263
  packet = read_at_index(0, :FORWARD)
264
- @start_time = packet.received_time.formatted(true, 3, true) if packet and packet.received_time
264
+ @start_time = packet.packet_time.formatted(true, 3, true) if packet and packet.packet_time
265
265
  end
266
266
  else
267
267
  stop()
@@ -277,7 +277,7 @@ module Cosmos
277
277
  @current_time_object = @end_time_object.dup
278
278
  else
279
279
  packet = read_at_index(@packet_offsets.length - 1, :FORWARD)
280
- @end_time = packet.received_time.formatted(true, 3, true) if packet and packet.received_time
280
+ @end_time = packet.packet_time.formatted(true, 3, true) if packet and packet.packet_time
281
281
  end
282
282
  else
283
283
  stop()
@@ -337,12 +337,12 @@ module Cosmos
337
337
  if @playback_delay
338
338
  # Fixed Time Delay
339
339
  delay_time = @playback_delay - (Time.now.sys - packet_start)
340
- elsif previous_packet and packet.received_time and previous_packet.received_time
340
+ elsif previous_packet and packet.packet_time and previous_packet.packet_time
341
341
  # Realtime
342
342
  if direction == :FORWARD
343
- delay_time = packet.received_time - previous_packet.received_time - (Time.now.sys - packet_start)
343
+ delay_time = packet.packet_time - previous_packet.packet_time - (Time.now.sys - packet_start)
344
344
  else
345
- delay_time = previous_packet.received_time - packet.received_time - (Time.now.sys - packet_start)
345
+ delay_time = previous_packet.packet_time - packet.packet_time - (Time.now.sys - packet_start)
346
346
  end
347
347
  end
348
348
  if delay_time > 0.0
@@ -386,8 +386,8 @@ module Cosmos
386
386
  else
387
387
  @playback_index = index - 1
388
388
  end
389
- @current_time_object = packet.received_time
390
- @current_time = packet.received_time.formatted(true, 3, true) if packet and packet.received_time
389
+ @current_time_object = packet.packet_time
390
+ @current_time = packet.packet_time.formatted(true, 3, true) if packet and packet.packet_time
391
391
 
392
392
  return packet
393
393
  else
@@ -431,8 +431,8 @@ module Cosmos
431
431
  end
432
432
  handle_packet(packet)
433
433
 
434
- @current_time_object = packet.received_time
435
- @current_time = packet.received_time.formatted(true, 3, true)
434
+ @current_time_object = packet.packet_time
435
+ @current_time = packet.packet_time.formatted(true, 3, true)
436
436
  if @first
437
437
  @first = false
438
438
  @start_time_object = @current_time_object.dup
@@ -462,12 +462,16 @@ module Cosmos
462
462
 
463
463
  if identified_packet and packet.target_name != 'UNKNOWN'
464
464
  identified_packet.received_time = packet.received_time
465
+ identified_packet.stored = packet.stored
466
+ identified_packet.extra = packet.extra
465
467
  packet = identified_packet
466
468
  target = System.targets[packet.target_name.upcase]
467
469
  interface = target.interface if target
468
470
  else
469
471
  unknown_packet = System.telemetry.update!('UNKNOWN', 'UNKNOWN', packet.buffer)
470
472
  unknown_packet.received_time = packet.received_time
473
+ unknown_packet.stored = packet.stored
474
+ unknown_packet.extra = packet.extra
471
475
  packet = unknown_packet
472
476
  data_length = packet.length
473
477
  string = "Unknown #{data_length} byte packet starting: "
@@ -19,6 +19,11 @@ module Cosmos
19
19
  protected
20
20
 
21
21
  def handle_packet(packet)
22
+ unless System.allow_router_commanding
23
+ Logger.error "Router received command with router commanding disabled"
24
+ return
25
+ end
26
+
22
27
  # Start out assuming we will route to all associated interfaces
23
28
  interfaces = @interface.interfaces
24
29
 
@@ -49,6 +49,7 @@ module Cosmos
49
49
  router.interfaces << interface
50
50
  interface.routers << router
51
51
  end
52
+ router
52
53
  end
53
54
 
54
55
  # Adds a Preidentified command router to the system with given name and port.
@@ -72,6 +73,7 @@ module Cosmos
72
73
  @config.interfaces.each do |interface_name, interface|
73
74
  interface.cmd_routers << cmd_router
74
75
  end
76
+ cmd_router
75
77
  end
76
78
 
77
79
  # Recreate a router with new initialization parameters
@@ -11,9 +11,10 @@
11
11
  require 'cosmos'
12
12
  Cosmos.catch_fatal_exception do
13
13
  require 'cosmos/gui/qt_tool'
14
- require 'cosmos/tools/config_editor/config_editor_frame'
15
14
  require 'cosmos/gui/dialogs/progress_dialog'
16
15
  require 'cosmos/gui/dialogs/scroll_text_dialog'
16
+ require 'cosmos/tools/config_editor/config_editor_frame'
17
+ require 'cosmos/tools/config_editor/system_config_dialog'
17
18
  end
18
19
 
19
20
  module Cosmos
@@ -33,6 +34,7 @@ module Cosmos
33
34
 
34
35
  UNTITLED = 'Untitled'
35
36
  UNTITLED_TAB_TEXT = " #{UNTITLED} "
37
+ MAX_RECENT_FILES = 20
36
38
  # Mapping of the human readable configuration name to an array containing the
37
39
  # yaml file name and typical location of the configuration file
38
40
  CONFIGURATION_FILES = {
@@ -47,6 +49,8 @@ module Cosmos
47
49
  "Screen Definition" =>
48
50
  ["screen", "/config/targets/TARGET/screens/*.txt"],
49
51
  "Separator" => [nil, nil],
52
+ "Command Sequence Configuration" =>
53
+ ["cmd_sequence", "/config/tools/cmd_sequence/cmd_sequence.txt"],
50
54
  "Data Viewer Configuration" =>
51
55
  ["data_viewer", "/config/tools/data_viewer/data_viewer.txt"],
52
56
  "Handbook Creator Configuration" =>
@@ -69,6 +73,12 @@ module Cosmos
69
73
  ["tlm_viewer", "/config/tools/tlm_viewer/tlm_viewer.txt"],
70
74
  }
71
75
 
76
+ # Class instance variable to store all the parsed metadata
77
+ @meta = {}
78
+ class << self
79
+ attr_reader :meta
80
+ end
81
+
72
82
  def initialize(options)
73
83
  # All code before super is executed twice in RubyQt Based classes
74
84
  super(options) # MUST BE FIRST
@@ -83,8 +93,27 @@ module Cosmos
83
93
  initialize_central_widget()
84
94
  complete_initialize()
85
95
 
96
+ # Process all the configuration yaml files up front
97
+ # If they passed in a filename we need to wait for all meta files to be processed
98
+ wait = options.filename ? true : false
99
+ Splash.execute(self, wait) do |splash|
100
+ count = 1.0
101
+ CONFIGURATION_FILES.each do |key, vals|
102
+ type = vals[0]
103
+ next unless type
104
+ splash.message = "Processing #{type}.yaml"
105
+ splash.progress = count / CONFIGURATION_FILES.length
106
+ begin
107
+ ConfigEditor.meta[key] = @file_meta = MetaConfigParser.load("#{type}.yaml")
108
+ rescue => error
109
+ Kernel.raise $! if error.is_a? Psych::SyntaxError
110
+ end
111
+ count += 1.0
112
+ end
113
+ end
114
+
86
115
  if options.filename
87
- file_open(options.filename)
116
+ file_open(File.expand_path(options.filename))
88
117
  else
89
118
  create_tab()
90
119
  end
@@ -94,106 +123,110 @@ module Cosmos
94
123
  super()
95
124
 
96
125
  # File actions
97
- @file_new = Qt::Action.new(Cosmos.get_icon('file.png'), tr('&New'), self)
98
- @file_new_keyseq = Qt::KeySequence.new(tr('Ctrl+N'))
126
+ @file_new = Qt::Action.new(Cosmos.get_icon('file.png'), '&New', self)
127
+ @file_new_keyseq = Qt::KeySequence.new('Ctrl+N')
99
128
  @file_new.shortcut = @file_new_keyseq
100
- @file_new.statusTip = tr('Start a new file')
129
+ @file_new.statusTip = 'Start a new file'
101
130
  @file_new.connect(SIGNAL('triggered()')) { file_new() }
102
131
 
103
- @file_close = Qt::Action.new(tr('&Close'), self)
104
- @file_close_keyseq = Qt::KeySequence.new(tr('Ctrl+W'))
132
+ @clear_file_open_recent = Qt::Action.new('&Clear Recent', self)
133
+ @clear_file_open_recent.statusTip = 'Clear the recently opened file list'
134
+ @clear_file_open_recent.connect(SIGNAL('triggered()')) { clear_file_open_recent() }
135
+
136
+ @file_close = Qt::Action.new('&Close', self)
137
+ @file_close_keyseq = Qt::KeySequence.new('Ctrl+W')
105
138
  @file_close.shortcut = @file_close_keyseq
106
- @file_close.statusTip = tr('Close the file')
139
+ @file_close.statusTip = 'Close the file'
107
140
  @file_close.connect(SIGNAL('triggered()')) { file_close() }
108
141
 
109
- @file_reload = Qt::Action.new(tr('&Reload'), self)
110
- @file_reload_keyseq = Qt::KeySequence.new(tr('Ctrl+R'))
142
+ @file_reload = Qt::Action.new('Re&load', self)
143
+ @file_reload_keyseq = Qt::KeySequence.new('Ctrl+R')
111
144
  @file_reload.shortcut = @file_reload_keyseq
112
- @file_reload.statusTip = tr('Reload a file')
145
+ @file_reload.statusTip = 'Reload a file'
113
146
  @file_reload.connect(SIGNAL('triggered()')) { file_reload() }
114
147
 
115
- @file_save = Qt::Action.new(Cosmos.get_icon('save.png'), tr('&Save'), self)
116
- @file_save_keyseq = Qt::KeySequence.new(tr('Ctrl+S'))
148
+ @file_save = Qt::Action.new(Cosmos.get_icon('save.png'), '&Save', self)
149
+ @file_save_keyseq = Qt::KeySequence.new('Ctrl+S')
117
150
  @file_save.shortcut = @file_save_keyseq
118
- @file_save.statusTip = tr('Save the file')
151
+ @file_save.statusTip = 'Save the file'
119
152
  @file_save.connect(SIGNAL('triggered()')) { file_save(false) }
120
153
 
121
- @file_save_as = Qt::Action.new(Cosmos.get_icon('save_as.png'), tr('Save &As'), self)
122
- @file_save_as.statusTip = tr('Save the file')
154
+ @file_save_as = Qt::Action.new(Cosmos.get_icon('save_as.png'), 'Save &As', self)
155
+ @file_save_as.statusTip = 'Save the file'
123
156
  @file_save_as.connect(SIGNAL('triggered()')) { file_save(true) }
124
157
 
125
158
  # Edit actions
126
- @edit_undo = Qt::Action.new(Cosmos.get_icon('undo.png'), tr('&Undo'), self)
127
- @edit_undo_keyseq = Qt::KeySequence.new(tr('Ctrl+Z'))
159
+ @edit_undo = Qt::Action.new(Cosmos.get_icon('undo.png'), '&Undo', self)
160
+ @edit_undo_keyseq = Qt::KeySequence.new('Ctrl+Z')
128
161
  @edit_undo.shortcut = @edit_undo_keyseq
129
- @edit_undo.statusTip = tr('Undo')
162
+ @edit_undo.statusTip = 'Undo'
130
163
  @edit_undo.connect(SIGNAL('triggered()')) { active_config_editor_frame().undo }
131
164
 
132
- @edit_redo = Qt::Action.new(Cosmos.get_icon('redo.png'), tr('&Redo'), self)
133
- @edit_redo_keyseq = Qt::KeySequence.new(tr('Ctrl+Y'))
165
+ @edit_redo = Qt::Action.new(Cosmos.get_icon('redo.png'), '&Redo', self)
166
+ @edit_redo_keyseq = Qt::KeySequence.new('Ctrl+Y')
134
167
  @edit_redo.shortcut = @edit_redo_keyseq
135
- @edit_redo.statusTip = tr('Redo')
168
+ @edit_redo.statusTip = 'Redo'
136
169
  @edit_redo.connect(SIGNAL('triggered()')) { active_config_editor_frame().redo }
137
170
 
138
- @edit_cut = Qt::Action.new(Cosmos.get_icon('cut.png'), tr('Cu&t'), self)
139
- @edit_cut_keyseq = Qt::KeySequence.new(tr('Ctrl+X'))
171
+ @edit_cut = Qt::Action.new(Cosmos.get_icon('cut.png'), 'Cu&t', self)
172
+ @edit_cut_keyseq = Qt::KeySequence.new('Ctrl+X')
140
173
  @edit_cut.shortcut = @edit_cut_keyseq
141
- @edit_cut.statusTip = tr('Cut')
174
+ @edit_cut.statusTip = 'Cut'
142
175
  @edit_cut.connect(SIGNAL('triggered()')) { active_config_editor_frame().cut }
143
176
 
144
- @edit_copy = Qt::Action.new(Cosmos.get_icon('copy.png'), tr('&Copy'), self)
145
- @edit_copy_keyseq = Qt::KeySequence.new(tr('Ctrl+C'))
177
+ @edit_copy = Qt::Action.new(Cosmos.get_icon('copy.png'), '&Copy', self)
178
+ @edit_copy_keyseq = Qt::KeySequence.new('Ctrl+C')
146
179
  @edit_copy.shortcut = @edit_copy_keyseq
147
- @edit_copy.statusTip = tr('Copy')
180
+ @edit_copy.statusTip = 'Copy'
148
181
  @edit_copy.connect(SIGNAL('triggered()')) { active_config_editor_frame().copy }
149
182
 
150
- @edit_paste = Qt::Action.new(tr('&Paste'), self)
151
- @edit_paste_keyseq = Qt::KeySequence.new(tr('Ctrl+V'))
183
+ @edit_paste = Qt::Action.new('&Paste', self)
184
+ @edit_paste_keyseq = Qt::KeySequence.new('Ctrl+V')
152
185
  @edit_paste.shortcut = @edit_paste_keyseq
153
- @edit_paste.statusTip = tr('Paste')
186
+ @edit_paste.statusTip = 'Paste'
154
187
  @edit_paste.connect(SIGNAL('triggered()')) { active_config_editor_frame().paste }
155
188
 
156
- @edit_select_all = Qt::Action.new(tr('Select &All'), self)
157
- @edit_select_all_keyseq = Qt::KeySequence.new(tr('Ctrl+A'))
189
+ @edit_select_all = Qt::Action.new('Select &All', self)
190
+ @edit_select_all_keyseq = Qt::KeySequence.new('Ctrl+A')
158
191
  @edit_select_all.shortcut = @edit_select_all_keyseq
159
- @edit_select_all.statusTip = tr('Select All')
192
+ @edit_select_all.statusTip = 'Select All'
160
193
  @edit_select_all.connect(SIGNAL('triggered()')) { active_config_editor_frame().select_all }
161
194
 
162
- @edit_comment = Qt::Action.new(tr('Comment/Uncomment &Lines'), self)
163
- @edit_comment_keyseq = Qt::KeySequence.new(tr('Ctrl+K'))
195
+ @edit_comment = Qt::Action.new('Comment/Uncomment &Lines', self)
196
+ @edit_comment_keyseq = Qt::KeySequence.new('Ctrl+K')
164
197
  @edit_comment.shortcut = @edit_comment_keyseq
165
- @edit_comment.statusTip = tr('Comment/Uncomment Lines')
198
+ @edit_comment.statusTip = 'Comment/Uncomment Lines'
166
199
  @edit_comment.connect(SIGNAL('triggered()')) { active_config_editor_frame().comment_or_uncomment_lines }
167
200
 
168
201
  # Search Actions
169
- @search_find = Qt::Action.new(Cosmos.get_icon('search.png'), tr('&Find'), self)
170
- @search_find_keyseq = Qt::KeySequence.new(tr('Ctrl+F'))
202
+ @search_find = Qt::Action.new(Cosmos.get_icon('search.png'), '&Find', self)
203
+ @search_find_keyseq = Qt::KeySequence.new('Ctrl+F')
171
204
  @search_find.shortcut = @search_find_keyseq
172
- @search_find.statusTip = tr('Find text')
205
+ @search_find.statusTip = 'Find text'
173
206
  @search_find.connect(SIGNAL('triggered()')) do
174
207
  FindReplaceDialog.show_find(self)
175
208
  end
176
209
 
177
- @search_find_next = Qt::Action.new(tr('Find &Next'), self)
178
- @search_find_next_keyseq = Qt::KeySequence.new(tr('F3'))
210
+ @search_find_next = Qt::Action.new('Find &Next', self)
211
+ @search_find_next_keyseq = Qt::KeySequence.new('F3')
179
212
  @search_find_next.shortcut = @search_find_next_keyseq
180
- @search_find_next.statusTip = tr('Find next instance')
213
+ @search_find_next.statusTip = 'Find next instance'
181
214
  @search_find_next.connect(SIGNAL('triggered()')) do
182
215
  FindReplaceDialog.find_next(self)
183
216
  end
184
217
 
185
- @search_find_previous = Qt::Action.new(tr('Find &Previous'), self)
186
- @search_find_previous_keyseq = Qt::KeySequence.new(tr('Shift+F3'))
218
+ @search_find_previous = Qt::Action.new('Find &Previous', self)
219
+ @search_find_previous_keyseq = Qt::KeySequence.new('Shift+F3')
187
220
  @search_find_previous.shortcut = @search_find_previous_keyseq
188
- @search_find_previous.statusTip = tr('Find previous instance')
221
+ @search_find_previous.statusTip = 'Find previous instance'
189
222
  @search_find_previous.connect(SIGNAL('triggered()')) do
190
223
  FindReplaceDialog.find_previous(self)
191
224
  end
192
225
 
193
- @search_replace = Qt::Action.new(tr('&Replace'), self)
194
- @search_replace_keyseq = Qt::KeySequence.new(tr('Ctrl+H'))
226
+ @search_replace = Qt::Action.new('&Replace', self)
227
+ @search_replace_keyseq = Qt::KeySequence.new('Ctrl+H')
195
228
  @search_replace.shortcut = @search_replace_keyseq
196
- @search_replace.statusTip = tr('Replace')
229
+ @search_replace.statusTip = 'Replace'
197
230
  @search_replace.connect(SIGNAL('triggered()')) do
198
231
  FindReplaceDialog.show_replace(self)
199
232
  end
@@ -220,25 +253,43 @@ module Cosmos
220
253
  update_cursor()
221
254
  end
222
255
 
223
- @create_target = Qt::Action.new(tr('&Create Target'), self)
224
- @create_target.statusTip = tr('Create a new COSMOS target')
256
+ @create_target = Qt::Action.new('Create &Target', self)
257
+ @create_target.statusTip = 'Create a new COSMOS target'
225
258
  @create_target.connect(SIGNAL('triggered()')) { create_target() }
259
+
260
+ @create_system_config = Qt::Action.new('Create New &System Config', self)
261
+ @create_system_config.statusTip = 'Create a new system configuration'
262
+ @create_system_config.connect(SIGNAL('triggered()')) { SystemConfigDialog.new(self) }
226
263
  end
227
264
 
228
265
  def initialize_menus
229
266
  # File Menu
230
- @file_menu = menuBar.addMenu(tr('&File'))
267
+ @file_menu = menuBar.addMenu('&File')
231
268
  @file_menu.addAction(@file_new)
232
269
 
233
270
  open_action = Qt::Action.new(self)
234
- open_action.shortcut = Qt::KeySequence.new(tr('Ctrl+O'))
271
+ open_action.shortcut = Qt::KeySequence.new('Ctrl+O')
235
272
  open_action.connect(SIGNAL('triggered()')) { file_open(@procedure_dir) }
236
273
  self.addAction(open_action)
237
274
 
238
- @file_open = @file_menu.addMenu(tr('&Open'))
275
+ @file_open = @file_menu.addMenu('&Open')
239
276
  @file_open.setIcon(Cosmos.get_icon('open.png'))
240
277
  target_dirs_action(@file_open, File.join(Cosmos::USERPATH,'config'), '', method(:file_open))
241
278
 
279
+ @file_open_recent = @file_menu.addMenu('Open &Recent')
280
+ @file_open_recent.setIcon(Cosmos.get_icon('open.png'))
281
+ settings = Qt::Settings.new('Ball Aerospace', self.class.to_s)
282
+ if settings.contains('recent_files')
283
+ recent = settings.value('recent_files').toStringList()
284
+ recent.each do |filename|
285
+ action = Qt::Action.new(filename, self)
286
+ action.connect(SIGNAL('triggered()')) { open_filename(filename) }
287
+ @file_open_recent.addAction(action)
288
+ end
289
+ end
290
+ @file_open_recent.addSeparator()
291
+ @file_open_recent.addAction(@clear_file_open_recent)
292
+
242
293
  @file_menu.addAction(@file_close)
243
294
  @file_menu.addAction(@file_reload)
244
295
  @file_menu.addSeparator()
@@ -248,7 +299,7 @@ module Cosmos
248
299
  @file_menu.addAction(@exit_action)
249
300
 
250
301
  # Edit Menu
251
- mode_menu = menuBar.addMenu(tr('&Edit'))
302
+ mode_menu = menuBar.addMenu('&Edit')
252
303
  mode_menu.addAction(@edit_undo)
253
304
  mode_menu.addAction(@edit_redo)
254
305
  mode_menu.addSeparator()
@@ -261,18 +312,19 @@ module Cosmos
261
312
  mode_menu.addAction(@edit_comment)
262
313
 
263
314
  # Search Menu
264
- view_menu = menuBar.addMenu(tr('&Search'))
315
+ view_menu = menuBar.addMenu('&Search')
265
316
  view_menu.addAction(@search_find)
266
317
  view_menu.addAction(@search_find_next)
267
318
  view_menu.addAction(@search_find_previous)
268
319
  view_menu.addAction(@search_replace)
269
320
 
270
321
  # File Type Menu
271
- type_menu = menuBar.addMenu(tr('File &Type'))
322
+ type_menu = menuBar.addMenu('File &Type')
272
323
  type_menu.addActions(@type_group.actions)
273
324
 
274
325
  # Actions Menu
275
- actions_menu = menuBar.addMenu(tr('&Actions'))
326
+ actions_menu = menuBar.addMenu('&Actions')
327
+ actions_menu.addAction(@create_system_config)
276
328
  actions_menu.addAction(@create_target)
277
329
 
278
330
  # Help Menu
@@ -376,8 +428,8 @@ module Cosmos
376
428
  def tree_context_menu(point)
377
429
  menu = Qt::Menu.new()
378
430
 
379
- delete_action = Qt::Action.new(tr("Delete"), self)
380
- delete_action.statusTip = tr("Delete file")
431
+ delete_action = Qt::Action.new("Delete", self)
432
+ delete_action.statusTip = "Delete file"
381
433
  delete_action.connect(SIGNAL('triggered()')) do
382
434
  delete_path(@fs_model.filePath(@tree_view.indexAt(point)))
383
435
  end
@@ -408,36 +460,67 @@ module Cosmos
408
460
  # File->Open
409
461
  def file_open(filename = nil)
410
462
  if File.directory?(filename)
411
- filename = Qt::FileDialog.getOpenFileName(self, "Select File", filename)
412
- end
413
- unless filename.nil? || filename.empty?
414
- # If the user opens a file we already have open
415
- # just set the current tab to that file and return
416
- @tab_book.tabs.each_with_index do |tab, index|
417
- if tab.filename == filename
418
- @tab_book.setCurrentIndex(index)
419
- @tab_book.currentTab.set_text_from_file(filename)
420
- @tab_book.currentTab.filename = filename
421
- return
422
- end
463
+ filenames = Qt::FileDialog.getOpenFileNames(self, "Select File(s)", filename, "COSMOS (*.rb *.txt);;All Files(*.*)")
464
+ else
465
+ filenames = [filename]
466
+ end
467
+ # Remove nils and convert filenames to UNIX path structure
468
+ filenames = filenames.compact.map {|filename| filename.gsub("\\","/") }
469
+ return if filenames.nil? || filenames.empty?
470
+ Qt::Application.setOverrideCursor(Qt::Cursor.new(Qt::WaitCursor))
471
+ filenames.each do |filename|
472
+ open_filename(filename)
473
+
474
+ found = false
475
+ @file_open_recent.actions.each do |action|
476
+ found = true if action.text == filename
477
+ end
478
+ next if found
479
+ action = Qt::Action.new(filename, self)
480
+ action.connect(SIGNAL('triggered()')) { open_filename(filename) }
481
+ @file_open_recent.insertAction(@file_open_recent.actions[0], action)
482
+ # Add 2 for the separator and Clear Recent action
483
+ if @file_open_recent.actions.length > (MAX_RECENT_FILES + 2)
484
+ @file_open_recent.removeAction(@file_open_recent.actions[-3]) # ignore last 2
423
485
  end
486
+ end
487
+ update_tree()
488
+ Qt::Application.restoreOverrideCursor()
489
+ end
490
+
491
+ def clear_file_open_recent
492
+ # Subtract 2 for the separator and Clear Recent action
493
+ (@file_open_recent.actions.length - 2).times do
494
+ @file_open_recent.removeAction(@file_open_recent.actions[0])
495
+ end
496
+ end
424
497
 
425
- if ((@tab_book.count == 1) &&
426
- @tab_book.currentTab.filename.empty? &&
427
- !@tab_book.currentTab.modified)
428
- # Active Tab is an unmodified Untitled so just open the file in it
498
+ def open_filename(filename)
499
+ # If the user opens a file we already have open
500
+ # just set the current tab to that file and return
501
+ @tab_book.tabs.each_with_index do |tab, index|
502
+ if tab.filename == filename
503
+ @tab_book.setCurrentIndex(index)
429
504
  @tab_book.currentTab.set_text_from_file(filename)
430
505
  @tab_book.currentTab.filename = filename
431
- @tab_book.setTabText(@tab_book.currentIndex, File.basename(filename))
432
- else
433
- create_tab(filename)
506
+ return
434
507
  end
508
+ end
435
509
 
436
- update_title()
437
- @procedure_dir = File.dirname(filename)
438
- @procedure_dir << '/' if @procedure_dir[-1..-1] != '/' and @procedure_dir[-1..-1] != '\\'
510
+ if ((@tab_book.count == 1) &&
511
+ @tab_book.currentTab.filename.empty? &&
512
+ !@tab_book.currentTab.modified)
513
+ # Active Tab is an unmodified Untitled so just open the file in it
514
+ @tab_book.currentTab.set_text_from_file(filename)
515
+ @tab_book.currentTab.filename = filename
516
+ @tab_book.setTabText(@tab_book.currentIndex, File.basename(filename))
517
+ else
518
+ create_tab(filename)
439
519
  end
440
- update_tree()
520
+
521
+ update_title()
522
+ @procedure_dir = File.dirname(filename)
523
+ @procedure_dir << '/' if @procedure_dir[-1..-1] != '/' and @procedure_dir[-1..-1] != '\\'
441
524
  end
442
525
 
443
526
  # File->Reload
@@ -490,11 +573,11 @@ module Cosmos
490
573
  saved = true
491
574
  update_title()
492
575
  update_tree()
493
- statusBar.showMessage(tr("#{filename} saved"))
576
+ statusBar.showMessage("#{filename} saved")
494
577
  @procedure_dir = File.dirname(filename)
495
578
  @procedure_dir << '/' if @procedure_dir[-1..-1] != '/' and @procedure_dir[-1..-1] != '\\'
496
579
  rescue => error
497
- statusBar.showMessage(tr("Error Saving File : #{error.class} : #{error.message}"))
580
+ statusBar.showMessage("Error Saving File : #{error.class} : #{error.message}")
498
581
  end
499
582
  end
500
583
 
@@ -570,7 +653,7 @@ module Cosmos
570
653
  end
571
654
  File.open(File.join(target_folder, 'procedures', "#{target.downcase}_noop.rb"), 'w') do |file|
572
655
  file.puts "require 'cosmos'"
573
- file.puts "require '#{File.basename(lib_filename)}'"
656
+ file.puts "load_utility '#{File.basename(lib_filename)}'"
574
657
  file.puts "\n"
575
658
  file.puts "#{target.downcase} = #{lib_filename.filename_to_class_name}.new"
576
659
  file.puts "#{target.downcase}.noop"
@@ -615,6 +698,10 @@ module Cosmos
615
698
 
616
699
  def closeEvent(event)
617
700
  if prompt_for_save_if_needed_on_close()
701
+ settings = Qt::Settings.new('Ball Aerospace', self.class.to_s)
702
+ recent_files = @file_open_recent.actions.collect {|action| action.text }
703
+ # Ignore the last 2 because of the separator and Clear Recent action
704
+ settings.setValue('recent_files', Qt::Variant.new(recent_files[0..-3]))
618
705
  super(event)
619
706
  else
620
707
  event.ignore()
@@ -656,23 +743,23 @@ module Cosmos
656
743
 
657
744
  menu = Qt::Menu.new()
658
745
 
659
- new_action = Qt::Action.new(tr("&New"), self)
660
- new_action.statusTip = tr("Create a new file")
746
+ new_action = Qt::Action.new("&New", self)
747
+ new_action.statusTip = "Create a new file"
661
748
  new_action.connect(SIGNAL('triggered()')) { file_new() }
662
749
  menu.addAction(new_action)
663
750
 
664
- close_action = Qt::Action.new(tr("&Close"), self)
665
- close_action.statusTip = tr("Close the file")
751
+ close_action = Qt::Action.new("&Close", self)
752
+ close_action.statusTip = "Close the file"
666
753
  close_action.connect(SIGNAL('triggered()')) { file_close() }
667
754
  menu.addAction(close_action)
668
755
 
669
- save_action = Qt::Action.new(tr("&Save"), self)
670
- save_action.statusTip = tr("Save the file")
756
+ save_action = Qt::Action.new("&Save", self)
757
+ save_action.statusTip = "Save the file"
671
758
  save_action.connect(SIGNAL('triggered()')) { file_save(false) }
672
759
  menu.addAction(save_action)
673
760
 
674
- save_action = Qt::Action.new(tr("Save &As"), self)
675
- save_action.statusTip = tr("Save the file as")
761
+ save_action = Qt::Action.new("Save &As", self)
762
+ save_action.statusTip = "Save the file as"
676
763
  save_action.connect(SIGNAL('triggered()')) { file_save(true) }
677
764
  menu.addAction(save_action)
678
765