source: src/mlx/gui/weighthelp.py@ 1143:dbe6c974f227

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

The tables on the payload page and the weight help are easier to extend (re #386).

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