from .common import * from .dcdata import getTable from .info import FlightInfo from .flight import comboModel from mlx.pirep import PIREP from mlx.flight import Flight from mlx.const import * import time import re #------------------------------------------------------------------------------ ## @package mlx.gui.pirep # # The detailed PIREP viewer and editor windows. # # The \ref PIREPViewer class is a dialog displaying all information found in a # PIREP. It consists of three tabs. The Data tab displays the simple, # itemizable data. The Comments & defects tab contains the flight comments and # defects, while the Log tab contains the flight log collected by the # \ref mlx.logger.Logger "logger". #------------------------------------------------------------------------------ class MessageFrame(Gtk.Frame): """A frame containing the information about a PIREP message. It consists of a text view with the heading information (author, time) and another text view with the actual message.""" def __init__(self, message, senderPID, senderName): """Construct the frame.""" Gtk.Frame.__init__(self) vbox = Gtk.VBox() self._heading = heading = Gtk.TextView() heading.set_editable(False) heading.set_can_focus(False) heading.set_wrap_mode(Gtk.WrapMode.WORD) heading.set_size_request(-1, 16) buffer = heading.get_buffer() self._headingTag = buffer.create_tag("heading", weight=Pango.Weight.BOLD) buffer.set_text("%s - %s" % (senderPID, senderName)) buffer.apply_tag(self._headingTag, buffer.get_start_iter(), buffer.get_end_iter()) headingAlignment = Gtk.Alignment(xalign = 0.0, yalign = 0.0, xscale = 1.0, yscale = 0.0) headingAlignment.set_padding(padding_top = 0, padding_bottom = 0, padding_left = 2, padding_right = 2) headingAlignment.add(heading) vbox.pack_start(headingAlignment, True, True, 4) self._messageView = messageView = Gtk.TextView() messageView.set_wrap_mode(Gtk.WrapMode.WORD) messageView.set_editable(False) messageView.set_can_focus(False) messageView.set_accepts_tab(False) messageView.set_size_request(-1, -1) buffer = messageView.get_buffer() buffer.set_text(message) vbox.pack_start(messageView, True, True, 4) self.add(vbox) self.show_all() styleContext = self.get_style_context() color = styleContext.get_background_color(Gtk.StateFlags.NORMAL) heading.override_background_color(0, color) #------------------------------------------------------------------------------- class MessagesWidget(Gtk.Frame): """The widget for the messages.""" @staticmethod def getFaultFrame(alignment): """Get the fault frame from the given alignment.""" return alignment.get_children()[0] def __init__(self, gui): Gtk.Frame.__init__(self) self._gui = gui self.set_label(xstr("pirep_messages")) label = self.get_label_widget() label.set_use_underline(True) alignment = Gtk.Alignment(xalign = 0.5, yalign = 0.5, xscale = 1.0, yscale = 1.0) alignment.set_padding(padding_top = 4, padding_bottom = 4, padding_left = 4, padding_right = 4) self._outerBox = outerBox = Gtk.EventBox() outerBox.add(alignment) self._innerBox = innerBox = Gtk.EventBox() alignment.add(self._innerBox) alignment = Gtk.Alignment(xalign = 0.5, yalign = 0.5, xscale = 1.0, yscale = 1.0) alignment.set_padding(padding_top = 0, padding_bottom = 0, padding_left = 0, padding_right = 0) innerBox.add(alignment) scroller = Gtk.ScrolledWindow() scroller.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scroller.set_shadow_type(Gtk.ShadowType.NONE) self._messages = Gtk.VBox() self._messages.set_homogeneous(False) scroller.add_with_viewport(self._messages) alignment.add(scroller) self._messageWidgets = [] self.add(outerBox) self.show_all() def addMessage(self, message): """Add a message from the given sender.""" alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.0, xscale = 1.0, yscale = 0.0) alignment.set_padding(padding_top = 2, padding_bottom = 2, padding_left = 4, padding_right = 4) messageFrame = MessageFrame(message.message, message.senderPID, message.senderName) alignment.add(messageFrame) self._messages.pack_start(alignment, False, False, 4) self._messages.show_all() self._messageWidgets.append((alignment, messageFrame)) def reset(self): """Reset the widget by removing all messages.""" for (alignment, messageFrame) in self._messageWidgets: self._messages.remove(alignment) self._messages.show_all() self._messageWidgets = [] #------------------------------------------------------------------------------ class PIREPViewer(Gtk.Dialog): """The dialog for PIREP viewing.""" @staticmethod def createFrame(label): """Create a frame with the given label. The frame will contain an alignment to properly distance the insides. The alignment will contain a VBox to contain the real contents. The function returns a tuple with the following items: - the frame, - the inner VBox.""" frame = Gtk.Frame(label = label) alignment = Gtk.Alignment(xalign = 0.0, yalign = 0.0, xscale = 1.0, yscale = 1.0) frame.add(alignment) alignment.set_padding(padding_top = 4, padding_bottom = 4, padding_left = 4, padding_right = 4) box = Gtk.VBox() alignment.add(box) return (frame, box) @staticmethod def getLabel(text, extraText = ""): """Get a bold label with the given text.""" label = Gtk.Label("" + text + "" + extraText) label.set_use_markup(True) label.set_alignment(0.0, 0.5) return label @staticmethod def getDataLabel(width = None, xAlignment = 0.0): """Get a bold label with the given text.""" label = Gtk.Label() if width is not None: label.set_width_chars(width) label.set_alignment(xAlignment, 0.5) return label @staticmethod def getTextWindow(heightRequest = 40, editable = False): """Get a scrollable text window. Returns a tuple of the following items: - the window, - the text view.""" scrolledWindow = Gtk.ScrolledWindow() scrolledWindow.set_shadow_type(Gtk.ShadowType.IN) scrolledWindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) textView = Gtk.TextView() textView.set_wrap_mode(Gtk.WrapMode.WORD) textView.set_editable(editable) textView.set_cursor_visible(editable) textView.set_size_request(-1, heightRequest) scrolledWindow.add(textView) return (scrolledWindow, textView) @staticmethod def tableAttach(table, column, row, labelText, width = None, dataLabelXAlignment = 0.0): """Attach a labeled data to the given column and row of the table. If width is given, that will be the width of the data label. Returns the data label attached.""" dataBox = Gtk.HBox() table.attach(dataBox, column, column+1, row, row+1) dataLabel = PIREPViewer.addLabeledData(dataBox, labelText, width = width) dataLabel.set_alignment(dataLabelXAlignment, 0.5) return dataLabel @staticmethod def addLabeledData(hBox, labelText, width = None, dataPadding = 8): """Add a label and a data label to the given HBox. Returns the data label.""" label = PIREPViewer.getLabel(labelText) hBox.pack_start(label, False, False, 0) dataLabel = PIREPViewer.getDataLabel(width = width) hBox.pack_start(dataLabel, False, False, dataPadding) return dataLabel @staticmethod def addHFiller(hBox, width = 8): """Add a filler to the given horizontal box.""" filler = Gtk.Alignment(xalign = 0.0, yalign = 0.0, xscale = 1.0, yscale = 1.0) filler.set_size_request(width, -1) hBox.pack_start(filler, False, False, 0) @staticmethod def addVFiller(vBox, height = 4): """Add a filler to the given vertical box.""" filler = Gtk.Alignment(xalign = 0.0, yalign = 0.0, xscale = 1.0, yscale = 1.0) filler.set_size_request(-1, height) vBox.pack_start(filler, False, False, 0) @staticmethod def timestamp2text(label, timestamp): """Convert the given timestamp into a text containing the hour and minute in UTC and put that text into the given label.""" tm = time.gmtime(timestamp) label.set_text("%02d:%02d" % (tm.tm_hour, tm.tm_min)) def __init__(self, gui, showMessages = False): """Construct the PIREP viewer.""" super(PIREPViewer, self).__init__(title = WINDOW_TITLE_BASE + " - " + xstr("pirepView_title"), parent = gui.mainWindow) self.set_resizable(False) self._gui = gui contentArea = self.get_content_area() self._notebook = Gtk.Notebook() contentArea.pack_start(self._notebook, False, False, 4) dataTab = self._buildDataTab() label = Gtk.Label(xstr("pirepView_tab_data")) label.set_use_underline(True) label.set_tooltip_text(xstr("pirepView_tab_data_tooltip")) self._notebook.append_page(dataTab, label) commentsTab = self._buildCommentsTab() label = Gtk.Label(xstr("pirepView_tab_comments")) label.set_use_underline(True) label.set_tooltip_text(xstr("pirepView_tab_comments_tooltip")) self._notebook.append_page(commentsTab, label) logTab = self._buildLogTab() label = Gtk.Label(xstr("pirepView_tab_log")) label.set_use_underline(True) label.set_tooltip_text(xstr("pirepView_tab_log_tooltip")) self._notebook.append_page(logTab, label) self._showMessages = showMessages if showMessages: messagesTab = self._buildMessagesTab() label = Gtk.Label(xstr("pirepView_tab_messages")) label.set_use_underline(True) label.set_tooltip_text(xstr("pirepView_tab_messages_tooltip")) self._notebook.append_page(messagesTab, label) self._okButton = self.add_button(xstr("button_ok"), Gtk.ResponseType.OK) self._okButton.set_can_default(True) def setPIREP(self, pirep): """Setup the data in the dialog from the given PIREP.""" bookedFlight = pirep.bookedFlight self._callsign.set_text(bookedFlight.callsign) self._tailNumber.set_text(bookedFlight.tailNumber) aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower()) self._aircraftType.set_text(aircraftType) self._departureICAO.set_text(bookedFlight.departureICAO) self._departureTime.set_text("%02d:%02d" % \ (bookedFlight.departureTime.hour, bookedFlight.departureTime.minute)) self._arrivalICAO.set_text(bookedFlight.arrivalICAO) self._arrivalTime.set_text("%02d:%02d" % \ (bookedFlight.arrivalTime.hour, bookedFlight.arrivalTime.minute)) self._numPassengers.set_text(str(bookedFlight.numPassengers) + " + " + str(bookedFlight.numChildren) + " + " + str(bookedFlight.numInfants)) self._numCrew.set_text(str(bookedFlight.numCockpitCrew) + " + " + str(bookedFlight.numCabinCrew)) self._bagWeight.set_text(str(bookedFlight.bagWeight)) self._cargoWeight.set_text(str(bookedFlight.cargoWeight)) self._mailWeight.set_text(str(bookedFlight.mailWeight)) self._route.get_buffer().set_text(bookedFlight.route) self._filedCruiseLevel.set_text("FL" + str(pirep.filedCruiseAltitude/100)) if pirep.cruiseAltitude != pirep.filedCruiseAltitude: self._modifiedCruiseLevel.set_text("FL" + str(pirep.cruiseAltitude/100)) else: self._modifiedCruiseLevel.set_text("-") self._userRoute.get_buffer().set_text(pirep.route) self._departureMETAR.get_buffer().set_text(pirep.departureMETAR) self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR) self._departureRunway.set_text(pirep.departureRunway) self._sid.set_text(pirep.sid) self._star.set_text("-" if pirep.star is None else pirep.star) self._transition.set_text("-" if pirep.transition is None else pirep.transition) self._approachType.set_text(pirep.approachType) self._arrivalRunway.set_text(pirep.arrivalRunway) PIREPViewer.timestamp2text(self._blockTimeStart, pirep.blockTimeStart) PIREPViewer.timestamp2text(self._blockTimeEnd, pirep.blockTimeEnd) PIREPViewer.timestamp2text(self._flightTimeStart, pirep.flightTimeStart) PIREPViewer.timestamp2text(self._flightTimeEnd, pirep.flightTimeEnd) self._flownDistance.set_text("%.1f" % (pirep.flownDistance,)) self._fuelUsed.set_text("%.0f" % (pirep.fuelUsed,)) rating = pirep.rating if rating<0: self._rating.set_markup('NO GO') else: self._rating.set_text("%.1f %%" % (rating,)) self._flownNumCabinCrew.set_text("%d" % (pirep.numCabinCrew,)) self._flownNumPassengers.set_text("%d" % (pirep.numPassengers,)) self._flownBagWeight.set_text("%.0f" % (pirep.bagWeight,)) self._flownCargoWeight.set_text("%.0f" % (pirep.cargoWeight,)) self._flownMailWeight.set_text("%.0f" % (pirep.mailWeight,)) self._flightType.set_text(xstr("flighttype_" + flightType2string(pirep.bookedFlight.flightType))) self._online.set_text(xstr("pirepView_" + ("yes" if pirep.online else "no"))) delayCodes = "" for code in pirep.delayCodes: if delayCodes: delayCodes += ", " delayCodes += code self._delayCodes.get_buffer().set_text(delayCodes) self._comments.get_buffer().set_text(pirep.comments) self._flightDefects.get_buffer().set_text(pirep.flightDefects) logBuffer = self._log.get_buffer() logBuffer.set_text("") lineIndex = 0 for (timeStr, line) in pirep.logLines: isFault = lineIndex in pirep.faultLineIndexes appendTextBuffer(logBuffer, formatFlightLogLine(timeStr, line), isFault = isFault) lineIndex += 1 if self._showMessages: self._messages.reset() for message in pirep.messages: self._messages.addMessage(message) self._notebook.set_current_page(0) self._okButton.grab_default() def _buildDataTab(self): """Build the data tab of the viewer.""" table = Gtk.Table(1, 2) table.set_row_spacings(4) table.set_col_spacings(16) table.set_homogeneous(True) box1 = Gtk.VBox() table.attach(box1, 0, 1, 0, 1) box2 = Gtk.VBox() table.attach(box2, 1, 2, 0, 1) flightFrame = self._buildFlightFrame() box1.pack_start(flightFrame, False, False, 4) routeFrame = self._buildRouteFrame() box1.pack_start(routeFrame, False, False, 4) departureFrame = self._buildDepartureFrame() box2.pack_start(departureFrame, True, True, 4) arrivalFrame = self._buildArrivalFrame() box2.pack_start(arrivalFrame, True, True, 4) statisticsFrame = self._buildStatisticsFrame() box2.pack_start(statisticsFrame, False, False, 4) miscellaneousFrame = self._buildMiscellaneousFrame() box1.pack_start(miscellaneousFrame, False, False, 4) return table def _buildFlightFrame(self): """Build the frame for the flight data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight")) dataBox = Gtk.HBox() mainBox.pack_start(dataBox, False, False, 0) self._callsign = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_callsign"), width = 8) self._tailNumber = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_tailNumber"), width = 7) PIREPViewer.addVFiller(mainBox) dataBox = Gtk.HBox() mainBox.pack_start(dataBox, False, False, 0) self._aircraftType = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_aircraftType"), width = 25) PIREPViewer.addVFiller(mainBox) table = Gtk.Table(3, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) self._departureICAO = \ PIREPViewer.tableAttach(table, 0, 0, xstr("pirepView_departure"), width = 5) self._departureTime = \ PIREPViewer.tableAttach(table, 1, 0, xstr("pirepView_departure_time"), width = 6) self._arrivalICAO = \ PIREPViewer.tableAttach(table, 0, 1, xstr("pirepView_arrival"), width = 5) self._arrivalTime = \ PIREPViewer.tableAttach(table, 1, 1, xstr("pirepView_arrival_time"), width = 6) table = Gtk.Table(3, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) self._numPassengers = \ PIREPViewer.tableAttach(table, 0, 0, xstr("pirepView_numPassengers"), width = 4) self._numCrew = \ PIREPViewer.tableAttach(table, 1, 0, xstr("pirepView_numCrew"), width = 3) self._bagWeight = \ PIREPViewer.tableAttach(table, 0, 1, xstr("pirepView_bagWeight"), width = 5) self._cargoWeight = \ PIREPViewer.tableAttach(table, 1, 1, xstr("pirepView_cargoWeight"), width = 5) self._mailWeight = \ PIREPViewer.tableAttach(table, 2, 1, xstr("pirepView_mailWeight"), width = 5) PIREPViewer.addVFiller(mainBox) mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")), False, False, 0) (routeWindow, self._route) = PIREPViewer.getTextWindow() mainBox.pack_start(routeWindow, False, False, 0) return frame def _buildRouteFrame(self): """Build the frame for the user-specified route and flight level.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route")) levelBox = Gtk.HBox() mainBox.pack_start(levelBox, False, False, 0) self._filedCruiseLevel = \ PIREPViewer.addLabeledData(levelBox, xstr("pirepView_filedCruiseLevel"), width = 6) self._modifiedCruiseLevel = \ PIREPViewer.addLabeledData(levelBox, xstr("pirepView_modifiedCruiseLevel"), width = 6) PIREPViewer.addVFiller(mainBox) (routeWindow, self._userRoute) = PIREPViewer.getTextWindow() mainBox.pack_start(routeWindow, False, False, 0) return frame def _buildDepartureFrame(self): """Build the frame for the departure data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure")) mainBox.pack_start(PIREPViewer.getLabel("METAR:"), False, False, 0) (metarWindow, self._departureMETAR) = \ PIREPViewer.getTextWindow(heightRequest = -1) mainBox.pack_start(metarWindow, True, True, 0) PIREPViewer.addVFiller(mainBox) dataBox = Gtk.HBox() mainBox.pack_start(dataBox, False, False, 0) self._departureRunway = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_runway"), width = 5) self._sid = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_sid"), width = 12) return frame def _buildArrivalFrame(self): """Build the frame for the arrival data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival")) mainBox.pack_start(PIREPViewer.getLabel("METAR:"), False, False, 0) (metarWindow, self._arrivalMETAR) = \ PIREPViewer.getTextWindow(heightRequest = -1) mainBox.pack_start(metarWindow, True, True, 0) PIREPViewer.addVFiller(mainBox) table = Gtk.Table(2, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) self._star = \ PIREPViewer.tableAttach(table, 0, 0, xstr("pirepView_star"), width = 12) self._transition = \ PIREPViewer.tableAttach(table, 1, 0, xstr("pirepView_transition"), width = 12) self._approachType = \ PIREPViewer.tableAttach(table, 0, 1, xstr("pirepView_approachType"), width = 7) self._arrivalRunway = \ PIREPViewer.tableAttach(table, 1, 1, xstr("pirepView_runway"), width = 5) return frame def _buildStatisticsFrame(self): """Build the frame for the statistics data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics")) table = Gtk.Table(4, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) table.set_homogeneous(False) self._blockTimeStart = \ PIREPViewer.tableAttach(table, 0, 0, xstr("pirepView_blockTimeStart"), width = 6) self._blockTimeEnd = \ PIREPViewer.tableAttach(table, 1, 0, xstr("pirepView_blockTimeEnd"), width = 8) self._flightTimeStart = \ PIREPViewer.tableAttach(table, 0, 1, xstr("pirepView_flightTimeStart"), width = 6) self._flightTimeEnd = \ PIREPViewer.tableAttach(table, 1, 1, xstr("pirepView_flightTimeEnd"), width = 6) self._flownDistance = \ PIREPViewer.tableAttach(table, 0, 2, xstr("pirepView_flownDistance"), width = 8) self._fuelUsed = \ PIREPViewer.tableAttach(table, 1, 2, xstr("pirepView_fuelUsed"), width = 6) self._rating = \ PIREPViewer.tableAttach(table, 0, 3, xstr("pirepView_rating"), width = 7) return frame def _buildMiscellaneousFrame(self): """Build the frame for the miscellaneous data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous")) table = Gtk.Table(3, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) self._flownNumPassengers = \ PIREPViewer.tableAttach(table, 0, 0, xstr("pirepView_numPassengers"), width = 4) self._flownNumCabinCrew = \ PIREPViewer.tableAttach(table, 1, 0, xstr("pirepView_numCrew"), width = 3) self._flownBagWeight = \ PIREPViewer.tableAttach(table, 0, 1, xstr("pirepView_bagWeight"), width = 5) self._flownCargoWeight = \ PIREPViewer.tableAttach(table, 1, 1, xstr("pirepView_cargoWeight"), width = 6) self._flownMailWeight = \ PIREPViewer.tableAttach(table, 2, 1, xstr("pirepView_mailWeight"), width = 5) self._flightType = \ PIREPViewer.tableAttach(table, 0, 2, xstr("pirepView_flightType"), width = 15) self._online = \ PIREPViewer.tableAttach(table, 1, 2, xstr("pirepView_online"), width = 5) PIREPViewer.addVFiller(mainBox) mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")), False, False, 0) (textWindow, self._delayCodes) = PIREPViewer.getTextWindow() mainBox.pack_start(textWindow, False, False, 0) return frame def _buildCommentsTab(self): """Build the tab with the comments and flight defects.""" table = Gtk.Table(2, 1) table.set_col_spacings(16) (frame, commentsBox) = \ PIREPViewer.createFrame(xstr("pirepView_comments")) table.attach(frame, 0, 1, 0, 1) (commentsWindow, self._comments) = \ PIREPViewer.getTextWindow(heightRequest = -1) commentsBox.pack_start(commentsWindow, True, True, 0) (frame, flightDefectsBox) = \ PIREPViewer.createFrame(xstr("pirepView_flightDefects")) table.attach(frame, 1, 2, 0, 1) (flightDefectsWindow, self._flightDefects) = \ PIREPViewer.getTextWindow(heightRequest = -1) flightDefectsBox.pack_start(flightDefectsWindow, True, True, 0) return table def _buildLogTab(self): """Build the log tab.""" mainBox = Gtk.VBox() (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1) addFaultTag(self._log.get_buffer()) mainBox.pack_start(logWindow, True, True, 0) return mainBox def _buildMessagesTab(self): """Build the messages tab.""" mainBox = Gtk.VBox() self._messages = MessagesWidget(self._gui) mainBox.pack_start(self._messages, True, True, 0) return mainBox #------------------------------------------------------------------------------ class PIREPEditor(Gtk.Dialog): """A PIREP editor dialog.""" _delayCodeRE = re.compile("([0-9]{2,3})( \([^\)]*\))") @staticmethod def tableAttachWidget(table, column, row, labelText, widget): """Attach the given widget with the given label to the given table. The label will got to cell (column, row), the widget to cell (column+1, row).""" label = Gtk.Label("" + labelText + "") 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, column, column + 1, row, row + 1) table.attach(widget, column + 1, column + 2, row, row + 1) @staticmethod def tableAttachSpinButton(table, column, row, labelText, maxValue, minValue = 0, stepIncrement = 1, pageIncrement = 10, numeric = True, width = 3): """Attach a spin button with the given label to the given table. The label will got to cell (column, row), the spin button to cell (column+1, row).""" button = Gtk.SpinButton() button.set_range(min = minValue, max = maxValue) button.set_increments(step = stepIncrement, page = pageIncrement) button.set_numeric(True) button.set_width_chars(width) button.set_alignment(1.0) PIREPEditor.tableAttachWidget(table, column, row, labelText, button) return button @staticmethod def tableAttachTimeEntry(table, column, row, labelText): """Attach a time entry widget with the given label to the given table. The label will got to cell (column, row), the spin button to cell (column+1, row).""" entry = TimeEntry() entry.set_width_chars(5) entry.set_alignment(1.0) PIREPEditor.tableAttachWidget(table, column, row, labelText, entry) return entry def __init__(self, gui): """Construct the PIREP viewer.""" super(PIREPEditor, self).__init__(title = WINDOW_TITLE_BASE + " - " + xstr("pirepEdit_title"), parent = gui.mainWindow) self.set_resizable(False) self._gui = gui self._pirep = None contentArea = self.get_content_area() self._notebook = Gtk.Notebook() contentArea.pack_start(self._notebook, False, False, 4) dataTab = self._buildDataTab() label = Gtk.Label(xstr("pirepView_tab_data")) label.set_use_underline(True) label.set_tooltip_text(xstr("pirepView_tab_data_tooltip")) self._notebook.append_page(dataTab, label) self._flightInfo = self._buildCommentsTab() label = Gtk.Label(xstr("pirepView_tab_comments")) label.set_use_underline(True) label.set_tooltip_text(xstr("pirepView_tab_comments_tooltip")) self._notebook.append_page(self._flightInfo, label) logTab = self._buildLogTab() label = Gtk.Label(xstr("pirepView_tab_log")) label.set_use_underline(True) label.set_tooltip_text(xstr("pirepView_tab_log_tooltip")) self._notebook.append_page(logTab, label) self.add_button(xstr("button_cancel"), Gtk.ResponseType.CANCEL) self._okButton = self.add_button(xstr("button_save"), Gtk.ResponseType.NONE) self._okButton.connect("clicked", self._okClicked) self._okButton.set_can_default(True) self._modified = False self._toSave = False def setPIREP(self, pirep): """Setup the data in the dialog from the given PIREP.""" self._pirep = pirep bookedFlight = pirep.bookedFlight self._callsign.set_text(bookedFlight.callsign) self._tailNumber.set_text(bookedFlight.tailNumber) aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower()) self._aircraftType.set_text(aircraftType) self._departureICAO.set_text(bookedFlight.departureICAO) self._departureTime.set_text("%02d:%02d" % \ (bookedFlight.departureTime.hour, bookedFlight.departureTime.minute)) self._arrivalICAO.set_text(bookedFlight.arrivalICAO) self._arrivalTime.set_text("%02d:%02d" % \ (bookedFlight.arrivalTime.hour, bookedFlight.arrivalTime.minute)) self._numPassengers.set_text(str(bookedFlight.numPassengers) + " + " + str(bookedFlight.numChildren) + " + " + str(bookedFlight.numInfants)) self._numCrew.set_text(str(bookedFlight.numCockpitCrew) + " + " + str(bookedFlight.numCabinCrew)) self._bagWeight.set_text(str(bookedFlight.bagWeight)) self._cargoWeight.set_text(str(bookedFlight.cargoWeight)) self._mailWeight.set_text(str(bookedFlight.mailWeight)) self._route.get_buffer().set_text(bookedFlight.route) self._filedCruiseLevel.set_value(pirep.filedCruiseAltitude/100) self._modifiedCruiseLevel.set_value(pirep.cruiseAltitude/100) self._userRoute.get_buffer().set_text(pirep.route) self._departureMETAR.get_buffer().set_text(pirep.departureMETAR) self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR) self._departureRunway.set_text(pirep.departureRunway) self._sid.get_child().set_text(pirep.sid) if not pirep.star: self._star.set_active(0) else: self._star.get_child().set_text(pirep.star) if not pirep.transition: self._transition.set_active(0) else: self._transition.get_child().set_text(pirep.transition) self._approachType.set_text(pirep.approachType) self._arrivalRunway.set_text(pirep.arrivalRunway) self._blockTimeStart.setTimestamp(pirep.blockTimeStart) self._blockTimeEnd.setTimestamp(pirep.blockTimeEnd) self._flightTimeStart.setTimestamp(pirep.flightTimeStart) self._flightTimeEnd.setTimestamp(pirep.flightTimeEnd) self._flownDistance.set_text("%.1f" % (pirep.flownDistance,)) self._fuelUsed.set_value(int(pirep.fuelUsed)) rating = pirep.rating if rating<0: self._rating.set_markup('NO GO') else: self._rating.set_text("%.1f %%" % (rating,)) self._flownNumCabinCrew.set_value(pirep.numCabinCrew) self._flownNumPassengers.set_value(pirep.numPassengers) self._flownNumChildren.set_value(pirep.numChildren) self._flownNumInfants.set_value(pirep.numInfants) self._flownBagWeight.set_value(pirep.bagWeight) self._flownCargoWeight.set_value(pirep.cargoWeight) self._flownMailWeight.set_value(pirep.mailWeight) self._flightType.set_text(xstr("flighttype_" + flightType2string(pirep.bookedFlight.flightType))) self._online.set_active(pirep.online) self._flightInfo.reset() self._flightInfo.enable(bookedFlight.aircraftType) delayCodes = "" for code in pirep.delayCodes: if delayCodes: delayCodes += ", " delayCodes += code m = PIREPEditor._delayCodeRE.match(code) if m: self._flightInfo.activateDelayCode(m.group(1)) self._delayCodes.get_buffer().set_text(delayCodes) self._flightInfo.comments = pirep.comments if pirep.flightDefects.find("
")!=-1: flightDefects = pirep.flightDefects.split("
") caption = flightDefects[0] index = 0 for defect in flightDefects[1:]: if defect.find("")!=-1: (explanation, nextCaption) = defect.split("") else: explanation = defect nextCaption = None self._flightInfo.addFault(index, caption) self._flightInfo.setExplanation(index, explanation) index += 1 caption = nextCaption # self._comments.get_buffer().set_text(pirep.comments) # self._flightDefects.get_buffer().set_text(pirep.flightDefects) logBuffer = self._log.get_buffer() logBuffer.set_text("") lineIndex = 0 for (timeStr, line) in pirep.logLines: isFault = lineIndex in pirep.faultLineIndexes appendTextBuffer(logBuffer, formatFlightLogLine(timeStr, line), isFault = isFault) lineIndex += 1 self._notebook.set_current_page(0) self._okButton.grab_default() self._modified = False self._updateButtons() self._modified = True self._toSave = False def delayCodesChanged(self): """Called when the delay codes have changed.""" self._updateButtons() def commentsChanged(self): """Called when the comments have changed.""" self._updateButtons() def faultExplanationsChanged(self): """Called when the fault explanations have changed.""" self._updateButtons() def _buildDataTab(self): """Build the data tab of the viewer.""" table = Gtk.Table(1, 2) table.set_row_spacings(4) table.set_col_spacings(16) table.set_homogeneous(True) box1 = Gtk.VBox() table.attach(box1, 0, 1, 0, 1) box2 = Gtk.VBox() table.attach(box2, 1, 2, 0, 1) flightFrame = self._buildFlightFrame() box1.pack_start(flightFrame, False, False, 4) routeFrame = self._buildRouteFrame() box1.pack_start(routeFrame, False, False, 4) departureFrame = self._buildDepartureFrame() box2.pack_start(departureFrame, True, True, 4) arrivalFrame = self._buildArrivalFrame() box2.pack_start(arrivalFrame, True, True, 4) statisticsFrame = self._buildStatisticsFrame() box2.pack_start(statisticsFrame, False, False, 4) miscellaneousFrame = self._buildMiscellaneousFrame() box1.pack_start(miscellaneousFrame, False, False, 4) return table def _buildFlightFrame(self): """Build the frame for the flight data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight")) dataBox = Gtk.HBox() mainBox.pack_start(dataBox, False, False, 0) self._callsign = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_callsign"), width = 8) self._tailNumber = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_tailNumber"), width = 7) PIREPViewer.addVFiller(mainBox) dataBox = Gtk.HBox() mainBox.pack_start(dataBox, False, False, 0) self._aircraftType = \ PIREPViewer.addLabeledData(dataBox, xstr("pirepView_aircraftType"), width = 25) PIREPViewer.addVFiller(mainBox) table = Gtk.Table(3, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) self._departureICAO = \ PIREPViewer.tableAttach(table, 0, 0, xstr("pirepView_departure"), width = 5) self._departureTime = \ PIREPViewer.tableAttach(table, 1, 0, xstr("pirepView_departure_time"), width = 6) self._arrivalICAO = \ PIREPViewer.tableAttach(table, 0, 1, xstr("pirepView_arrival"), width = 5) self._arrivalTime = \ PIREPViewer.tableAttach(table, 1, 1, xstr("pirepView_arrival_time"), width = 6) table = Gtk.Table(3, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) self._numPassengers = \ PIREPViewer.tableAttach(table, 0, 0, xstr("pirepView_numPassengers"), width = 4) self._numCrew = \ PIREPViewer.tableAttach(table, 1, 0, xstr("pirepView_numCrew"), width = 3) self._bagWeight = \ PIREPViewer.tableAttach(table, 0, 1, xstr("pirepView_bagWeight"), width = 5) self._cargoWeight = \ PIREPViewer.tableAttach(table, 1, 1, xstr("pirepView_cargoWeight"), width = 5) self._mailWeight = \ PIREPViewer.tableAttach(table, 2, 1, xstr("pirepView_mailWeight"), width = 5) PIREPViewer.addVFiller(mainBox) mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")), False, False, 0) (routeWindow, self._route) = PIREPViewer.getTextWindow() mainBox.pack_start(routeWindow, False, False, 0) return frame def _buildRouteFrame(self): """Build the frame for the user-specified route and flight level.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route")) levelBox = Gtk.HBox() mainBox.pack_start(levelBox, False, False, 0) label = PIREPViewer.getLabel(xstr("pirepView_filedCruiseLevel"), xstr("pirepEdit_FL")) levelBox.pack_start(label, False, False, 0) self._filedCruiseLevel = Gtk.SpinButton() self._filedCruiseLevel.set_increments(step = 10, page = 100) self._filedCruiseLevel.set_range(min = 0, max = 500) self._filedCruiseLevel.set_tooltip_text(xstr("route_level_tooltip")) self._filedCruiseLevel.set_numeric(True) self._filedCruiseLevel.connect("value-changed", self._updateButtons) levelBox.pack_start(self._filedCruiseLevel, False, False, 0) PIREPViewer.addHFiller(levelBox) label = PIREPViewer.getLabel(xstr("pirepView_modifiedCruiseLevel"), xstr("pirepEdit_FL")) levelBox.pack_start(label, False, False, 0) self._modifiedCruiseLevel = Gtk.SpinButton() self._modifiedCruiseLevel.set_increments(step = 10, page = 100) self._modifiedCruiseLevel.set_range(min = 0, max = 500) self._modifiedCruiseLevel.set_tooltip_text(xstr("pirepEdit_modified_route_level_tooltip")) self._modifiedCruiseLevel.set_numeric(True) self._modifiedCruiseLevel.connect("value-changed", self._updateButtons) levelBox.pack_start(self._modifiedCruiseLevel, False, False, 0) PIREPViewer.addVFiller(mainBox) (routeWindow, self._userRoute) = \ PIREPViewer.getTextWindow(editable = True) mainBox.pack_start(routeWindow, False, False, 0) self._userRoute.get_buffer().connect("changed", self._updateButtons) self._userRoute.set_tooltip_text(xstr("route_route_tooltip")) return frame def _buildDepartureFrame(self): """Build the frame for the departure data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure")) mainBox.pack_start(PIREPViewer.getLabel("METAR:"), False, False, 0) (metarWindow, self._departureMETAR) = \ PIREPViewer.getTextWindow(heightRequest = -1, editable = True) self._departureMETAR.get_buffer().connect("changed", self._updateButtons) self._departureMETAR.set_tooltip_text(xstr("takeoff_metar_tooltip")) mainBox.pack_start(metarWindow, True, True, 0) PIREPViewer.addVFiller(mainBox) dataBox = Gtk.HBox() mainBox.pack_start(dataBox, False, False, 0) label = Gtk.Label("" + xstr("pirepView_runway") + "") label.set_use_markup(True) dataBox.pack_start(label, False, False, 0) # FIXME: quite the same as the runway entry boxes in the wizard self._departureRunway = Gtk.Entry() self._departureRunway.set_width_chars(5) self._departureRunway.set_tooltip_text(xstr("takeoff_runway_tooltip")) self._departureRunway.connect("changed", self._upperChanged) dataBox.pack_start(self._departureRunway, False, False, 8) label = Gtk.Label("" + xstr("pirepView_sid") + "") label.set_use_markup(True) dataBox.pack_start(label, False, False, 0) # FIXME: quite the same as the SID combo box in # the flight wizard self._sid = Gtk.ComboBox.new_with_model_and_entry(comboModel) self._sid.set_entry_text_column(0) self._sid.get_child().set_width_chars(10) self._sid.set_tooltip_text(xstr("takeoff_sid_tooltip")) self._sid.connect("changed", self._upperChangedComboBox) dataBox.pack_start(self._sid, False, False, 8) return frame def _buildArrivalFrame(self): """Build the frame for the arrival data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival")) mainBox.pack_start(PIREPViewer.getLabel("METAR:"), False, False, 0) (metarWindow, self._arrivalMETAR) = \ PIREPViewer.getTextWindow(heightRequest = -1, editable = True) self._arrivalMETAR.get_buffer().connect("changed", self._updateButtons) self._arrivalMETAR.set_tooltip_text(xstr("landing_metar_tooltip")) mainBox.pack_start(metarWindow, True, True, 0) PIREPViewer.addVFiller(mainBox) table = Gtk.Table(2, 4) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) # FIXME: quite the same as in the wizard self._star = Gtk.ComboBox.new_with_model_and_entry(comboModel) self._star.set_entry_text_column(0) self._star.get_child().set_width_chars(10) self._star.set_tooltip_text(xstr("landing_star_tooltip")) self._star.connect("changed", self._upperChangedComboBox) PIREPEditor.tableAttachWidget(table, 0, 0, xstr("pirepView_star"), self._star) # FIXME: quite the same as in the wizard self._transition = Gtk.ComboBox.new_with_model_and_entry(comboModel) self._transition.set_entry_text_column(0) self._transition.get_child().set_width_chars(10) self._transition.set_tooltip_text(xstr("landing_transition_tooltip")) self._transition.connect("changed", self._upperChangedComboBox) PIREPEditor.tableAttachWidget(table, 2, 0, xstr("pirepView_transition"), self._transition) # FIXME: quite the same as in the wizard self._approachType = Gtk.Entry() self._approachType.set_width_chars(10) self._approachType.set_tooltip_text(xstr("landing_approach_tooltip")) self._approachType.connect("changed", self._upperChanged) PIREPEditor.tableAttachWidget(table, 0, 1, xstr("pirepView_approachType"), self._approachType) # FIXME: quite the same as in the wizard self._arrivalRunway = Gtk.Entry() self._arrivalRunway.set_width_chars(10) self._arrivalRunway.set_tooltip_text(xstr("landing_runway_tooltip")) self._arrivalRunway.connect("changed", self._upperChanged) PIREPEditor.tableAttachWidget(table, 2, 1, xstr("pirepView_runway"), self._arrivalRunway) return frame def _buildStatisticsFrame(self): """Build the frame for the statistics data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics")) table = Gtk.Table(4, 4) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) table.set_homogeneous(False) self._blockTimeStart = \ PIREPEditor.tableAttachTimeEntry(table, 0, 0, xstr("pirepView_blockTimeStart")) self._blockTimeStart.connect("changed", self._updateButtons) self._blockTimeStart.set_tooltip_text(xstr("pirepEdit_block_time_start_tooltip")) self._blockTimeEnd = \ PIREPEditor.tableAttachTimeEntry(table, 2, 0, xstr("pirepView_blockTimeEnd")) self._blockTimeEnd.connect("changed", self._updateButtons) self._blockTimeEnd.set_tooltip_text(xstr("pirepEdit_block_time_end_tooltip")) self._flightTimeStart = \ PIREPEditor.tableAttachTimeEntry(table, 0, 1, xstr("pirepView_flightTimeStart")) self._flightTimeStart.connect("changed", self._updateButtons) self._flightTimeStart.set_tooltip_text(xstr("pirepEdit_flight_time_start_tooltip")) self._flightTimeEnd = \ PIREPEditor.tableAttachTimeEntry(table, 2, 1, xstr("pirepView_flightTimeEnd")) self._flightTimeEnd.connect("changed", self._updateButtons) self._flightTimeEnd.set_tooltip_text(xstr("pirepEdit_flight_time_end_tooltip")) self._flownDistance = PIREPViewer.getDataLabel(width = 3) PIREPEditor.tableAttachWidget(table, 0, 2, xstr("pirepView_flownDistance"), self._flownDistance) self._fuelUsed = \ PIREPEditor.tableAttachSpinButton(table, 2, 2, xstr("pirepView_fuelUsed"), 1000000) self._fuelUsed.connect("value-changed", self._updateButtons) self._fuelUsed.set_tooltip_text(xstr("pirepEdit_fuel_used_tooltip")) self._rating = PIREPViewer.getDataLabel(width = 3) PIREPEditor.tableAttachWidget(table, 0, 3, xstr("pirepView_rating"), self._rating) return frame def _buildMiscellaneousFrame(self): """Build the frame for the miscellaneous data.""" (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous")) table = Gtk.Table(6, 2) mainBox.pack_start(table, False, False, 0) table.set_row_spacings(4) table.set_col_spacings(8) table.set_homogeneous(False) label = Gtk.Label("" + xstr("pirepView_numPassengers") + "") 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, 0, 1) self._flownNumPassengers = button = Gtk.SpinButton() button.set_range(min = 0, max = 300) button.set_increments(step = 1, page = 10) button.set_numeric(True) button.set_width_chars(2) button.set_alignment(1.0) button.connect("value-changed", self._updateButtons) button.set_tooltip_text(xstr("payload_pax_tooltip")) self._flownNumChildren = button = Gtk.SpinButton() button.set_range(min = 0, max = 300) button.set_increments(step = 1, page = 10) button.set_numeric(True) button.set_width_chars(2) button.set_alignment(1.0) button.connect("value-changed", self._updateButtons) button.set_tooltip_text(xstr("payload_pax_children_tooltip")) self._flownNumInfants = button = Gtk.SpinButton() button.set_range(min = 0, max = 300) button.set_increments(step = 1, page = 10) button.set_numeric(True) button.set_width_chars(2) button.set_alignment(1.0) button.connect("value-changed", self._updateButtons) button.set_tooltip_text(xstr("payload_pax_infants_tooltip")) paxBox = Gtk.HBox() paxBox.pack_start(self._flownNumPassengers, False, False, 0) paxBox.pack_start(Gtk.Label("+"), False, False, 4) paxBox.pack_start(self._flownNumChildren, False, False, 0) paxBox.pack_start(Gtk.Label("+"), False, False, 4) paxBox.pack_start(self._flownNumInfants, False, False, 0) paxBox.set_halign(Gtk.Align.END) table.attach(paxBox, 1, 4, 0, 1) self._flownNumCabinCrew = \ PIREPEditor.tableAttachSpinButton(table, 4, 0, xstr("pirepView_numCrew"), 10) self._flownNumCabinCrew.connect("value-changed", self._updateButtons) self._flownNumCabinCrew.set_tooltip_text(xstr("payload_crew_tooltip")) self._flownBagWeight = \ PIREPEditor.tableAttachSpinButton(table, 0, 1, xstr("pirepView_bagWeight"), 100000, width = 6) self._flownBagWeight.connect("value-changed", self._updateButtons) self._flownBagWeight.set_tooltip_text(xstr("payload_bag_tooltip")) self._flownCargoWeight = \ PIREPEditor.tableAttachSpinButton(table, 2, 1, xstr("pirepView_cargoWeight"), 100000, width = 6) self._flownCargoWeight.connect("value-changed", self._updateButtons) self._flownCargoWeight.set_tooltip_text(xstr("payload_cargo_tooltip")) self._flownMailWeight = \ PIREPEditor.tableAttachSpinButton(table, 4, 1, xstr("pirepView_mailWeight"), 100000, width = 6) self._flownMailWeight.connect("value-changed", self._updateButtons) self._flownMailWeight.set_tooltip_text(xstr("payload_mail_tooltip")) self._flightType = PIREPViewer.getDataLabel(width = 3) PIREPEditor.tableAttachWidget(table, 0, 2, xstr("pirepView_flightType"), self._flightType) self._online = Gtk.CheckButton(xstr("pirepEdit_online")) table.attach(self._online, 2, 3, 2, 3) self._online.connect("toggled", self._updateButtons) self._online.set_tooltip_text(xstr("pirepEdit_online_tooltip")) PIREPViewer.addVFiller(mainBox) mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")), False, False, 0) (textWindow, self._delayCodes) = PIREPViewer.getTextWindow() mainBox.pack_start(textWindow, False, False, 0) self._delayCodes.set_tooltip_text(xstr("pirepEdit_delayCodes_tooltip")) return frame def _buildCommentsTab(self): """Build the tab with the comments and flight defects.""" return FlightInfo(self._gui, callbackObject = self) def _buildLogTab(self): """Build the log tab.""" mainBox = Gtk.VBox() (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1) addFaultTag(self._log.get_buffer()) mainBox.pack_start(logWindow, True, True, 0) return mainBox def _upperChanged(self, entry, arg = None): """Called when the value of some entry widget has changed and the value should be converted to uppercase.""" entry.set_text(entry.get_text().upper()) self._updateButtons() #self._valueChanged(entry, arg) def _upperChangedComboBox(self, comboBox): """Called for combo box widgets that must be converted to uppercase.""" entry = comboBox.get_child() if comboBox.get_active()==-1: entry.set_text(entry.get_text().upper()) self._updateButtons() #self._valueChanged(entry) def _updateButtons(self, *kwargs): """Update the activity state of the buttons.""" pirep = self._pirep bookedFlight = pirep.bookedFlight departureMinutes = \ bookedFlight.departureTime.hour*60 + bookedFlight.departureTime.minute departureDifference = abs(Flight.getMinutesDifference(self._blockTimeStart.minutes, departureMinutes)) flightStartDifference = \ Flight.getMinutesDifference(self._flightTimeStart.minutes, self._blockTimeStart.minutes) arrivalMinutes = \ bookedFlight.arrivalTime.hour*60 + bookedFlight.arrivalTime.minute arrivalDifference = abs(Flight.getMinutesDifference(self._blockTimeEnd.minutes, arrivalMinutes)) flightEndDifference = \ Flight.getMinutesDifference(self._blockTimeEnd.minutes, self._flightTimeEnd.minutes) timesOK = self._flightInfo.hasComments or \ self._flightInfo.hasDelayCode or \ (departureDifference<=Flight.TIME_ERROR_DIFFERENCE and arrivalDifference<=Flight.TIME_ERROR_DIFFERENCE and flightStartDifference>=0 and flightStartDifference<30 and flightEndDifference>=0 and flightEndDifference<30) text = self._sid.get_child().get_text() sid = text if self._sid.get_active()!=0 and text and text!="N/A" \ else None text = self._star.get_child().get_text() star = text if self._star.get_active()!=0 and text and text!="N/A" \ else None text = self._transition.get_child().get_text() transition = text if self._transition.get_active()!=0 \ and text and text!="N/A" else None buffer = self._userRoute.get_buffer() route = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), True) numPassengers = \ self._flownNumPassengers.get_value_as_int() + \ self._flownNumChildren.get_value_as_int() + \ self._flownNumInfants.get_value_as_int() minCabinCrew = 0 if numPassengers==0 else \ (bookedFlight.maxPassengers // 50) + 1 self._okButton.set_sensitive(self._modified and timesOK and self._flightInfo.faultsFullyExplained and numPassengers<=bookedFlight.maxPassengers and self._flownNumCabinCrew.get_value_as_int()>=minCabinCrew and self._fuelUsed.get_value_as_int()>0 and self._departureRunway.get_text_length()>0 and self._arrivalRunway.get_text_length()>0 and self._departureMETAR.get_buffer().get_char_count()>0 and self._arrivalMETAR.get_buffer().get_char_count()>0 and self._filedCruiseLevel.get_value_as_int()>=50 and self._modifiedCruiseLevel.get_value_as_int()>=50 and sid is not None and (star is not None or transition is not None) and route!="" and self._approachType.get_text()!="") def _okClicked(self, button): """Called when the OK button has been clicked. The PIREP is updated from the data in the window.""" if not askYesNo(xstr("pirepEdit_save_question"), parent = self): self.response(Gtk.ResponseType.CANCEL) pirep = self._pirep pirep.filedCruiseAltitude = \ self._filedCruiseLevel.get_value_as_int() * 100 pirep.cruiseAltitude = \ self._modifiedCruiseLevel.get_value_as_int() * 100 pirep.route = getTextViewText(self._userRoute) pirep.departureMETAR = getTextViewText(self._departureMETAR) pirep.departureRunway = self._departureRunway.get_text() pirep.sid = self._sid.get_child().get_text() pirep.arrivalMETAR = getTextViewText(self._arrivalMETAR) pirep.star = None if self._star.get_active()==0 \ else self._star.get_child().get_text() pirep.transition = None if self._transition.get_active()==0 \ else self._transition.get_child().get_text() pirep.approachType = self._approachType.get_text() pirep.arrivalRunway = self._arrivalRunway.get_text() pirep.blockTimeStart = \ self._blockTimeStart.getTimestampFrom(pirep.blockTimeStart) pirep.blockTimeEnd = \ self._blockTimeEnd.getTimestampFrom(pirep.blockTimeEnd) pirep.flightTimeStart = \ self._flightTimeStart.getTimestampFrom(pirep.flightTimeStart) pirep.flightTimeEnd = \ self._flightTimeEnd.getTimestampFrom(pirep.flightTimeEnd) pirep.fuelUsed = self._fuelUsed.get_value() pirep.numCabinCrew = self._flownNumCabinCrew.get_value() pirep.numPassengers = self._flownNumPassengers.get_value() pirep.bagWeight = self._flownBagWeight.get_value() pirep.cargoWeight = self._flownCargoWeight.get_value() pirep.mailWeight = self._flownMailWeight.get_value() pirep.online = self._online.get_active() pirep.delayCodes = self._flightInfo.delayCodes pirep.comments = self._flightInfo.comments pirep.flightDefects = self._flightInfo.faultsAndExplanations self.response(Gtk.ResponseType.OK) #------------------------------------------------------------------------------