cosmos 3.8.3 → 3.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/Manifest.txt +14 -0
- data/Rakefile +35 -2
- data/autohotkey/config/targets/INST/screens/_footer.txt +4 -0
- data/autohotkey/config/targets/INST/screens/hs.txt +1 -4
- data/autohotkey/config/tools/table_manager/OldOneDimensionalTable_def.txt +19 -0
- data/autohotkey/config/tools/table_manager/OldTwoDimensionalTable_def.txt +248 -0
- data/autohotkey/config/tools/table_manager/OneDimensionalTable_def.txt +27 -15
- data/autohotkey/config/tools/table_manager/TwoDimensionalTable_def.txt +12 -232
- data/autohotkey/procedures/example_test.rb +4 -0
- data/autohotkey/tools/TableManagerAHK +4 -9
- data/autohotkey/tools/TableManagerAHK2 +18 -0
- data/autohotkey/tools/TableManagerAHK3 +18 -0
- data/autohotkey/tools/TableManagerAHK4 +24 -0
- data/autohotkey/tools/TlmViewerAHK +1 -1
- data/autohotkey/tools/autohotkey.rb +2 -1
- data/autohotkey/tools/open_gl_builder.ahk +1 -1
- data/autohotkey/tools/table_manager.ahk +141 -70
- data/cosmos.gemspec +3 -3
- data/data/crc.txt +70 -68
- data/data/legal.txt +4 -5
- data/demo/config/data/crc.txt +10 -9
- data/demo/config/targets/INST/screens/_footer.txt +4 -0
- data/demo/config/targets/INST/screens/hs.txt +1 -6
- data/demo/config/targets/INST/screens/limits.txt +3 -11
- data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +33 -22
- data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +30 -22
- data/demo/config/tools/table_manager/PPSSelectionTable_def.txt +8 -7
- data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +13 -13
- data/demo/lib/example_background_task.rb +6 -12
- data/demo/procedures/example_test.rb +5 -0
- data/lib/cosmos/conversions/conversion.rb +3 -7
- data/lib/cosmos/core_ext/class.rb +3 -1
- data/lib/cosmos/core_ext/file.rb +1 -0
- data/lib/cosmos/core_ext/io.rb +18 -0
- data/lib/cosmos/core_ext/range.rb +1 -5
- data/lib/cosmos/core_ext/time.rb +3 -3
- data/lib/cosmos/gui/dialogs/about_dialog.rb +60 -36
- data/lib/cosmos/gui/dialogs/calendar_dialog.rb +10 -14
- data/lib/cosmos/gui/dialogs/cmd_details_dialog.rb +4 -5
- data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +31 -17
- data/lib/cosmos/gui/dialogs/details_dialog.rb +63 -47
- data/lib/cosmos/gui/dialogs/exception_dialog.rb +77 -68
- data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +6 -5
- data/lib/cosmos/gui/dialogs/legal_dialog.rb +34 -21
- data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +19 -43
- data/lib/cosmos/gui/dialogs/progress_dialog.rb +79 -42
- data/lib/cosmos/gui/dialogs/pry_dialog.rb +9 -5
- data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +6 -4
- data/lib/cosmos/gui/dialogs/select_dialog.rb +23 -18
- data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +34 -10
- data/lib/cosmos/gui/dialogs/splash.rb +18 -8
- data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +38 -43
- data/lib/cosmos/gui/dialogs/tlm_edit_dialog.rb +51 -53
- data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +1 -1
- data/lib/cosmos/gui/line_graph/lines.rb +1 -1
- data/lib/cosmos/gui/qt.rb +9 -2
- data/lib/cosmos/gui/qt_tool.rb +50 -8
- data/lib/cosmos/gui/widgets/packet_log_frame.rb +53 -27
- data/lib/cosmos/interfaces/linc_interface.rb +103 -62
- data/lib/cosmos/io/json_drb_object.rb +3 -3
- data/lib/cosmos/io/raw_logger.rb +4 -8
- data/lib/cosmos/io/tcpip_server.rb +2 -2
- data/lib/cosmos/packets/binary_accessor.rb +1 -1
- data/lib/cosmos/packets/limits.rb +2 -5
- data/lib/cosmos/packets/packet.rb +1 -1
- data/lib/cosmos/packets/packet_config.rb +54 -19
- data/lib/cosmos/packets/parsers/packet_item_parser.rb +7 -1
- data/lib/cosmos/script/scripting.rb +4 -5
- data/lib/cosmos/system/system.rb +2 -1
- data/lib/cosmos/system/target.rb +4 -0
- data/lib/cosmos/tools/cmd_tlm_server/background_task.rb +13 -5
- data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +37 -27
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +6 -2
- data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +7 -5
- data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +21 -10
- data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +11 -11
- data/lib/cosmos/tools/script_runner/script_runner.rb +2 -18
- data/lib/cosmos/tools/script_runner/script_runner_frame.rb +6 -6
- data/lib/cosmos/tools/table_manager/table.rb +32 -41
- data/lib/cosmos/tools/table_manager/table_config.rb +140 -729
- data/lib/cosmos/tools/table_manager/table_item.rb +20 -36
- data/lib/cosmos/tools/table_manager/table_item_parser.rb +46 -0
- data/lib/cosmos/tools/table_manager/table_manager.rb +754 -691
- data/lib/cosmos/tools/table_manager/table_manager_core.rb +172 -358
- data/lib/cosmos/tools/table_manager/table_parser.rb +75 -0
- data/lib/cosmos/tools/test_runner/results_writer.rb +1 -1
- data/lib/cosmos/tools/test_runner/test_runner.rb +11 -0
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/singlexy_data_object_adder.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +2 -2
- data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +4 -4
- data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +13 -13
- data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +9 -9
- data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +9 -9
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +4 -4
- data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +1 -1
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +8 -18
- data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +7 -4
- data/lib/cosmos/top_level.rb +12 -0
- data/lib/cosmos/version.rb +5 -5
- data/run_gui_tests.bat +6 -0
- data/spec/core_ext/array_spec.rb +1 -1
- data/spec/interfaces/linc_interface_spec.rb +4 -4
- data/spec/io/json_drb_spec.rb +2 -2
- data/spec/io/json_rpc_spec.rb +1 -1
- data/spec/io/raw_logger_spec.rb +5 -1
- data/spec/packet_logs/packet_log_writer_spec.rb +1 -1
- data/spec/packets/packet_config_spec.rb +144 -0
- data/spec/packets/parsers/packet_item_parser_spec.rb +60 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/system/target_spec.rb +5 -1
- data/spec/tools/cmd_tlm_server/background_task_spec.rb +15 -3
- data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +117 -31
- data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +4 -0
- data/spec/tools/launcher/launcher_config_spec.rb +1 -1
- data/spec/tools/table_manager/table_config_spec.rb +226 -0
- data/spec/tools/table_manager/table_item_spec.rb +57 -0
- data/spec/tools/table_manager/table_parser_spec.rb +96 -0
- data/spec/tools/table_manager/table_spec.rb +90 -0
- data/spec/tools/table_manager/tablemanager_core_spec.rb +557 -0
- data/spec/top_level/top_level_spec.rb +9 -0
- data/spec/utilities/csv_spec.rb +3 -3
- metadata +30 -11
@@ -14,17 +14,16 @@
|
|
14
14
|
require 'cosmos'
|
15
15
|
|
16
16
|
module Cosmos
|
17
|
-
|
18
|
-
# CalendarDialog class
|
19
|
-
#
|
17
|
+
# Creates a dialog with a date and optional time selection
|
20
18
|
class CalendarDialog < Qt::Dialog
|
21
|
-
|
22
|
-
# The selected time
|
19
|
+
# @return [Time] User entered time
|
23
20
|
attr_reader :time
|
24
21
|
|
25
|
-
#
|
26
|
-
|
27
|
-
|
22
|
+
# @param parent [Qt::Widget] Parent of this dialog
|
23
|
+
# @param title [String] Dialog title
|
24
|
+
# @param initial_time [Time] Initial time to display
|
25
|
+
# @param show_time [Boolean] Whether to display the time selection
|
26
|
+
def initialize(parent, title, initial_time = nil, show_time = true)
|
28
27
|
super(parent)
|
29
28
|
setWindowTitle(title)
|
30
29
|
|
@@ -90,13 +89,12 @@ module Cosmos
|
|
90
89
|
@layout.addLayout(@button_layout)
|
91
90
|
|
92
91
|
setLayout(@layout)
|
93
|
-
end
|
92
|
+
end
|
94
93
|
|
95
94
|
protected
|
96
95
|
|
97
96
|
# Handler for the OK button being pressed - builds the time object
|
98
97
|
def handle_ok_button
|
99
|
-
# Get calendar selected day
|
100
98
|
@date = @calendar.selectedDate
|
101
99
|
|
102
100
|
# Reduce @time to time at midnight of day
|
@@ -130,7 +128,5 @@ module Cosmos
|
|
130
128
|
@date = @calendar.selectedDate
|
131
129
|
@year_month_day.setText(sprintf("%04u/%02u/%02u", @date.year, @date.month, @date.day))
|
132
130
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end # module Cosmos
|
131
|
+
end
|
132
|
+
end
|
@@ -15,8 +15,9 @@ require 'cosmos'
|
|
15
15
|
require 'cosmos/gui/dialogs/details_dialog'
|
16
16
|
|
17
17
|
module Cosmos
|
18
|
-
|
18
|
+
# Creates a dialog which shows the details of the given command.
|
19
19
|
class CmdDetailsDialog < DetailsDialog
|
20
|
+
# (see DetailsDialog#initialize)
|
20
21
|
def initialize(parent, target_name, packet_name, item_name)
|
21
22
|
super(parent, target_name, packet_name, item_name)
|
22
23
|
|
@@ -45,8 +46,6 @@ module Cosmos
|
|
45
46
|
rescue DRb::DRbConnError
|
46
47
|
# Just do nothing
|
47
48
|
end
|
48
|
-
|
49
49
|
end
|
50
|
-
end
|
51
|
-
|
52
|
-
end # module Cosmos
|
50
|
+
end
|
51
|
+
end
|
@@ -15,19 +15,27 @@ require 'cosmos'
|
|
15
15
|
require 'cosmos/gui/qt'
|
16
16
|
|
17
17
|
module Cosmos
|
18
|
-
|
18
|
+
# Creates a dialog showing a packet formatted as a binary hex dump
|
19
19
|
class RawDialog < Qt::Dialog
|
20
20
|
slots 'packet_update_timeout()'
|
21
21
|
|
22
|
+
# Constant to indicate a command packet dump
|
22
23
|
CMD_TYPE = 'cmd'
|
24
|
+
# Constant to indicate a telemetry packet dump
|
23
25
|
TLM_TYPE = 'tlm'
|
26
|
+
# Dialog update period
|
24
27
|
PACKET_UPDATE_PERIOD_MS = 1000
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
# Header string to display over the dump
|
29
|
+
HEADER = "Address Data Ascii\n"\
|
30
|
+
"---------------------------------------------------------------------------\n"
|
28
31
|
|
32
|
+
# @return [Qt::Font] Font to display the dialog dump (should be monospaced)
|
29
33
|
@@font = nil
|
30
34
|
|
35
|
+
# @param parent [Qt::Dialog] Parent for the dialog
|
36
|
+
# @param type [String] Dialog type which must be 'cmd' or 'tlm'
|
37
|
+
# @param target_name [String] Name of the target
|
38
|
+
# @param packet_name [String] Name of the packet
|
31
39
|
def initialize(parent, type, target_name, packet_name)
|
32
40
|
super(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
|
33
41
|
raise "RawDialog: Undefined type:#{type}" if type != CMD_TYPE and type != TLM_TYPE
|
@@ -97,6 +105,7 @@ module Cosmos
|
|
97
105
|
end
|
98
106
|
end
|
99
107
|
|
108
|
+
# Callback to get the latest packet and update the dialog
|
100
109
|
def packet_update_timeout
|
101
110
|
if (@type == CMD_TYPE)
|
102
111
|
packet = System.commands.packet(@target_name, @packet_name)
|
@@ -115,35 +124,40 @@ module Cosmos
|
|
115
124
|
|
116
125
|
def reject
|
117
126
|
super()
|
118
|
-
if @timer
|
119
|
-
@timer.stop
|
120
|
-
@timer.dispose
|
121
|
-
@timer = nil
|
122
|
-
end
|
127
|
+
stop_timer if @timer
|
123
128
|
self.dispose
|
124
129
|
end
|
125
130
|
|
126
131
|
def closeEvent(event)
|
127
132
|
super(event)
|
128
|
-
if @timer
|
129
|
-
@timer.stop
|
130
|
-
@timer.dispose
|
131
|
-
@timer = nil
|
132
|
-
end
|
133
|
+
stop_timer if @timer
|
133
134
|
self.dispose
|
134
135
|
end
|
135
|
-
end # class RawDialog
|
136
136
|
|
137
|
+
def stop_timer
|
138
|
+
@timer.stop
|
139
|
+
@timer.dispose
|
140
|
+
@timer = nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Creates a dialog which displays a command packet as a hex dump
|
137
145
|
class CmdRawDialog < RawDialog
|
146
|
+
# @param parent (see RawDialog#initialize)
|
147
|
+
# @param target_name (see RawDialog#initialize)
|
148
|
+
# @param packet_name (see RawDialog#initialize)
|
138
149
|
def initialize(parent, target_name, packet_name)
|
139
150
|
super(parent, RawDialog::CMD_TYPE, target_name, packet_name)
|
140
151
|
end
|
141
152
|
end
|
142
153
|
|
154
|
+
# Creates a dialog which displays a telemetry packet as a hex dump
|
143
155
|
class TlmRawDialog < RawDialog
|
156
|
+
# @param parent (see RawDialog#initialize)
|
157
|
+
# @param target_name (see RawDialog#initialize)
|
158
|
+
# @param packet_name (see RawDialog#initialize)
|
144
159
|
def initialize(parent, target_name, packet_name)
|
145
160
|
super(parent, RawDialog::TLM_TYPE, target_name, packet_name)
|
146
161
|
end
|
147
162
|
end
|
148
|
-
|
149
|
-
end # module Cosmos
|
163
|
+
end
|
@@ -13,11 +13,17 @@ require 'cosmos/gui/qt'
|
|
13
13
|
require 'cosmos/script'
|
14
14
|
|
15
15
|
module Cosmos
|
16
|
-
|
16
|
+
# Creates a dialog showing the details about a given command or telemetry
|
17
|
+
# item. This class is a base class and should not be instantiated. Use
|
18
|
+
# CmdDetailsDialog or TlmDetailsDialog.
|
17
19
|
class DetailsDialog < Qt::Dialog
|
18
|
-
|
20
|
+
# @return [Array<DetailsDialog>] Instances of the details dialog
|
19
21
|
@@instances = []
|
20
22
|
|
23
|
+
# @param parent [Qt::Dialog] Parent for the dialog
|
24
|
+
# @param target_name [String] Name of the target
|
25
|
+
# @param packet_name [String] Name of the packet
|
26
|
+
# @param item_name [String] Name of the item
|
21
27
|
def initialize(parent, target_name, packet_name, item_name)
|
22
28
|
super(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
|
23
29
|
|
@@ -30,6 +36,9 @@ module Cosmos
|
|
30
36
|
@@instances << self
|
31
37
|
end
|
32
38
|
|
39
|
+
protected
|
40
|
+
|
41
|
+
# Creates and populates the layout for the dialog
|
33
42
|
def build_details_layout(item, cmd_tlm)
|
34
43
|
details_layout = Qt::FormLayout.new
|
35
44
|
details_layout.addRow("Bit Offset:", Qt::Label.new(tr("#{show_nil(item.bit_offset)}")))
|
@@ -51,34 +60,8 @@ module Cosmos
|
|
51
60
|
details_layout.addRow("Units Full:", Qt::Label.new(tr("#{show_nil(item.units_full)}")))
|
52
61
|
details_layout.addRow("Units Abbreviation:", Qt::Label.new(tr("#{show_nil(item.units)}")))
|
53
62
|
details_layout.addRow("Endianness:", Qt::Label.new(tr("#{show_endianness(item.endianness)}")))
|
54
|
-
state_colors = item.state_colors
|
55
63
|
if item.states
|
56
|
-
|
57
|
-
scroll_layout = Qt::VBoxLayout.new
|
58
|
-
states_details.setLayout(scroll_layout)
|
59
|
-
scroll_area = Qt::ScrollArea.new
|
60
|
-
scroll_area.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
|
61
|
-
scroll_layout.addWidget(scroll_area)
|
62
|
-
scroll_widget = Qt::Widget.new
|
63
|
-
scroll_area.setWidget(scroll_widget)
|
64
|
-
states_layout = Qt::FormLayout.new
|
65
|
-
scroll_widget.setLayout(states_layout)
|
66
|
-
item.states.sort {|a, b| a[1] <=> b[1]}.each do |state_name, state_value|
|
67
|
-
if state_colors
|
68
|
-
states_layout.addRow(tr("#{state_name}:"), Qt::Label.new(tr("#{state_value} #{state_colors[state_name]}")))
|
69
|
-
else
|
70
|
-
states_layout.addRow(tr("#{state_name}:"), Qt::Label.new(tr("#{state_value}")))
|
71
|
-
end
|
72
|
-
end
|
73
|
-
# Figure out the how big the states layout wants to be and set the
|
74
|
-
# scroll area to this height if possible. Otherwise limit it to 200px.
|
75
|
-
if states_layout.minimumSize.height > 200
|
76
|
-
scroll_area.setMinimumHeight(200)
|
77
|
-
else
|
78
|
-
scroll_area.setMinimumHeight(states_layout.minimumSize.height + 5)
|
79
|
-
end
|
80
|
-
scroll_widget.adjustSize
|
81
|
-
details_layout.addRow(states_details)
|
64
|
+
details_layout.addRow(build_states_details(item))
|
82
65
|
else
|
83
66
|
details_layout.addRow("States:", Qt::Label.new(tr("None")))
|
84
67
|
end
|
@@ -87,23 +70,11 @@ module Cosmos
|
|
87
70
|
else
|
88
71
|
limits = item.limits.values
|
89
72
|
if limits
|
90
|
-
|
91
|
-
@limits_layout = Qt::FormLayout.new
|
92
|
-
limits.each do |limits_set_name, limits_settings|
|
93
|
-
if limits_settings[4] and limits_settings[5]
|
94
|
-
label = Qt::Label.new("RL/#{limits_settings[0]} YL/#{limits_settings[1]} YH/#{limits_settings[2]} RH/#{limits_settings[3]} GL/#{limits_settings[4]} GH/#{limits_settings[5]}")
|
95
|
-
else
|
96
|
-
label = Qt::Label.new("RL/#{limits_settings[0]} YL/#{limits_settings[1]} YH/#{limits_settings[2]} RH/#{limits_settings[3]}")
|
97
|
-
end
|
98
|
-
@limits_labels[limits_set_name] = label
|
99
|
-
@limits_layout.addRow(tr("#{limits_set_name}:"), label)
|
100
|
-
end
|
101
|
-
limits_details.setLayout(@limits_layout)
|
102
|
-
details_layout.addRow(limits_details)
|
73
|
+
details_layout.addRow(build_limits_details(limits))
|
103
74
|
else
|
104
75
|
details_layout.addRow(tr("Limits:"), Qt::Label.new("None"))
|
105
76
|
end
|
106
|
-
if limits || state_colors
|
77
|
+
if limits || item.state_colors
|
107
78
|
details_layout.addRow(tr("Limits Checking Enabled:"), Qt::Label.new(tr("#{show_nil(item.limits.enabled)}")))
|
108
79
|
end
|
109
80
|
if limits
|
@@ -121,6 +92,53 @@ module Cosmos
|
|
121
92
|
details_layout
|
122
93
|
end
|
123
94
|
|
95
|
+
# Create the states details layout
|
96
|
+
def build_states_details(item)
|
97
|
+
states_details = Qt::GroupBox.new(tr("States"))
|
98
|
+
scroll_layout = Qt::VBoxLayout.new
|
99
|
+
states_details.setLayout(scroll_layout)
|
100
|
+
scroll_area = Qt::ScrollArea.new
|
101
|
+
scroll_area.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff)
|
102
|
+
scroll_layout.addWidget(scroll_area)
|
103
|
+
scroll_widget = Qt::Widget.new
|
104
|
+
scroll_area.setWidget(scroll_widget)
|
105
|
+
states_layout = Qt::FormLayout.new
|
106
|
+
scroll_widget.setLayout(states_layout)
|
107
|
+
item.states.sort {|a, b| a[1] <=> b[1]}.each do |state_name, state_value|
|
108
|
+
if item.state_colors
|
109
|
+
states_layout.addRow(tr("#{state_name}:"), Qt::Label.new(tr("#{state_value} #{item.state_colors[state_name]}")))
|
110
|
+
else
|
111
|
+
states_layout.addRow(tr("#{state_name}:"), Qt::Label.new(tr("#{state_value}")))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
# Figure out the how big the states layout wants to be and set the
|
115
|
+
# scroll area to this height if possible. Otherwise limit it to 200px.
|
116
|
+
if states_layout.minimumSize.height > 200
|
117
|
+
scroll_area.setMinimumHeight(200)
|
118
|
+
else
|
119
|
+
scroll_area.setMinimumHeight(states_layout.minimumSize.height + 5)
|
120
|
+
end
|
121
|
+
scroll_widget.adjustSize
|
122
|
+
states_details
|
123
|
+
end
|
124
|
+
|
125
|
+
# Create the limits details layout
|
126
|
+
def build_limits_details(limits)
|
127
|
+
limits_details = Qt::GroupBox.new(tr("Limits"))
|
128
|
+
@limits_layout = Qt::FormLayout.new
|
129
|
+
limits.each do |limits_set_name, limits_settings|
|
130
|
+
if limits_settings[4] and limits_settings[5]
|
131
|
+
label = Qt::Label.new("RL/#{limits_settings[0]} YL/#{limits_settings[1]} YH/#{limits_settings[2]} RH/#{limits_settings[3]} GL/#{limits_settings[4]} GH/#{limits_settings[5]}")
|
132
|
+
else
|
133
|
+
label = Qt::Label.new("RL/#{limits_settings[0]} YL/#{limits_settings[1]} YH/#{limits_settings[2]} RH/#{limits_settings[3]}")
|
134
|
+
end
|
135
|
+
@limits_labels[limits_set_name] = label
|
136
|
+
@limits_layout.addRow(tr("#{limits_set_name}:"), label)
|
137
|
+
end
|
138
|
+
limits_details.setLayout(@limits_layout)
|
139
|
+
limits_details
|
140
|
+
end
|
141
|
+
|
124
142
|
def show_nil(object, show_as = 'nil')
|
125
143
|
if object.nil?
|
126
144
|
return show_as
|
@@ -168,7 +186,5 @@ module Cosmos
|
|
168
186
|
@@instances.delete(self)
|
169
187
|
self.dispose
|
170
188
|
end
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end # module Cosmos
|
189
|
+
end
|
190
|
+
end
|
@@ -15,83 +15,92 @@ require 'cosmos'
|
|
15
15
|
require 'cosmos/gui/qt'
|
16
16
|
|
17
17
|
module Cosmos
|
18
|
-
|
18
|
+
# Creates a dialog to display a COSMOS exception to the user. The dialog can
|
19
|
+
# close the application and log the exception. This is the primary dialog to
|
20
|
+
# display when something goes unexpectedly wrong.
|
19
21
|
class ExceptionDialog
|
22
|
+
# @return [Mutex] Mutex to make this dialog single threaded
|
20
23
|
@@mutex = Mutex.new
|
21
24
|
|
25
|
+
# @param parent [Qt::Dialog] Parent of this dialog
|
26
|
+
# @param exception [Exception] Ruby Exception to display details about
|
27
|
+
# @param title [String] Title of the dialog
|
28
|
+
# @param exit_afterwards [Boolean] Whether to completely exit the
|
29
|
+
# application after displaying the dialog. Useful for fatal exceptions.
|
30
|
+
# @param log_exception [Boolean] Whether to create an exception log file
|
31
|
+
# @param log_file [String] Name of the log file to create
|
22
32
|
def initialize(parent, exception, title = 'COSMOS Exception', exit_afterwards = true, log_exception = true, log_file = nil)
|
23
|
-
|
24
|
-
unless exception.class == SystemExit or exception.class == Interrupt
|
25
|
-
# ConfigParser::Errors are configuration user errors. We don't want to clutter
|
26
|
-
# up list of real exceptions with user configuration errors.
|
27
|
-
# Same goes for FatalErrors
|
28
|
-
unless exception.class == ConfigParser::Error || exception.class == FatalError
|
29
|
-
log_file = Cosmos.write_exception_file(exception) if log_exception
|
30
|
-
end
|
33
|
+
return unless @@mutex.try_lock
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
#
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
# First read the log_file we wrote out to the logs directory
|
57
|
-
# Change newlines to %0A for Outlook and remove all quotes to avoid breaking the link
|
58
|
-
begin
|
59
|
-
message = exception.message.gsub("\n","<br/>")
|
60
|
-
file_contents = File.read(log_file).gsub("\n","%0A").gsub("'","").gsub("\"","") if log_file
|
61
|
-
rescue
|
62
|
-
end
|
63
|
-
text = "The following error occurred:<br/>#{message}"
|
64
|
-
text << "<br/><br/>Please contact your local COSMOS expert.<br/><br/>This error has been logged:<br/>#{log_file}<br/><br/> <a href='mailto:rmelton@ball.com;jmthomas@ball.com?subject=COSMOS exception&body=#{file_contents}'>Click here</a> to email this log to the COSMOS developers." if log_file
|
35
|
+
unless exception.class == SystemExit || exception.class == Interrupt
|
36
|
+
# ConfigParser::Errors are configuration user errors. We don't want to clutter
|
37
|
+
# up list of real exceptions with user configuration errors.
|
38
|
+
# Same goes for FatalErrors
|
39
|
+
unless exception.class == ConfigParser::Error || exception.class == FatalError
|
40
|
+
log_file = Cosmos.write_exception_file(exception) if log_exception
|
41
|
+
end
|
42
|
+
|
43
|
+
if Qt::CoreApplication.instance
|
44
|
+
msg = Qt::MessageBox.new(parent)
|
45
|
+
msg.setWindowTitle(title)
|
46
|
+
msg.setTextFormat(Qt::RichText)
|
47
|
+
msg.setIcon(Qt::MessageBox::Critical)
|
48
|
+
case exception
|
49
|
+
# ConfigParser::Errors are a special case generated with a known format
|
50
|
+
# by the ConfigParser
|
51
|
+
when ConfigParser::Error
|
52
|
+
# Substitute the html tags '<' and '>' and then replace newlines with html breaks
|
53
|
+
usage = exception.usage.gsub("<","<").gsub(">",">").gsub("\n","<br/>")
|
54
|
+
message = exception.message.gsub("<","<").gsub(">",">").gsub("\n","<br/>")
|
55
|
+
line = exception.keyword + ' ' + exception.parameters.join(' ').gsub("<","<").gsub(">",">").gsub("\n","<br/>")
|
56
|
+
text = "Error in #{exception.filename}<br/><br/>Line #{exception.line_number}: #{line}<br/><br/>#{message}<br/><br/>#{usage}"
|
57
|
+
unless exception.url.nil?
|
58
|
+
text << "<br/><br/>For more information see <a href='#{exception.url}'>#{exception.url}</a>."
|
65
59
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
60
|
+
# FatalErrors are errors explicitly raised when a known fatal issue
|
61
|
+
# occurs. Since it is a known issue we don't put up the full error
|
62
|
+
# dialog.
|
63
|
+
when FatalError
|
64
|
+
text = "Error: #{exception.message.gsub("\n","<br/>")}"
|
65
|
+
else
|
66
|
+
file_contents = ""
|
67
|
+
# First read the log_file we wrote out to the logs directory
|
68
|
+
# Change newlines to %0A for Outlook and remove all quotes to avoid breaking the link
|
69
|
+
begin
|
70
|
+
message = exception.message.gsub("\n","<br/>")
|
71
|
+
file_contents = File.read(log_file).gsub("\n","%0A").gsub("'","").gsub("\"","") if log_file
|
72
|
+
rescue
|
75
73
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
74
|
+
text = "The following error occurred:<br/>#{message}"
|
75
|
+
text << "<br/><br/>Please contact your local COSMOS expert.<br/><br/>This error has been logged:<br/>#{log_file}<br/><br/> <a href='mailto:rmelton@ball.com;jmthomas@ball.com?subject=COSMOS exception&body=#{file_contents}'>Click here</a> to email this log to the COSMOS developers." if log_file
|
76
|
+
end
|
77
|
+
text << "<br/><br/>NOTE!: The application will exit once you accept or dismiss this dialog!" if exit_afterwards
|
78
|
+
msg.setText(text)
|
79
|
+
if log_file
|
80
|
+
open_button = Qt::PushButton.new("Open Exception Log in Text Editor")
|
81
|
+
open_button.connect(SIGNAL('clicked()')) do
|
82
|
+
Cosmos.open_in_text_editor(log_file)
|
83
|
+
sleep(2)
|
84
|
+
end
|
85
|
+
msg.addButton(open_button, Qt::MessageBox::ResetRole)
|
86
|
+
end
|
87
|
+
close_button = Qt::PushButton.new("Close")
|
88
|
+
msg.addButton(close_button, Qt::MessageBox::ActionRole)
|
89
|
+
msg.raise
|
90
|
+
msg.exec
|
91
|
+
msg.dispose
|
92
|
+
end # if Qt::CoreApplication.instance
|
93
|
+
end # unless exception.class == SystemExit or exception.class == Interrupt
|
94
|
+
@@mutex.unlock
|
95
|
+
if exit_afterwards
|
96
|
+
Qt::CoreApplication.instance.exit(1) if Qt::CoreApplication.instance
|
97
|
+
exit 1 # incase CoreApplication doesn't exit yet or didn't complete the exit
|
98
|
+
end
|
89
99
|
end # def initialize
|
90
100
|
|
101
|
+
# @return [Boolean] Whether this dialog has already been instantiated
|
91
102
|
def self.dialog_open?
|
92
103
|
@@mutex.locked?
|
93
104
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end # module Cosmos
|
105
|
+
end
|
106
|
+
end
|