Ignore:
Timestamp:
04/15/17 12:32:05 (8 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

All data is displayed and is editable in the PIREP editor (re #307)

Location:
src/mlx/gui
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/mlx/gui/common.py

    r828 r833  
    88
    99import os
     10import time
    1011
    1112#-----------------------------------------------------------------------------
     
    283284                      else str(self._currentInteger))
    284285        self._selfSetting = False
     286
     287#------------------------------------------------------------------------------
     288
     289class TimeEntry(gtk.Entry):
     290    """Widget to display and edit a time value in HH:MM format."""
     291    def __init__(self):
     292        """Construct the entry"""
     293        super(TimeEntry, self).__init__(max = 5)
     294
     295        self.connect("insert-text", self._insertText)
     296        self.connect("delete-text", self._deleteText)
     297        self.connect("focus-out-event", self._focusOutEvent)
     298
     299    @property
     300    def hour(self):
     301        """Get the hour from the current text"""
     302        text = self.get_text()
     303        if not text or text==":":
     304            return 0
     305
     306        words = text.split(":")
     307        if len(words)==1:
     308            return 0
     309        elif len(words)>=2:
     310            return 0 if len(words[0])==0 else int(words[0])
     311        else:
     312            return 0
     313
     314    @property
     315    def minute(self):
     316        """Get the hour from the current text"""
     317        text = self.get_text()
     318        if not text or text==":":
     319            return 0
     320
     321        words = text.split(":")
     322        if len(words)==1:
     323            return 0 if len(words[0])==0 else int(words[0])
     324        elif len(words)>=2:
     325            return 0 if len(words[1])==0 else int(words[1])
     326        else:
     327            return 0
     328
     329    def setTimestamp(self, timestamp):
     330        """Set the hour and minute from the given timestamp in UTC."""
     331        tm = time.gmtime(timestamp)
     332        self.set_text("%02d:%02d" % (tm.tm_hour, tm.tm_min))
     333
     334    def _focusOutEvent(self, widget, event):
     335        """Reformat the text to match pattern HH:MM"""
     336        text = "%02d:%02d" % (self.hour, self.minute)
     337        if text!=self.get_text():
     338            self.set_text(text)
     339
     340    def _insertText(self, entry, text, length, position):
     341        """Called when some text is inserted into the entry."""
     342        text=text[:length]
     343        currentText = self.get_text()
     344        position = self.get_position()
     345        newText = currentText[:position] + text + currentText[position:]
     346        self._checkText(newText, "insert-text")
     347
     348    def _deleteText(self, entry, start, end):
     349        """Called when some text is erased from the entry."""
     350        currentText = self.get_text()
     351        newText = currentText[:start] + currentText[end:]
     352        self._checkText(newText, "delete-text")
     353
     354    def _checkText(self, newText, signal):
     355        """Check the given text.
     356
     357        If it is not suitable, stop the emission of the signal to prevent the
     358        change from appearing."""
     359        if not newText or newText==":":
     360            return
     361
     362        words = newText.split(":")
     363        if (len(words)==1 and
     364            len(words[0])<=2 and (len(words[0])==0 or
     365                                  (words[0].isdigit() and int(words[0])<60))) or \
     366           (len(words)==2 and
     367            len(words[0])<=2 and (len(words[0])==0 or
     368                                  (words[0].isdigit() and int(words[0])<24)) and
     369            len(words[1])<=2 and (len(words[1])==0 or
     370                                  (words[1].isdigit() and int(words[1])<60))):
     371            pass
     372        else:
     373            gtk.gdk.display_get_default().beep()
     374            self.stop_emission(signal)
    285375
    286376#------------------------------------------------------------------------------
     
    519609
    520610#------------------------------------------------------------------------------
     611
     612def createFlightTypeComboBox():
     613        flightTypeModel = gtk.ListStore(str, int)
     614        for type in _const.flightTypes:
     615            name = "flighttype_" + _const.flightType2string(type)
     616            flightTypeModel.append([xstr(name), type])
     617
     618        flightType = gtk.ComboBox(model = flightTypeModel)
     619        renderer = gtk.CellRendererText()
     620        flightType.pack_start(renderer, True)
     621        flightType.add_attribute(renderer, "text", 0)
     622
     623        return flightType
     624
     625#------------------------------------------------------------------------------
  • src/mlx/gui/delaycodes.py

    r768 r833  
    380380        self.show_all()
    381381
     382    def activateCode(self, code):
     383        """Check the checkbox for the given code."""
     384        index = 0
     385        for (type, data) in self._delayCodeData[2]:
     386            if type==DELAYCODE:
     387                if code==data[0].strip():
     388                    self._checkButtons[index].set_active(True)
     389                    break
     390                index += 1
     391
    382392    def _delayCodesChanged(self, button):
    383393        """Called when one of the delay codes have changed."""
  • src/mlx/gui/faultexplain.py

    r620 r833  
    9494                               buffer.get_end_iter(), True)
    9595
     96    @explanation.setter
     97    def explanation(self, explanation):
     98        """Set the explanation."""
     99        self._explanation.get_buffer().set_text(explanation)
     100
    96101    @property
    97102    def hasExplanation(self):
     
    126131
    127132class FaultExplainWidget(gtk.Frame):
    128     """The widget for the failts and their explanations."""
     133    """The widget for the faults and their explanations."""
    129134    @staticmethod
    130135    def getFaultFrame(alignment):
     
    235240                          numExplanations = self._numExplanations -
    236241                          (1 if hasExplanation else 0))
     242
     243    def setExplanation(self, id, explanation):
     244        """Set the explanation for the fault with the given ID"""
     245        self._faultWidgets[id][1].explanation = explanation
    237246
    238247    def reset(self):
  • src/mlx/gui/flight.py

    r824 r833  
    45214521class FinishPage(Page):
    45224522    """Flight finish page."""
    4523     _flightTypes = [ ("flighttype_scheduled", const.FLIGHTTYPE_SCHEDULED),
    4524                      ("flighttype_ot", const.FLIGHTTYPE_OLDTIMER),
    4525                      ("flighttype_vip", const.FLIGHTTYPE_VIP),
    4526                      ("flighttype_charter", const.FLIGHTTYPE_CHARTER) ]
    4527 
    45284523    def __init__(self, wizard, saveHelper):
    45294524        """Construct the finish page."""
     
    46584653        table.attach(labelAlignment, 0, 1, row, row+1)
    46594654
    4660         flightTypeModel = gtk.ListStore(str, int)
    4661         for (name, type) in FinishPage._flightTypes:
    4662             flightTypeModel.append([xstr(name), type])
    4663 
    4664         self._flightType = gtk.ComboBox(model = flightTypeModel)
    4665         renderer = gtk.CellRendererText()
    4666         self._flightType.pack_start(renderer, True)
    4667         self._flightType.add_attribute(renderer, "text", 0)
     4655        self._flightType = createFlightTypeComboBox()
    46684656        self._flightType.set_tooltip_text(xstr("finish_type_tooltip"))
    46694657        self._flightType.set_active(0)
  • src/mlx/gui/gui.py

    r832 r833  
    1313from mlx.gui.checklist import ChecklistEditor
    1414from mlx.gui.callouts import ApproachCalloutsEditor
    15 from mlx.gui.pirep import PIREPViewer
     15from mlx.gui.pirep import PIREPViewer, PIREPEditor
    1616from mlx.gui.bugreport import BugReportDialog
    1717from mlx.gui.acars import ACARS
     
    183183
    184184        self._pirepViewer = PIREPViewer(self)
     185
     186        self._pirepEditor = PIREPEditor(self)
    185187
    186188        window.show_all()
     
    12621264    def editPIREP(self, pirep):
    12631265        """Display the PIREP editor window and allow editing the PIREP."""
    1264         self.viewPIREP(pirep)
     1266        self._pirepEditor.setPIREP(pirep)
     1267        self._pirepEditor.show_all()
     1268        self._pirepEditor.run()
     1269        self._pirepEditor.hide()
    12651270
    12661271    def _loadPIREP(self, menuItem):
  • src/mlx/gui/info.py

    r620 r833  
    5454        return (frame, comments)
    5555
    56     def __init__(self, gui):
     56    def __init__(self, gui, mainInstance = True):
    5757        """Construct the flight info tab."""
    5858        super(FlightInfo, self).__init__()
    5959        self._gui = gui
     60        self._mainInstance = mainInstance
    6061
    6162        self._commentsAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
     
    110111                                            buffer.get_end_iter(), True))
    111112
     113    @comments.setter
     114    def comments(self, comments):
     115        """Set the comments."""
     116        self._comments.get_buffer().set_text(comments)
     117
    112118    @property
    113119    def hasComments(self):
     
    147153        self._faultExplainWidget.clearFault(id)
    148154
     155    def setExplanation(self, id, explanation):
     156        """Set the explanation of the given fault."""
     157        self._faultExplainWidget.setExplanation(id, explanation)
     158
    149159    def enable(self, aircraftType):
    150160        """Enable the flight info tab."""
     
    168178        self._delayCodeTable.reset()
    169179
     180    def activateDelayCode(self, code):
     181        """Active the checkbox corresponding to the given code."""
     182        self._delayCodeTable.activateCode(code)
     183
    170184    def delayCodesChanged(self):
    171185        """Callewd when the delay codes have changed."""
    172         self._gui.delayCodesChanged()
     186        if self._mainInstance:
     187            self._gui.delayCodesChanged()
    173188
    174189    def _commentsChanged(self, textbuffer):
    175190        """Called when the comments have changed."""
    176         self._gui.commentsChanged()
     191        if self._mainInstance:
     192            self._gui.commentsChanged()
    177193
    178194    def _faultExplanationsChanged(self, faultExplainWidget, fullyExplained):
    179195        """Called when the status of the fault explanations has changed."""
    180         self._gui.faultExplanationsChanged()
     196        if self._mainInstance:
     197            self._gui.faultExplanationsChanged()
  • src/mlx/gui/pirep.py

    r831 r833  
    11
    22from common import *
     3from dcdata import getTable
     4from info import FlightInfo
     5from flight import comboModel
    36
    47from mlx.pirep import PIREP
     
    69
    710import time
     11import re
    812
    913#------------------------------------------------------------------------------
     
    1115## @package mlx.gui.pirep
    1216#
    13 # The detailed PIREP viewer.
     17# The detailed PIREP viewer and editor windows.
    1418#
    1519# The \ref PIREPViewer class is a dialog displaying all information found in a
     
    4751
    4852    @staticmethod
    49     def getLabel(text):
     53    def getLabel(text, extraText = ""):
    5054        """Get a bold label with the given text."""
    51         label = gtk.Label("<b>" + text + "</b>")
     55        label = gtk.Label("<b>" + text + "</b>" + extraText)
    5256        label.set_use_markup(True)
    5357        label.set_alignment(0.0, 0.5)
     
    6468
    6569    @staticmethod
    66     def getTextWindow(heightRequest = 40):
     70    def getTextWindow(heightRequest = 40, editable = False):
    6771        """Get a scrollable text window.
    6872
     
    7680        textView = gtk.TextView()
    7781        textView.set_wrap_mode(WRAP_WORD)
    78         textView.set_editable(False)
    79         textView.set_cursor_visible(False)
     82        textView.set_editable(editable)
     83        textView.set_cursor_visible(editable)
    8084        textView.set_size_request(-1, heightRequest)
    8185        scrolledWindow.add(textView)
     
    106110        """Add a label and a data label to the given HBox.
    107111
    108         Returnsd the data label."""
     112        Returns the data label."""
    109113        label = PIREPViewer.getLabel(labelText)
    110114        hBox.pack_start(label, False, False, 0)
     
    114118
    115119        return dataLabel
     120
     121    @staticmethod
     122    def addHFiller(hBox, width = 8):
     123        """Add a filler to the given horizontal box."""
     124        filler = gtk.Alignment(xalign = 0.0, yalign = 0.0,
     125                               xscale = 1.0, yscale = 1.0)
     126        filler.set_size_request(width, -1)
     127        hBox.pack_start(filler, False, False, 0)
    116128
    117129    @staticmethod
     
    615627
    616628#------------------------------------------------------------------------------
     629
     630class PIREPEditor(gtk.Dialog):
     631    """A PIREP editor dialog."""
     632    _delayCodeRE = re.compile("([0-9]{2,3})( \([^\)]*\))")
     633
     634    @staticmethod
     635    def tableAttachWidget(table, column, row, labelText, widget):
     636        """Attach the given widget with the given label to the given table.
     637
     638        The label will got to cell (column, row), the widget to cell
     639        (column+1, row)."""
     640        label = gtk.Label("<b>" + labelText + "</b>")
     641        label.set_use_markup(True)
     642        alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
     643                                  xscale = 0.0, yscale = 0.0)
     644        alignment.add(label)
     645        table.attach(alignment, column, column + 1, row, row + 1)
     646
     647        table.attach(widget, column + 1, column + 2, row, row + 1)
     648
     649    @staticmethod
     650    def tableAttachSpinButton(table, column, row, labelText, maxValue,
     651                              minValue = 0, stepIncrement = 1,
     652                              pageIncrement = 10, numeric = True,
     653                              width = 3):
     654        """Attach a spin button with the given label to the given table.
     655
     656        The label will got to cell (column, row), the spin button to cell
     657        (column+1, row)."""
     658        button = gtk.SpinButton()
     659        button.set_range(min = minValue, max = maxValue)
     660        button.set_increments(step = stepIncrement, page = pageIncrement)
     661        button.set_numeric(True)
     662        button.set_width_chars(width)
     663        button.set_alignment(1.0)
     664
     665        PIREPEditor.tableAttachWidget(table, column, row, labelText, button)
     666
     667        return button
     668
     669    @staticmethod
     670    def tableAttachTimeEntry(table, column, row, labelText):
     671        """Attach a time entry widget with the given label to the given table.
     672
     673        The label will got to cell (column, row), the spin button to cell
     674        (column+1, row)."""
     675        entry = TimeEntry()
     676        entry.set_width_chars(5)
     677        entry.set_alignment(1.0)
     678
     679        PIREPEditor.tableAttachWidget(table, column, row, labelText, entry)
     680
     681        return entry
     682
     683    def __init__(self, gui):
     684        """Construct the PIREP viewer."""
     685        super(PIREPEditor, self).__init__(title = WINDOW_TITLE_BASE +
     686                                          " - " +
     687                                          xstr("pirepEdit_title"),
     688                                          parent = gui.mainWindow)
     689
     690        self.set_resizable(False)
     691
     692        self._gui = gui
     693
     694        contentArea = self.get_content_area()
     695
     696        self._notebook = gtk.Notebook()
     697        contentArea.pack_start(self._notebook, False, False, 4)
     698
     699        dataTab = self._buildDataTab()
     700        label = gtk.Label(xstr("pirepView_tab_data"))
     701        label.set_use_underline(True)
     702        label.set_tooltip_text(xstr("pirepView_tab_data_tooltip"))
     703        self._notebook.append_page(dataTab, label)
     704
     705        self._flightInfo = self._buildCommentsTab()
     706        label = gtk.Label(xstr("pirepView_tab_comments"))
     707        label.set_use_underline(True)
     708        label.set_tooltip_text(xstr("pirepView_tab_comments_tooltip"))
     709        self._notebook.append_page(self._flightInfo, label)
     710
     711        logTab = self._buildLogTab()
     712        label = gtk.Label(xstr("pirepView_tab_log"))
     713        label.set_use_underline(True)
     714        label.set_tooltip_text(xstr("pirepView_tab_log_tooltip"))
     715        self._notebook.append_page(logTab, label)
     716
     717        self._okButton = self.add_button(xstr("button_ok"), RESPONSETYPE_OK)
     718        self._okButton.set_can_default(True)
     719
     720    def setPIREP(self, pirep):
     721        """Setup the data in the dialog from the given PIREP."""
     722        bookedFlight = pirep.bookedFlight
     723
     724        self._callsign.set_text(bookedFlight.callsign)
     725        self._tailNumber.set_text(bookedFlight.tailNumber)
     726        aircraftType = xstr("aircraft_" + icaoCodes[bookedFlight.aircraftType].lower())
     727        self._aircraftType.set_text(aircraftType)
     728
     729        self._departureICAO.set_text(bookedFlight.departureICAO)
     730        self._departureTime.set_text("%02d:%02d" % \
     731                                     (bookedFlight.departureTime.hour,
     732                                      bookedFlight.departureTime.minute))
     733
     734        self._arrivalICAO.set_text(bookedFlight.arrivalICAO)
     735        self._arrivalTime.set_text("%02d:%02d" % \
     736                                   (bookedFlight.arrivalTime.hour,
     737                                    bookedFlight.arrivalTime.minute))
     738
     739        self._numPassengers.set_text(str(bookedFlight.numPassengers))
     740        self._numCrew.set_text(str(bookedFlight.numCrew))
     741        self._bagWeight.set_text(str(bookedFlight.bagWeight))
     742        self._cargoWeight.set_text(str(bookedFlight.cargoWeight))
     743        self._mailWeight.set_text(str(bookedFlight.mailWeight))
     744
     745        self._route.get_buffer().set_text(bookedFlight.route)
     746
     747        self._filedCruiseLevel.set_value(pirep.filedCruiseAltitude/100)
     748        self._modifiedCruiseLevel.set_value(pirep.cruiseAltitude/100)
     749
     750        self._userRoute.get_buffer().set_text(pirep.route)
     751
     752        self._departureMETAR.get_buffer().set_text(pirep.departureMETAR)
     753
     754        self._arrivalMETAR.get_buffer().set_text(pirep.arrivalMETAR)
     755        self._departureRunway.set_text(pirep.departureRunway)
     756        self._sid.get_child().set_text(pirep.sid)
     757
     758        if not pirep.star:
     759            self._star.set_active(0)
     760        else:
     761            self._star.get_child().set_text(pirep.star)
     762
     763        if not pirep.transition:
     764            self._transition.set_active(0)
     765        else:
     766            self._transition.get_child().set_text(pirep.transition)
     767        self._approachType.set_text(pirep.approachType)
     768        self._arrivalRunway.set_text(pirep.arrivalRunway)
     769
     770        self._blockTimeStart.setTimestamp(pirep.blockTimeStart)
     771        self._blockTimeEnd.setTimestamp(pirep.blockTimeEnd)
     772        self._flightTimeStart.setTimestamp(pirep.flightTimeStart)
     773        self._flightTimeEnd.setTimestamp(pirep.flightTimeEnd)
     774
     775        self._flownDistance.set_text("%.1f" % (pirep.flownDistance,))
     776        self._fuelUsed.set_value(int(pirep.fuelUsed))
     777
     778        rating = pirep.rating
     779        if rating<0:
     780            self._rating.set_markup('<b><span foreground="red">NO GO</span></b>')
     781        else:
     782            self._rating.set_text("%.1f %%" % (rating,))
     783
     784        self._flownNumCrew.set_value(pirep.numCrew)
     785        self._flownNumPassengers.set_value(pirep.numPassengers)
     786        self._flownBagWeight.set_value(pirep.bagWeight)
     787        self._flownCargoWeight.set_value(pirep.cargoWeight)
     788        self._flownMailWeight.set_value(pirep.mailWeight)
     789        self._flightType.set_active(flightType2index(pirep.flightType))
     790        self._online.set_active(pirep.online)
     791
     792        self._flightInfo.reset()
     793        self._flightInfo.enable(bookedFlight.aircraftType)
     794
     795        delayCodes = ""
     796        for code in pirep.delayCodes:
     797            if delayCodes: delayCodes += ", "
     798            delayCodes += code
     799            m = PIREPEditor._delayCodeRE.match(code)
     800            if m:
     801                self._flightInfo.activateDelayCode(m.group(1))
     802
     803        self._delayCodes.get_buffer().set_text(delayCodes)
     804
     805        self._flightInfo.comments = pirep.comments
     806        if pirep.flightDefects.find("<br/></b>")!=-1:
     807            flightDefects = pirep.flightDefects.split("<br/></b>")
     808            caption = flightDefects[0]
     809            index = 0
     810            for defect in flightDefects[1:]:
     811                if defect.find("<b>")!=-1:
     812                    (explanation, nextCaption) = defect.split("<b>")
     813                else:
     814                    explanation = defect
     815                    nextCaption = None
     816                self._flightInfo.addFault(index, caption)
     817                self._flightInfo.setExplanation(index, explanation)
     818                index += 1
     819                caption = nextCaption
     820
     821        # self._comments.get_buffer().set_text(pirep.comments)
     822        # self._flightDefects.get_buffer().set_text(pirep.flightDefects)
     823
     824        logBuffer = self._log.get_buffer()
     825        logBuffer.set_text("")
     826        lineIndex = 0
     827        for (timeStr, line) in pirep.logLines:
     828            isFault = lineIndex in pirep.faultLineIndexes
     829            appendTextBuffer(logBuffer,
     830                             formatFlightLogLine(timeStr, line),
     831                             isFault = isFault)
     832            lineIndex += 1
     833
     834        self._notebook.set_current_page(0)
     835        self._okButton.grab_default()
     836
     837    def _buildDataTab(self):
     838        """Build the data tab of the viewer."""
     839        table = gtk.Table(1, 2)
     840        table.set_row_spacings(4)
     841        table.set_col_spacings(16)
     842        table.set_homogeneous(True)
     843
     844        box1 = gtk.VBox()
     845        table.attach(box1, 0, 1, 0, 1)
     846
     847        box2 = gtk.VBox()
     848        table.attach(box2, 1, 2, 0, 1)
     849
     850        flightFrame = self._buildFlightFrame()
     851        box1.pack_start(flightFrame, False, False, 4)
     852
     853        routeFrame = self._buildRouteFrame()
     854        box1.pack_start(routeFrame, False, False, 4)
     855
     856        departureFrame = self._buildDepartureFrame()
     857        box2.pack_start(departureFrame, True, True, 4)
     858
     859        arrivalFrame = self._buildArrivalFrame()
     860        box2.pack_start(arrivalFrame, True, True, 4)
     861
     862        statisticsFrame = self._buildStatisticsFrame()
     863        box2.pack_start(statisticsFrame, False, False, 4)
     864
     865        miscellaneousFrame = self._buildMiscellaneousFrame()
     866        box1.pack_start(miscellaneousFrame, False, False, 4)
     867
     868        return table
     869
     870    def _buildFlightFrame(self):
     871        """Build the frame for the flight data."""
     872
     873        (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_flight"))
     874
     875        dataBox = gtk.HBox()
     876        mainBox.pack_start(dataBox, False, False, 0)
     877
     878        self._callsign = \
     879            PIREPViewer.addLabeledData(dataBox,
     880                                       xstr("pirepView_callsign"),
     881                                       width = 8)
     882
     883        self._tailNumber = \
     884            PIREPViewer.addLabeledData(dataBox,
     885                                       xstr("pirepView_tailNumber"),
     886                                       width = 7)
     887
     888        PIREPViewer.addVFiller(mainBox)
     889
     890        dataBox = gtk.HBox()
     891        mainBox.pack_start(dataBox, False, False, 0)
     892
     893        self._aircraftType = \
     894            PIREPViewer.addLabeledData(dataBox,
     895                                       xstr("pirepView_aircraftType"),
     896                                       width = 25)
     897
     898        PIREPViewer.addVFiller(mainBox)
     899
     900        table = gtk.Table(3, 2)
     901        mainBox.pack_start(table, False, False, 0)
     902        table.set_row_spacings(4)
     903        table.set_col_spacings(8)
     904
     905        self._departureICAO = \
     906            PIREPViewer.tableAttach(table, 0, 0,
     907                                    xstr("pirepView_departure"),
     908                                    width = 5)
     909
     910        self._departureTime = \
     911            PIREPViewer.tableAttach(table, 1, 0,
     912                                    xstr("pirepView_departure_time"),
     913                                    width = 6)
     914
     915        self._arrivalICAO = \
     916            PIREPViewer.tableAttach(table, 0, 1,
     917                                    xstr("pirepView_arrival"),
     918                                    width = 5)
     919
     920        self._arrivalTime = \
     921            PIREPViewer.tableAttach(table, 1, 1,
     922                                    xstr("pirepView_arrival_time"),
     923                                    width = 6)
     924
     925        table = gtk.Table(3, 2)
     926        mainBox.pack_start(table, False, False, 0)
     927        table.set_row_spacings(4)
     928        table.set_col_spacings(8)
     929
     930        self._numPassengers = \
     931            PIREPViewer.tableAttach(table, 0, 0,
     932                                    xstr("pirepView_numPassengers"),
     933                                    width = 4)
     934
     935        self._numCrew = \
     936            PIREPViewer.tableAttach(table, 1, 0,
     937                                    xstr("pirepView_numCrew"),
     938                                    width = 3)
     939
     940        self._bagWeight = \
     941            PIREPViewer.tableAttach(table, 0, 1,
     942                                    xstr("pirepView_bagWeight"),
     943                                    width = 5)
     944
     945        self._cargoWeight = \
     946            PIREPViewer.tableAttach(table, 1, 1,
     947                                    xstr("pirepView_cargoWeight"),
     948                                    width = 5)
     949
     950        self._mailWeight = \
     951            PIREPViewer.tableAttach(table, 2, 1,
     952                                    xstr("pirepView_mailWeight"),
     953                                    width = 5)
     954
     955        PIREPViewer.addVFiller(mainBox)
     956
     957        mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_route")),
     958                           False, False, 0)
     959
     960        (routeWindow, self._route) = PIREPViewer.getTextWindow()
     961        mainBox.pack_start(routeWindow, False, False, 0)
     962
     963        return frame
     964
     965    def _buildRouteFrame(self):
     966        """Build the frame for the user-specified route and flight
     967        level."""
     968
     969        (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_route"))
     970
     971        levelBox = gtk.HBox()
     972        mainBox.pack_start(levelBox, False, False, 0)
     973
     974        label = PIREPViewer.getLabel(xstr("pirepView_filedCruiseLevel"),
     975                                     xstr("pirepEdit_FL"))
     976        levelBox.pack_start(label, False, False, 0)
     977
     978        self._filedCruiseLevel = gtk.SpinButton()
     979        self._filedCruiseLevel.set_increments(step = 10, page = 100)
     980        self._filedCruiseLevel.set_range(min = 0, max = 500)
     981        #self._filedCruiseLevel.set_tooltip_text(xstr("route_level_tooltip"))
     982        self._filedCruiseLevel.set_numeric(True)
     983
     984        levelBox.pack_start(self._filedCruiseLevel, False, False, 0)
     985
     986        PIREPViewer.addHFiller(levelBox)
     987
     988        label = PIREPViewer.getLabel(xstr("pirepView_modifiedCruiseLevel"),
     989                                     xstr("pirepEdit_FL"))
     990        levelBox.pack_start(label, False, False, 0)
     991
     992        self._modifiedCruiseLevel = gtk.SpinButton()
     993        self._modifiedCruiseLevel.set_increments(step = 10, page = 100)
     994        self._modifiedCruiseLevel.set_range(min = 0, max = 500)
     995        #self._modifiedCruiseLevel.set_tooltip_text(xstr("route_level_tooltip"))
     996        self._modifiedCruiseLevel.set_numeric(True)
     997
     998        levelBox.pack_start(self._modifiedCruiseLevel, False, False, 0)
     999
     1000        PIREPViewer.addVFiller(mainBox)
     1001
     1002        (routeWindow, self._userRoute) = \
     1003          PIREPViewer.getTextWindow(editable = True)
     1004        mainBox.pack_start(routeWindow, False, False, 0)
     1005
     1006        return frame
     1007
     1008    def _buildDepartureFrame(self):
     1009        """Build the frame for the departure data."""
     1010        (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_departure"))
     1011
     1012        mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
     1013                           False, False, 0)
     1014        (metarWindow, self._departureMETAR) = \
     1015            PIREPViewer.getTextWindow(heightRequest = -1,
     1016                                      editable = True)
     1017        mainBox.pack_start(metarWindow, True, True, 0)
     1018
     1019        PIREPViewer.addVFiller(mainBox)
     1020
     1021        dataBox = gtk.HBox()
     1022        mainBox.pack_start(dataBox, False, False, 0)
     1023
     1024        label = gtk.Label("<b>" + xstr("pirepView_runway") + "</b>")
     1025        label.set_use_markup(True)
     1026        dataBox.pack_start(label, False, False, 0)
     1027
     1028        # FIXME: quite the same as the runway entry boxes in the wizard
     1029        self._departureRunway = gtk.Entry()
     1030        self._departureRunway.set_width_chars(5)
     1031        self._departureRunway.set_tooltip_text(xstr("takeoff_runway_tooltip"))
     1032        self._departureRunway.connect("changed", self._upperChanged)
     1033        dataBox.pack_start(self._departureRunway, False, False, 8)
     1034
     1035        label = gtk.Label("<b>" + xstr("pirepView_sid") + "</b>")
     1036        label.set_use_markup(True)
     1037        dataBox.pack_start(label, False, False, 0)
     1038
     1039        # FIXME: quite the same as the SID combo box in
     1040        # the flight wizard
     1041        if pygobject:
     1042            self._sid = gtk.ComboBox.new_with_model_and_entry(comboModel)
     1043        else:
     1044            self._sid = gtk.ComboBoxEntry(comboModel)
     1045
     1046        self._sid.set_entry_text_column(0)
     1047        self._sid.get_child().set_width_chars(10)
     1048        self._sid.set_tooltip_text(xstr("takeoff_sid_tooltip"))
     1049        self._sid.connect("changed", self._upperChangedComboBox)
     1050
     1051        dataBox.pack_start(self._sid, False, False, 8)
     1052
     1053        return frame
     1054
     1055    def _buildArrivalFrame(self):
     1056        """Build the frame for the arrival data."""
     1057        (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_arrival"))
     1058
     1059        mainBox.pack_start(PIREPViewer.getLabel("METAR:"),
     1060                           False, False, 0)
     1061        (metarWindow, self._arrivalMETAR) = \
     1062            PIREPViewer.getTextWindow(heightRequest = -1,
     1063                                      editable = True)
     1064        mainBox.pack_start(metarWindow, True, True, 0)
     1065
     1066        PIREPViewer.addVFiller(mainBox)
     1067
     1068        table = gtk.Table(2, 4)
     1069        mainBox.pack_start(table, False, False, 0)
     1070        table.set_row_spacings(4)
     1071        table.set_col_spacings(8)
     1072
     1073        # FIXME: quite the same as in the wizard
     1074        if pygobject:
     1075            self._star = gtk.ComboBox.new_with_model_and_entry(comboModel)
     1076        else:
     1077            self._star = gtk.ComboBoxEntry(comboModel)
     1078
     1079        self._star.set_entry_text_column(0)
     1080        self._star.get_child().set_width_chars(10)
     1081        self._star.set_tooltip_text(xstr("landing_star_tooltip"))
     1082        self._star.connect("changed", self._upperChangedComboBox)
     1083
     1084        PIREPEditor.tableAttachWidget(table, 0, 0,
     1085                                      xstr("pirepView_star"),
     1086                                      self._star)
     1087
     1088        # FIXME: quite the same as in the wizard
     1089        if pygobject:
     1090            self._transition = gtk.ComboBox.new_with_model_and_entry(comboModel)
     1091        else:
     1092            self._transition = gtk.ComboBoxEntry(comboModel)
     1093
     1094        self._transition.set_entry_text_column(0)
     1095        self._transition.get_child().set_width_chars(10)
     1096        self._transition.set_tooltip_text(xstr("landing_transition_tooltip"))
     1097        self._transition.connect("changed", self._upperChangedComboBox)
     1098
     1099        PIREPEditor.tableAttachWidget(table, 2, 0,
     1100                                      xstr("pirepView_transition"),
     1101                                      self._transition)
     1102
     1103
     1104        # FIXME: quite the same as in the wizard
     1105        self._approachType = gtk.Entry()
     1106        self._approachType.set_width_chars(10)
     1107        self._approachType.set_tooltip_text(xstr("landing_approach_tooltip"))
     1108        self._approachType.connect("changed", self._upperChanged)
     1109
     1110        PIREPEditor.tableAttachWidget(table, 0, 1,
     1111                                      xstr("pirepView_approachType"),
     1112                                      self._approachType)
     1113
     1114        # FIXME: quite the same as in the wizard
     1115        self._arrivalRunway = gtk.Entry()
     1116        self._arrivalRunway.set_width_chars(10)
     1117        self._arrivalRunway.set_tooltip_text(xstr("landing_runway_tooltip"))
     1118        self._arrivalRunway.connect("changed", self._upperChanged)
     1119
     1120        PIREPEditor.tableAttachWidget(table, 2, 1,
     1121                                      xstr("pirepView_runway"),
     1122                                      self._arrivalRunway)
     1123
     1124        return frame
     1125
     1126    def _buildStatisticsFrame(self):
     1127        """Build the frame for the statistics data."""
     1128        (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_statistics"))
     1129
     1130        table = gtk.Table(4, 4)
     1131        mainBox.pack_start(table, False, False, 0)
     1132        table.set_row_spacings(4)
     1133        table.set_col_spacings(8)
     1134        table.set_homogeneous(False)
     1135
     1136        self._blockTimeStart = \
     1137            PIREPEditor.tableAttachTimeEntry(table, 0, 0,
     1138                                             xstr("pirepView_blockTimeStart"))
     1139
     1140        self._blockTimeEnd = \
     1141            PIREPEditor.tableAttachTimeEntry(table, 2, 0,
     1142                                             xstr("pirepView_blockTimeEnd"))
     1143
     1144        self._flightTimeStart = \
     1145            PIREPEditor.tableAttachTimeEntry(table, 0, 1,
     1146                                             xstr("pirepView_flightTimeStart"))
     1147
     1148        self._flightTimeEnd = \
     1149            PIREPEditor.tableAttachTimeEntry(table, 2, 1,
     1150                                             xstr("pirepView_flightTimeEnd"))
     1151
     1152        self._flownDistance = PIREPViewer.getDataLabel(width = 3)
     1153        PIREPEditor.tableAttachWidget(table, 0, 2,
     1154                                      xstr("pirepView_flownDistance"),
     1155                                      self._flownDistance)
     1156
     1157        self._fuelUsed = \
     1158            PIREPEditor.tableAttachSpinButton(table, 2, 2,
     1159                                              xstr("pirepView_fuelUsed"),
     1160                                              1000000)
     1161
     1162
     1163        self._rating = PIREPViewer.getDataLabel(width = 3)
     1164        PIREPEditor.tableAttachWidget(table, 0, 3,
     1165                                      xstr("pirepView_rating"),
     1166                                      self._rating)
     1167        return frame
     1168
     1169    def _buildMiscellaneousFrame(self):
     1170        """Build the frame for the miscellaneous data."""
     1171        (frame, mainBox) = PIREPViewer.createFrame(xstr("pirepView_frame_miscellaneous"))
     1172
     1173        table = gtk.Table(6, 2)
     1174        mainBox.pack_start(table, False, False, 0)
     1175        table.set_row_spacings(4)
     1176        table.set_col_spacings(8)
     1177        table.set_homogeneous(False)
     1178
     1179        self._flownNumPassengers = \
     1180            PIREPEditor.tableAttachSpinButton(table, 0, 0,
     1181                                              xstr("pirepView_numPassengers"),
     1182                                              300)
     1183
     1184        self._flownNumCrew = \
     1185            PIREPEditor.tableAttachSpinButton(table, 2, 0,
     1186                                              xstr("pirepView_numCrew"),
     1187                                              10)
     1188
     1189        self._flownBagWeight = \
     1190            PIREPEditor.tableAttachSpinButton(table, 0, 1,
     1191                                              xstr("pirepView_bagWeight"),
     1192                                              100000, width = 6)
     1193
     1194        self._flownCargoWeight = \
     1195            PIREPEditor.tableAttachSpinButton(table, 2, 1,
     1196                                              xstr("pirepView_cargoWeight"),
     1197                                              100000, width = 6)
     1198
     1199        self._flownMailWeight = \
     1200            PIREPEditor.tableAttachSpinButton(table, 4, 1,
     1201                                              xstr("pirepView_mailWeight"),
     1202                                              100000, width = 6)
     1203
     1204        self._flightType = createFlightTypeComboBox()
     1205        PIREPEditor.tableAttachWidget(table, 0, 2,
     1206                                      xstr("pirepView_flightType"),
     1207                                      self._flightType)
     1208
     1209        self._online = gtk.CheckButton(xstr("pirepView_online"))
     1210        table.attach(self._online, 2, 3, 2, 3)
     1211
     1212        PIREPViewer.addVFiller(mainBox)
     1213
     1214        mainBox.pack_start(PIREPViewer.getLabel(xstr("pirepView_delayCodes")),
     1215                           False, False, 0)
     1216
     1217        (textWindow, self._delayCodes) = PIREPViewer.getTextWindow()
     1218        mainBox.pack_start(textWindow, False, False, 0)
     1219
     1220        return frame
     1221
     1222    def _buildCommentsTab(self):
     1223        """Build the tab with the comments and flight defects."""
     1224        return FlightInfo(self._gui, mainInstance = False)
     1225
     1226    def _buildLogTab(self):
     1227        """Build the log tab."""
     1228        mainBox = gtk.VBox()
     1229
     1230        (logWindow, self._log) = PIREPViewer.getTextWindow(heightRequest = -1)
     1231        addFaultTag(self._log.get_buffer())
     1232        mainBox.pack_start(logWindow, True, True, 0)
     1233
     1234        return mainBox
     1235
     1236    def _upperChanged(self, entry, arg = None):
     1237        """Called when the value of some entry widget has changed and the value
     1238        should be converted to uppercase."""
     1239        entry.set_text(entry.get_text().upper())
     1240        #self._valueChanged(entry, arg)
     1241
     1242    def _upperChangedComboBox(self, comboBox):
     1243        """Called for combo box widgets that must be converted to uppercase."""
     1244        entry = comboBox.get_child()
     1245        if comboBox.get_active()==-1:
     1246            entry.set_text(entry.get_text().upper())
     1247        #self._valueChanged(entry)
     1248
     1249#------------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.