cosmos 3.8.3 → 3.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/Manifest.txt +14 -0
  4. data/Rakefile +35 -2
  5. data/autohotkey/config/targets/INST/screens/_footer.txt +4 -0
  6. data/autohotkey/config/targets/INST/screens/hs.txt +1 -4
  7. data/autohotkey/config/tools/table_manager/OldOneDimensionalTable_def.txt +19 -0
  8. data/autohotkey/config/tools/table_manager/OldTwoDimensionalTable_def.txt +248 -0
  9. data/autohotkey/config/tools/table_manager/OneDimensionalTable_def.txt +27 -15
  10. data/autohotkey/config/tools/table_manager/TwoDimensionalTable_def.txt +12 -232
  11. data/autohotkey/procedures/example_test.rb +4 -0
  12. data/autohotkey/tools/TableManagerAHK +4 -9
  13. data/autohotkey/tools/TableManagerAHK2 +18 -0
  14. data/autohotkey/tools/TableManagerAHK3 +18 -0
  15. data/autohotkey/tools/TableManagerAHK4 +24 -0
  16. data/autohotkey/tools/TlmViewerAHK +1 -1
  17. data/autohotkey/tools/autohotkey.rb +2 -1
  18. data/autohotkey/tools/open_gl_builder.ahk +1 -1
  19. data/autohotkey/tools/table_manager.ahk +141 -70
  20. data/cosmos.gemspec +3 -3
  21. data/data/crc.txt +70 -68
  22. data/data/legal.txt +4 -5
  23. data/demo/config/data/crc.txt +10 -9
  24. data/demo/config/targets/INST/screens/_footer.txt +4 -0
  25. data/demo/config/targets/INST/screens/hs.txt +1 -6
  26. data/demo/config/targets/INST/screens/limits.txt +3 -11
  27. data/demo/config/tools/cmd_tlm_server/cmd_tlm_server.txt +1 -0
  28. data/demo/config/tools/table_manager/MCConfigurationTable_fsw1_def.txt +33 -22
  29. data/demo/config/tools/table_manager/MCConfigurationTable_fsw2_def.txt +30 -22
  30. data/demo/config/tools/table_manager/PPSSelectionTable_def.txt +8 -7
  31. data/demo/config/tools/table_manager/TLMMonitoringTable_def.txt +13 -13
  32. data/demo/lib/example_background_task.rb +6 -12
  33. data/demo/procedures/example_test.rb +5 -0
  34. data/lib/cosmos/conversions/conversion.rb +3 -7
  35. data/lib/cosmos/core_ext/class.rb +3 -1
  36. data/lib/cosmos/core_ext/file.rb +1 -0
  37. data/lib/cosmos/core_ext/io.rb +18 -0
  38. data/lib/cosmos/core_ext/range.rb +1 -5
  39. data/lib/cosmos/core_ext/time.rb +3 -3
  40. data/lib/cosmos/gui/dialogs/about_dialog.rb +60 -36
  41. data/lib/cosmos/gui/dialogs/calendar_dialog.rb +10 -14
  42. data/lib/cosmos/gui/dialogs/cmd_details_dialog.rb +4 -5
  43. data/lib/cosmos/gui/dialogs/cmd_tlm_raw_dialog.rb +31 -17
  44. data/lib/cosmos/gui/dialogs/details_dialog.rb +63 -47
  45. data/lib/cosmos/gui/dialogs/exception_dialog.rb +77 -68
  46. data/lib/cosmos/gui/dialogs/exception_list_dialog.rb +6 -5
  47. data/lib/cosmos/gui/dialogs/legal_dialog.rb +34 -21
  48. data/lib/cosmos/gui/dialogs/packet_log_dialog.rb +19 -43
  49. data/lib/cosmos/gui/dialogs/progress_dialog.rb +79 -42
  50. data/lib/cosmos/gui/dialogs/pry_dialog.rb +9 -5
  51. data/lib/cosmos/gui/dialogs/scroll_text_dialog.rb +6 -4
  52. data/lib/cosmos/gui/dialogs/select_dialog.rb +23 -18
  53. data/lib/cosmos/gui/dialogs/set_tlm_dialog.rb +34 -10
  54. data/lib/cosmos/gui/dialogs/splash.rb +18 -8
  55. data/lib/cosmos/gui/dialogs/tlm_details_dialog.rb +38 -43
  56. data/lib/cosmos/gui/dialogs/tlm_edit_dialog.rb +51 -53
  57. data/lib/cosmos/gui/line_graph/line_graph_scaling.rb +1 -1
  58. data/lib/cosmos/gui/line_graph/lines.rb +1 -1
  59. data/lib/cosmos/gui/qt.rb +9 -2
  60. data/lib/cosmos/gui/qt_tool.rb +50 -8
  61. data/lib/cosmos/gui/widgets/packet_log_frame.rb +53 -27
  62. data/lib/cosmos/interfaces/linc_interface.rb +103 -62
  63. data/lib/cosmos/io/json_drb_object.rb +3 -3
  64. data/lib/cosmos/io/raw_logger.rb +4 -8
  65. data/lib/cosmos/io/tcpip_server.rb +2 -2
  66. data/lib/cosmos/packets/binary_accessor.rb +1 -1
  67. data/lib/cosmos/packets/limits.rb +2 -5
  68. data/lib/cosmos/packets/packet.rb +1 -1
  69. data/lib/cosmos/packets/packet_config.rb +54 -19
  70. data/lib/cosmos/packets/parsers/packet_item_parser.rb +7 -1
  71. data/lib/cosmos/script/scripting.rb +4 -5
  72. data/lib/cosmos/system/system.rb +2 -1
  73. data/lib/cosmos/system/target.rb +4 -0
  74. data/lib/cosmos/tools/cmd_tlm_server/background_task.rb +13 -5
  75. data/lib/cosmos/tools/cmd_tlm_server/background_tasks.rb +37 -27
  76. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server.rb +6 -2
  77. data/lib/cosmos/tools/cmd_tlm_server/cmd_tlm_server_config.rb +7 -5
  78. data/lib/cosmos/tools/cmd_tlm_server/gui/status_tab.rb +21 -10
  79. data/lib/cosmos/tools/limits_monitor/limits_monitor.rb +11 -11
  80. data/lib/cosmos/tools/script_runner/script_runner.rb +2 -18
  81. data/lib/cosmos/tools/script_runner/script_runner_frame.rb +6 -6
  82. data/lib/cosmos/tools/table_manager/table.rb +32 -41
  83. data/lib/cosmos/tools/table_manager/table_config.rb +140 -729
  84. data/lib/cosmos/tools/table_manager/table_item.rb +20 -36
  85. data/lib/cosmos/tools/table_manager/table_item_parser.rb +46 -0
  86. data/lib/cosmos/tools/table_manager/table_manager.rb +754 -691
  87. data/lib/cosmos/tools/table_manager/table_manager_core.rb +172 -358
  88. data/lib/cosmos/tools/table_manager/table_parser.rb +75 -0
  89. data/lib/cosmos/tools/test_runner/results_writer.rb +1 -1
  90. data/lib/cosmos/tools/test_runner/test_runner.rb +11 -0
  91. data/lib/cosmos/tools/tlm_grapher/data_object_adders/housekeeping_data_object_adder.rb +2 -2
  92. data/lib/cosmos/tools/tlm_grapher/data_object_adders/singlexy_data_object_adder.rb +2 -2
  93. data/lib/cosmos/tools/tlm_grapher/data_object_adders/xy_data_object_adder.rb +2 -2
  94. data/lib/cosmos/tools/tlm_grapher/data_objects/data_object.rb +4 -4
  95. data/lib/cosmos/tools/tlm_grapher/data_objects/housekeeping_data_object.rb +13 -13
  96. data/lib/cosmos/tools/tlm_grapher/data_objects/linegraph_data_object.rb +9 -9
  97. data/lib/cosmos/tools/tlm_grapher/data_objects/xy_data_object.rb +9 -9
  98. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_config.rb +4 -4
  99. data/lib/cosmos/tools/tlm_grapher/tabbed_plots_tool/tabbed_plots_tool.rb +1 -1
  100. data/lib/cosmos/tools/tlm_viewer/tlm_viewer.rb +8 -18
  101. data/lib/cosmos/tools/tlm_viewer/tlm_viewer_config.rb +7 -4
  102. data/lib/cosmos/top_level.rb +12 -0
  103. data/lib/cosmos/version.rb +5 -5
  104. data/run_gui_tests.bat +6 -0
  105. data/spec/core_ext/array_spec.rb +1 -1
  106. data/spec/interfaces/linc_interface_spec.rb +4 -4
  107. data/spec/io/json_drb_spec.rb +2 -2
  108. data/spec/io/json_rpc_spec.rb +1 -1
  109. data/spec/io/raw_logger_spec.rb +5 -1
  110. data/spec/packet_logs/packet_log_writer_spec.rb +1 -1
  111. data/spec/packets/packet_config_spec.rb +144 -0
  112. data/spec/packets/parsers/packet_item_parser_spec.rb +60 -0
  113. data/spec/spec_helper.rb +11 -0
  114. data/spec/system/target_spec.rb +5 -1
  115. data/spec/tools/cmd_tlm_server/background_task_spec.rb +15 -3
  116. data/spec/tools/cmd_tlm_server/background_tasks_spec.rb +117 -31
  117. data/spec/tools/cmd_tlm_server/cmd_tlm_server_spec.rb +4 -0
  118. data/spec/tools/launcher/launcher_config_spec.rb +1 -1
  119. data/spec/tools/table_manager/table_config_spec.rb +226 -0
  120. data/spec/tools/table_manager/table_item_spec.rb +57 -0
  121. data/spec/tools/table_manager/table_parser_spec.rb +96 -0
  122. data/spec/tools/table_manager/table_spec.rb +90 -0
  123. data/spec/tools/table_manager/tablemanager_core_spec.rb +557 -0
  124. data/spec/top_level/top_level_spec.rb +9 -0
  125. data/spec/utilities/csv_spec.rb +3 -3
  126. 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
