source: src/mlx/gui/weighthelp.py@ 1099:a2d5a4d1c6c1

python3
Last change on this file since 1099:a2d5a4d1c6c1 was 1034:4836f52b49cd, checked in by István Váradi <ivaradi@…>, 3 years ago

Updated the flight type handling (re #357)

File size: 19.6 KB
Line 
1
2from mlx.gui.common import *
3
4from mlx.i18n import xstr
5from mlx.checks import PayloadChecker
6
7import mlx.const as const
8
9#-------------------------------------------------------------------------------
10
11## @package mlx.gui.weighthelp
12#
13# The weight calculation help tab.
14#
15# This module implements the tab containing the weight calculation help.
16
17#-------------------------------------------------------------------------------
18
19class WeightHelp(Gtk.VBox):
20 """The weight calculation help tab."""
21 @staticmethod
22 def _getMarkup(value, expectedValue = None, tolerance = None):
23 """Get the markup for the given value.
24
25 If it is too much different from the expected value, it will be
26 colored yellow (if within the tolerance), or red (if out of the tolerance)."""
27 markup = "%.0f" % (value,)
28 if expectedValue is not None and tolerance is not None:
29 colour = None
30 diff = abs(value - expectedValue)
31 if diff>tolerance: colour = "red"
32 elif (diff*10)>=tolerance: colour = "orange"
33 else: colour = "darkgreen"
34 if colour is not None:
35 markup = '<span foreground="' + colour + '">' + markup + '</span>'
36 return markup
37
38 def __init__(self, gui):
39 """Construct the tab."""
40 super(WeightHelp, self).__init__()
41
42 self._gui = gui
43
44 mainAlignment = Gtk.Alignment(xalign = 0.5, yalign = 0.5,
45 xscale = 1.0, yscale = 1.0)
46 mainAlignment.set_padding(padding_top = 4, padding_bottom = 4,
47 padding_left = 12, padding_right = 12)
48 self.add(mainAlignment)
49
50 self._mainBox = mainBox = Gtk.VBox()
51 mainAlignment.add(mainBox)
52
53 self._usingHelp = Gtk.CheckButton(xstr("weighthelp_usinghelp"))
54 self._usingHelp.set_use_underline(True)
55 self._usingHelp.set_tooltip_text(xstr("weighthelp_usinghelp_tooltip"))
56 self._usingHelp.connect("toggled", self._usingHelpToggled)
57 mainBox.pack_start(self._usingHelp, False, False, 4)
58
59
60 self._weightsTable = table = Gtk.Table(16, 5)
61 table.set_homogeneous(False)
62 table.set_row_spacings(4)
63 table.set_col_spacings(16)
64 alignment = Gtk.Alignment(xalign = 0.5, yalign = 0.5,
65 xscale = 0.0, yscale = 0.0)
66 alignment.add(table)
67 mainBox.pack_start(alignment, True, True, 4)
68
69 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.0,
70 xscale = 0.0, yscale = 0.0)
71 alignment.set_padding(padding_bottom = 16, padding_top = 0,
72 padding_left = 0, padding_right = 0)
73 label = Gtk.Label(xstr("weighthelp_header_calculated"))
74 label.set_use_markup(True)
75 # FIXME: should be a constant in common
76 label.set_justify(Gtk.Justification.CENTER)
77 alignment.add(label)
78 table.attach(alignment, 1, 2, 0, 1)
79
80 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.0,
81 xscale = 0.0, yscale = 0.0)
82 alignment.set_padding(padding_bottom = 16, padding_top = 0,
83 padding_left = 0, padding_right = 0)
84 button = Gtk.Button(xstr("weighthelp_header_simulator"))
85 button.set_tooltip_markup(xstr("weighthelp_header_simulator_tooltip"))
86 button.connect("clicked", self._fsButtonClicked)
87 label = button.get_child()
88 label.set_justify(Gtk.Justification.CENTER)
89 alignment.add(button)
90 table.attach(alignment, 3, 4, 0, 1)
91
92
93 self._crewLabel = Gtk.Label(xstr("weighthelp_crew") % ("99",))
94 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
95 xscale = 0.0, yscale = 0.0)
96 alignment.add(self._crewLabel)
97 table.attach(alignment, 0, 1, 1, 2)
98
99 self._crewWeight = Gtk.Label("0")
100 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
101 xscale = 0.0, yscale = 0.0)
102 alignment.add(self._crewWeight)
103 table.attach(alignment, 1, 2, 1, 2)
104
105 table.attach(Gtk.Label("kg"), 2, 3, 1, 2)
106
107 text = xstr("weighthelp_pax") % ("999",)
108 self._paxLabel = Gtk.Label(text)
109 self._paxLabel.set_width_chars(len(text))
110 self._paxLabel.set_alignment(0.0, 0.5)
111 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
112 xscale = 0.0, yscale = 0.0)
113 alignment.add(self._paxLabel)
114 table.attach(alignment, 0, 1, 2, 3)
115
116 self._paxWeight = Gtk.Label("20000")
117 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
118 xscale = 0.0, yscale = 0.0)
119 alignment.add(self._paxWeight)
120 table.attach(alignment, 1, 2, 2, 3)
121
122 table.attach(Gtk.Label("kg"), 2, 3, 2, 3)
123
124 label = Gtk.Label(xstr("weighthelp_baggage"))
125 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
126 xscale = 0.0, yscale = 0.0)
127 alignment.add(label)
128 table.attach(alignment, 0, 1, 3, 4)
129
130 self._bagWeight = Gtk.Label("2000")
131 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
132 xscale = 0.0, yscale = 0.0)
133 alignment.add(self._bagWeight)
134 table.attach(alignment, 1, 2, 3, 4)
135
136 table.attach(Gtk.Label("kg"), 2, 3, 3, 4)
137
138 label = Gtk.Label(xstr("weighthelp_cargo"))
139 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
140 xscale = 0.0, yscale = 0.0)
141 alignment.add(label)
142 table.attach(alignment, 0, 1, 4, 5)
143
144 self._cargoWeight = Gtk.Label("2000")
145 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
146 xscale = 0.0, yscale = 0.0)
147 alignment.add(self._cargoWeight)
148 table.attach(alignment, 1, 2, 4, 5)
149
150 table.attach(Gtk.Label("kg"), 2, 3, 4, 5)
151
152 label = Gtk.Label(xstr("weighthelp_mail"))
153 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
154 xscale = 0.0, yscale = 0.0)
155 alignment.add(label)
156 table.attach(alignment, 0, 1, 5, 6)
157
158 self._mailWeight = Gtk.Label("2000")
159 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
160 xscale = 0.0, yscale = 0.0)
161 alignment.add(self._mailWeight)
162 table.attach(alignment, 1, 2, 5, 6)
163
164 table.attach(Gtk.Label("kg"), 2, 3, 5, 6)
165
166 table.attach(Gtk.HSeparator(), 1, 2, 6, 7)
167
168 label = Gtk.Label("<b>" + xstr("weighthelp_payload") + "</b>")
169 label.set_use_markup(True)
170 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
171 xscale = 0.0, yscale = 0.0)
172 alignment.add(label)
173 table.attach(alignment, 0, 1, 7, 8)
174
175 self._payload = Gtk.Label("<b>32000</b>")
176 self._payload.set_use_markup(True)
177 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
178 xscale = 0.0, yscale = 0.0)
179 alignment.add(self._payload)
180 table.attach(alignment, 1, 2, 7, 8)
181
182 table.attach(Gtk.Label("kg"), 2, 3, 7, 8)
183
184 self._fsPayload = Gtk.Label("<b>32001</b>")
185 self._fsPayload.set_use_markup(True)
186 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
187 xscale = 0.0, yscale = 0.0)
188 alignment.add(self._fsPayload)
189 table.attach(alignment, 3, 4, 7, 8)
190
191 table.attach(Gtk.Label("kg"), 4, 5, 7, 8)
192
193 label = Gtk.Label(xstr("weighthelp_dow"))
194 label.set_use_markup(True)
195 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
196 xscale = 0.0, yscale = 0.0)
197 alignment.add(label)
198 table.attach(alignment, 0, 1, 8, 9)
199
200 self._dow = Gtk.Label("35000")
201 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
202 xscale = 0.0, yscale = 0.0)
203 alignment.add(self._dow)
204 table.attach(alignment, 1, 2, 8, 9)
205
206 table.attach(Gtk.Label("kg"), 2, 3, 8, 9)
207
208 self._fsDOW = Gtk.Label("33012")
209 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
210 xscale = 0.0, yscale = 0.0)
211 alignment.add(self._fsDOW)
212 table.attach(alignment, 3, 4, 8, 9)
213
214 table.attach(Gtk.Label("kg"), 4, 5, 8, 9)
215
216 table.attach(Gtk.HSeparator(), 1, 2, 9, 10)
217
218 table.attach(Gtk.HSeparator(), 3, 4, 9, 10)
219
220 label = Gtk.Label("<b>" + xstr("weighthelp_zfw") + "</b>")
221 label.set_use_markup(True)
222 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
223 xscale = 0.0, yscale = 0.0)
224 alignment.add(label)
225 table.attach(alignment, 0, 1, 10, 11)
226
227 self._zfw = Gtk.Label("<b>122000</b>")
228 self._zfw.set_use_markup(True)
229 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
230 xscale = 0.0, yscale = 0.0)
231 alignment.add(self._zfw)
232 table.attach(alignment, 1, 2, 10, 11)
233
234 table.attach(Gtk.Label("kg"), 2, 3, 10, 11)
235
236 self._fsZFW = Gtk.Label("<b>124000</b>")
237 self._fsZFW.set_use_markup(True)
238 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
239 xscale = 0.0, yscale = 0.0)
240 alignment.add(self._fsZFW)
241 table.attach(alignment, 3, 4, 10, 11)
242
243 table.attach(Gtk.Label("kg"), 4, 5, 10, 11)
244
245 table.attach(Gtk.HSeparator(), 0, 5, 11, 12)
246
247 label = Gtk.Label(xstr("weighthelp_gross"))
248 label.set_use_markup(True)
249 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
250 xscale = 0.0, yscale = 0.0)
251 alignment.add(label)
252 table.attach(alignment, 0, 1, 12, 13)
253
254 self._fsGross = Gtk.Label("124000")
255 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
256 xscale = 0.0, yscale = 0.0)
257 alignment.add(self._fsGross)
258 table.attach(alignment, 3, 4, 12, 13)
259
260 table.attach(Gtk.Label("kg"), 4, 5, 12, 13)
261
262 label = Gtk.Label(xstr("weighthelp_mzfw"))
263 label.set_use_markup(True)
264 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
265 xscale = 0.0, yscale = 0.0)
266 alignment.add(label)
267 table.attach(alignment, 0, 1, 13, 14)
268
269 self._mzfw = Gtk.Label("35000")
270 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
271 xscale = 0.0, yscale = 0.0)
272 alignment.add(self._mzfw)
273 table.attach(alignment, 1, 2, 13, 14)
274
275 table.attach(Gtk.Label("kg"), 2, 3, 13, 14)
276
277 label = Gtk.Label(xstr("weighthelp_mtow"))
278 label.set_use_markup(True)
279 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
280 xscale = 0.0, yscale = 0.0)
281 alignment.add(label)
282 table.attach(alignment, 0, 1, 14, 15)
283
284 self._mtow = Gtk.Label("35000")
285 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
286 xscale = 0.0, yscale = 0.0)
287 alignment.add(self._mtow)
288 table.attach(alignment, 1, 2, 14, 15)
289
290 table.attach(Gtk.Label("kg"), 2, 3, 14, 15)
291
292 label = Gtk.Label(xstr("weighthelp_mlw"))
293 label.set_use_markup(True)
294 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
295 xscale = 0.0, yscale = 0.0)
296 alignment.add(label)
297 table.attach(alignment, 0, 1, 15, 16)
298
299 self._mlw = Gtk.Label("35000")
300 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
301 xscale = 0.0, yscale = 0.0)
302 alignment.add(self._mlw)
303 table.attach(alignment, 1, 2, 15, 16)
304
305 table.attach(Gtk.Label("kg"), 2, 3, 15, 16)
306
307 self.show_all()
308
309 def disable(self):
310 """Disable the widget."""
311 self._mainBox.set_sensitive(False)
312
313 def enable(self):
314 """Enable the widget."""
315 self._mainBox.set_sensitive(True)
316
317 def reset(self):
318 """Reset all calculated and FS data."""
319
320 self._usingHelp.set_active(False)
321 self._usingHelp.set_sensitive(True)
322 self._weightsTable.set_sensitive(False)
323
324 self._flightType = -1
325 self._dowCabinCrew = -1
326 self._cockpitCrew = -1
327 self._cabinCrew = -1
328 self._pax = -1
329 self._children = -1
330 self._infants = -1
331 self._bag = -1
332 self._cargo = -1
333 self._mail = -1
334 self._dowValue = -1
335 self._mzfwValue = -1
336 self._mtowValue = -1
337 self._mlwValue = -1
338
339 self._fsPayloadValue = -1
340 self._fsDOWValue = -1
341 self._fsZFWValue = -1
342 self._fsGrossValue = -1
343
344 self._setupCalculated()
345 self._setupFS()
346
347 def _setupCalculated(self):
348 """Setup the labels for the calculated values."""
349 crewWeight = self._getCrewWeight()
350 if crewWeight is None:
351 self._crewLabel.set_text(xstr("weighthelp_crew") % ("-",))
352 self._crewWeight.set_text("-")
353 else:
354 self._crewLabel.set_text(xstr("weighthelp_crew") %
355 (str(self._cockpitCrew) + "+" +
356 str(self._cabinCrew),))
357 self._crewWeight.set_text("%.0f" % (crewWeight,))
358
359 paxWeight = self._getPaxWeight()
360 if paxWeight<0:
361 self._paxLabel.set_text(xstr("weighthelp_pax") % ("-",))
362 self._paxWeight.set_text("-")
363 else:
364 self._paxLabel.set_text(xstr("weighthelp_pax") %
365 (str(self._pax) + "+" +
366 str(self._children) + "+" +
367 str(self._infants),))
368 self._paxWeight.set_text("%.0f" % (paxWeight,))
369
370 self._setWeightLabel(self._bagWeight, self._bag)
371
372 self._setWeightLabel(self._cargoWeight, self._cargo)
373
374 self._setWeightLabel(self._mailWeight, self._mail)
375
376 (payload, zfw) = self._calculateWeights()
377
378 self._setWeightLabel(self._payload, payload, bold = True)
379
380 self._setWeightLabel(self._dow, self._dowValue)
381
382 if zfw<0:
383 self._zfw.set_text("-")
384 else:
385 markup = "%.0f" % (zfw,)
386 if self._mzfwValue>0 and zfw>self._mzfwValue:
387 markup = '<span foreground="red">' + markup + '</span>'
388 markup = '<b>' + markup + '</b>'
389 self._zfw.set_markup(markup)
390
391 self._setWeightLabel(self._mzfw, self._mzfwValue)
392
393 self._setWeightLabel(self._mtow, self._mtowValue)
394
395 self._setWeightLabel(self._mlw, self._mlwValue)
396
397 def _setupFS(self):
398 if self._dowValue<0:
399 self._dow.set_text("-")
400 else:
401 self._dow.set_text("%.0f" % (self._dowValue,))
402
403 """Setup the labels for the FS values."""
404 (payload, zfw) = self._calculateWeights()
405
406 if self._fsPayloadValue<0:
407 self._fsPayload.set_text("-")
408 else:
409 markup = WeightHelp._getMarkup(self._fsPayloadValue, payload,
410 PayloadChecker.TOLERANCE)
411 self._fsPayload.set_markup("<b>" + markup + "</b>")
412
413 if self._fsDOWValue<0:
414 self._fsDOW.set_text("-")
415 else:
416 markup = WeightHelp._getMarkup(self._fsDOWValue, self._dowValue,
417 PayloadChecker.TOLERANCE)
418 self._fsDOW.set_markup(markup)
419
420 if self._fsZFWValue<0:
421 self._fsZFW.set_text("-")
422 else:
423 markup = WeightHelp._getMarkup(self._fsZFWValue, zfw,
424 PayloadChecker.TOLERANCE)
425 self._fsZFW.set_markup("<b>" + markup + "</b>")
426
427 self._setWeightLabel(self._fsGross, self._fsGrossValue)
428
429 def _getCrewWeight(self):
430 """Get the crew weight for the flight."""
431 if self._cockpitCrew>=0 and self._dowCabinCrew>=0 and self._cabinCrew>=0:
432 return (self._cabinCrew - self._dowCabinCrew) * const.WEIGHT_CABIN_CREW
433 else:
434 return None
435
436 def _getPaxWeight(self):
437 """Get the passenger weight for the flight."""
438 if self._flightType>=0 and self._pax>=0 and self._children>=0 and \
439 self._infants>=0:
440 return self._pax * \
441 (const.WEIGHT_PASSENGER_CHARTER
442 if self._flightType==const.FLIGHTTYPE_CHARTER
443 else const.WEIGHT_PASSENGER) + \
444 self._children * const.WEIGHT_CHILD + \
445 self._infants * const.WEIGHT_INFANT
446 else:
447 return -1
448
449 def _calculateWeights(self):
450 """Calculate the payload and the zero-fuel weight.
451
452 It returns a tuple with these two items. If any of the items cannot be
453 calculated, that is -1."""
454 crewWeight = self._getCrewWeight()
455 paxWeight = self._getPaxWeight()
456 if crewWeight is None or paxWeight<0 or \
457 self._bag<0 or self._cargo<0 or self._mail<0:
458 payload = -1
459 else:
460 payload = crewWeight + paxWeight + self._bag + self._cargo + self._mail
461
462 if payload<0 or self._dowValue<0:
463 zfw = -1
464 else:
465 zfw = payload + self._dowValue
466
467 return (payload, zfw)
468
469 def _usingHelpToggled(self, button):
470 """Called when the Using help button is toggled."""
471 assert self._usingHelp.get_active()
472 self._usingHelp.set_sensitive(False)
473
474 self._gui.logger.untimedMessage("The weight calculation help function was used by the pilot")
475
476 bookedFlight = self._gui.bookedFlight
477 self._flightType = bookedFlight.flightType
478 self._dowCabinCrew = bookedFlight.dowNumCabinCrew
479 self._cockpitCrew = self._gui.numCockpitCrew
480 self._cabinCrew = self._gui.numCabinCrew
481 self._pax = self._gui.numPassengers
482 self._children = self._gui.numChildren
483 self._infants = self._gui.numInfants
484 self._bag = self._gui.bagWeight
485 self._cargo = self._gui.cargoWeight
486 self._mail = self._gui.mailWeight
487 self._dowValue = bookedFlight.dow
488
489 aircraft = self._gui.flight.aircraft
490 self._mzfwValue = aircraft.mzfw
491 self._mtowValue = aircraft.mtow
492 self._mlwValue = aircraft.mlw
493
494 self._setupCalculated()
495 self._weightsTable.set_sensitive(True)
496
497 def _fsButtonClicked(self, button):
498 """Callback for the FS button being clicked."""
499 gui = self._gui
500 gui.beginBusy(xstr("weighthelp_busy"))
501 gui.simulator.requestWeights(self._handleWeights)
502
503 def _handleWeights(self, dow, payload, zfw, grossWeight):
504 """Handle the given weights."""
505 GObject.idle_add(self._processWeights, dow, payload, zfw, grossWeight)
506
507 def _processWeights(self, dow, payload, zfw, grossWeight):
508 """Process the given weights."""
509 self._gui.endBusy()
510 if self._usingHelp.get_active():
511 self._fsPayloadValue = payload
512 self._fsDOWValue = dow
513 self._fsZFWValue = zfw
514 self._fsGrossValue = grossWeight
515 self._setupFS()
516
517 def _setWeightLabel(self, label, weight, bold = False):
518 """Set the given weight label to the given weight."""
519 if weight<0:
520 label.set_text("-")
521 else:
522 markup = "%.0f" % (weight,)
523 if bold: markup = "<b>" + markup + "</b>"
524 label.set_markup(markup)
525
526
Note: See TracBrowser for help on using the repository browser.