cosmos 3.9.2 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +23 -0
- data/.travis.yml +1 -0
- data/.yardopts +3 -0
- data/Gemfile +1 -1
- data/Manifest.txt +137 -52
- data/Rakefile +50 -44
- data/autohotkey/config/system/system.txt +0 -5
- data/autohotkey/config/targets/INST/cmd_tlm/inst_cmds.txt +6 -1
- data/autohotkey/config/targets/INST/screens/extra.txt +19 -0
- data/autohotkey/config/targets/INST/sequences/run_sequence.txt +1 -0
- data/autohotkey/config/targets/META/screens/data.txt +12 -0
- data/autohotkey/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
- data/autohotkey/config/targets/{COSMOS/cmd_tlm/cosmos_server_cmds.txt → SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
- data/autohotkey/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
- data/autohotkey/config/targets/SYSTEM/screens/limits_change.txt +14 -0
- data/autohotkey/config/targets/SYSTEM/screens/meta.txt +14 -0
- data/autohotkey/config/targets/SYSTEM/target.txt +12 -0
- data/autohotkey/config/tools/cmd_tlm_server/cmd_tlm_server.txt +2 -2
- data/autohotkey/config/tools/test_runner/test_runner2.txt +1 -1
- data/autohotkey/tools/CmdSequence +14 -0
- data/autohotkey/tools/CmdSequenceAHK +23 -0
- data/autohotkey/tools/CmdSequenceAHK2 +16 -0
- data/autohotkey/tools/cmd_extractor.ahk +2 -2
- data/autohotkey/tools/cmd_sender.ahk +4 -6
- data/autohotkey/tools/cmd_sequence.ahk +215 -0
- data/autohotkey/tools/cmd_sequence2.ahk +23 -0
- data/autohotkey/tools/data_viewer.ahk +2 -3
- data/autohotkey/tools/limits_monitor.ahk +9 -11
- data/autohotkey/tools/open_gl_builder.ahk +1 -2
- data/autohotkey/tools/packet_viewer.ahk +51 -35
- data/autohotkey/tools/replay.ahk +1 -2
- data/autohotkey/tools/script_runner.ahk +1 -2
- data/autohotkey/tools/script_runner2.ahk +1 -2
- data/autohotkey/tools/test_runner2.ahk +1 -5
- data/autohotkey/tools/test_runner3.ahk +1 -3
- data/autohotkey/tools/tlm_grapher.ahk +1 -3
- data/autohotkey/tools/tlm_grapher3.ahk +1 -2
- data/autohotkey/tools/tlm_viewer.ahk +8 -3
- data/autohotkey/tools/tlm_viewer2.ahk +2 -3
- data/autohotkey/tools/tlm_viewer5.ahk +1 -2
- data/cosmos.gemspec +26 -20
- data/data/cmd_sequence.png +0 -0
- data/data/config/_array_params.yaml +23 -0
- data/data/config/_id_items.yaml +24 -0
- data/data/config/_id_params.yaml +58 -0
- data/data/config/_interfaces.yaml +206 -0
- data/data/config/_items.yaml +20 -0
- data/data/config/_params.yaml +58 -0
- data/data/config/cmd_tlm_server.yaml +110 -0
- data/data/config/command.yaml +38 -0
- data/data/config/command_modifiers.yaml +127 -0
- data/data/config/command_telemetry.yaml +3 -0
- data/data/config/data_viewer.yaml +43 -0
- data/data/config/handbook_creator.yaml +23 -0
- data/data/config/housekeeping_params.yaml +71 -0
- data/data/config/interface_modifiers.yaml +44 -0
- data/data/config/item_modifiers.yaml +172 -0
- data/data/config/launcher.yaml +117 -0
- data/data/config/limits_monitor.yaml +53 -0
- data/data/config/linegraph_params.yaml +30 -0
- data/data/config/linegraph_plot.yaml +106 -0
- data/data/config/page_modifiers.yaml +128 -0
- data/data/config/param_item_modifiers.yaml +41 -0
- data/data/config/parameter_modifiers.yaml +144 -0
- data/data/config/protocols.yaml +257 -0
- data/data/config/screen.yaml +151 -0
- data/data/config/script_runner.yaml +15 -0
- data/data/config/system.yaml +153 -0
- data/data/config/table_manager.yaml +76 -0
- data/data/config/table_parameter_modifiers.yaml +9 -0
- data/data/config/target.yaml +71 -0
- data/data/config/telemetry.yaml +73 -0
- data/data/config/telemetry_modifiers.yaml +129 -0
- data/data/config/test_runner.yaml +118 -0
- data/data/config/tlm_extractor.yaml +109 -0
- data/data/config/tlm_grapher.yaml +78 -0
- data/data/config/tlm_viewer.yaml +107 -0
- data/data/config/unknown.yaml +3 -0
- data/data/config/widgets.yaml +1339 -0
- data/data/config/xy_params.yaml +50 -0
- data/data/config/xy_plot.yaml +12 -0
- data/data/config_editor.png +0 -0
- data/data/crc.txt +172 -161
- data/data/delete.png +0 -0
- data/demo/config/data/crc.txt +56 -36
- data/demo/config/data/meta_init.txt +1 -4
- data/demo/config/system/system.txt +15 -3
- data/demo/config/system/system2.txt +13 -3
- data/demo/config/targets/EXAMPLE/lib/example_interface.rb +2 -6
- data/demo/config/targets/EXAMPLE/target.txt +3 -1
- data/demo/config/targets/INST/cmd_tlm/inst_cmds.txt +1 -0
- data/demo/config/targets/INST/lib/inst_dump_component.rb +34 -0
- data/demo/config/targets/INST/screens/adcs.txt +39 -15
- data/demo/config/targets/INST/screens/commanding.txt +26 -19
- data/demo/config/targets/INST/screens/spacing_box.txt +44 -0
- data/demo/config/targets/INST/screens/spacing_grid.txt +78 -0
- data/demo/config/targets/INST/screens/tabs.txt +0 -2
- data/demo/config/targets/INST/sequences/sequence.tsv +3 -0
- data/demo/config/targets/INST/tables/EventAction.csv +9 -0
- data/demo/config/targets/INST/tables/EventAction.dat +0 -0
- data/demo/config/targets/INST/tables/McConfigTable.csv +20 -0
- data/demo/config/targets/INST/tables/McConfigTable.dat +0 -0
- data/demo/config/targets/INST/target.txt +4 -0
- data/demo/config/targets/INST/tools/data_viewer/data_viewer.txt +2 -0
- data/demo/config/targets/INST/tools/data_viewer/data_viewer2.txt +2 -0
- data/demo/config/targets/INST/tools/table_manager/EventAction_def.txt +6 -0
- data/demo/config/targets/INST/tools/table_manager/McConfigTable_def.txt +38 -0
- data/demo/config/targets/SYSTEM/cmd_tlm/limits_groups.txt +7 -3
- data/demo/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
- data/demo/config/targets/{COSMOS/cmd_tlm/cosmos_server_cmds.txt → SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
- data/demo/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
- data/demo/config/targets/{COSMOS → SYSTEM}/cmd_tlm_server.txt +2 -2
- data/demo/config/targets/SYSTEM/lib/limits_groups.rb +39 -0
- data/demo/config/targets/SYSTEM/screens/status.txt +1 -1
- data/demo/config/targets/SYSTEM/target.txt +12 -0
- data/demo/config/targets/TEMPLATED/cmd_tlm_server.txt +1 -1
- data/demo/config/targets/TEMPLATED/lib/templated_interface.rb +8 -5
- data/demo/config/targets/TEMPLATED/target.txt +2 -0
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +15 -6
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server2.txt +13 -5
- data/demo/config/tools/data_viewer/data_viewer.txt +9 -0
- data/demo/config/tools/launcher/launcher.txt +9 -6
- data/demo/config/tools/launcher/launcher2.txt +16 -13
- data/demo/config/tools/launcher/launcher_mini.txt +45 -0
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +12 -11
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +12 -11
- data/demo/config/tools/test_runner/test_runner.txt +1 -1
- data/demo/config/tools/tlm_viewer/tlm_viewer.txt +5 -5
- data/demo/lib/example_background_task.rb +9 -5
- data/demo/lib/example_target.rb +5 -15
- data/demo/lib/scpi_target.rb +4 -10
- data/demo/procedures/cosmos_api_test.rb +17 -0
- data/demo/tools/CmdSequence +16 -0
- data/demo/tools/CmdSequence.bat +9 -0
- data/demo/tools/ConfigEditor +16 -0
- data/demo/tools/ConfigEditor.bat +9 -0
- data/demo/tools/mac/CmdSequence.app/Contents/Info.plist +38 -0
- data/demo/tools/mac/CmdSequence.app/Contents/MacOS/CmdSequence.rb +16 -0
- data/demo/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +10 -0
- data/demo/tools/mac/CmdSequence.app/Contents/MacOS/tool_launch.rb +38 -0
- data/demo/tools/mac/CmdSequence.app/Contents/Resources/appIcon.icns +0 -0
- data/ext/cosmos/ext/packet/packet.c +5 -5
- data/install/config/data/crc.txt +12 -8
- data/install/config/system/system.txt +13 -3
- data/install/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +14 -0
- data/install/config/targets/SYSTEM/target.txt +12 -0
- data/install/tools/CmdSequence +16 -0
- data/install/tools/CmdSequence.bat +9 -0
- data/install/tools/ConfigEditor +16 -0
- data/install/tools/ConfigEditor.bat +9 -0
- data/install/tools/mac/CmdSequence.app/Contents/Info.plist +38 -0
- data/install/tools/mac/CmdSequence.app/Contents/MacOS/CmdSequence.rb +16 -0
- data/install/tools/mac/CmdSequence.app/Contents/MacOS/main.sh +10 -0
- data/install/tools/mac/CmdSequence.app/Contents/MacOS/tool_launch.rb +38 -0
- data/install/tools/mac/CmdSequence.app/Contents/Resources/appIcon.icns +0 -0
- data/lib/cosmos.rb +1 -1
- data/lib/cosmos/config/config_parser.rb +147 -59
- data/lib/cosmos/config/meta_config_parser.rb +57 -0
- data/lib/cosmos/conversions/polynomial_conversion.rb +20 -4
- data/lib/cosmos/conversions/unix_time_conversion.rb +4 -4
- data/lib/cosmos/core_ext/array.rb +45 -5
- data/lib/cosmos/core_ext/cosmos_io.rb +31 -15
- data/lib/cosmos/core_ext/file.rb +2 -2
- data/lib/cosmos/core_ext/kernel.rb +1 -6
- data/lib/cosmos/core_ext/objectspace.rb +0 -2
- data/lib/cosmos/core_ext/string.rb +27 -4
- data/lib/cosmos/core_ext/time.rb +39 -10
- data/lib/cosmos/gui/choosers/combobox_chooser.rb +37 -26
- data/lib/cosmos/gui/choosers/file_chooser.rb +23 -6
- data/lib/cosmos/gui/choosers/float_chooser.rb +13 -11
- data/lib/cosmos/gui/choosers/integer_chooser.rb +13 -11
- data/lib/cosmos/gui/choosers/string_chooser.rb +18 -36
- data/lib/cosmos/gui/choosers/telemetry_chooser.rb +64 -64
- data/lib/cosmos/gui/choosers/value_chooser.rb +15 -15
- data/lib/cosmos/gui/dialogs/about_dialog.rb +18 -13
- data/lib/cosmos/gui/dialogs/calendar_dialog.rb +11 -3
- data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/details_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/exception_dialog.rb +7 -7
- data/lib/cosmos/gui/dialogs/find_replace_dialog.rb +20 -15
- data/lib/cosmos/gui/dialogs/interface_raw_dialog.rb +143 -0
- data/lib/cosmos/gui/dialogs/legal_dialog.rb +6 -5
- data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +5 -2
- data/lib/cosmos/gui/dialogs/progress_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/pry_dialog.rb +4 -4
- data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +3 -0
- data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +7 -6
- data/lib/cosmos/gui/dialogs/splash.rb +1 -1
- data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +1 -1
- data/lib/cosmos/gui/dialogs/tlm_graph_dialog.rb +114 -0
- data/lib/cosmos/gui/line_graph/line_graph.rb +9 -10
- data/lib/cosmos/gui/line_graph/line_graph_dialog.rb +7 -5
- data/lib/cosmos/gui/line_graph/line_graph_drawing.rb +3 -7
- data/lib/cosmos/gui/line_graph/line_graph_popups.rb +3 -8
- data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +2 -7
- data/lib/cosmos/gui/line_graph/overview_graph.rb +6 -1
- data/lib/cosmos/gui/opengl/earth_model.rb +6 -3
- data/lib/cosmos/gui/opengl/gl_bounds.rb +11 -23
- data/lib/cosmos/gui/opengl/gl_light.rb +3 -4
- data/lib/cosmos/gui/opengl/gl_material.rb +3 -4
- data/lib/cosmos/gui/opengl/gl_scene.rb +10 -4
- data/lib/cosmos/gui/opengl/gl_shape.rb +6 -2
- data/lib/cosmos/gui/opengl/gl_viewer.rb +5 -5
- data/lib/cosmos/gui/opengl/gl_viewport.rb +11 -12
- data/lib/cosmos/gui/opengl/moon_model.rb +6 -3
- data/lib/cosmos/gui/opengl/stl_reader.rb +8 -9
- data/lib/cosmos/gui/opengl/stl_shape.rb +4 -5
- data/lib/cosmos/gui/opengl/texture_mapped_sphere.rb +7 -7
- data/lib/cosmos/gui/qt.rb +1 -1
- data/lib/cosmos/gui/qt_tool.rb +21 -10
- data/lib/cosmos/gui/text/completion.rb +23 -2
- data/lib/cosmos/gui/text/completion_text_edit.rb +38 -23
- data/lib/cosmos/gui/utilities/analyze_log.rb +1 -1
- data/lib/cosmos/gui/utilities/screenshot.rb +2 -2
- data/lib/cosmos/gui/widgets/full_text_search_line_edit.rb +11 -1
- data/lib/cosmos/gui/widgets/packet_log_frame.rb +19 -6
- data/lib/cosmos/interfaces.rb +10 -0
- data/lib/cosmos/interfaces/cmd_tlm_server_interface.rb +28 -47
- data/lib/cosmos/interfaces/interface.rb +240 -22
- data/lib/cosmos/interfaces/linc_interface.rb +3 -5
- data/lib/cosmos/interfaces/protocols/burst_protocol.rb +173 -0
- data/lib/cosmos/interfaces/protocols/crc_protocol.rb +141 -0
- data/lib/cosmos/{streams/fixed_stream_protocol.rb → interfaces/protocols/fixed_protocol.rb} +40 -37
- data/lib/cosmos/{streams/length_stream_protocol.rb → interfaces/protocols/length_protocol.rb} +55 -48
- data/lib/cosmos/interfaces/protocols/override_protocol.rb +52 -0
- data/lib/cosmos/interfaces/protocols/preidentified_protocol.rb +141 -0
- data/lib/cosmos/interfaces/protocols/protocol.rb +60 -0
- data/lib/cosmos/interfaces/protocols/template_protocol.rb +209 -0
- data/lib/cosmos/interfaces/protocols/terminated_protocol.rb +81 -0
- data/lib/cosmos/interfaces/serial_interface.rb +28 -23
- data/lib/cosmos/interfaces/simulated_target_interface.rb +27 -16
- data/lib/cosmos/interfaces/stream_interface.rb +36 -108
- data/lib/cosmos/interfaces/tcpip_client_interface.rb +21 -21
- data/lib/cosmos/interfaces/tcpip_server_interface.rb +555 -94
- data/lib/cosmos/interfaces/udp_interface.rb +51 -83
- data/lib/cosmos/io/buffered_file.rb +92 -2
- data/lib/cosmos/io/json_drb.rb +2 -2
- data/lib/cosmos/io/posix_serial_driver.rb +3 -1
- data/lib/cosmos/io/raw_logger.rb +3 -3
- data/lib/cosmos/io/serial_driver.rb +14 -5
- data/lib/cosmos/io/win32_serial_driver.rb +16 -4
- data/lib/cosmos/packet_logs.rb +0 -1
- data/lib/cosmos/packet_logs/packet_log_reader.rb +11 -1
- data/lib/cosmos/packet_logs/packet_log_writer.rb +31 -13
- data/lib/cosmos/packets/binary_accessor.rb +599 -32
- data/lib/cosmos/packets/commands.rb +48 -24
- data/lib/cosmos/packets/packet.rb +140 -54
- data/lib/cosmos/packets/packet_config.rb +0 -2
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +10 -2
- data/lib/cosmos/packets/structure.rb +81 -33
- data/lib/cosmos/packets/structure_item.rb +45 -5
- data/lib/cosmos/packets/telemetry.rb +149 -55
- data/lib/cosmos/script/api_shared.rb +1000 -0
- data/lib/cosmos/script/commands.rb +2 -2
- data/lib/cosmos/script/extract.rb +19 -4
- data/lib/cosmos/script/limits.rb +2 -0
- data/lib/cosmos/script/script.rb +1 -1
- data/lib/cosmos/script/scripting.rb +4 -784
- data/lib/cosmos/script/telemetry.rb +44 -23
- data/lib/cosmos/script/tools.rb +15 -69
- data/lib/cosmos/streams/serial_stream.rb +12 -19
- data/lib/cosmos/streams/stream.rb +2 -11
- data/lib/cosmos/streams/tcpip_socket_stream.rb +3 -13
- data/lib/cosmos/system/system.rb +187 -31
- data/lib/cosmos/system/target.rb +11 -2
- data/lib/cosmos/tools/cmd_extractor/cmd_extractor.rb +12 -11
- data/lib/cosmos/tools/cmd_sender/{cmd_sender_item_delegate.rb → cmd_param_table_item_delegate.rb} +11 -10
- data/lib/cosmos/tools/cmd_sender/cmd_sender.rb +209 -164
- data/lib/cosmos/tools/cmd_sequence/cmd_sequence.rb +652 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_item.rb +510 -0
- data/lib/cosmos/tools/cmd_sequence/sequence_list.rb +194 -0
- data/lib/cosmos/tools/cmd_tlm_server/api.rb +179 -5
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +31 -14
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +23 -16
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_gui.rb +92 -20
- data/lib/cosmos/tools/cmd_tlm_server/commanding.rb +1 -1
- data/lib/cosmos/tools/cmd_tlm_server/gui/interfaces_tab.rb +17 -4
- data/lib/cosmos/tools/cmd_tlm_server/gui/targets_tab.rb +0 -5
- data/lib/cosmos/tools/cmd_tlm_server/interface_thread.rb +1 -2
- data/lib/cosmos/tools/cmd_tlm_server/interfaces.rb +4 -4
- data/lib/cosmos/tools/cmd_tlm_server/limits_groups_background_task.rb +121 -0
- data/lib/cosmos/tools/cmd_tlm_server/routers.rb +8 -4
- data/lib/cosmos/tools/config_editor/config_editor.rb +720 -0
- data/lib/cosmos/tools/config_editor/config_editor_frame.rb +675 -0
- data/lib/cosmos/tools/data_viewer/data_viewer.rb +44 -27
- data/lib/cosmos/tools/data_viewer/data_viewer_component.rb +8 -22
- data/lib/cosmos/tools/launcher/launcher.rb +29 -12
- data/lib/cosmos/tools/launcher/launcher_config.rb +1 -1
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +153 -42
- data/lib/cosmos/tools/packet_viewer/packet_viewer.rb +44 -6
- data/lib/cosmos/tools/replay/replay.rb +36 -20
- data/lib/cosmos/tools/replay/replay_server.rb +1 -1
- data/lib/cosmos/tools/script_runner/script_runner_config.rb +1 -1
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +31 -21
- data/lib/cosmos/tools/table_manager/table_config.rb +9 -3
- data/lib/cosmos/tools/table_manager/table_manager.rb +27 -7
- data/lib/cosmos/tools/test_runner/results_writer.rb +6 -6
- data/lib/cosmos/tools/test_runner/test_runner.rb +4 -6
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor.rb +4 -5
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_config.rb +1 -1
- data/lib/cosmos/tools/tlm_extractor/tlm_extractor_processor.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +23 -6
- data/lib/cosmos/tools/tlm_grapher/data_object_editors/housekeeping_data_object_editor.rb +44 -3
- data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +20 -7
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots/overview_tabbed_plots.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +11 -4
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_plot_editor.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_realtime_thread.rb +1 -1
- data/lib/cosmos/tools/tlm_grapher/tlm_grapher.rb +16 -0
- data/lib/cosmos/tools/tlm_viewer/screen.rb +36 -32
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +59 -50
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +2 -2
- data/lib/cosmos/tools/tlm_viewer/widgets.rb +1 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/canvasvalue_widget.rb +1 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/labelvalue_widget.rb +22 -4
- data/lib/cosmos/tools/tlm_viewer/widgets/matrixbycolumns_widget.rb +9 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/spacer_widget.rb +55 -0
- data/lib/cosmos/tools/tlm_viewer/widgets/vertical_widget.rb +3 -2
- data/lib/cosmos/tools/tlm_viewer/widgets/verticalbox_widget.rb +3 -2
- data/lib/cosmos/tools/tlm_viewer/widgets/widget.rb +12 -12
- data/lib/cosmos/top_level.rb +34 -24
- data/lib/cosmos/utilities/crc.rb +108 -6
- data/lib/cosmos/utilities/csv.rb +68 -14
- data/lib/cosmos/utilities/logger.rb +2 -2
- data/lib/cosmos/utilities/low_fragmentation_array.rb +9 -1
- data/lib/cosmos/version.rb +6 -6
- data/lib/cosmos/win32/win32_main.rb +50 -46
- data/run_gui_tests.bat +3 -1
- data/spec/conversions/unix_time_formatted_conversion_spec.rb +2 -2
- data/spec/conversions/unix_time_seconds_conversion_spec.rb +2 -2
- data/spec/core_ext/file_spec.rb +1 -1
- data/spec/core_ext/objectspace_spec.rb +12 -9
- data/spec/core_ext/string_spec.rb +6 -0
- data/spec/core_ext/time_spec.rb +10 -0
- data/spec/gui/line_graph/line_clip_spec.rb +226 -224
- data/spec/gui/qt_spec.rb +81 -79
- data/spec/install/config/system/system.txt +0 -6
- data/spec/install/config/targets/INST/cmd_tlm/inst_cmd_linc.txt +5 -5
- data/spec/install/config/targets/INST/cmd_tlm/inst_tlm_linc.txt +8 -8
- data/spec/install/config/targets/SYSTEM/cmd_tlm/meta_cmd_tlm.txt +16 -0
- data/{install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt → spec/install/config/targets/SYSTEM/cmd_tlm/system_cmds.txt} +8 -8
- data/spec/install/config/targets/SYSTEM/cmd_tlm/system_tlm.txt +7 -0
- data/spec/install/config/targets/{COSMOS → SYSTEM}/cmd_tlm_server.txt +2 -2
- data/spec/install/config/targets/SYSTEM/screens/status.txt +12 -0
- data/spec/install/config/targets/SYSTEM/target.txt +12 -0
- data/spec/interfaces/cmd_tlm_server_interface_spec.rb +9 -13
- data/spec/interfaces/interface_spec.rb +402 -18
- data/spec/interfaces/linc_interface_spec.rb +37 -39
- data/spec/interfaces/protocols/burst_protocol_spec.rb +300 -0
- data/spec/interfaces/protocols/crc_protocol_spec.rb +709 -0
- data/spec/interfaces/protocols/fixed_protocol_spec.rb +119 -0
- data/spec/interfaces/protocols/length_protocol_spec.rb +499 -0
- data/spec/interfaces/protocols/override_protocol_spec.rb +158 -0
- data/spec/interfaces/protocols/preidentified_protocol_spec.rb +149 -0
- data/spec/interfaces/protocols/template_protocol_spec.rb +218 -0
- data/spec/interfaces/protocols/terminated_protocol_spec.rb +174 -0
- data/spec/interfaces/serial_interface_spec.rb +35 -34
- data/spec/interfaces/simulated_target_interface_spec.rb +13 -13
- data/spec/interfaces/tcpip_client_interface_spec.rb +21 -16
- data/spec/interfaces/tcpip_server_interface_spec.rb +66 -69
- data/spec/interfaces/udp_interface_spec.rb +120 -55
- data/spec/io/serial_driver_spec.rb +41 -39
- data/spec/io/udp_sockets_spec.rb +13 -8
- data/spec/io/win32_serial_driver_spec.rb +62 -59
- data/spec/packet_logs/packet_log_reader_spec.rb +68 -47
- data/spec/packet_logs/packet_log_writer_spec.rb +7 -5
- data/spec/packets/commands_spec.rb +5 -5
- data/spec/packets/packet_spec.rb +2 -14
- data/spec/script/extract_spec.rb +21 -7
- data/spec/script/scripting_spec.rb +261 -6
- data/spec/script/telemetry_spec.rb +17 -9
- data/spec/spec_helper.rb +26 -10
- data/spec/streams/serial_stream_spec.rb +87 -82
- data/spec/streams/tcpip_client_stream_spec.rb +12 -4
- data/spec/streams/tcpip_socket_stream_spec.rb +5 -0
- data/spec/system/system_spec.rb +66 -50
- data/spec/system/target_spec.rb +33 -11
- data/spec/tools/cmd_tlm_server/api_spec.rb +5 -5
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +75 -15
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_config_spec.rb +125 -5
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +244 -232
- data/spec/tools/cmd_tlm_server/commanding_spec.rb +18 -18
- data/spec/tools/cmd_tlm_server/interface_thread_spec.rb +124 -29
- data/spec/tools/cmd_tlm_server/interfaces_spec.rb +2 -2
- data/spec/tools/cmd_tlm_server/limits_groups_background_task_spec.rb +145 -0
- data/spec/tools/cmd_tlm_server/router_thread_spec.rb +50 -10
- data/spec/tools/table_manager/tablemanager_core_spec.rb +0 -1
- data/spec/top_level/top_level_spec.rb +39 -11
- data/spec/utilities/csv_spec.rb +62 -20
- data/tasks/gemfile_stats.rake +6 -3
- data/test/performance/config/system/system_packets.txt +0 -1
- data/test/performance/config/system/system_threads.txt +0 -1
- metadata +177 -92
- data/autohotkey/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/autohotkey/config/targets/COSMOS/cmd_tlm_server.txt +0 -6
- data/autohotkey/config/targets/COSMOS/target.txt +0 -5
- data/autohotkey/userpath.txt +0 -1
- data/demo/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/demo/config/targets/COSMOS/screens/limits_change.txt +0 -20
- data/demo/config/targets/COSMOS/screens/version.txt +0 -19
- data/demo/config/targets/COSMOS/target.txt +0 -11
- data/demo/config/targets/META/cmd_tlm/meta_cmd.txt +0 -10
- data/demo/config/targets/META/cmd_tlm/meta_tlm.txt +0 -13
- data/demo/userpath.txt +0 -1
- data/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/install/config/targets/COSMOS/cmd_tlm_server.txt +0 -6
- data/install/config/targets/COSMOS/screens/limits_change.txt +0 -20
- data/install/config/targets/COSMOS/screens/version.txt +0 -19
- data/install/config/targets/COSMOS/target.txt +0 -9
- data/install/config/targets/SYSTEM/README.txt +0 -1
- data/install/userpath.txt +0 -1
- data/lib/cosmos/io/tcpip_server.rb +0 -571
- data/lib/cosmos/packet_logs/meta_packet_log_writer.rb +0 -107
- data/lib/cosmos/streams/burst_stream_protocol.rb +0 -25
- data/lib/cosmos/streams/preidentified_stream_protocol.rb +0 -118
- data/lib/cosmos/streams/stream_protocol.rb +0 -373
- data/lib/cosmos/streams/template_stream_protocol.rb +0 -140
- data/lib/cosmos/streams/terminated_stream_protocol.rb +0 -85
- data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_cmds.txt +0 -41
- data/spec/install/config/targets/COSMOS/cmd_tlm/cosmos_server_tlm.txt +0 -15
- data/spec/install/config/targets/COSMOS/screens/limits_change.txt +0 -20
- data/spec/install/config/targets/COSMOS/screens/version.txt +0 -19
- data/spec/install/config/targets/COSMOS/target.txt +0 -5
- data/spec/install/config/targets/META/cmd_tlm/meta_cmd.txt +0 -4
- data/spec/install/config/targets/META/cmd_tlm/meta_tlm.txt +0 -4
- data/spec/install/userpath.txt +0 -1
- data/spec/interfaces/stream_interface_spec.rb +0 -157
- data/spec/io/tcpip_server_spec.rb +0 -338
- data/spec/packet_logs/meta_packet_log_writer_spec.rb +0 -170
- data/spec/streams/burst_stream_protocol_spec.rb +0 -32
- data/spec/streams/fixed_stream_protocol_spec.rb +0 -113
- data/spec/streams/length_stream_protocol_spec.rb +0 -300
- data/spec/streams/preidentified_stream_protocol_spec.rb +0 -121
- data/spec/streams/stream_protocol_spec.rb +0 -346
- data/spec/streams/template_stream_protocol_spec.rb +0 -156
- data/spec/streams/terminated_stream_protocol_spec.rb +0 -127
- data/test/performance/userpath.txt +0 -1
@@ -38,6 +38,8 @@ module Cosmos
|
|
38
38
|
router = TcpipServerInterface.new(port, port, 10.0, nil, 'PREIDENTIFIED')
|
39
39
|
router.name = router_name
|
40
40
|
router.disable_disconnect = true
|
41
|
+
router.set_option('LISTEN_ADDRESS', [System.listen_hosts['CTS_PREIDENTIFIED']])
|
42
|
+
router.set_option('AUTO_SYSTEM_META', [true])
|
41
43
|
@config.routers[router_name] = router
|
42
44
|
@config.interfaces.each do |interface_name, interface|
|
43
45
|
router.interfaces << interface
|
@@ -56,6 +58,8 @@ module Cosmos
|
|
56
58
|
cmd_router = TcpipServerInterface.new(port, nil, 10.0, nil, 'PREIDENTIFIED')
|
57
59
|
cmd_router.name = cmd_router_name
|
58
60
|
cmd_router.disable_disconnect = true
|
61
|
+
cmd_router.set_option('LISTEN_ADDRESS', [System.listen_hosts['CTS_CMD_ROUTER']])
|
62
|
+
cmd_router.set_option('AUTO_SYSTEM_META', [true])
|
59
63
|
@config.routers[cmd_router_name] = cmd_router
|
60
64
|
@config.interfaces.each do |interface_name, interface|
|
61
65
|
interface.cmd_routers << cmd_router
|
@@ -92,15 +96,15 @@ module Cosmos
|
|
92
96
|
|
93
97
|
# Get info about an router by name
|
94
98
|
#
|
95
|
-
# @return [Array<String, Numeric, Numeric, Numeric, Numeric, Numeric,
|
96
|
-
# Numeric, Numeric>] Array containing \[state, num_clients,
|
97
|
-
# write_queue_size, read_queue_size, bytes_written, bytes_read,
|
99
|
+
# @return [Array<String, Numeric, Numeric, Numeric, Numeric, Numeric,
|
100
|
+
# Numeric, Numeric>] Array containing \[state, num_clients,
|
101
|
+
# write_queue_size, read_queue_size, bytes_written, bytes_read,
|
98
102
|
# read_count, write_count] for the interface
|
99
103
|
def get_info(router_name)
|
100
104
|
router = @config.routers[router_name.upcase]
|
101
105
|
raise "Unknown router: #{router_name}" unless router
|
102
106
|
|
103
|
-
return [state(router_name), router.num_clients,
|
107
|
+
return [state(router_name), router.num_clients,
|
104
108
|
router.write_queue_size, router.read_queue_size,
|
105
109
|
router.bytes_written, router.bytes_read,
|
106
110
|
router.read_count, router.write_count]
|
@@ -0,0 +1,720 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2014 Ball Aerospace & Technologies Corp.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
|
11
|
+
require 'cosmos'
|
12
|
+
Cosmos.catch_fatal_exception do
|
13
|
+
require 'cosmos/gui/qt_tool'
|
14
|
+
require 'cosmos/tools/config_editor/config_editor_frame'
|
15
|
+
require 'cosmos/gui/dialogs/progress_dialog'
|
16
|
+
require 'cosmos/gui/dialogs/scroll_text_dialog'
|
17
|
+
end
|
18
|
+
|
19
|
+
module Cosmos
|
20
|
+
|
21
|
+
class ConfigEditor < QtTool
|
22
|
+
slots 'handle_tab_change(int)'
|
23
|
+
slots 'context_menu(const QPoint&)'
|
24
|
+
slots 'undo_available(bool)'
|
25
|
+
|
26
|
+
UNTITLED = 'Untitled'
|
27
|
+
UNTITLED_TAB_TEXT = " #{UNTITLED} "
|
28
|
+
# Mapping of the human readable configuration name to an array containing the
|
29
|
+
# yaml file name and typical location of the configuration file
|
30
|
+
CONFIGURATION_FILES = {
|
31
|
+
"System Configuration" =>
|
32
|
+
["system", "/config/system/system.txt"],
|
33
|
+
"Target Configuration" =>
|
34
|
+
["target", "/config/targets/TARGET/target.txt"],
|
35
|
+
"Server Configuration" =>
|
36
|
+
["cmd_tlm_server", "/config/tools/cmd_tlm_server/cmd_tlm_server.txt"],
|
37
|
+
"Command and Telemetry Configuration" =>
|
38
|
+
["command_telemetry", "/config/targets/TARGET/cmd_tlm/*.txt"],
|
39
|
+
"Screen Definition" =>
|
40
|
+
["screen", "/config/targets/TARGET/screens/*.txt"],
|
41
|
+
"Separator" => [nil, nil],
|
42
|
+
"Data Viewer Configuration" =>
|
43
|
+
["data_viewer", "/config/tools/data_viewer/data_viewer.txt"],
|
44
|
+
"Handbook Creator Configuration" =>
|
45
|
+
["handbook_creator", "/config/tools/handbook_creator/handbook_creator.txt"],
|
46
|
+
"Launcher Configuration" =>
|
47
|
+
["launcher", "/config/tools/launcher/launcher.txt"],
|
48
|
+
"Limits Monitor Configuration" =>
|
49
|
+
["limits_monitor", "/config/tools/limits_monitor/limits_monitor.txt"],
|
50
|
+
"Script Runner Configuration" =>
|
51
|
+
["script_runner", "/config/tools/script_runner/script_runner.txt"],
|
52
|
+
"Table Manager Configuration" =>
|
53
|
+
["table_manager", "/config/tools/table_manager/table_manager.txt"],
|
54
|
+
"Test Runner Configuration" =>
|
55
|
+
["test_runner", "/config/tools/test_runner/test_runner.txt"],
|
56
|
+
"Telemetry Extractor Configuration" =>
|
57
|
+
["tlm_extractor", "/config/tools/tlm_extractor/tlm_extractor.txt"],
|
58
|
+
"Telemetry Grapher Configuration" =>
|
59
|
+
["tlm_grapher", "/config/tools/tlm_grapher/tlm_grapher.txt"],
|
60
|
+
"Telemetry Viewer Configuration" =>
|
61
|
+
["tlm_viewer", "/config/tools/tlm_viewer/tlm_viewer.txt"],
|
62
|
+
}
|
63
|
+
|
64
|
+
def initialize(options)
|
65
|
+
# All code before super is executed twice in RubyQt Based classes
|
66
|
+
super(options) # MUST BE FIRST
|
67
|
+
Cosmos.load_cosmos_icon("config_editor.png")
|
68
|
+
setAcceptDrops(true) # Allow dropping in files
|
69
|
+
|
70
|
+
@procedure_dir = Cosmos::USERPATH
|
71
|
+
@file_type = "none"
|
72
|
+
|
73
|
+
initialize_actions()
|
74
|
+
initialize_menus()
|
75
|
+
initialize_central_widget()
|
76
|
+
complete_initialize()
|
77
|
+
|
78
|
+
create_tab()
|
79
|
+
end
|
80
|
+
|
81
|
+
def initialize_actions
|
82
|
+
super()
|
83
|
+
|
84
|
+
# File actions
|
85
|
+
@file_new = Qt::Action.new(Cosmos.get_icon('file.png'), tr('&New'), self)
|
86
|
+
@file_new_keyseq = Qt::KeySequence.new(tr('Ctrl+N'))
|
87
|
+
@file_new.shortcut = @file_new_keyseq
|
88
|
+
@file_new.statusTip = tr('Start a new file')
|
89
|
+
@file_new.connect(SIGNAL('triggered()')) { file_new() }
|
90
|
+
|
91
|
+
@file_close = Qt::Action.new(tr('&Close'), self)
|
92
|
+
@file_close_keyseq = Qt::KeySequence.new(tr('Ctrl+W'))
|
93
|
+
@file_close.shortcut = @file_close_keyseq
|
94
|
+
@file_close.statusTip = tr('Close the file')
|
95
|
+
@file_close.connect(SIGNAL('triggered()')) { file_close() }
|
96
|
+
|
97
|
+
@file_reload = Qt::Action.new(tr('&Reload'), self)
|
98
|
+
@file_reload_keyseq = Qt::KeySequence.new(tr('Ctrl+R'))
|
99
|
+
@file_reload.shortcut = @file_reload_keyseq
|
100
|
+
@file_reload.statusTip = tr('Reload a file')
|
101
|
+
@file_reload.connect(SIGNAL('triggered()')) { file_reload() }
|
102
|
+
|
103
|
+
@file_save = Qt::Action.new(Cosmos.get_icon('save.png'), tr('&Save'), self)
|
104
|
+
@file_save_keyseq = Qt::KeySequence.new(tr('Ctrl+S'))
|
105
|
+
@file_save.shortcut = @file_save_keyseq
|
106
|
+
@file_save.statusTip = tr('Save the file')
|
107
|
+
@file_save.connect(SIGNAL('triggered()')) { file_save(false) }
|
108
|
+
|
109
|
+
@file_save_as = Qt::Action.new(Cosmos.get_icon('save_as.png'), tr('Save &As'), self)
|
110
|
+
@file_save_as.statusTip = tr('Save the file')
|
111
|
+
@file_save_as.connect(SIGNAL('triggered()')) { file_save(true) }
|
112
|
+
|
113
|
+
# Edit actions
|
114
|
+
@edit_undo = Qt::Action.new(Cosmos.get_icon('undo.png'), tr('&Undo'), self)
|
115
|
+
@edit_undo_keyseq = Qt::KeySequence.new(tr('Ctrl+Z'))
|
116
|
+
@edit_undo.shortcut = @edit_undo_keyseq
|
117
|
+
@edit_undo.statusTip = tr('Undo')
|
118
|
+
@edit_undo.connect(SIGNAL('triggered()')) { active_config_editor_frame().undo }
|
119
|
+
|
120
|
+
@edit_redo = Qt::Action.new(Cosmos.get_icon('redo.png'), tr('&Redo'), self)
|
121
|
+
@edit_redo_keyseq = Qt::KeySequence.new(tr('Ctrl+Y'))
|
122
|
+
@edit_redo.shortcut = @edit_redo_keyseq
|
123
|
+
@edit_redo.statusTip = tr('Redo')
|
124
|
+
@edit_redo.connect(SIGNAL('triggered()')) { active_config_editor_frame().redo }
|
125
|
+
|
126
|
+
@edit_cut = Qt::Action.new(Cosmos.get_icon('cut.png'), tr('Cu&t'), self)
|
127
|
+
@edit_cut_keyseq = Qt::KeySequence.new(tr('Ctrl+X'))
|
128
|
+
@edit_cut.shortcut = @edit_cut_keyseq
|
129
|
+
@edit_cut.statusTip = tr('Cut')
|
130
|
+
@edit_cut.connect(SIGNAL('triggered()')) { active_config_editor_frame().cut }
|
131
|
+
|
132
|
+
@edit_copy = Qt::Action.new(Cosmos.get_icon('copy.png'), tr('&Copy'), self)
|
133
|
+
@edit_copy_keyseq = Qt::KeySequence.new(tr('Ctrl+C'))
|
134
|
+
@edit_copy.shortcut = @edit_copy_keyseq
|
135
|
+
@edit_copy.statusTip = tr('Copy')
|
136
|
+
@edit_copy.connect(SIGNAL('triggered()')) { active_config_editor_frame().copy }
|
137
|
+
|
138
|
+
@edit_paste = Qt::Action.new(tr('&Paste'), self)
|
139
|
+
@edit_paste_keyseq = Qt::KeySequence.new(tr('Ctrl+V'))
|
140
|
+
@edit_paste.shortcut = @edit_paste_keyseq
|
141
|
+
@edit_paste.statusTip = tr('Paste')
|
142
|
+
@edit_paste.connect(SIGNAL('triggered()')) { active_config_editor_frame().paste }
|
143
|
+
|
144
|
+
@edit_select_all = Qt::Action.new(tr('Select &All'), self)
|
145
|
+
@edit_select_all_keyseq = Qt::KeySequence.new(tr('Ctrl+A'))
|
146
|
+
@edit_select_all.shortcut = @edit_select_all_keyseq
|
147
|
+
@edit_select_all.statusTip = tr('Select All')
|
148
|
+
@edit_select_all.connect(SIGNAL('triggered()')) { active_config_editor_frame().select_all }
|
149
|
+
|
150
|
+
@edit_comment = Qt::Action.new(tr('Comment/Uncomment &Lines'), self)
|
151
|
+
@edit_comment_keyseq = Qt::KeySequence.new(tr('Ctrl+K'))
|
152
|
+
@edit_comment.shortcut = @edit_comment_keyseq
|
153
|
+
@edit_comment.statusTip = tr('Comment/Uncomment Lines')
|
154
|
+
@edit_comment.connect(SIGNAL('triggered()')) { active_config_editor_frame().comment_or_uncomment_lines }
|
155
|
+
|
156
|
+
# Search Actions
|
157
|
+
@search_find = Qt::Action.new(Cosmos.get_icon('search.png'), tr('&Find'), self)
|
158
|
+
@search_find_keyseq = Qt::KeySequence.new(tr('Ctrl+F'))
|
159
|
+
@search_find.shortcut = @search_find_keyseq
|
160
|
+
@search_find.statusTip = tr('Find text')
|
161
|
+
@search_find.connect(SIGNAL('triggered()')) do
|
162
|
+
FindReplaceDialog.show_find(self)
|
163
|
+
end
|
164
|
+
|
165
|
+
@search_find_next = Qt::Action.new(tr('Find &Next'), self)
|
166
|
+
@search_find_next_keyseq = Qt::KeySequence.new(tr('F3'))
|
167
|
+
@search_find_next.shortcut = @search_find_next_keyseq
|
168
|
+
@search_find_next.statusTip = tr('Find next instance')
|
169
|
+
@search_find_next.connect(SIGNAL('triggered()')) do
|
170
|
+
FindReplaceDialog.find_next(self)
|
171
|
+
end
|
172
|
+
|
173
|
+
@search_find_previous = Qt::Action.new(tr('Find &Previous'), self)
|
174
|
+
@search_find_previous_keyseq = Qt::KeySequence.new(tr('Shift+F3'))
|
175
|
+
@search_find_previous.shortcut = @search_find_previous_keyseq
|
176
|
+
@search_find_previous.statusTip = tr('Find previous instance')
|
177
|
+
@search_find_previous.connect(SIGNAL('triggered()')) do
|
178
|
+
FindReplaceDialog.find_previous(self)
|
179
|
+
end
|
180
|
+
|
181
|
+
@search_replace = Qt::Action.new(tr('&Replace'), self)
|
182
|
+
@search_replace_keyseq = Qt::KeySequence.new(tr('Ctrl+H'))
|
183
|
+
@search_replace.shortcut = @search_replace_keyseq
|
184
|
+
@search_replace.statusTip = tr('Replace')
|
185
|
+
@search_replace.connect(SIGNAL('triggered()')) do
|
186
|
+
FindReplaceDialog.show_replace(self)
|
187
|
+
end
|
188
|
+
|
189
|
+
@type_group = Qt::ActionGroup.new(self)
|
190
|
+
CONFIGURATION_FILES.each do |name, info|
|
191
|
+
if name == 'Separator'
|
192
|
+
action = Qt::Action.new(@type_group)
|
193
|
+
action.setSeparator(true)
|
194
|
+
else
|
195
|
+
action = Qt::Action.new(name, @type_group)
|
196
|
+
action.statusTip = info[1] # Path
|
197
|
+
action.setCheckable(true)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
# Throw Unknown on the end after a separator
|
201
|
+
action = Qt::Action.new(@type_group)
|
202
|
+
action.setSeparator(true)
|
203
|
+
action = Qt::Action.new("Unknown", @type_group)
|
204
|
+
action.setCheckable(true)
|
205
|
+
|
206
|
+
@type_group.connect(SIGNAL('triggered(QAction*)')) do |action|
|
207
|
+
active_config_editor_frame.set_file_type(action.text)
|
208
|
+
update_cursor()
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def initialize_menus
|
213
|
+
# File Menu
|
214
|
+
@file_menu = menuBar.addMenu(tr('&File'))
|
215
|
+
@file_menu.addAction(@file_new)
|
216
|
+
|
217
|
+
open_action = Qt::Action.new(self)
|
218
|
+
open_action.shortcut = Qt::KeySequence.new(tr('Ctrl+O'))
|
219
|
+
open_action.connect(SIGNAL('triggered()')) { file_open(@procedure_dir) }
|
220
|
+
self.addAction(open_action)
|
221
|
+
|
222
|
+
@file_open = @file_menu.addMenu(tr('&Open'))
|
223
|
+
@file_open.setIcon(Cosmos.get_icon('open.png'))
|
224
|
+
target_dirs_action(@file_open, File.join(Cosmos::USERPATH,'config'), '', method(:file_open))
|
225
|
+
|
226
|
+
@file_menu.addAction(@file_close)
|
227
|
+
@file_menu.addAction(@file_reload)
|
228
|
+
@file_menu.addSeparator()
|
229
|
+
@file_menu.addAction(@file_save)
|
230
|
+
@file_menu.addAction(@file_save_as)
|
231
|
+
@file_menu.addSeparator()
|
232
|
+
@file_menu.addAction(@exit_action)
|
233
|
+
|
234
|
+
# Edit Menu
|
235
|
+
mode_menu = menuBar.addMenu(tr('&Edit'))
|
236
|
+
mode_menu.addAction(@edit_undo)
|
237
|
+
mode_menu.addAction(@edit_redo)
|
238
|
+
mode_menu.addSeparator()
|
239
|
+
mode_menu.addAction(@edit_cut)
|
240
|
+
mode_menu.addAction(@edit_copy)
|
241
|
+
mode_menu.addAction(@edit_paste)
|
242
|
+
mode_menu.addSeparator()
|
243
|
+
mode_menu.addAction(@edit_select_all)
|
244
|
+
mode_menu.addSeparator()
|
245
|
+
mode_menu.addAction(@edit_comment)
|
246
|
+
|
247
|
+
# Search Menu
|
248
|
+
view_menu = menuBar.addMenu(tr('&Search'))
|
249
|
+
view_menu.addAction(@search_find)
|
250
|
+
view_menu.addAction(@search_find_next)
|
251
|
+
view_menu.addAction(@search_find_previous)
|
252
|
+
view_menu.addAction(@search_replace)
|
253
|
+
|
254
|
+
# File Type Menu
|
255
|
+
type_menu = menuBar.addMenu(tr('File &Type'))
|
256
|
+
type_menu.addActions(@type_group.actions)
|
257
|
+
|
258
|
+
# Help Menu
|
259
|
+
@about_string = "Config Editor allows the user to edit COSMOS configuration "\
|
260
|
+
"files with contextual help. "\
|
261
|
+
|
262
|
+
initialize_help_menu()
|
263
|
+
end
|
264
|
+
|
265
|
+
def initialize_central_widget
|
266
|
+
# Create a splitter to hold the file tree and tab widget
|
267
|
+
@splitter = Qt::Splitter.new(Qt::Horizontal, self)
|
268
|
+
|
269
|
+
@fs_model = Qt::FileSystemModel.new
|
270
|
+
@fs_model.setRootPath(Cosmos::USERPATH)
|
271
|
+
@tree_view = Qt::TreeView.new(@splitter)
|
272
|
+
@tree_view.setModel(@fs_model)
|
273
|
+
@tree_view.setRootIndex(@fs_model.index(Cosmos::USERPATH))
|
274
|
+
@tree_view.setColumnHidden(1, true) # Size
|
275
|
+
@tree_view.setColumnHidden(2, true) # Type
|
276
|
+
@tree_view.setColumnHidden(3, true) # Date Modified
|
277
|
+
@tree_view.connect(SIGNAL('activated(const QModelIndex&)')) do |index|
|
278
|
+
select_or_load_file(@fs_model.filePath(index))
|
279
|
+
end
|
280
|
+
@tree_view.connect(SIGNAL('clicked(const QModelIndex&)')) do |index|
|
281
|
+
select_or_load_file(@fs_model.filePath(index))
|
282
|
+
end
|
283
|
+
|
284
|
+
@tab_book = Qt::TabWidget.new(@splitter)
|
285
|
+
@tab_book.setMovable(true)
|
286
|
+
@tab_book.setContextMenuPolicy(Qt::CustomContextMenu)
|
287
|
+
connect(@tab_book,
|
288
|
+
SIGNAL('customContextMenuRequested(const QPoint&)'),
|
289
|
+
self,
|
290
|
+
SLOT('context_menu(const QPoint&)'))
|
291
|
+
connect(@tab_book,
|
292
|
+
SIGNAL('currentChanged(int)'),
|
293
|
+
self,
|
294
|
+
SLOT('handle_tab_change(int)'))
|
295
|
+
@splitter.setSizes([200, 800]) # Rough split of the widget
|
296
|
+
setCentralWidget(@splitter)
|
297
|
+
|
298
|
+
# Display a blank message to force the statusBar to show
|
299
|
+
statusBar.showMessage("")
|
300
|
+
@status_bar_right_label = Qt::Label.new
|
301
|
+
statusBar.addPermanentWidget(@status_bar_right_label)
|
302
|
+
end
|
303
|
+
|
304
|
+
def select_or_load_file(file_path)
|
305
|
+
return if File.directory?(file_path)
|
306
|
+
found = false
|
307
|
+
# If the file is already open select the tab
|
308
|
+
@tab_book.tabs.each_with_index do |tab, index|
|
309
|
+
if tab.filename == file_path
|
310
|
+
found = true
|
311
|
+
@tab_book.setCurrentIndex(index)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
file_open(file_path) unless found
|
315
|
+
end
|
316
|
+
|
317
|
+
def dragEnterEvent(event)
|
318
|
+
if event.mimeData.hasUrls
|
319
|
+
event.acceptProposedAction();
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def dragMoveEvent(event)
|
324
|
+
if event.mimeData.hasUrls
|
325
|
+
event.acceptProposedAction();
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def dropEvent(event)
|
330
|
+
event.mimeData.urls.each do |url|
|
331
|
+
filename = url.toLocalFile
|
332
|
+
extension = File.extname(filename).to_s.downcase
|
333
|
+
if extension == '.rb' or extension == '.txt'
|
334
|
+
file_open(filename)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
###########################################
|
340
|
+
# File Menu Options
|
341
|
+
###########################################
|
342
|
+
|
343
|
+
# File->New
|
344
|
+
def file_new
|
345
|
+
create_tab()
|
346
|
+
end
|
347
|
+
|
348
|
+
# File->Open
|
349
|
+
def file_open(filename = nil)
|
350
|
+
if File.directory?(filename)
|
351
|
+
filename = Qt::FileDialog.getOpenFileName(self, "Select File", filename)
|
352
|
+
end
|
353
|
+
unless filename.nil? || filename.empty?
|
354
|
+
# If the user opens a file we already have open
|
355
|
+
# just set the current tab to that file and return
|
356
|
+
@tab_book.tabs.each_with_index do |tab, index|
|
357
|
+
if tab.filename == filename
|
358
|
+
@tab_book.setCurrentIndex(index)
|
359
|
+
@tab_book.currentTab.set_text_from_file(filename)
|
360
|
+
@tab_book.currentTab.filename = filename
|
361
|
+
return
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
if ((@tab_book.count == 1) &&
|
366
|
+
@tab_book.currentTab.filename.empty? &&
|
367
|
+
!@tab_book.currentTab.modified)
|
368
|
+
# Active Tab is an unmodified Untitled so just open the file in it
|
369
|
+
@tab_book.currentTab.set_text_from_file(filename)
|
370
|
+
@tab_book.currentTab.filename = filename
|
371
|
+
@tab_book.setTabText(@tab_book.currentIndex, File.basename(filename))
|
372
|
+
else
|
373
|
+
create_tab(filename)
|
374
|
+
end
|
375
|
+
|
376
|
+
update_title()
|
377
|
+
@procedure_dir = File.dirname(filename)
|
378
|
+
@procedure_dir << '/' if @procedure_dir[-1..-1] != '/' and @procedure_dir[-1..-1] != '\\'
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
# File->Reload
|
383
|
+
def file_reload
|
384
|
+
safe_to_continue = true
|
385
|
+
if @tab_book.currentTab.modified
|
386
|
+
case Qt::MessageBox.question(self, # parent
|
387
|
+
'Discard Changes?', # title
|
388
|
+
'Warning: Changes will be lost. Continue?', # text
|
389
|
+
Qt::MessageBox::Yes | Qt::MessageBox::No, # buttons
|
390
|
+
Qt::MessageBox::No) # default button
|
391
|
+
when Qt::MessageBox::No
|
392
|
+
safe_to_continue = false
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
if safe_to_continue
|
397
|
+
if active_config_editor_frame().filename.empty?
|
398
|
+
active_config_editor_frame().set_text('')
|
399
|
+
else
|
400
|
+
active_config_editor_frame().set_text_from_file(active_config_editor_frame().filename)
|
401
|
+
end
|
402
|
+
@tab_book.currentTab.modified = false
|
403
|
+
update_title()
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
# File->Save and File->Save As
|
408
|
+
def file_save(save_as = false)
|
409
|
+
saved = false
|
410
|
+
filename = active_config_editor_frame().filename
|
411
|
+
if filename.empty?
|
412
|
+
filename = Qt::FileDialog::getSaveFileName(self, # parent
|
413
|
+
'Save As...', # caption
|
414
|
+
@procedure_dir + '/procedure.rb', # dir
|
415
|
+
'Procedure Files (*.rb)') # filter
|
416
|
+
elsif save_as
|
417
|
+
filename = Qt::FileDialog::getSaveFileName(self, # parent
|
418
|
+
'Save As...', # caption
|
419
|
+
filename, # dir
|
420
|
+
'Procedure Files (*.rb)') # filter
|
421
|
+
end
|
422
|
+
if not filename.nil? and not filename.empty?
|
423
|
+
begin
|
424
|
+
@tab_book.currentTab.filename = filename
|
425
|
+
@tab_book.currentTab.modified = false
|
426
|
+
@tab_book.setTabText(@tab_book.currentIndex, File.basename(filename))
|
427
|
+
active_config_editor_frame().filename = filename
|
428
|
+
File.open(filename, "w") {|file| file.write(active_config_editor_frame().text)}
|
429
|
+
saved = true
|
430
|
+
update_title()
|
431
|
+
statusBar.showMessage(tr("#{filename} saved"))
|
432
|
+
@procedure_dir = File.dirname(filename)
|
433
|
+
@procedure_dir << '/' if @procedure_dir[-1..-1] != '/' and @procedure_dir[-1..-1] != '\\'
|
434
|
+
rescue => error
|
435
|
+
statusBar.showMessage(tr("Error Saving File : #{error.class} : #{error.message}"))
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
return saved
|
440
|
+
end
|
441
|
+
|
442
|
+
# File->Close
|
443
|
+
def file_close
|
444
|
+
if prompt_for_save_if_needed('Save Current File?')
|
445
|
+
if @tab_book.count > 1
|
446
|
+
close_active_tab()
|
447
|
+
else
|
448
|
+
@tab_book.setTabText(0, UNTITLED_TAB_TEXT)
|
449
|
+
@tab_book.currentTab.clear
|
450
|
+
end
|
451
|
+
update_title()
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
###########################################
|
456
|
+
# Callbacks
|
457
|
+
###########################################
|
458
|
+
|
459
|
+
# Called by the FindReplaceDialog to get the text to search
|
460
|
+
def search_text
|
461
|
+
active_config_editor_frame().editor
|
462
|
+
end
|
463
|
+
|
464
|
+
def undo_available(bool)
|
465
|
+
update_title()
|
466
|
+
end
|
467
|
+
|
468
|
+
def closeEvent(event)
|
469
|
+
if prompt_for_save_if_needed_on_close()
|
470
|
+
super(event)
|
471
|
+
else
|
472
|
+
event.ignore()
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
def enable_menu_items
|
477
|
+
# Enable File Menu Items
|
478
|
+
@file_new.setEnabled(true)
|
479
|
+
@file_open.setEnabled(true)
|
480
|
+
@file_close.setEnabled(true)
|
481
|
+
@file_reload.setEnabled(true)
|
482
|
+
@file_save.setEnabled(true)
|
483
|
+
@file_save_as.setEnabled(true)
|
484
|
+
@file_options.setEnabled(true)
|
485
|
+
|
486
|
+
# Enable Edit Menu Items
|
487
|
+
@edit_undo.setEnabled(true)
|
488
|
+
@edit_redo.setEnabled(true)
|
489
|
+
@edit_cut.setEnabled(true)
|
490
|
+
@edit_copy.setEnabled(true)
|
491
|
+
@edit_paste.setEnabled(true)
|
492
|
+
@edit_select_all.setEnabled(true)
|
493
|
+
@edit_comment.setEnabled(true)
|
494
|
+
end
|
495
|
+
|
496
|
+
def disable_menu_items
|
497
|
+
# Disable File Menu Items
|
498
|
+
@file_new.setEnabled(false)
|
499
|
+
@file_open.setEnabled(false)
|
500
|
+
@file_close.setEnabled(false)
|
501
|
+
@file_reload.setEnabled(false)
|
502
|
+
@file_save.setEnabled(false)
|
503
|
+
@file_save_as.setEnabled(false)
|
504
|
+
@file_options.setEnabled(false)
|
505
|
+
|
506
|
+
# Disable Edit Menu Items
|
507
|
+
@edit_undo.setEnabled(false)
|
508
|
+
@edit_redo.setEnabled(false)
|
509
|
+
@edit_cut.setEnabled(false)
|
510
|
+
@edit_copy.setEnabled(false)
|
511
|
+
@edit_paste.setEnabled(false)
|
512
|
+
@edit_select_all.setEnabled(false)
|
513
|
+
@edit_comment.setEnabled(false)
|
514
|
+
end
|
515
|
+
|
516
|
+
# Handle the user changing tabs
|
517
|
+
def handle_tab_change(index)
|
518
|
+
update_title()
|
519
|
+
update_type_group()
|
520
|
+
update_tree()
|
521
|
+
end
|
522
|
+
|
523
|
+
def handle_script_keypress(event)
|
524
|
+
update_title()
|
525
|
+
if event.matches(Qt::KeySequence::NextChild)
|
526
|
+
index = @tab_book.currentIndex + 1
|
527
|
+
index = 0 if index >= @tab_book.count
|
528
|
+
@tab_book.setCurrentIndex(index)
|
529
|
+
elsif event.matches(Qt::KeySequence::PreviousChild)
|
530
|
+
index = @tab_book.currentIndex - 1
|
531
|
+
index = @tab_book.count - 1 if index < 0
|
532
|
+
@tab_book.setCurrentIndex(index)
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
def context_menu(point)
|
537
|
+
index = 0
|
538
|
+
@tab_book.tabBar.count.times do
|
539
|
+
break if @tab_book.tabBar.tabRect(index).contains(point)
|
540
|
+
index += 1
|
541
|
+
end
|
542
|
+
|
543
|
+
return if (index == @tab_book.tabBar.count)
|
544
|
+
|
545
|
+
# Bring the right clicked tab to the front
|
546
|
+
@tab_book.setCurrentIndex(index)
|
547
|
+
|
548
|
+
menu = Qt::Menu.new()
|
549
|
+
|
550
|
+
new_action = Qt::Action.new(tr("&New"), self)
|
551
|
+
new_action.statusTip = tr("Create a new file")
|
552
|
+
new_action.connect(SIGNAL('triggered()')) { file_new() }
|
553
|
+
menu.addAction(new_action)
|
554
|
+
|
555
|
+
close_action = Qt::Action.new(tr("&Close"), self)
|
556
|
+
close_action.statusTip = tr("Close the file")
|
557
|
+
close_action.connect(SIGNAL('triggered()')) { file_close() }
|
558
|
+
menu.addAction(close_action)
|
559
|
+
|
560
|
+
save_action = Qt::Action.new(tr("&Save"), self)
|
561
|
+
save_action.statusTip = tr("Save the file")
|
562
|
+
save_action.connect(SIGNAL('triggered()')) { file_save(false) }
|
563
|
+
menu.addAction(save_action)
|
564
|
+
|
565
|
+
save_action = Qt::Action.new(tr("Save &As"), self)
|
566
|
+
save_action.statusTip = tr("Save the file as")
|
567
|
+
save_action.connect(SIGNAL('triggered()')) { file_save(true) }
|
568
|
+
menu.addAction(save_action)
|
569
|
+
|
570
|
+
menu.exec(@tab_book.mapToGlobal(point))
|
571
|
+
menu.dispose
|
572
|
+
end
|
573
|
+
|
574
|
+
#############################################################
|
575
|
+
# Helper Methods
|
576
|
+
#############################################################
|
577
|
+
|
578
|
+
def show_message(message, right_label = nil)
|
579
|
+
statusBar.showMessage(message)
|
580
|
+
if right_label
|
581
|
+
@status_bar_right_label.text = right_label
|
582
|
+
else
|
583
|
+
@status_bar_right_label.text = ''
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
def update_cursor
|
588
|
+
num = active_config_editor_frame.line_number
|
589
|
+
col = active_config_editor_frame.column_number
|
590
|
+
status = "#{num}:#{col} #{active_config_editor_frame.line_keyword}"
|
591
|
+
show_message(status, active_config_editor_frame.file_type)
|
592
|
+
end
|
593
|
+
|
594
|
+
def update_type_group
|
595
|
+
@type_group.actions[-1].setChecked(true)
|
596
|
+
@type_group.actions.each do |action|
|
597
|
+
if action.text == active_config_editor_frame.file_type
|
598
|
+
action.setChecked(true)
|
599
|
+
end
|
600
|
+
end
|
601
|
+
update_cursor()
|
602
|
+
end
|
603
|
+
|
604
|
+
# Updates the title appropriately to show the tabs filename and modified status
|
605
|
+
def update_title
|
606
|
+
if @tab_book.currentTab.filename.empty?
|
607
|
+
self.setWindowTitle("Config Editor : #{UNTITLED}")
|
608
|
+
else
|
609
|
+
self.setWindowTitle("Config Editor : #{@tab_book.currentTab.filename}")
|
610
|
+
end
|
611
|
+
self.setWindowTitle(self.windowTitle << '*') if @tab_book.currentTab.modified
|
612
|
+
update_cursor()
|
613
|
+
end
|
614
|
+
|
615
|
+
def update_tree
|
616
|
+
@tree_view.setCurrentIndex(@fs_model.index(@tab_book.currentTab.filename))
|
617
|
+
end
|
618
|
+
|
619
|
+
# Returns the frame of the active tab
|
620
|
+
def active_config_editor_frame
|
621
|
+
@tab_book.currentTab
|
622
|
+
end
|
623
|
+
|
624
|
+
# Creates a new tab
|
625
|
+
def create_tab(filename = '')
|
626
|
+
if filename.empty?
|
627
|
+
tab_item_name = UNTITLED_TAB_TEXT
|
628
|
+
else
|
629
|
+
tab_item_name = ' ' + File.basename(filename) + ' '
|
630
|
+
end
|
631
|
+
|
632
|
+
config_editor_frame = ConfigEditorFrame.new(self)
|
633
|
+
config_editor_frame.setContentsMargins(5,5,5,5)
|
634
|
+
connect(config_editor_frame,
|
635
|
+
SIGNAL('undoAvailable(bool)'),
|
636
|
+
self,
|
637
|
+
SLOT('undo_available(bool)'))
|
638
|
+
config_editor_frame.set_text_from_file(filename) unless filename.empty?
|
639
|
+
config_editor_frame.filename = filename
|
640
|
+
# Register a keypress handler so we can Ctrl-Tab our way through the tabs
|
641
|
+
config_editor_frame.key_press_callback = method(:handle_script_keypress)
|
642
|
+
# Update the title if the frame changes so we can add/remove the asterix
|
643
|
+
config_editor_frame.connect(SIGNAL('modificationChanged(bool)')) { update_title() }
|
644
|
+
config_editor_frame.connect(SIGNAL('cursorPositionChanged()')) { update_cursor() }
|
645
|
+
config_editor_frame.connect(SIGNAL('file_type_changed()')) { update_type_group() }
|
646
|
+
|
647
|
+
@tab_book.addTab(config_editor_frame, tab_item_name)
|
648
|
+
@tab_book.setCurrentIndex(@tab_book.count-1) # index is 0 based
|
649
|
+
# Set the focus on the input now that we've added the tab
|
650
|
+
config_editor_frame.setFocus
|
651
|
+
update_title()
|
652
|
+
end
|
653
|
+
|
654
|
+
# Closes the active tab
|
655
|
+
def close_active_tab
|
656
|
+
if @tab_book.count > 1
|
657
|
+
tab_index = @tab_book.currentIndex
|
658
|
+
@tab_book.removeTab(tab_index)
|
659
|
+
if tab_index >= 1
|
660
|
+
@tab_book.setCurrentIndex(tab_index - 1)
|
661
|
+
else
|
662
|
+
@tab_book.setCurrentIndex(0)
|
663
|
+
end
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
# Prompts for save if the current tab has been modified
|
668
|
+
def prompt_for_save_if_needed(message = 'Save?')
|
669
|
+
safe_to_continue = true
|
670
|
+
if @tab_book.currentTab.modified
|
671
|
+
case Qt::MessageBox.question(
|
672
|
+
self, # parent
|
673
|
+
'Save?', # title
|
674
|
+
message, # text
|
675
|
+
Qt::MessageBox::Yes | Qt::MessageBox::No | Qt::MessageBox::Cancel, # buttons
|
676
|
+
Qt::MessageBox::Cancel) # default button
|
677
|
+
when Qt::MessageBox::Cancel
|
678
|
+
safe_to_continue = false
|
679
|
+
when Qt::MessageBox::Yes
|
680
|
+
saved = file_save(false)
|
681
|
+
if not saved
|
682
|
+
safe_to_continue = false
|
683
|
+
end
|
684
|
+
end
|
685
|
+
end
|
686
|
+
return safe_to_continue
|
687
|
+
end
|
688
|
+
|
689
|
+
# Prompts the user that unsaved changes have been made before they close the app
|
690
|
+
def prompt_for_save_if_needed_on_close
|
691
|
+
safe_to_continue = true
|
692
|
+
@tab_book.tabs.each_with_index do |tab, index|
|
693
|
+
if tab.modified
|
694
|
+
@tab_book.setCurrentIndex(index)
|
695
|
+
if tab.filename.empty?
|
696
|
+
message = "Save changes to '#{UNTITLED}'?"
|
697
|
+
else
|
698
|
+
message = "Save changes to '#{tab.filename}'?"
|
699
|
+
end
|
700
|
+
safe_to_continue = prompt_for_save_if_needed(message)
|
701
|
+
#~ break unless safe_to_continue
|
702
|
+
end
|
703
|
+
end
|
704
|
+
return safe_to_continue
|
705
|
+
end
|
706
|
+
|
707
|
+
def self.run(option_parser = nil, options = nil)
|
708
|
+
Cosmos.catch_fatal_exception do
|
709
|
+
unless option_parser and options
|
710
|
+
option_parser, options = create_default_options()
|
711
|
+
options.width = 80
|
712
|
+
options.height = 600
|
713
|
+
options.title = "Config Editor : #{UNTITLED}"
|
714
|
+
options.auto_size = false
|
715
|
+
end
|
716
|
+
super(option_parser, options)
|
717
|
+
end
|
718
|
+
end
|
719
|
+
end
|
720
|
+
end
|