- # Constructor
26
- def initialize (parent, title, initial_time = nil, show_time = true)
27
- # Call base class constructor
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 # def initialize
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
- end # class CalendarDialog
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 # class CmdDetailsDialog
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
- HEADER1 = "Address Data Ascii\n"
26
- HEADER2 = "---------------------------------------------------------------------------\n"
27
- HEADER = HEADER1 + HEADER2
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
- states_details = Qt::GroupBox.new(tr("States"))
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
- limits_details = Qt::GroupBox.new(tr("Limits"))
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
- end # class DetailsDialog
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
- if @@mutex.try_lock
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
- if Qt::CoreApplication.instance
33
- msg = Qt::MessageBox.new(parent)
34
- msg.setWindowTitle(title)
35
- msg.setTextFormat(Qt::RichText)
36
- msg.setIcon(Qt::MessageBox::Critical)
37
- case exception
38
- # ConfigParser::Errors are a special case generated with a known format
39
- # by the ConfigParser
40
- when ConfigParser::Error
41
- # Substitute the html tags '<' and '>' and then replace newlines with html breaks
42
- usage = exception.usage.gsub("<","&#060;").gsub(">","&#062;").gsub("\n","<br/>")
43
- message = exception.message.gsub("<","&#060;").gsub(">","&#062;").gsub("\n","<br/>")
44
- line = exception.keyword + ' ' + exception.parameters.join(' ').gsub("<","&#060;").gsub(">","&#062;").gsub("\n","<br/>")
45
- text = "Error in #{exception.filename}<br/><br/>Line #{exception.line_number}: #{line}<br/><br/>#{message}<br/><br/>#{usage}"
46
- unless exception.url.nil?
47
- text << "<br/><br/>For more information see <a href='#{exception.url}'>#{exception.url}</a>."
48
- end
49
- # FatalErrors are errors explicitly raised when a known fatal issue
50
- # occurs. Since it is a known issue we don't put up the full error
51
- # dialog.
52
- when FatalError
53
- text = "Error: #{exception.message.gsub("\n","<br/>")}"
54
- else
55
- file_contents = ""
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("<","&#060;").gsub(">","&#062;").gsub("\n","<br/>")
54
+ message = exception.message.gsub("<","&#060;").gsub(">","&#062;").gsub("\n","<br/>")
55
+ line = exception.keyword + ' ' + exception.parameters.join(' ').gsub("<","&#060;").gsub(">","&#062;").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
- text << "<br/><br/>NOTE!: The application will exit once you accept or dismiss this dialog!" if exit_afterwards
67
- msg.setText(text)
68
- if log_file
69
- open_button = Qt::PushButton.new("Open Exception Log in Text Editor")
70
- open_button.connect(SIGNAL('clicked()')) do
71
- Cosmos.open_in_text_editor(log_file)
72
- sleep(2)
73
- end
74
- msg.addButton(open_button, Qt::MessageBox::ResetRole)
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
- close_button = Qt::PushButton.new("Close")
77
- msg.addButton(close_button, Qt::MessageBox::ActionRole)
78
- msg.raise
79
- msg.exec
80
- msg.dispose
81
- end # if Qt::CoreApplication.instance
82
- end # unless exception.class == SystemExit or exception.class == Interrupt
83
- @@mutex.unlock
84
- if exit_afterwards
85
- Qt::CoreApplication.instance.exit(1) if Qt::CoreApplication.instance
86
- exit 1 # incase CoreApplication doesn't exit yet or didn't complete the exit
87
- end
88
- end # if @@mutex.try_lock
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
- end # class ExceptionDialog
96
-
97
- end # module Cosmos
105
+ end
106
+ end