source: src/mlx/gui/weighthelp.py@ 1160:a10a0c1b0b19

python3
Last change on this file since 1160:a10a0c1b0b19 was 1144:a73548e0c689, checked in by István Váradi <ivaradi@…>, 6 months ago

More info is provided for the weight calculations (re #386)

File size: 21.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(17, 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 row = 0
70
71 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.0,
72 xscale = 0.0, yscale = 0.0)
73 alignment.set_padding(padding_bottom = 16, padding_top = 0,
74 padding_left = 0, padding_right = 0)
75 label = Gtk.Label(xstr("weighthelp_header_calculated"))
76 label.set_use_markup(True)
77 # FIXME: should be a constant in common
78 label.set_justify(Gtk.Justification.CENTER)
79 alignment.add(label)
80 table.attach(alignment, 1, 2, row, row+1)
81
82 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.0,
83 xscale = 0.0, yscale = 0.0)
84 alignment.set_padding(padding_bottom = 16, padding_top = 0,
85 padding_left = 0, padding_right = 0)
86 button = Gtk.Button(xstr("weighthelp_header_simulator"))
87 button.set_tooltip_markup(xstr("weighthelp_header_simulator_tooltip"))
88 button.connect("clicked", self._fsButtonClicked)
89 label = button.get_child()
90 label.set_justify(Gtk.Justification.CENTER)
91 alignment.add(button)
92 table.attach(alignment, 3, 4, row, row+1)
93
94 row += 1
95
96
97 label = Gtk.Label(xstr("weighthelp_flight_type"))
98 label.set_alignment(0.0, 0.5)
99 table.attach(label, 0, 1, row, row+1)
100
101 self._flightTypeLabel = label = Gtk.Label(xstr("flighttype_scheduled"))
102 label.set_alignment(1.0, 0.5)
103 table.attach(label, 1, 2, row, row + 1)
104
105 row += 1
106
107 self._crewLabel = Gtk.Label(xstr("weighthelp_crew") % ("99",))
108 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
109 xscale = 0.0, yscale = 0.0)
110 alignment.add(self._crewLabel)
111 table.attach(alignment, 0, 1, row, row+1)
112
113 self._crewWeight = Gtk.Label("0")
114 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
115 xscale = 0.0, yscale = 0.0)
116 alignment.add(self._crewWeight)
117 table.attach(alignment, 1, 2, row, row+1)
118
119 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
120
121 self._crewInfo = Gtk.Label(xstr("weighthelp_crew_info") % ("-",))
122 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
123 xscale = 0.0, yscale = 0.0)
124 alignment.add(self._crewInfo)
125 table.attach(alignment, 3, 5, row, row+1)
126
127 row += 1
128
129 text = xstr("weighthelp_pax") % ("999",)
130 self._paxLabel = Gtk.Label(text)
131 self._paxLabel.set_width_chars(len(text))
132 self._paxLabel.set_alignment(0.0, 0.5)
133 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
134 xscale = 0.0, yscale = 0.0)
135 alignment.add(self._paxLabel)
136 table.attach(alignment, 0, 1, row, row+1)
137
138 self._paxWeight = Gtk.Label("20000")
139 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
140 xscale = 0.0, yscale = 0.0)
141 alignment.add(self._paxWeight)
142 table.attach(alignment, 1, 2, row, row+1)
143
144 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
145
146 self._paxInfo = Gtk.Label(xstr("weighthelp_pax_info") %
147 ("-", "-", "-"))
148 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
149 xscale = 0.0, yscale = 0.0)
150 alignment.add(self._paxInfo)
151 table.attach(alignment, 3, 5, row, row+1)
152
153 row += 1
154
155 label = Gtk.Label(xstr("weighthelp_baggage"))
156 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
157 xscale = 0.0, yscale = 0.0)
158 alignment.add(label)
159 table.attach(alignment, 0, 1, row, row+1)
160
161 self._bagWeight = Gtk.Label("2000")
162 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
163 xscale = 0.0, yscale = 0.0)
164 alignment.add(self._bagWeight)
165 table.attach(alignment, 1, 2, row, row+1)
166
167 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
168
169 row += 1
170
171 label = Gtk.Label(xstr("weighthelp_cargo"))
172 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
173 xscale = 0.0, yscale = 0.0)
174 alignment.add(label)
175 table.attach(alignment, 0, 1, row, row+1)
176
177 self._cargoWeight = Gtk.Label("2000")
178 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
179 xscale = 0.0, yscale = 0.0)
180 alignment.add(self._cargoWeight)
181 table.attach(alignment, 1, 2, row, row+1)
182
183 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
184
185 row += 1
186
187 label = Gtk.Label(xstr("weighthelp_mail"))
188 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
189 xscale = 0.0, yscale = 0.0)
190 alignment.add(label)
191 table.attach(alignment, 0, 1, row, row+1)
192
193 self._mailWeight = Gtk.Label("2000")
194 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
195 xscale = 0.0, yscale = 0.0)
196 alignment.add(self._mailWeight)
197 table.attach(alignment, 1, 2, row, row+1)
198
199 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
200
201 row += 1
202
203 table.attach(Gtk.HSeparator(), 1, 2, row, row+1)
204
205 row += 1
206
207 label = Gtk.Label("<b>" + xstr("weighthelp_payload") + "</b>")
208 label.set_use_markup(True)
209 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
210 xscale = 0.0, yscale = 0.0)
211 alignment.add(label)
212 table.attach(alignment, 0, 1, row, row+1)
213
214 self._payload = Gtk.Label("<b>32000</b>")
215 self._payload.set_use_markup(True)
216 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
217 xscale = 0.0, yscale = 0.0)
218 alignment.add(self._payload)
219 table.attach(alignment, 1, 2, row, row+1)
220
221 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
222
223 self._fsPayload = Gtk.Label("<b>32001</b>")
224 self._fsPayload.set_use_markup(True)
225 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
226 xscale = 0.0, yscale = 0.0)
227 alignment.add(self._fsPayload)
228 table.attach(alignment, 3, 4, row, row+1)
229
230 table.attach(Gtk.Label("kg"), 4, 5, row, row+1)
231
232 row += 1
233
234 label = Gtk.Label(xstr("weighthelp_dow"))
235 label.set_use_markup(True)
236 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
237 xscale = 0.0, yscale = 0.0)
238 alignment.add(label)
239 table.attach(alignment, 0, 1, row, row+1)
240
241 self._dow = Gtk.Label("35000")
242 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
243 xscale = 0.0, yscale = 0.0)
244 alignment.add(self._dow)
245 table.attach(alignment, 1, 2, row, row+1)
246
247 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
248
249 self._fsDOW = Gtk.Label("33012")
250 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
251 xscale = 0.0, yscale = 0.0)
252 alignment.add(self._fsDOW)
253 table.attach(alignment, 3, 4, row, row+1)
254
255 table.attach(Gtk.Label("kg"), 4, 5, row, row+1)
256
257 row += 1
258
259 table.attach(Gtk.HSeparator(), 1, 2, row, row+1)
260
261 table.attach(Gtk.HSeparator(), 3, 4, row, row+1)
262
263 row += 1
264
265 label = Gtk.Label("<b>" + xstr("weighthelp_zfw") + "</b>")
266 label.set_use_markup(True)
267 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
268 xscale = 0.0, yscale = 0.0)
269 alignment.add(label)
270 table.attach(alignment, 0, 1, row, row+1)
271
272 self._zfw = Gtk.Label("<b>122000</b>")
273 self._zfw.set_use_markup(True)
274 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
275 xscale = 0.0, yscale = 0.0)
276 alignment.add(self._zfw)
277 table.attach(alignment, 1, 2, row, row+1)
278
279 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
280
281 self._fsZFW = Gtk.Label("<b>124000</b>")
282 self._fsZFW.set_use_markup(True)
283 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
284 xscale = 0.0, yscale = 0.0)
285 alignment.add(self._fsZFW)
286 table.attach(alignment, 3, 4, row, row+1)
287
288 table.attach(Gtk.Label("kg"), 4, 5, row, row+1)
289
290 row += 1
291
292 table.attach(Gtk.HSeparator(), 0, 5, row, row+1)
293
294 row += 1
295
296 label = Gtk.Label(xstr("weighthelp_gross"))
297 label.set_use_markup(True)
298 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
299 xscale = 0.0, yscale = 0.0)
300 alignment.add(label)
301 table.attach(alignment, 0, 1, row, row+1)
302
303 self._fsGross = Gtk.Label("124000")
304 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
305 xscale = 0.0, yscale = 0.0)
306 alignment.add(self._fsGross)
307 table.attach(alignment, 3, 4, row, row+1)
308
309 table.attach(Gtk.Label("kg"), 4, 5, row, row+1)
310
311 row += 1
312
313 label = Gtk.Label(xstr("weighthelp_mzfw"))
314 label.set_use_markup(True)
315 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
316 xscale = 0.0, yscale = 0.0)
317 alignment.add(label)
318 table.attach(alignment, 0, 1, row, row+1)
319
320 self._mzfw = Gtk.Label("35000")
321 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
322 xscale = 0.0, yscale = 0.0)
323 alignment.add(self._mzfw)
324 table.attach(alignment, 1, 2, row, row+1)
325
326 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
327
328 row += 1
329
330 label = Gtk.Label(xstr("weighthelp_mtow"))
331 label.set_use_markup(True)
332 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
333 xscale = 0.0, yscale = 0.0)
334 alignment.add(label)
335 table.attach(alignment, 0, 1, row, row+1)
336
337 self._mtow = Gtk.Label("35000")
338 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
339 xscale = 0.0, yscale = 0.0)
340 alignment.add(self._mtow)
341 table.attach(alignment, 1, 2, row, row+1)
342
343 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
344
345 row += 1
346
347 label = Gtk.Label(xstr("weighthelp_mlw"))
348 label.set_use_markup(True)
349 alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
350 xscale = 0.0, yscale = 0.0)
351 alignment.add(label)
352 table.attach(alignment, 0, 1, row, row+1)
353
354 self._mlw = Gtk.Label("35000")
355 alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
356 xscale = 0.0, yscale = 0.0)
357 alignment.add(self._mlw)
358 table.attach(alignment, 1, 2, row, row+1)
359
360 table.attach(Gtk.Label("kg"), 2, 3, row, row+1)
361
362 self.show_all()
363
364 def disable(self):
365 """Disable the widget."""
366 self._mainBox.set_sensitive(False)
367
368 def enable(self):
369 """Enable the widget."""
370 self._mainBox.set_sensitive(True)
371
372 def reset(self):
373 """Reset all calculated and FS data."""
374
375 self._usingHelp.set_active(False)
376 self._usingHelp.set_sensitive(True)
377 self._weightsTable.set_sensitive(False)
378
379 self._flightType = -1
380 self._dowCabinCrew = -1
381 self._cockpitCrew = -1
382 self._cabinCrew = -1
383 self._pax = -1
384 self._children = -1
385 self._infants = -1
386 self._bag = -1
387 self._cargo = -1
388 self._mail = -1
389 self._dowValue = -1
390 self._mzfwValue = -1
391 self._mtowValue = -1
392 self._mlwValue = -1
393
394 self._fsPayloadValue = -1
395 self._fsDOWValue = -1
396 self._fsZFWValue = -1
397 self._fsGrossValue = -1
398
399 self._setupCalculated()
400 self._setupFS()
401
402 def _setupCalculated(self):
403 """Setup the labels for the calculated values."""
404 crewWeight = self._getCrewWeight()
405 if crewWeight is None:
406 self._flightTypeLabel.set_text("-")
407 self._crewLabel.set_text(xstr("weighthelp_crew") % ("-",))
408 self._crewWeight.set_text("-")
409 self._crewInfo.set_text(xstr("weighthelp_crew_info") % ("-",))
410 else:
411 self._flightTypeLabel.set_text(xstr("flighttype_" +
412 const.flightType2string(self._flightType)))
413 self._crewLabel.set_text(xstr("weighthelp_crew") %
414 (str(self._cockpitCrew) + "+" +
415 str(self._cabinCrew),))
416 self._crewWeight.set_text("%.0f" % (crewWeight,))
417 self._crewInfo.set_text(xstr("weighthelp_crew_info") %
418 (self._dowCabinCrew,))
419
420
421 paxWeight = self._getPaxWeight()
422 if paxWeight<0:
423 self._paxLabel.set_text(xstr("weighthelp_pax") % ("-",))
424 self._paxWeight.set_text("-")
425 self._paxInfo.set_text(xstr("weighthelp_pax_info") % ("-", "-", "-"))
426 else:
427 self._paxLabel.set_text(xstr("weighthelp_pax") %
428 (str(self._pax) + "+" +
429 str(self._children) + "+" +
430 str(self._infants),))
431 self._paxWeight.set_text("%.0f" % (paxWeight,))
432 self._paxInfo.set_text(xstr("weighthelp_pax_info") %
433 (const.getPassengerWeight(self._flightType),
434 const.WEIGHT_CHILD, const.WEIGHT_INFANT))
435
436 self._setWeightLabel(self._bagWeight, self._bag)
437
438 self._setWeightLabel(self._cargoWeight, self._cargo)
439
440 self._setWeightLabel(self._mailWeight, self._mail)
441
442 (payload, zfw) = self._calculateWeights()
443
444 self._setWeightLabel(self._payload, payload, bold = True)
445
446 self._setWeightLabel(self._dow, self._dowValue)
447
448 if zfw<0:
449 self._zfw.set_text("-")
450 else:
451 markup = "%.0f" % (zfw,)
452 if self._mzfwValue>0 and zfw>self._mzfwValue:
453 markup = '<span foreground="red">' + markup + '</span>'
454 markup = '<b>' + markup + '</b>'
455 self._zfw.set_markup(markup)
456
457 self._setWeightLabel(self._mzfw, self._mzfwValue)
458
459 self._setWeightLabel(self._mtow, self._mtowValue)
460
461 self._setWeightLabel(self._mlw, self._mlwValue)
462
463 def _setupFS(self):
464 if self._dowValue<0:
465 self._dow.set_text("-")
466 else:
467 self._dow.set_text("%.0f" % (self._dowValue,))
468
469 """Setup the labels for the FS values."""
470 (payload, zfw) = self._calculateWeights()
471
472 if self._fsPayloadValue<0:
473 self._fsPayload.set_text("-")
474 else:
475 markup = WeightHelp._getMarkup(self._fsPayloadValue, payload,
476 PayloadChecker.TOLERANCE)
477 self._fsPayload.set_markup("<b>" + markup + "</b>")
478
479 if self._fsDOWValue<0:
480 self._fsDOW.set_text("-")
481 else:
482 markup = WeightHelp._getMarkup(self._fsDOWValue, self._dowValue,
483 PayloadChecker.TOLERANCE)
484 self._fsDOW.set_markup(markup)
485
486 if self._fsZFWValue<0:
487 self._fsZFW.set_text("-")
488 else:
489 markup = WeightHelp._getMarkup(self._fsZFWValue, zfw,
490 PayloadChecker.TOLERANCE)
491 self._fsZFW.set_markup("<b>" + markup + "</b>")
492
493 self._setWeightLabel(self._fsGross, self._fsGrossValue)
494
495 def _getCrewWeight(self):
496 """Get the crew weight for the flight."""
497 if self._cockpitCrew>=0 and self._dowCabinCrew>=0 and self._cabinCrew>=0:
498 return (self._cabinCrew - self._dowCabinCrew) * const.WEIGHT_CABIN_CREW
499 else:
500 return None
501
502 def _getPaxWeight(self):
503 """Get the passenger weight for the flight."""
504 if self._flightType>=0 and self._pax>=0 and self._children>=0 and \
505 self._infants>=0:
506 return self._pax * const.getPassengerWeight(self._flightType) + \
507 self._children * const.WEIGHT_CHILD + \
508 self._infants * const.WEIGHT_INFANT
509 else:
510 return -1
511
512 def _calculateWeights(self):
513 """Calculate the payload and the zero-fuel weight.
514
515 It returns a tuple with these two items. If any of the items cannot be
516 calculated, that is -1."""
517 crewWeight = self._getCrewWeight()
518 paxWeight = self._getPaxWeight()
519 if crewWeight is None or paxWeight<0 or \
520 self._bag<0 or self._cargo<0 or self._mail<0:
521 payload = -1
522 else:
523 payload = crewWeight + paxWeight + self._bag + self._cargo + self._mail
524
525 if payload<0 or self._dowValue<0:
526 zfw = -1
527 else:
528 zfw = payload + self._dowValue
529
530 return (payload, zfw)
531
532 def _usingHelpToggled(self, button):
533 """Called when the Using help button is toggled."""
534 assert self._usingHelp.get_active()
535 self._usingHelp.set_sensitive(False)
536
537 self._gui.logger.untimedMessage("The weight calculation help function was used by the pilot")
538
539 bookedFlight = self._gui.bookedFlight
540 self._flightType = bookedFlight.flightType
541 self._dowCabinCrew = bookedFlight.dowNumCabinCrew
542 self._cockpitCrew = self._gui.numCockpitCrew
543 self._cabinCrew = self._gui.numCabinCrew
544 self._pax = self._gui.numPassengers
545 self._children = self._gui.numChildren
546 self._infants = self._gui.numInfants
547 self._bag = self._gui.bagWeight
548 self._cargo = self._gui.cargoWeight
549 self._mail = self._gui.mailWeight
550 self._dowValue = bookedFlight.dow
551
552 aircraft = self._gui.flight.aircraft
553 self._mzfwValue = aircraft.mzfw
554 self._mtowValue = aircraft.mtow
555 self._mlwValue = aircraft.mlw
556
557 self._setupCalculated()
558 self._weightsTable.set_sensitive(True)
559
560 def _fsButtonClicked(self, button):
561 """Callback for the FS button being clicked."""
562 gui = self._gui
563 gui.beginBusy(xstr("weighthelp_busy"))
564 gui.simulator.requestWeights(self._handleWeights)
565
566 def _handleWeights(self, dow, payload, zfw, grossWeight):
567 """Handle the given weights."""
568 GObject.idle_add(self._processWeights, dow, payload, zfw, grossWeight)
569
570 def _processWeights(self, dow, payload, zfw, grossWeight):
571 """Process the given weights."""
572 self._gui.endBusy()
573 if self._usingHelp.get_active():
574 self._fsPayloadValue = payload
575 self._fsDOWValue = dow
576 self._fsZFWValue = zfw
577 self._fsGrossValue = grossWeight
578 self._setupFS()
579
580 def _setWeightLabel(self, label, weight, bold = False):
581 """Set the given weight label to the given weight."""
582 if weight<0:
583 label.set_text("-")
584 else:
585 markup = "%.0f" % (weight,)
586 if bold: markup = "<b>" + markup + "</b>"
587 label.set_markup(markup)
588
589
Note: See TracBrowser for help on using the repository browser.