Ignore:
Timestamp:
03/30/12 15:26:43 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
hg-Phase:
(<MercurialRepository 1 'hg:/home/ivaradi/mlx/hg' '/'>, 'public')
Message:

Fleet retrieval and gate selection works, started new connection handling and the fsuipc simulator

File:
1 edited

Legend:

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

    r50 r51  
    22
    33from mlx.gui.common import *
     4
     5import mlx.const as const
     6import mlx.fs as fs
     7from mlx.logger import Logger
     8from mlx.flight import Flight
     9from mlx.acft import Aircraft
    410
    511#-----------------------------------------------------------------------------
     
    6268        self._mainAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
    6369                                            xscale = 1.0, yscale = 1.0)
    64         table.attach(self._mainAlignment, 0, 1, 1, 3)                                   
     70        table.attach(self._mainAlignment, 0, 1, 1, 3)
    6571                                           
    6672        buttonAlignment =  gtk.Alignment(xalign = 1.0, xscale=0.0, yscale = 0.0)
     
    182188        """Called when the login button was clicked."""
    183189        self._wizard.gui.beginBusy("Logging in...")
    184         self._wizard.gui.webHandler.login(self._pilotID.get_text(),
    185                                           self._password.get_text(),
    186                                           self._loginResultCallback)
     190        self._wizard.gui.webHandler.login(self._loginResultCallback,
     191                                          self._pilotID.get_text(),
     192                                          self._password.get_text())
    187193
    188194    def _loginResultCallback(self, returned, result):
     
    275281        self._button.set_use_stock(True)
    276282        self._button.set_sensitive(False)
     283        self._button.connect("clicked", self._forwardClicked)
    277284
    278285        self._activated = False
     
    292299        self._button.set_sensitive(selection.count_selected_rows()==1)
    293300
     301    def _forwardClicked(self, button):
     302        """Called when the forward button was clicked."""
     303        selection = self._flightList.get_selection()
     304        (listStore, iter) = selection.get_selected()
     305        path = listStore.get_path(iter)
     306        [index] = path.get_indices() if pygobject else path
     307
     308        flight = self._wizard.loginResult.flights[index]
     309        self._wizard._bookedFlight = flight
     310
     311        self._updateDepartureGate()
     312       
     313    def _updateDepartureGate(self):
     314        """Update the departure gate for the booked flight."""
     315        flight = self._wizard._bookedFlight
     316        if flight.departureICAO=="LHBP":
     317            self._wizard._getFleet(self._fleetRetrieved)
     318        else:
     319            self._wizard.jumpPage(2)
     320
     321    def _fleetRetrieved(self, fleet):
     322        """Called when the fleet has been retrieved."""
     323        if fleet is None:
     324            self._wizard.jumpPage(2)
     325        else:
     326            plane = fleet[self._wizard._bookedFlight.tailNumber]
     327            if plane is None:
     328                self._wizard.jumpPage(2)
     329           
     330            if plane.gateNumber is not None and \
     331               not fleet.isGateConflicting(plane):
     332                self._wizard._departureGate = plane.gateNumber
     333                self._wizard.jumpPage(2)
     334            else:
     335                self._wizard.nextPage()
     336       
     337#-----------------------------------------------------------------------------
     338
     339class GateSelectionPage(Page):
     340    """Page to select a free gate at LHBP.
     341
     342    This page should be displayed only if we have fleet information!."""
     343    def __init__(self, wizard):
     344        """Construct the gate selection page."""
     345        help = "The airplane's gate position is invalid.\n\n" \
     346               "Select the gate from which you\n" \
     347               "would like to begin the flight."
     348        super(GateSelectionPage, self).__init__(wizard,
     349                                                "LHBP gate selection",
     350                                                help)
     351
     352        self._listStore = gtk.ListStore(str)
     353        self._gateList = gtk.TreeView(self._listStore)
     354        column = gtk.TreeViewColumn(None, gtk.CellRendererText(),
     355                                    text = 0)
     356        column.set_expand(True)
     357        self._gateList.append_column(column)
     358        self._gateList.set_headers_visible(False)
     359
     360        gateSelection = self._gateList.get_selection()
     361        gateSelection.connect("changed", self._selectionChanged)
     362
     363        scrolledWindow = gtk.ScrolledWindow()
     364        scrolledWindow.add(self._gateList)
     365        scrolledWindow.set_size_request(50, -1)
     366        scrolledWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
     367                                  else gtk.POLICY_AUTOMATIC,
     368                                  gtk.PolicyType.ALWAYS if pygobject
     369                                  else gtk.POLICY_ALWAYS)
     370
     371        alignment = gtk.Alignment(xalign = 0.5, yalign = 0.0, xscale = 0.0, yscale = 1.0)
     372        alignment.add(scrolledWindow)
     373
     374        self.setMainWidget(alignment)       
     375
     376        self._button = self.addButton(gtk.STOCK_GO_FORWARD, default = True)
     377        self._button.set_use_stock(True)
     378        self._button.set_sensitive(False)
     379        self._button.connect("clicked", self._forwardClicked)
     380
     381    def activate(self):
     382        """Fill the gate list."""
     383        self._listStore.clear()
     384        occupiedGateNumbers = self._wizard._fleet.getOccupiedGateNumbers()
     385        for gateNumber in const.lhbpGateNumbers:
     386            if gateNumber not in occupiedGateNumbers:
     387                self._listStore.append([gateNumber])
     388
     389    def _selectionChanged(self, selection):
     390        """Called when the selection is changed."""
     391        self._button.set_sensitive(selection.count_selected_rows()==1)
     392
     393    def _forwardClicked(self, button):
     394        """Called when the forward button is clicked."""
     395        selection = self._gateList.get_selection()
     396        (listStore, iter) = selection.get_selected()
     397        (gateNumber,) = listStore.get(iter, 0)
     398
     399        self._wizard._departureGate = gateNumber
     400
     401        self._wizard._updatePlane(self._planeUpdated,
     402                                  self._wizard._bookedFlight.tailNumber,
     403                                  const.PLANE_HOME,
     404                                  gateNumber)
     405
     406    def _planeUpdated(self, success):
     407        """Callback for the plane updating call."""
     408        if success is None or success:
     409            self._wizard.nextPage()
     410        else:
     411            dialog = gtk.MessageDialog(type = MESSAGETYPE_ERROR,
     412                                       buttons = BUTTONSTYPE_OK,
     413                                       message_format = "Gate conflict detected again")
     414            dialog.format_secondary_markup("Try to select a different gate.")
     415            dialog.run()
     416            dialog.hide()
     417
     418            self._wizard._getFleet(self._fleetRetrieved)
     419
     420    def _fleetRetrieved(self, fleet):
     421        """Called when the fleet has been retrieved."""
     422        if fleet is None:
     423            self._wizard.nextPage()
     424        else:
     425            self.activate()
     426           
     427#-----------------------------------------------------------------------------
     428
     429class ConnectPage(Page):
     430    """Page which displays the departure airport and gate (if at LHBP)."""
     431    def __init__(self, wizard):
     432        """Construct the connect page."""
     433        help = "The flight begins at the airport given below.\n" \
     434               "Park your aircraft there, at the gate below, if given.\n\n" \
     435               "Then press the Connect button to connect to the simulator."
     436        super(ConnectPage, self).__init__(wizard,
     437                                          "Connect to the simulator",
     438                                          help)
     439       
     440        alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
     441                                  xscale = 0.0, yscale = 0.0)
     442
     443        table = gtk.Table(2, 2)
     444        table.set_row_spacings(4)
     445        table.set_col_spacings(16)
     446        table.set_homogeneous(True)
     447        alignment.add(table)
     448        self.setMainWidget(alignment)
     449
     450        labelAlignment = gtk.Alignment(xalign=1.0, xscale=0.0)
     451        label = gtk.Label("ICAO code:")
     452        labelAlignment.add(label)
     453        table.attach(labelAlignment, 0, 1, 0, 1)
     454
     455        labelAlignment = gtk.Alignment(xalign=0.0, xscale=0.0)
     456        self._departureICAO = gtk.Label()
     457        self._departureICAO.set_width_chars(5)
     458        self._departureICAO.set_alignment(0.0, 0.5)
     459        labelAlignment.add(self._departureICAO)
     460        table.attach(labelAlignment, 1, 2, 0, 1)
     461
     462        labelAlignment = gtk.Alignment(xalign=1.0, xscale=0.0)
     463        label = gtk.Label("Gate:")
     464        label.set_use_underline(True)
     465        labelAlignment.add(label)
     466        table.attach(labelAlignment, 0, 1, 1, 2)
     467
     468        labelAlignment = gtk.Alignment(xalign=0.0, xscale=0.0)
     469        self._departureGate = gtk.Label()
     470        self._departureGate.set_width_chars(5)
     471        self._departureGate.set_alignment(0.0, 0.5)
     472        labelAlignment.add(self._departureGate)
     473        table.attach(labelAlignment, 1, 2, 1, 2)
     474
     475
     476        self._button = self.addButton("_Connect", default = True)
     477        self._button.set_use_underline(True)
     478        self._button.connect("clicked", self._connectClicked)
     479
     480    def activate(self):
     481        """Setup the deprature information."""
     482        icao = self._wizard._bookedFlight.departureICAO
     483        self._departureICAO.set_markup("<b>" + icao + "</b>")
     484        gate = self._wizard._departureGate
     485        if gate!="-":
     486            gate = "<b>" + gate + "</b>"
     487        self._departureGate.set_markup(gate)
     488
     489    def _connectClicked(self, button):
     490        """Called when the Connect button is pressed."""
     491        self._wizard._connectSimulator()
     492
    294493#-----------------------------------------------------------------------------
    295494
     
    307506        self._pages.append(LoginPage(self))
    308507        self._pages.append(FlightSelectionPage(self))
    309 
     508        self._pages.append(GateSelectionPage(self))
     509        self._pages.append(ConnectPage(self))
     510
     511        maxWidth = 0
     512        maxHeight = 0
     513        for page in self._pages:
     514            page.show_all()
     515            pageSizeRequest = page.size_request()
     516            width = pageSizeRequest.width if pygobject else pageSizeRequest[0]
     517            height = pageSizeRequest.height if pygobject else pageSizeRequest[1]
     518            maxWidth = max(maxWidth, width)
     519            maxHeight = max(maxHeight, height)
     520        maxWidth += 16
     521        maxHeight += 32
     522        self.set_size_request(maxWidth, maxHeight)
     523
     524        self._fleet = None
     525        self._fleetCallback = None
     526        self._updatePlaneCallback = None
     527       
    310528        self._loginResult = None
    311 
     529        self._bookedFlight = None
     530        self._departureGate = "-"
     531
     532        self._logger = Logger(output = gui)
     533        self._flight = None
     534        self._simulator = None
     535       
    312536        self.setCurrentPage(0)
    313 
     537       
    314538    @property
    315539    def loginResult(self):
     
    331555    def nextPage(self):
    332556        """Go to the next page."""
    333         self.setCurrentPage(self._currentPage + 1)
     557        self.jumpPage(1)
     558
     559    def jumpPage(self, count):
     560        """Go to the page which is 'count' pages after the current one."""
     561        self.setCurrentPage(self._currentPage + count)
    334562        self.grabDefault()
    335563
     
    337565        """Make the default button of the current page the default."""
    338566        self._pages[self._currentPage].grabDefault()
     567
     568    def _getFleet(self, callback, force = False):
     569        """Get the fleet, if needed.
     570
     571        callback is function that will be called, when the feet is retrieved,
     572        or the retrieval fails. It should have a single argument that will
     573        receive the fleet object on success, None otherwise.
     574        """
     575        if self._fleet is not None and not force:
     576            callback(self._fleet)
     577
     578        self.gui.beginBusy("Retrieving fleet...")
     579        self._fleetCallback = callback
     580        self.gui.webHandler.getFleet(self._fleetResultCallback)
     581
     582    def _fleetResultCallback(self, returned, result):
     583        """Called when the fleet has been queried."""
     584        gobject.idle_add(self._handleFleetResult, returned, result)
     585
     586    def _handleFleetResult(self, returned, result):
     587        """Handle the fleet result."""
     588        self.gui.endBusy()
     589        if returned:
     590            self._fleet = result.fleet
     591        else:
     592            self._fleet = None
     593
     594            dialog = gtk.MessageDialog(type = MESSAGETYPE_ERROR,
     595                                       buttons = BUTTONSTYPE_OK,
     596                                       message_format =
     597                                       "Failed to retrieve the information on "
     598                                       "the fleet.")
     599            dialog.run()
     600            dialog.hide()
     601
     602        self._fleetCallback(self._fleet)
     603
     604    def _updatePlane(self, callback, tailNumber, status, gateNumber = None):
     605        """Update the given plane's gate information."""
     606        self.gui.beginBusy("Updating plane status...")
     607        self._updatePlaneCallback = callback
     608        self.gui.webHandler.updatePlane(self._updatePlaneResultCallback,
     609                                        tailNumber, status, gateNumber)
     610
     611    def _updatePlaneResultCallback(self, returned, result):
     612        """Callback for the plane updating operation."""
     613        gobject.idle_add(self._handleUpdatePlaneResult, returned, result)
     614
     615    def _handleUpdatePlaneResult(self, returned, result):
     616        """Handle the result of a plane update operation."""
     617        self.gui.endBusy()
     618        if returned:
     619            success = result.success
     620        else:
     621            success = None
     622
     623            dialog = gtk.MessageDialog(type = MESSAGETYPE_ERROR,
     624                                       buttons = BUTTONSTYPE_OK,
     625                                       message_format =
     626                                       "Failed to update the statuis of "
     627                                       "the airplane.")
     628            dialog.run()
     629            dialog.hide()
     630
     631        self._updatePlaneCallback(success)
     632
     633    def _connectSimulator(self):
     634        """Connect to the simulator."""
     635        self._logger.reset()
     636        self._flight = Flight(self.gui._logger, self.gui)
     637
     638        self._flight.aircraftType = self._bookedFlight.aircraftType
     639        aircraft = self._flight.aircraft = Aircraft.create(self._flight)
     640        self._flight.aircraft._checkers.append(self.gui)
     641       
     642        self._flight.cruiseAltitude = -1       
     643        self._flight.zfw = -1
     644
     645        if self._simulator is None:
     646            self._simulator = fs.createSimulator(const.SIM_MSFS9, self.gui)
     647
     648        self._flight.simulator = self._simulator
     649        self._simulator.connect(aircraft)
     650        #self._simulator.startMonitoring()
    339651   
    340652#-----------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.