Ignore:
File:
1 edited

Legend:

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

    r728 r675  
    11
    22from mlx.gui.common import *
    3 import mlx.gui.cef as cef
    43
    54import mlx.const as const
     
    1817import time
    1918import os
    20 import tempfile
    21 import threading
    2219
    2320#-----------------------------------------------------------------------------
     
    14281425#-----------------------------------------------------------------------------
    14291426
    1430 class RoutePage(Page):
    1431     """The page containing the route and the flight level."""
    1432     def __init__(self, wizard):
    1433         """Construct the page."""
    1434         super(RoutePage, self).__init__(wizard, xstr("route_title"),
    1435                                         xstr("route_help"),
    1436                                         completedHelp = xstr("route_chelp"))
    1437 
    1438         alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
    1439                                   xscale = 0.0, yscale = 0.0)
    1440 
    1441         mainBox = gtk.VBox()
    1442         alignment.add(mainBox)
    1443         self.setMainWidget(alignment)
    1444 
    1445         levelBox = gtk.HBox()
    1446 
    1447         label = gtk.Label(xstr("route_level"))
    1448         label.set_use_underline(True)
    1449         levelBox.pack_start(label, True, True, 0)
    1450 
    1451         self._cruiseLevel = gtk.SpinButton()
    1452         self._cruiseLevel.set_increments(step = 10, page = 100)
    1453         self._cruiseLevel.set_range(min = 0, max = 500)
    1454         self._cruiseLevel.set_tooltip_text(xstr("route_level_tooltip"))
    1455         self._cruiseLevel.set_numeric(True)
    1456         self._cruiseLevel.connect("changed", self._cruiseLevelChanged)
    1457         self._cruiseLevel.connect("value-changed", self._cruiseLevelChanged)
    1458         label.set_mnemonic_widget(self._cruiseLevel)
    1459 
    1460         levelBox.pack_start(self._cruiseLevel, False, False, 8)
    1461 
    1462         alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
    1463                                   xscale = 0.0, yscale = 0.0)
    1464         alignment.add(levelBox)
    1465 
    1466         mainBox.pack_start(alignment, False, False, 0)
    1467 
    1468 
    1469         routeBox = gtk.VBox()
    1470 
    1471         alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
    1472                                   xscale = 0.0, yscale = 0.0)
    1473         label = gtk.Label(xstr("route_route"))
    1474         label.set_use_underline(True)
    1475         alignment.add(label)
    1476         routeBox.pack_start(alignment, True, True, 0)
    1477 
    1478         routeWindow = gtk.ScrolledWindow()
    1479         routeWindow.set_size_request(400, 80)
    1480         routeWindow.set_shadow_type(gtk.ShadowType.IN if pygobject
    1481                                     else gtk.SHADOW_IN)
    1482         routeWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
    1483                                else gtk.POLICY_AUTOMATIC,
    1484                                gtk.PolicyType.AUTOMATIC if pygobject
    1485                                else gtk.POLICY_AUTOMATIC)
    1486 
    1487         self._uppercasingRoute = False
    1488 
    1489         self._route = gtk.TextView()
    1490         self._route.set_tooltip_text(xstr("route_route_tooltip"))
    1491         self._route.set_wrap_mode(WRAP_WORD)
    1492         self._route.get_buffer().connect("changed", self._routeChanged)
    1493         self._route.get_buffer().connect_after("insert-text", self._routeInserted)
    1494         routeWindow.add(self._route)
    1495 
    1496         label.set_mnemonic_widget(self._route)
    1497         routeBox.pack_start(routeWindow, True, True, 0)
    1498 
    1499         mainBox.pack_start(routeBox, True, True, 8)
    1500 
    1501         alternateBox = gtk.HBox()
    1502 
    1503         label = gtk.Label(xstr("route_altn"))
    1504         label.set_use_underline(True)
    1505         alternateBox.pack_start(label, True, True, 0)
    1506 
    1507         self._alternate = gtk.Entry()
    1508         self._alternate.set_width_chars(6)
    1509         self._alternate.connect("changed", self._alternateChanged)
    1510         self._alternate.set_tooltip_text(xstr("route_altn_tooltip"))
    1511         label.set_mnemonic_widget(self._alternate)
    1512 
    1513         alternateBox.pack_start(self._alternate, False, False, 8)
    1514 
    1515         alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
    1516                                   xscale = 0.0, yscale = 0.0)
    1517         alignment.add(alternateBox)
    1518 
    1519         mainBox.pack_start(alignment, False, False, 0)
    1520 
    1521         self.addCancelFlightButton()
    1522 
    1523         self._backButton = self.addPreviousButton(clicked = self._backClicked)
    1524         self._button = self.addNextButton(clicked = self._forwardClicked)
    1525 
    1526     @property
    1527     def filedCruiseLevel(self):
    1528         """Get the filed cruise level."""
    1529         return self._cruiseLevel.get_value_as_int()
    1530 
    1531     @property
    1532     def route(self):
    1533         """Get the route."""
    1534         return self._getRoute()
    1535 
    1536     @property
    1537     def alternate(self):
    1538         """Get the ICAO code of the alternate airport."""
    1539         return self._alternate.get_text()
    1540 
    1541     def activate(self):
    1542         """Setup the route from the booked flight."""
    1543         self._cruiseLevel.set_value(0)
    1544         self._cruiseLevel.set_text("")
    1545         self._route.get_buffer().set_text(self._wizard._bookedFlight.route)
    1546         self._alternate.set_text("")
    1547         self._updateForwardButton()
    1548 
    1549     def _getRoute(self):
    1550         """Get the text of the route."""
    1551         buffer = self._route.get_buffer()
    1552         return buffer.get_text(buffer.get_start_iter(),
    1553                                buffer.get_end_iter(), True)
    1554 
    1555     def _updateForwardButton(self):
    1556         """Update the sensitivity of the forward button."""
    1557         cruiseLevelText = self._cruiseLevel.get_text()
    1558         cruiseLevel = int(cruiseLevelText) if cruiseLevelText else 0
    1559         alternate = self._alternate.get_text()
    1560         self._button.set_sensitive(cruiseLevel>=50 and self._getRoute()!="" and
    1561                                    len(alternate)==4)
    1562 
    1563     def _cruiseLevelChanged(self, *arg):
    1564         """Called when the cruise level has changed."""
    1565         self._updateForwardButton()
    1566 
    1567     def _routeChanged(self, textBuffer):
    1568         """Called when the route has changed."""
    1569         if not self._uppercasingRoute:
    1570             self._updateForwardButton()
    1571 
    1572     def _routeInserted(self, textBuffer, iter, text, length):
    1573         """Called when new characters are inserted into the route.
    1574 
    1575         It uppercases all characters."""
    1576         if not self._uppercasingRoute:
    1577             self._uppercasingRoute = True
    1578 
    1579             iter1 = iter.copy()
    1580             iter1.backward_chars(length)
    1581             textBuffer.delete(iter, iter1)
    1582 
    1583             textBuffer.insert(iter, text.upper())
    1584 
    1585             self._uppercasingRoute = False
    1586 
    1587     def _alternateChanged(self, entry):
    1588         """Called when the alternate airport has changed."""
    1589         entry.set_text(entry.get_text().upper())
    1590         self._updateForwardButton()
    1591 
    1592     def _backClicked(self, button):
    1593         """Called when the Back button is pressed."""
    1594         self.goBack()
    1595 
    1596     def _forwardClicked(self, button):
    1597         """Called when the Forward button is clicked."""
    1598         if self._wizard.gui.flight.aircraft.simBriefData is None:
    1599             self._wizard.usingSimBrief = False
    1600         if self._wizard.gui.config.useSimBrief and \
    1601            self._wizard.usingSimBrief is not False:
    1602             self._wizard.nextPage()
    1603         else:
    1604             self._wizard.usingSimBrief = False
    1605             self._wizard.jumpPage(3)
    1606 
    1607 #-----------------------------------------------------------------------------
    1608 
    1609 class SimBriefCredentialsDialog(gtk.Dialog):
    1610     """A dialog window to ask for SimBrief credentials."""
    1611     def __init__(self, gui, userName, password, rememberPassword):
    1612         """Construct the dialog."""
    1613         super(SimBriefCredentialsDialog, self).__init__(WINDOW_TITLE_BASE + " - " +
    1614                                                         xstr("simbrief_credentials_title"),
    1615                                                         gui.mainWindow,
    1616                                                         DIALOG_MODAL)
    1617         self.add_button(xstr("button_cancel"), RESPONSETYPE_CANCEL)
    1618         self.add_button(xstr("button_ok"), RESPONSETYPE_OK)
    1619 
    1620         contentArea = self.get_content_area()
    1621 
    1622         contentAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
    1623                                          xscale = 0.0, yscale = 0.0)
    1624         contentAlignment.set_padding(padding_top = 4, padding_bottom = 16,
    1625                                      padding_left = 8, padding_right = 8)
    1626 
    1627         contentArea.pack_start(contentAlignment, False, False, 0)
    1628 
    1629         contentVBox = gtk.VBox()
    1630         contentAlignment.add(contentVBox)
    1631 
    1632         label = gtk.Label(xstr("simbrief_login_failed"))
    1633         label.set_alignment(0.0, 0.0)
    1634 
    1635         contentVBox.pack_start(label, False, False, 0)
    1636 
    1637         tableAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
    1638                                        xscale = 0.0, yscale = 0.0)
    1639         tableAlignment.set_padding(padding_top = 24, padding_bottom = 0,
    1640                                    padding_left = 0, padding_right = 0)
    1641 
    1642         table = gtk.Table(3, 2)
    1643         table.set_row_spacings(4)
    1644         table.set_col_spacings(16)
    1645         table.set_homogeneous(False)
    1646 
    1647         tableAlignment.add(table)
    1648         contentVBox.pack_start(tableAlignment, True, True, 0)
    1649 
    1650         label = gtk.Label(xstr("simbrief_username"))
    1651         label.set_use_underline(True)
    1652         label.set_alignment(0.0, 0.5)
    1653         table.attach(label, 0, 1, 0, 1)
    1654 
    1655         self._userName = gtk.Entry()
    1656         self._userName.set_width_chars(16)
    1657         #self._userName.connect("changed",
    1658         #                       lambda button: self._updateForwardButton())
    1659         self._userName.set_tooltip_text(xstr("simbrief_username_tooltip"))
    1660         self._userName.set_text(userName)
    1661         table.attach(self._userName, 1, 2, 0, 1)
    1662         label.set_mnemonic_widget(self._userName)
    1663 
    1664         label = gtk.Label(xstr("simbrief_password"))
    1665         label.set_use_underline(True)
    1666         label.set_alignment(0.0, 0.5)
    1667         table.attach(label, 0, 1, 1, 2)
    1668 
    1669         self._password = gtk.Entry()
    1670         self._password.set_visibility(False)
    1671         #self._password.connect("changed",
    1672         #                       lambda button: self._updateForwardButton())
    1673         self._password.set_tooltip_text(xstr("simbrief_password_tooltip"))
    1674         self._password.set_text(password)
    1675         table.attach(self._password, 1, 2, 1, 2)
    1676         label.set_mnemonic_widget(self._password)
    1677 
    1678         self._rememberButton = gtk.CheckButton(xstr("simbrief_remember_password"))
    1679         self._rememberButton.set_use_underline(True)
    1680         self._rememberButton.set_tooltip_text(xstr("simbrief_remember_tooltip"))
    1681         self._rememberButton.set_active(rememberPassword)
    1682         table.attach(self._rememberButton, 1, 2, 2, 3, ypadding = 8)
    1683 
    1684     @property
    1685     def userName(self):
    1686         """Get the user name entered."""
    1687         return self._userName.get_text()
    1688 
    1689     @property
    1690     def password(self):
    1691         """Get the password entered."""
    1692         return self._password.get_text()
    1693 
    1694     @property
    1695     def rememberPassword(self):
    1696         """Get whether the password is to be remembered."""
    1697         return self._rememberButton.get_active()
    1698 
    1699     def run(self):
    1700         """Run the dialog."""
    1701         self.show_all()
    1702 
    1703         response = super(SimBriefCredentialsDialog, self).run()
    1704 
    1705         self.hide()
    1706 
    1707         return response
    1708 
    1709 #-----------------------------------------------------------------------------
    1710 
    1711 class SimBriefSetupPage(Page):
    1712     """Page for setting up some parameters for SimBrief."""
    1713     monthNum2Name = [
    1714         "JAN",
    1715         "FEB",
    1716         "MAR",
    1717         "APR",
    1718         "MAY",
    1719         "JUN",
    1720         "JUL",
    1721         "AUG",
    1722         "SEP",
    1723         "OCT",
    1724         "NOV",
    1725         "DEC"
    1726         ]
    1727 
    1728     progress2Message = {
    1729         cef.SIMBRIEF_PROGRESS_SEARCHING_BROWSER: "simbrief_progress_searching_browser",
    1730         cef.SIMBRIEF_PROGRESS_LOADING_FORM: "simbrief_progress_loading_form",
    1731         cef.SIMBRIEF_PROGRESS_FILLING_FORM: "simbrief_progress_filling_form",
    1732         cef.SIMBRIEF_PROGRESS_WAITING_LOGIN: "simbrief_progress_waiting_login",
    1733         cef.SIMBRIEF_PROGRESS_LOGGING_IN: "simbrief_progress_logging_in",
    1734         cef.SIMBRIEF_PROGRESS_WAITING_RESULT: "simbrief_progress_waiting_result",
    1735         cef.SIMBRIEF_PROGRESS_RETRIEVING_BRIEFING: "simbrief_progress_retrieving_briefing"
    1736         }
    1737 
    1738     result2Message = {
    1739         cef.SIMBRIEF_RESULT_ERROR_OTHER: "simbrief_result_error_other",
    1740         cef.SIMBRIEF_RESULT_ERROR_NO_FORM: "simbrief_result_error_no_form",
    1741         cef.SIMBRIEF_RESULT_ERROR_NO_POPUP: "simbrief_result_error_no_popup",
    1742         cef.SIMBRIEF_RESULT_ERROR_LOGIN_FAILED: "simbrief_result_error_login_failed"
    1743         }
    1744 
    1745     @staticmethod
    1746     def getHTMLFilePath():
    1747         """Get the path of the HTML file to contain the generated flight
    1748         plan."""
    1749         if os.name=="nt":
    1750             return os.path.join(tempfile.gettempdir(),
    1751                                 "mlx_simbrief" +
    1752                                 (".secondary" if secondaryInstallation else "") +
    1753                                 ".html")
    1754         else:
    1755             import pwd
    1756             return os.path.join(tempfile.gettempdir(),
    1757                                 "mlx_simbrief." + pwd.getpwuid(os.getuid())[0] + "" +
    1758                                 (".secondary" if secondaryInstallation else "") +
    1759                                 ".html")
    1760 
    1761     def __init__(self, wizard):
    1762         """Construct the setup page."""
    1763 
    1764         super(SimBriefSetupPage, self).__init__(wizard,
    1765                                                 xstr("simbrief_setup_title"),
    1766                                                 xstr("simbrief_setup_help"),
    1767                                                 xstr("simbrief_setup_chelp"))
    1768 
    1769         alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
    1770                                   xscale = 0.0, yscale = 0.0)
    1771 
    1772         table = gtk.Table(9, 3)
    1773         table.set_row_spacings(4)
    1774         table.set_col_spacings(16)
    1775         table.set_homogeneous(False)
    1776         alignment.add(table)
    1777         self.setMainWidget(alignment)
    1778 
    1779         label = gtk.Label(xstr("simbrief_username"))
    1780         label.set_use_underline(True)
    1781         label.set_alignment(0.0, 0.5)
    1782         table.attach(label, 0, 1, 0, 1)
    1783 
    1784         self._userName = gtk.Entry()
    1785         self._userName.set_width_chars(16)
    1786         self._userName.connect("changed",
    1787                                lambda button: self._updateForwardButton())
    1788         self._userName.set_tooltip_text(xstr("simbrief_username_tooltip"))
    1789         table.attach(self._userName, 1, 2, 0, 1)
    1790         label.set_mnemonic_widget(self._userName)
    1791 
    1792         label = gtk.Label(xstr("simbrief_password"))
    1793         label.set_use_underline(True)
    1794         label.set_alignment(0.0, 0.5)
    1795         table.attach(label, 0, 1, 1, 2)
    1796 
    1797         self._password = gtk.Entry()
    1798         self._password.set_visibility(False)
    1799         self._password.connect("changed",
    1800                                lambda button: self._updateForwardButton())
    1801         self._password.set_tooltip_text(xstr("simbrief_password_tooltip"))
    1802         table.attach(self._password, 1, 2, 1, 2)
    1803         label.set_mnemonic_widget(self._password)
    1804 
    1805         self._rememberButton = gtk.CheckButton(xstr("simbrief_remember_password"))
    1806         self._rememberButton.set_use_underline(True)
    1807         self._rememberButton.set_tooltip_text(xstr("simbrief_remember_tooltip"))
    1808         table.attach(self._rememberButton, 1, 2, 2, 3, ypadding = 8)
    1809 
    1810         self._credentialsCondition = threading.Condition()
    1811         self._credentialsAvailable = False
    1812         self._credentialsUserName = None
    1813         self._credentialsPassword = None
    1814 
    1815         label = gtk.Label(xstr("simbrief_extra_fuel"))
    1816         label.set_use_underline(True)
    1817         label.set_alignment(0.0, 0.5)
    1818         table.attach(label, 0, 1, 3, 4)
    1819 
    1820         self._extraFuel = IntegerEntry(defaultValue = 0)
    1821         self._extraFuel.set_width_chars(6)
    1822         self._extraFuel.set_tooltip_text(xstr("simbrief_extra_fuel_tooltip"))
    1823         table.attach(self._extraFuel, 1, 2, 3, 4)
    1824         label.set_mnemonic_widget(self._extraFuel)
    1825 
    1826         table.attach(gtk.Label("kg"), 2, 3, 3, 4)
    1827 
    1828         label = gtk.Label(xstr("simbrief_takeoff_runway"))
    1829         label.set_use_underline(True)
    1830         label.set_alignment(0.0, 0.5)
    1831         table.attach(label, 0, 1, 4, 5)
    1832 
    1833         self._takeoffRunway = gtk.Entry()
    1834         self._takeoffRunway.set_width_chars(10)
    1835         self._takeoffRunway.set_tooltip_text(xstr("simbrief_takeoff_runway_tooltip"))
    1836         self._takeoffRunway.connect("changed", self._upperChanged)
    1837         table.attach(self._takeoffRunway, 1, 2, 4, 5)
    1838         label.set_mnemonic_widget(self._takeoffRunway)
    1839 
    1840         label = gtk.Label(xstr("simbrief_landing_runway"))
    1841         label.set_use_underline(True)
    1842         label.set_alignment(0.0, 0.5)
    1843         table.attach(label, 0, 1, 5, 6)
    1844 
    1845         self._landingRunway = gtk.Entry()
    1846         self._landingRunway.set_width_chars(10)
    1847         self._landingRunway.set_tooltip_text(xstr("simbrief_takeoff_runway_tooltip"))
    1848         self._landingRunway.connect("changed", self._upperChanged)
    1849         table.attach(self._landingRunway, 1, 2, 5, 6)
    1850         label.set_mnemonic_widget(self._landingRunway)
    1851 
    1852         label = gtk.Label(xstr("simbrief_climb_profile"))
    1853         label.set_use_underline(True)
    1854         label.set_alignment(0.0, 0.5)
    1855         table.attach(label, 0, 1, 6, 7)
    1856 
    1857         self._climbProfile = gtk.ComboBox()
    1858         renderer = gtk.CellRendererText()
    1859         self._climbProfile.pack_start(renderer, True)
    1860         self._climbProfile.add_attribute(renderer, "text", 0)
    1861         self._climbProfile.set_tooltip_text(xstr("simbrief_climb_profile_tooltip"))
    1862         table.attach(self._climbProfile, 1, 2, 6, 7)
    1863         label.set_mnemonic_widget(self._climbProfile)
    1864 
    1865         label = gtk.Label(xstr("simbrief_cruise_profile"))
    1866         label.set_use_underline(True)
    1867         label.set_alignment(0.0, 0.5)
    1868         table.attach(label, 0, 1, 7, 8)
    1869 
    1870         self._cruiseProfile = gtk.ComboBox()
    1871         renderer = gtk.CellRendererText()
    1872         self._cruiseProfile.pack_start(renderer, True)
    1873         self._cruiseProfile.add_attribute(renderer, "text", 0)
    1874         self._cruiseProfile.set_tooltip_text(xstr("simbrief_cruise_profile_tooltip"))
    1875         table.attach(self._cruiseProfile, 1, 2, 7, 8)
    1876         label.set_mnemonic_widget(self._cruiseProfile)
    1877 
    1878         label = gtk.Label(xstr("simbrief_descent_profile"))
    1879         label.set_use_underline(True)
    1880         label.set_alignment(0.0, 0.5)
    1881         table.attach(label, 0, 1, 8, 9)
    1882 
    1883         self._descentProfile = gtk.ComboBox()
    1884         renderer = gtk.CellRendererText()
    1885         self._descentProfile.pack_start(renderer, True)
    1886         self._descentProfile.add_attribute(renderer, "text", 0)
    1887         self._descentProfile.set_tooltip_text(xstr("simbrief_descent_profile_tooltip"))
    1888         table.attach(self._descentProfile, 1, 2, 8, 9)
    1889         label.set_mnemonic_widget(self._descentProfile)
    1890 
    1891         self.addCancelFlightButton()
    1892 
    1893         self._backButton = self.addPreviousButton(clicked = self._backClicked)
    1894         self._button = self.addNextButton(clicked = self._forwardClicked)
    1895 
    1896     def activate(self):
    1897         """Activate the SimBrief setup page"""
    1898         config = self._wizard.gui.config
    1899 
    1900         self._userName.set_text(config.simBriefUserName)
    1901         self._userName.set_sensitive(True)
    1902 
    1903         self._password.set_text(config.simBriefPassword)
    1904         self._password.set_sensitive(True)
    1905 
    1906         self._rememberButton.set_active(config.rememberSimBriefPassword)
    1907         self._rememberButton.set_sensitive(True)
    1908 
    1909         self._extraFuel.set_int(0)
    1910         self._extraFuel.set_sensitive(True)
    1911 
    1912         self._takeoffRunway.set_text("")
    1913         self._takeoffRunway.set_sensitive(True)
    1914 
    1915         self._landingRunway.set_text("")
    1916         self._landingRunway.set_sensitive(True)
    1917 
    1918         simBriefData = self._wizard.gui.flight.aircraft.simBriefData
    1919         for (control, profiles) in [(self._climbProfile,
    1920                                      simBriefData.climbProfiles),
    1921                                     (self._cruiseProfile,
    1922                                      simBriefData.cruiseProfiles),
    1923                                     (self._descentProfile,
    1924                                      simBriefData.descentProfiles)]:
    1925             model = gtk.ListStore(str)
    1926             for profile in profiles:
    1927                 model.append([profile])
    1928             control.set_model(model)
    1929             control.set_sensitive(True)
    1930 
    1931         self._climbProfile.set_active(0)
    1932         self._cruiseProfile.set_active(0)
    1933         self._descentProfile.set_active(0)
    1934 
    1935         self._updateForwardButton()
    1936 
    1937     def _updateForwardButton(self):
    1938         """Update the sensitivity of the forward button."""
    1939         self._button.set_sensitive(len(self._userName.get_text())>0 and
    1940                                    len(self._password.get_text())>0)
    1941 
    1942     def _backClicked(self, button):
    1943         """Called when the Back button is pressed."""
    1944         self.goBack()
    1945 
    1946     def _forwardClicked(self, button):
    1947         if self._completed:
    1948             self._wizard.nextPage()
    1949         else:
    1950             config = self._wizard.gui.config
    1951 
    1952             config.simBriefUserName = self._userName.get_text()
    1953 
    1954             rememberPassword = self._rememberButton.get_active()
    1955             config.simBriefPassword = \
    1956               self._password.get_text() if rememberPassword else ""
    1957             config.rememberSimBriefPassword = rememberPassword
    1958 
    1959             config.save()
    1960 
    1961             plan = self._getPlan()
    1962             print "plan:", plan
    1963 
    1964             takeoffRunway = self._takeoffRunway.get_text()
    1965             if takeoffRunway:
    1966                 self._wizard.takeoffRunway = takeoffRunway
    1967 
    1968             landingRunway = self._landingRunway.get_text()
    1969             if landingRunway:
    1970                 self._wizard.landingRunway = landingRunway
    1971 
    1972             self._userName.set_sensitive(False)
    1973             self._password.set_sensitive(False)
    1974             self._rememberButton.set_sensitive(False)
    1975             self._extraFuel.set_sensitive(False)
    1976             self._takeoffRunway.set_sensitive(False)
    1977             self._landingRunway.set_sensitive(False)
    1978 
    1979             self._climbProfile.set_sensitive(False)
    1980             self._cruiseProfile.set_sensitive(False)
    1981             self._descentProfile.set_sensitive(False)
    1982 
    1983             self._wizard.gui.beginBusy(xstr("simbrief_calling"))
    1984 
    1985             cef.startFastTimeout()
    1986             cef.callSimBrief(plan,
    1987                              self._getCredentialsCallback,
    1988                              self._simBriefProgressCallback,
    1989                              SimBriefSetupPage.getHTMLFilePath())
    1990 
    1991             startSound(const.SOUND_NOTAM)
    1992 
    1993     def _getCredentialsCallback(self, count):
    1994         """Called when the SimBrief home page requests the credentials."""
    1995         with self._credentialsCondition:
    1996             self._credentialsAvailable = False
    1997 
    1998             gobject.idle_add(self._getCredentials, count)
    1999 
    2000             while not self._credentialsAvailable:
    2001                 self._credentialsCondition.wait()
    2002 
    2003             return (self._credentialsUserName, self._credentialsPassword)
    2004 
    2005     def _getCredentials(self, count):
    2006         """Get the credentials.
    2007 
    2008         If count is 0, the user name and password entered into the setup page
    2009         are returned. Otherwise a dialog box is displayed informing the user of
    2010         invalid credentials and requesting another set of them."""
    2011         with self._credentialsCondition:
    2012             if count==0:
    2013                 self._credentialsUserName = self._userName.get_text()
    2014                 self._credentialsPassword = self._password.get_text()
    2015             else:
    2016                 gui = self._wizard.gui
    2017                 config = gui.config
    2018 
    2019                 dialog = SimBriefCredentialsDialog(gui,
    2020                                                    config.simBriefUserName,
    2021                                                    config.simBriefPassword,
    2022                                                    config.rememberSimBriefPassword)
    2023                 response = dialog.run()
    2024 
    2025                 if response==RESPONSETYPE_OK:
    2026                     self._credentialsUserName = dialog.userName
    2027                     self._userName.set_text(self._credentialsUserName)
    2028                     self._credentialsPassword = dialog.password
    2029                     self._password.set_text(self._credentialsPassword)
    2030                     rememberPassword = dialog.rememberPassword
    2031 
    2032                     config.simBriefUserName = self._credentialsUserName
    2033 
    2034                     config.simBriefPassword = \
    2035                         self._credentialsPassword if rememberPassword else ""
    2036                     config.rememberSimBriefPassword = rememberPassword
    2037 
    2038                     config.save()
    2039                 else:
    2040                     self._credentialsUserName = None
    2041                     self._credentialsPassword = None
    2042 
    2043             self._credentialsAvailable = True
    2044             self._credentialsCondition.notify()
    2045 
    2046     def _simBriefProgressCallback(self, progress, result, flightInfo):
    2047         """Called by the SimBrief handling thread."""
    2048         gobject.idle_add(self._simBriefProgress, progress, result, flightInfo)
    2049 
    2050     def _simBriefProgress(self, progress, result, flightInfo):
    2051         """The real SimBrief progress handler."""
    2052         print "_simBriefProgress", progress, result, flightInfo
    2053         if result==cef.SIMBRIEF_RESULT_NONE:
    2054             message = SimBriefSetupPage.progress2Message.get(progress,
    2055                                                              "simbrief_progress_unknown")
    2056             self._wizard.gui.updateBusyState(xstr(message))
    2057         else:
    2058             cef.stopFastTimeout()
    2059             self._wizard.gui.endBusy()
    2060 
    2061             if result==cef.SIMBRIEF_RESULT_OK:
    2062                 self._wizard.departureMETARChanged(flightInfo["orig_metar"],
    2063                                                    self)
    2064                 self._wizard.arrivalMETARChanged(flightInfo["dest_metar"], self)
    2065                 self._wizard.nextPage()
    2066             else:
    2067                 message = SimBriefSetupPage.result2Message.get(result,
    2068                                                                "simbrief_result_unknown")
    2069                 dialog = gtk.MessageDialog(parent = self._wizard.gui.mainWindow,
    2070                                            type = MESSAGETYPE_ERROR,
    2071                                            message_format =
    2072                                            xstr(message) + "\n"+
    2073                                            xstr("simbrief_cancelled"))
    2074 
    2075                 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
    2076                 dialog.set_title(WINDOW_TITLE_BASE)
    2077                 secondary = xstr("flightsel_save_failed_sec")
    2078                 dialog.format_secondary_markup(secondary)
    2079                 dialog.run()
    2080                 dialog.hide()
    2081 
    2082                 self._wizard.usingSimBrief = False
    2083                 self._wizard.jumpPage(2, fromPageShift = 1)
    2084 
    2085     def _getPlan(self):
    2086         """Get the flight plan data for SimBrief."""
    2087         plan = {
    2088             "airline": "MAH",
    2089             "selcal": "XXXX",
    2090             "fuelfactor": "P000",
    2091             "contpct": "0.05",
    2092             "resvrule": "45",
    2093             "taxiout": "10",
    2094             "taxiin": "10",
    2095             "civalue": "AUTO"
    2096             }
    2097 
    2098         wizard = self._wizard
    2099         gui = wizard.gui
    2100 
    2101         loginResult = wizard.loginResult
    2102         plan["cpt"] = loginResult.pilotName
    2103         plan["pid"] = loginResult.pilotID
    2104 
    2105         bookedFlight = wizard.bookedFlight
    2106         plan["fltnum"] = wizard.bookedFlight.callsign[2:]
    2107         plan["type"] = const.icaoCodes[bookedFlight.aircraftType]
    2108         plan["orig"] = bookedFlight.departureICAO
    2109         plan["dest"] = bookedFlight.arrivalICAO
    2110         plan["reg"] = bookedFlight.tailNumber
    2111         plan["fin"] = bookedFlight.tailNumber[3:]
    2112         plan["pax"] = str(bookedFlight.numPassengers)
    2113 
    2114         departureTime = bookedFlight.departureTime
    2115         plan["date"] = "%d%s%d" % (departureTime.day,
    2116                                    SimBriefSetupPage.monthNum2Name[departureTime.month-1],
    2117                                    departureTime.year%100)
    2118         plan["deph"] = str(departureTime.hour)
    2119         plan["depm"] = str(departureTime.minute)
    2120 
    2121         arrivalTime = bookedFlight.arrivalTime
    2122         plan["steh"] = str(arrivalTime.hour)
    2123         plan["stem"] = str(arrivalTime.minute)
    2124 
    2125         plan["manualzfw"] = str(wizard.zfw / 1000.0)
    2126         plan["cargo"] = str((wizard.bagWeight + wizard.cargoWeight + wizard.mailWeight)/1000.0)
    2127 
    2128         plan["route"] = wizard.route
    2129         plan["fl"] = str(wizard.filedCruiseAltitude)
    2130         plan["altn"] = wizard.alternate
    2131 
    2132         plan["addedfuel"] = str(self._extraFuel.get_int() / 1000.0)
    2133         plan["origrwy"] = self._takeoffRunway.get_text()
    2134         plan["destrwy"] = self._landingRunway.get_text()
    2135 
    2136         for (key, control) in [("climb", self._climbProfile),
    2137                                ("cruise", self._cruiseProfile),
    2138                                ("descent", self._descentProfile)]:
    2139             model = control.get_model()
    2140             active = control.get_active_iter()
    2141             value = model.get_value(active, 0)
    2142             plan[key] = value
    2143 
    2144         return plan
    2145 
    2146     def _upperChanged(self, entry, arg = None):
    2147         """Called when the value of some entry widget has changed and the value
    2148         should be converted to uppercase."""
    2149         entry.set_text(entry.get_text().upper())
    2150 
    2151 #-----------------------------------------------------------------------------
    2152 
    2153 class SimBriefingPage(Page):
    2154     """Page to display the SimBrief HTML briefing."""
    2155     class BrowserLifeSpanHandler(object):
    2156         """The life-span handler of a browser."""
    2157         def __init__(self, simBriefingPage):
    2158             """Construct the life-span handler for the given page."""
    2159             self._simBriefingPage = simBriefingPage
    2160 
    2161         def OnBeforeClose(self, browser):
    2162             """Called before closing the browser."""
    2163             self._simBriefingPage._invalidateBrowser()
    2164 
    2165     def __init__(self, wizard):
    2166         """Construct the setup page."""
    2167 
    2168         super(SimBriefingPage, self).__init__(wizard,
    2169                                               xstr("simbrief_result_title"), "")
    2170 
    2171         self._alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
    2172                                        xscale = 1.0, yscale = 1.0)
    2173 
    2174         self._container = cef.getContainer()
    2175         self._alignment.add(self._container)
    2176 
    2177         self.setMainWidget(self._alignment)
    2178 
    2179         self._browser = None
    2180 
    2181         self.addCancelFlightButton()
    2182 
    2183         self.addPreviousButton(clicked = self._backClicked)
    2184 
    2185         self._button = self.addNextButton(clicked = self._forwardClicked)
    2186         self._button.set_label(xstr("briefing_button"))
    2187         self._button.set_has_tooltip(False)
    2188         self._button.set_use_stock(False)
    2189 
    2190     def activate(self):
    2191         """Activate the SimBrief flight plan page"""
    2192         if self._browser is None:
    2193             self._startBrowser()
    2194         else:
    2195             self._browser.Reload()
    2196 
    2197     def grabDefault(self):
    2198         """If the page has a default button, make it the default one."""
    2199         super(SimBriefingPage, self).grabDefault()
    2200 
    2201         if self._browser is None:
    2202             self._startBrowser()
    2203 
    2204     def _backClicked(self, button):
    2205         """Called when the Back button has been pressed."""
    2206         self.goBack()
    2207 
    2208     def _forwardClicked(self, button):
    2209         """Called when the Forward button has been pressed."""
    2210         if not self._completed:
    2211             self._button.set_label(xstr("button_next"))
    2212             self._button.set_tooltip_text(xstr("button_next_tooltip"))
    2213             self._wizard.usingSimBrief = True
    2214             self.complete()
    2215 
    2216         self._wizard.nextPage()
    2217 
    2218     def _startBrowser(self):
    2219         """Start the browser.
    2220 
    2221         If a container is needed, create one."""
    2222         if self._container is None:
    2223             self._container = cef.getContainer()
    2224             self._alignment.add(self._container)
    2225 
    2226         url = "file://" + SimBriefSetupPage.getHTMLFilePath()
    2227         self._browser = cef.startInContainer(self._container, url)
    2228 
    2229         lifeSpanHandler = SimBriefingPage.BrowserLifeSpanHandler(self)
    2230         self._browser.SetClientHandler(lifeSpanHandler)
    2231 
    2232     def _invalidateBrowser(self):
    2233         """Invalidate the browser (and associated stuff)."""
    2234         self._alignment.remove(self._container)
    2235         self._container = None
    2236         self._browser = None
    2237 
    2238 #-----------------------------------------------------------------------------
    2239 
    22401427class FuelTank(gtk.VBox):
    22411428    """Widget for the fuel tank."""
     
    24731660            self._wizard.gui.beginBusy(xstr("fuel_pump_busy"))
    24741661            self._pump()
    2475         elif self._wizard.usingSimBrief:
    2476             self._wizard.jumpPage(3)
    24771662        else:
    24781663            self._wizard.nextPage()
     
    25201705        if fuelTank is None:
    25211706            self._wizard.gui.endBusy()
    2522             if self._wizard.usingSimBrief:
    2523                 self._wizard.gui.startMonitoring()
    2524                 self._wizard.jumpPage(3)
    2525             else:
    2526                 bookedFlight = self._wizard._bookedFlight
    2527                 self._wizard.gui.beginBusy(xstr("route_down_notams"))
    2528                 self._wizard.gui.webHandler.getNOTAMs(self._notamsCallback,
    2529                                                       bookedFlight.departureICAO,
    2530                                                       bookedFlight.arrivalICAO)
    2531                 startSound(const.SOUND_NOTAM)
     1707            self._wizard.nextPage()
    25321708        else:
    25331709            currentLevel = fuelTank.currentWeight / fuelTank.capacity
     
    25431719                                                      currentLevel)])
    25441720            gobject.timeout_add(50, self._pump)
     1721
     1722#-----------------------------------------------------------------------------
     1723
     1724class RoutePage(Page):
     1725    """The page containing the route and the flight level."""
     1726    def __init__(self, wizard):
     1727        """Construct the page."""
     1728        super(RoutePage, self).__init__(wizard, xstr("route_title"),
     1729                                        xstr("route_help"),
     1730                                        completedHelp = xstr("route_chelp"))
     1731
     1732        alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
     1733                                  xscale = 0.0, yscale = 0.0)
     1734
     1735        mainBox = gtk.VBox()
     1736        alignment.add(mainBox)
     1737        self.setMainWidget(alignment)
     1738
     1739        levelBox = gtk.HBox()
     1740
     1741        label = gtk.Label(xstr("route_level"))
     1742        label.set_use_underline(True)
     1743        levelBox.pack_start(label, True, True, 0)
     1744
     1745        self._cruiseLevel = gtk.SpinButton()
     1746        self._cruiseLevel.set_increments(step = 10, page = 100)
     1747        self._cruiseLevel.set_range(min = 0, max = 500)
     1748        self._cruiseLevel.set_tooltip_text(xstr("route_level_tooltip"))
     1749        self._cruiseLevel.set_numeric(True)
     1750        self._cruiseLevel.connect("changed", self._cruiseLevelChanged)
     1751        self._cruiseLevel.connect("value-changed", self._cruiseLevelChanged)
     1752        label.set_mnemonic_widget(self._cruiseLevel)
     1753
     1754        levelBox.pack_start(self._cruiseLevel, False, False, 8)
     1755
     1756        alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
     1757                                  xscale = 0.0, yscale = 0.0)
     1758        alignment.add(levelBox)
     1759
     1760        mainBox.pack_start(alignment, False, False, 0)
     1761
     1762
     1763        routeBox = gtk.VBox()
     1764
     1765        alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
     1766                                  xscale = 0.0, yscale = 0.0)
     1767        label = gtk.Label(xstr("route_route"))
     1768        label.set_use_underline(True)
     1769        alignment.add(label)
     1770        routeBox.pack_start(alignment, True, True, 0)
     1771
     1772        routeWindow = gtk.ScrolledWindow()
     1773        routeWindow.set_size_request(400, 80)
     1774        routeWindow.set_shadow_type(gtk.ShadowType.IN if pygobject
     1775                                    else gtk.SHADOW_IN)
     1776        routeWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
     1777                               else gtk.POLICY_AUTOMATIC,
     1778                               gtk.PolicyType.AUTOMATIC if pygobject
     1779                               else gtk.POLICY_AUTOMATIC)
     1780
     1781        self._uppercasingRoute = False
     1782
     1783        self._route = gtk.TextView()
     1784        self._route.set_tooltip_text(xstr("route_route_tooltip"))
     1785        self._route.set_wrap_mode(WRAP_WORD)
     1786        self._route.get_buffer().connect("changed", self._routeChanged)
     1787        self._route.get_buffer().connect_after("insert-text", self._routeInserted)
     1788        routeWindow.add(self._route)
     1789
     1790        label.set_mnemonic_widget(self._route)
     1791        routeBox.pack_start(routeWindow, True, True, 0)
     1792
     1793        mainBox.pack_start(routeBox, True, True, 8)
     1794
     1795        self.addCancelFlightButton()
     1796
     1797        self._backButton = self.addPreviousButton(clicked = self._backClicked)
     1798        self._button = self.addNextButton(clicked = self._forwardClicked)
     1799
     1800    @property
     1801    def filedCruiseLevel(self):
     1802        """Get the filed cruise level."""
     1803        return self._cruiseLevel.get_value_as_int()
     1804
     1805    @property
     1806    def route(self):
     1807        """Get the route."""
     1808        return self._getRoute()
     1809
     1810    def activate(self):
     1811        """Setup the route from the booked flight."""
     1812        self._cruiseLevel.set_value(0)
     1813        self._cruiseLevel.set_text("")
     1814        self._route.get_buffer().set_text(self._wizard._bookedFlight.route)
     1815        self._updateForwardButton()
     1816
     1817    def _getRoute(self):
     1818        """Get the text of the route."""
     1819        buffer = self._route.get_buffer()
     1820        return buffer.get_text(buffer.get_start_iter(),
     1821                               buffer.get_end_iter(), True)
     1822
     1823    def _updateForwardButton(self):
     1824        """Update the sensitivity of the forward button."""
     1825        cruiseLevelText = self._cruiseLevel.get_text()
     1826        cruiseLevel = int(cruiseLevelText) if cruiseLevelText else 0
     1827        self._button.set_sensitive(cruiseLevel>=50 and self._getRoute()!="")
     1828
     1829    def _cruiseLevelChanged(self, *arg):
     1830        """Called when the cruise level has changed."""
     1831        self._updateForwardButton()
     1832
     1833    def _routeChanged(self, textBuffer):
     1834        """Called when the route has changed."""
     1835        if not self._uppercasingRoute:
     1836            self._updateForwardButton()
     1837
     1838    def _routeInserted(self, textBuffer, iter, text, length):
     1839        """Called when new characters are inserted into the route.
     1840
     1841        It uppercases all characters."""
     1842        if not self._uppercasingRoute:
     1843            self._uppercasingRoute = True
     1844
     1845            iter1 = iter.copy()
     1846            iter1.backward_chars(length)
     1847            textBuffer.delete(iter, iter1)
     1848
     1849            textBuffer.insert(iter, text.upper())
     1850
     1851            self._uppercasingRoute = False
     1852
     1853    def _backClicked(self, button):
     1854        """Called when the Back button is pressed."""
     1855        self.goBack()
     1856
     1857    def _forwardClicked(self, button):
     1858        """Called when the Forward button is clicked."""
     1859        if self._completed:
     1860            self._wizard.nextPage()
     1861        else:
     1862            bookedFlight = self._wizard._bookedFlight
     1863            self._wizard.gui.beginBusy(xstr("route_down_notams"))
     1864            self._wizard.gui.webHandler.getNOTAMs(self._notamsCallback,
     1865                                                  bookedFlight.departureICAO,
     1866                                                  bookedFlight.arrivalICAO)
     1867            startSound(const.SOUND_NOTAM)
    25451868
    25461869    def _notamsCallback(self, returned, result):
     
    30152338        self._updatingMETAR = False
    30162339
    3017         if self._wizard.takeoffRunway is None:
    3018             self._runway.set_text("")
    3019         else:
    3020             self._runway.set_text(self._wizard.takeoffRunway)
     2340        self._runway.set_text("")
    30212341        self._runway.set_sensitive(True)
    30222342        self._sid.set_active(0)
     
    34052725        label.set_use_underline(True)
    34062726        label.set_alignment(0.0, 0.5)
    3407         table.attach(label, 1, 2, row, row+1)
     2727        table.attach(label, 0, 1, row, row+1)
    34082728
    34092729        self._metar = gtk.Entry()
     
    34122732        self._metar.connect("changed", self._metarChanged)
    34132733        self._metar.get_buffer().connect_after("inserted-text", self._metarInserted)
    3414         table.attach(self._metar, 2, 24, row, row+1)
     2734        table.attach(self._metar, 1, 24, row, row+1)
    34152735        label.set_mnemonic_widget(self._metar)
    34162736
     
    35772897        self._transition.set_sensitive(True)
    35782898
    3579         if self._wizard.landingRunway is None:
    3580             self._runway.set_text("")
    3581         else:
    3582             self._runway.set_text(self._wizard.landingRunway)
     2899        self._runway.set_text("")
    35832900        self._runway.set_sensitive(True)
    35842901
     
    42613578        self._payloadIndex = len(self._pages)
    42623579        self._pages.append(TimePage(self))
     3580        self._pages.append(FuelPage(self))
    42633581        self._routePage = RoutePage(self)
    42643582        self._pages.append(self._routePage)
    4265         self._simBriefSetupPage = SimBriefSetupPage(self)
    4266         self._pages.append(self._simBriefSetupPage)
    4267         self._simBriefingPage = SimBriefingPage(self)
    4268         self._pages.append(self._simBriefingPage)
    4269         self._pages.append(FuelPage(self))
    42703583        self._departureBriefingPage = BriefingPage(self, True)
    42713584        self._pages.append(self._departureBriefingPage)
     
    43403653        return self._loginResult
    43413654
    4342     def setCurrentPage(self, index, finalize = False, fromPageShift = None):
    4343         """Set the current page to the one with the given index.
    4344 
    4345         @param fromPageShift if given, the relative index of one of the
    4346         previous pages that should be used as the from-page of the next
    4347         page. E.g. if fromPageShift is 1, the previous page will be the
    4348         from-page."""
     3655    def setCurrentPage(self, index, finalize = False):
     3656        """Set the current page to the one with the given index."""
    43493657        assert index < len(self._pages)
    43503658
     
    43553663                page.complete()
    43563664            self.remove(page)
    4357             if fromPageShift is not None:
    4358                 fromPage -= fromPageShift
    43593665
    43603666        self._currentPage = index
     
    44353741
    44363742    @property
    4437     def alternate(self):
    4438         """Get the ICAO code of the alternate airport."""
    4439         return self._routePage.alternate
    4440 
    4441     @property
    44423743    def departureMETAR(self):
    44433744        """Get the METAR of the departure airport."""
     
    45393840        return self._finishPage.online
    45403841
    4541     @property
    4542     def usingSimBrief(self):
    4543         """Indicate if we are using a SimBrief briefing or not."""
    4544         return self._usingSimBrief
    4545 
    4546     @usingSimBrief.setter
    4547     def usingSimBrief(self, x):
    4548         """Set whether we are using a SimBrief briefing or not."""
    4549         self._usingSimBrief = x
    4550 
    45513842    def nextPage(self, finalize = True):
    45523843        """Go to the next page."""
    45533844        self.jumpPage(1, finalize)
    45543845
    4555     def jumpPage(self, count, finalize = True, fromPageShift = None):
     3846    def jumpPage(self, count, finalize = True):
    45563847        """Go to the page which is 'count' pages after the current one."""
    4557         self.setCurrentPage(self._currentPage + count,
    4558                             finalize = finalize, fromPageShift = fromPageShift)
     3848        self.setCurrentPage(self._currentPage + count, finalize = finalize)
    45593849
    45603850    def grabDefault(self):
     
    46053895        self._arrivalNOTAMs = None
    46063896        self._arrivalMETAR = None
    4607         self._usingSimBrief = None
    4608         self.takeoffRunway = None
    4609         self.landingRunway = None
    46103897
    46113898        firstPage = 0 if self._loginResult is None else 1
     
    46513938        metar = metar.upper()
    46523939        if originator in [self._departureBriefingPage, self._takeoffPage]:
    4653             self.departureMETARChanged(metar, originator)
     3940            self._departureMETARChanged(metar, originator)
    46543941        else:
    4655             self.arrivalMETARChanged(metar, originator)
    4656 
    4657     def departureMETARChanged(self, metar, originator):
     3942            self._arrivalMETARChanged(metar, originator)
     3943
     3944    def _departureMETARChanged(self, metar, originator):
    46583945        """Called when the departure METAR has been edited on one of the
    46593946        pages.
     
    46653952                page.changeMETAR(metar)
    46663953
    4667     def arrivalMETARChanged(self, metar, originator):
     3954    def _arrivalMETARChanged(self, metar, originator):
    46683955        """Called when the arrival METAR has been edited on one of the
    46693956        pages.
Note: See TracChangeset for help on using the changeset viewer.