from mlx.gui.common import *
from mlx.i18n import xstr
from mlx.checks import PayloadChecker
#-------------------------------------------------------------------------------
## @package mlx.gui.weighthelp
#
# The weight calculation help tab.
#
# This module implements the tab containing the weight calculation help.
#-------------------------------------------------------------------------------
class WeightHelp(Gtk.VBox):
"""The weight calculation help tab."""
@staticmethod
def _getMarkup(value, expectedValue = None, tolerance = None):
"""Get the markup for the given value.
If it is too much different from the expected value, it will be
colored yellow (if within the tolerance), or red (if out of the tolerance)."""
markup = "%.0f" % (value,)
if expectedValue is not None and tolerance is not None:
colour = None
diff = abs(value - expectedValue)
if diff>tolerance: colour = "red"
elif (diff*10)>=tolerance: colour = "orange"
else: colour = "darkgreen"
if colour is not None:
markup = '' + markup + ''
return markup
def __init__(self, gui):
"""Construct the tab."""
super(WeightHelp, self).__init__()
self._gui = gui
mainAlignment = Gtk.Alignment(xalign = 0.5, yalign = 0.5,
xscale = 1.0, yscale = 1.0)
mainAlignment.set_padding(padding_top = 4, padding_bottom = 4,
padding_left = 12, padding_right = 12)
self.add(mainAlignment)
self._mainBox = mainBox = Gtk.VBox()
mainAlignment.add(mainBox)
self._usingHelp = Gtk.CheckButton(xstr("weighthelp_usinghelp"))
self._usingHelp.set_use_underline(True)
self._usingHelp.set_tooltip_text(xstr("weighthelp_usinghelp_tooltip"))
self._usingHelp.connect("toggled", self._usingHelpToggled)
mainBox.pack_start(self._usingHelp, False, False, 4)
self._weightsTable = table = Gtk.Table(16, 5)
table.set_homogeneous(False)
table.set_row_spacings(4)
table.set_col_spacings(16)
alignment = Gtk.Alignment(xalign = 0.5, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(table)
mainBox.pack_start(alignment, True, True, 4)
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.0,
xscale = 0.0, yscale = 0.0)
alignment.set_padding(padding_bottom = 16, padding_top = 0,
padding_left = 0, padding_right = 0)
label = Gtk.Label(xstr("weighthelp_header_calculated"))
label.set_use_markup(True)
# FIXME: should be a constant in common
label.set_justify(Gtk.Justification.CENTER)
alignment.add(label)
table.attach(alignment, 1, 2, 0, 1)
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.0,
xscale = 0.0, yscale = 0.0)
alignment.set_padding(padding_bottom = 16, padding_top = 0,
padding_left = 0, padding_right = 0)
button = Gtk.Button(xstr("weighthelp_header_simulator"))
button.set_tooltip_markup(xstr("weighthelp_header_simulator_tooltip"))
button.connect("clicked", self._fsButtonClicked)
label = button.get_child()
label.set_justify(Gtk.Justification.CENTER)
alignment.add(button)
table.attach(alignment, 3, 4, 0, 1)
self._crewLabel = Gtk.Label(xstr("weighthelp_crew") % ("99",))
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._crewLabel)
table.attach(alignment, 0, 1, 1, 2)
self._crewWeight = Gtk.Label("0")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._crewWeight)
table.attach(alignment, 1, 2, 1, 2)
table.attach(Gtk.Label("kg"), 2, 3, 1, 2)
text = xstr("weighthelp_pax") % ("999",)
self._paxLabel = Gtk.Label(text)
self._paxLabel.set_width_chars(len(text))
self._paxLabel.set_alignment(0.0, 0.5)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._paxLabel)
table.attach(alignment, 0, 1, 2, 3)
self._paxWeight = Gtk.Label("20000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._paxWeight)
table.attach(alignment, 1, 2, 2, 3)
table.attach(Gtk.Label("kg"), 2, 3, 2, 3)
label = Gtk.Label(xstr("weighthelp_baggage"))
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 3, 4)
self._bagWeight = Gtk.Label("2000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._bagWeight)
table.attach(alignment, 1, 2, 3, 4)
table.attach(Gtk.Label("kg"), 2, 3, 3, 4)
label = Gtk.Label(xstr("weighthelp_cargo"))
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 4, 5)
self._cargoWeight = Gtk.Label("2000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._cargoWeight)
table.attach(alignment, 1, 2, 4, 5)
table.attach(Gtk.Label("kg"), 2, 3, 4, 5)
label = Gtk.Label(xstr("weighthelp_mail"))
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 5, 6)
self._mailWeight = Gtk.Label("2000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._mailWeight)
table.attach(alignment, 1, 2, 5, 6)
table.attach(Gtk.Label("kg"), 2, 3, 5, 6)
table.attach(Gtk.HSeparator(), 1, 2, 6, 7)
label = Gtk.Label("" + xstr("weighthelp_payload") + "")
label.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 7, 8)
self._payload = Gtk.Label("32000")
self._payload.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._payload)
table.attach(alignment, 1, 2, 7, 8)
table.attach(Gtk.Label("kg"), 2, 3, 7, 8)
self._fsPayload = Gtk.Label("32001")
self._fsPayload.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._fsPayload)
table.attach(alignment, 3, 4, 7, 8)
table.attach(Gtk.Label("kg"), 4, 5, 7, 8)
label = Gtk.Label(xstr("weighthelp_dow"))
label.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 8, 9)
self._dow = Gtk.Label("35000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._dow)
table.attach(alignment, 1, 2, 8, 9)
table.attach(Gtk.Label("kg"), 2, 3, 8, 9)
self._fsDOW = Gtk.Label("33012")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._fsDOW)
table.attach(alignment, 3, 4, 8, 9)
table.attach(Gtk.Label("kg"), 4, 5, 8, 9)
table.attach(Gtk.HSeparator(), 1, 2, 9, 10)
table.attach(Gtk.HSeparator(), 3, 4, 9, 10)
label = Gtk.Label("" + xstr("weighthelp_zfw") + "")
label.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 10, 11)
self._zfw = Gtk.Label("122000")
self._zfw.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._zfw)
table.attach(alignment, 1, 2, 10, 11)
table.attach(Gtk.Label("kg"), 2, 3, 10, 11)
self._fsZFW = Gtk.Label("124000")
self._fsZFW.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._fsZFW)
table.attach(alignment, 3, 4, 10, 11)
table.attach(Gtk.Label("kg"), 4, 5, 10, 11)
table.attach(Gtk.HSeparator(), 0, 5, 11, 12)
label = Gtk.Label(xstr("weighthelp_gross"))
label.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 12, 13)
self._fsGross = Gtk.Label("124000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._fsGross)
table.attach(alignment, 3, 4, 12, 13)
table.attach(Gtk.Label("kg"), 4, 5, 12, 13)
label = Gtk.Label(xstr("weighthelp_mzfw"))
label.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 13, 14)
self._mzfw = Gtk.Label("35000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._mzfw)
table.attach(alignment, 1, 2, 13, 14)
table.attach(Gtk.Label("kg"), 2, 3, 13, 14)
label = Gtk.Label(xstr("weighthelp_mtow"))
label.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 14, 15)
self._mtow = Gtk.Label("35000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._mtow)
table.attach(alignment, 1, 2, 14, 15)
table.attach(Gtk.Label("kg"), 2, 3, 14, 15)
label = Gtk.Label(xstr("weighthelp_mlw"))
label.set_use_markup(True)
alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(label)
table.attach(alignment, 0, 1, 15, 16)
self._mlw = Gtk.Label("35000")
alignment = Gtk.Alignment(xalign = 1.0, yalign = 0.5,
xscale = 0.0, yscale = 0.0)
alignment.add(self._mlw)
table.attach(alignment, 1, 2, 15, 16)
table.attach(Gtk.Label("kg"), 2, 3, 15, 16)
self.show_all()
def disable(self):
"""Disable the widget."""
self._mainBox.set_sensitive(False)
def enable(self):
"""Enable the widget."""
self._mainBox.set_sensitive(True)
def reset(self):
"""Reset all calculated and FS data."""
self._usingHelp.set_active(False)
self._usingHelp.set_sensitive(True)
self._weightsTable.set_sensitive(False)
self._crew = -1
self._pax = -1
self._humanWeight = 82.0
self._bag = -1
self._cargo = -1
self._mail = -1
self._dowValue = -1
self._mzfwValue = -1
self._mtowValue = -1
self._mlwValue = -1
self._fsPayloadValue = -1
self._fsDOWValue = -1
self._fsZFWValue = -1
self._fsGrossValue = -1
self._setupCalculated()
self._setupFS()
def _setupCalculated(self):
"""Setup the labels for the calculated values."""
if self._crew<0:
self._crewLabel.set_text(xstr("weighthelp_crew") % ("-",))
self._crewWeight.set_text("-")
else:
self._crewLabel.set_text(xstr("weighthelp_crew") % (str(self._crew),))
crewWeight = self._crew * self._humanWeight
self._crewWeight.set_text("%.0f" % (crewWeight,))
if self._pax<0:
self._paxLabel.set_text(xstr("weighthelp_pax") % ("-",))
self._paxWeight.set_text("-")
else:
self._paxLabel.set_text(xstr("weighthelp_pax") % (str(self._pax),))
paxWeight = self._pax * self._humanWeight
self._paxWeight.set_text("%.0f" % (paxWeight,))
self._setWeightLabel(self._bagWeight, self._bag)
self._setWeightLabel(self._cargoWeight, self._cargo)
self._setWeightLabel(self._mailWeight, self._mail)
(payload, zfw) = self._calculateWeights()
self._setWeightLabel(self._payload, payload, bold = True)
self._setWeightLabel(self._dow, self._dowValue)
if zfw<0:
self._zfw.set_text("-")
else:
markup = "%.0f" % (zfw,)
if self._mzfwValue>0 and zfw>self._mzfwValue:
markup = '' + markup + ''
markup = '' + markup + ''
self._zfw.set_markup(markup)
self._setWeightLabel(self._mzfw, self._mzfwValue)
self._setWeightLabel(self._mtow, self._mtowValue)
self._setWeightLabel(self._mlw, self._mlwValue)
def _setupFS(self):
if self._dowValue<0:
self._dow.set_text("-")
else:
self._dow.set_text("%.0f" % (self._dowValue,))
"""Setup the labels for the FS values."""
(payload, zfw) = self._calculateWeights()
if self._fsPayloadValue<0:
self._fsPayload.set_text("-")
else:
markup = WeightHelp._getMarkup(self._fsPayloadValue, payload,
PayloadChecker.TOLERANCE)
self._fsPayload.set_markup("" + markup + "")
if self._fsDOWValue<0:
self._fsDOW.set_text("-")
else:
markup = WeightHelp._getMarkup(self._fsDOWValue, self._dowValue,
PayloadChecker.TOLERANCE)
self._fsDOW.set_markup(markup)
if self._fsZFWValue<0:
self._fsZFW.set_text("-")
else:
markup = WeightHelp._getMarkup(self._fsZFWValue, zfw,
PayloadChecker.TOLERANCE)
self._fsZFW.set_markup("" + markup + "")
self._setWeightLabel(self._fsGross, self._fsGrossValue)
def _calculateWeights(self):
"""Calculate the payload and the zero-fuel weight.
It returns a tuple with these two items. If any of the items cannot be
calculated, that is -1."""
if self._crew<0 or self._pax<0 or \
self._bag<0 or self._cargo<0 or self._mail<0:
payload = -1
else:
payload = (self._crew + self._pax) * self._humanWeight + \
self._bag + self._cargo + self._mail
if payload<0 or self._dowValue<0:
zfw = -1
else:
zfw = payload + self._dowValue
return (payload, zfw)
def _usingHelpToggled(self, button):
"""Called when the Using help button is toggled."""
assert self._usingHelp.get_active()
self._usingHelp.set_sensitive(False)
self._gui.logger.untimedMessage("The weight calculation help function was used by the pilot")
self._crew = self._gui.numCrew
self._pax = self._gui.numPassengers
self._bag = self._gui.bagWeight
self._cargo = self._gui.cargoWeight
self._mail = self._gui.mailWeight
aircraft = self._gui.flight.aircraft
self._humanWeight = aircraft.humanWeight
self._dowValue = aircraft.dow
self._mzfwValue = aircraft.mzfw
self._mtowValue = aircraft.mtow
self._mlwValue = aircraft.mlw
self._setupCalculated()
self._weightsTable.set_sensitive(True)
def _fsButtonClicked(self, button):
"""Callback for the FS button being clicked."""
gui = self._gui
gui.beginBusy(xstr("weighthelp_busy"))
gui.simulator.requestWeights(self._handleWeights)
def _handleWeights(self, dow, payload, zfw, grossWeight):
"""Handle the given weights."""
GObject.idle_add(self._processWeights, dow, payload, zfw, grossWeight)
def _processWeights(self, dow, payload, zfw, grossWeight):
"""Process the given weights."""
self._gui.endBusy()
if self._usingHelp.get_active():
self._fsPayloadValue = payload
self._fsDOWValue = dow
self._fsZFWValue = zfw
self._fsGrossValue = grossWeight
self._setupFS()
def _setWeightLabel(self, label, weight, bold = False):
"""Set the given weight label to the given weight."""
if weight<0:
label.set_text("-")
else:
markup = "%.0f" % (weight,)
if bold: markup = "" + markup + ""
label.set_markup(markup)