- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mlx/gui/flight.py
r719 r675 1 1 2 2 from mlx.gui.common import * 3 import mlx.gui.cef as cef4 3 5 4 import mlx.const as const … … 18 17 import time 19 18 import os 20 import tempfile21 import threading22 19 23 20 #----------------------------------------------------------------------------- … … 1428 1425 #----------------------------------------------------------------------------- 1429 1426 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 pygobject1481 else gtk.SHADOW_IN)1482 routeWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject1483 else gtk.POLICY_AUTOMATIC,1484 gtk.PolicyType.AUTOMATIC if pygobject1485 else gtk.POLICY_AUTOMATIC)1486 1487 self._uppercasingRoute = False1488 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 @property1527 def filedCruiseLevel(self):1528 """Get the filed cruise level."""1529 return self._cruiseLevel.get_value_as_int()1530 1531 @property1532 def route(self):1533 """Get the route."""1534 return self._getRoute()1535 1536 @property1537 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 01559 alternate = self._alternate.get_text()1560 self._button.set_sensitive(cruiseLevel>=50 and self._getRoute()!="" and1561 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 = True1578 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 = False1586 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 = False1600 if self._wizard.gui.config.useSimBrief and \1601 self._wizard.usingSimBrief is not False:1602 self._wizard.nextPage()1603 else:1604 self._wizard.usingSimBrief = False1605 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 @property1685 def userName(self):1686 """Get the user name entered."""1687 return self._userName.get_text()1688 1689 @property1690 def password(self):1691 """Get the password entered."""1692 return self._password.get_text()1693 1694 @property1695 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 response1708 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 @staticmethod1746 def getHTMLFilePath():1747 """Get the path of the HTML file to contain the generated flight1748 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 pwd1756 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 = False1812 self._credentialsUserName = None1813 self._credentialsPassword = None1814 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.config1899 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.simBriefData1919 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 and1940 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.config1951 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 = rememberPassword1958 1959 config.save()1960 1961 plan = self._getPlan()1962 print "plan:", plan1963 1964 takeoffRunway = self._takeoffRunway.get_text()1965 if takeoffRunway:1966 self._wizard.takeoffRunway = takeoffRunway1967 1968 landingRunway = self._landingRunway.get_text()1969 if landingRunway:1970 self._wizard.landingRunway = landingRunway1971 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 = False1997 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 page2009 are returned. Otherwise a dialog box is displayed informing the user of2010 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.gui2017 config = gui.config2018 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.userName2027 self._userName.set_text(self._credentialsUserName)2028 self._credentialsPassword = dialog.password2029 self._password.set_text(self._credentialsPassword)2030 rememberPassword = dialog.rememberPassword2031 2032 config.simBriefUserName = self._credentialsUserName2033 2034 config.simBriefPassword = \2035 self._credentialsPassword if rememberPassword else ""2036 config.rememberSimBriefPassword = rememberPassword2037 2038 config.save()2039 else:2040 self._credentialsUserName = None2041 self._credentialsPassword = None2042 2043 self._credentialsAvailable = True2044 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, flightInfo2053 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 = False2083 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._wizard2099 gui = wizard.gui2100 2101 loginResult = wizard.loginResult2102 plan["cpt"] = loginResult.pilotName2103 plan["pid"] = loginResult.pilotID2104 2105 bookedFlight = wizard.bookedFlight2106 plan["fltnum"] = wizard.bookedFlight.callsign[2:]2107 plan["type"] = const.icaoCodes[bookedFlight.aircraftType]2108 plan["orig"] = bookedFlight.departureICAO2109 plan["dest"] = bookedFlight.arrivalICAO2110 plan["reg"] = bookedFlight.tailNumber2111 plan["fin"] = bookedFlight.tailNumber[3:]2112 plan["pax"] = str(bookedFlight.numPassengers)2113 2114 departureTime = bookedFlight.departureTime2115 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.arrivalTime2122 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.route2129 plan["fl"] = str(wizard.filedCruiseAltitude)2130 plan["altn"] = wizard.alternate2131 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] = value2143 2144 return plan2145 2146 def _upperChanged(self, entry, arg = None):2147 """Called when the value of some entry widget has changed and the value2148 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 = simBriefingPage2160 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 "SimBrief flight plan", "")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 = None2180 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 = True2214 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 = None2236 self._browser = None2237 2238 #-----------------------------------------------------------------------------2239 2240 1427 class FuelTank(gtk.VBox): 2241 1428 """Widget for the fuel tank.""" … … 2473 1660 self._wizard.gui.beginBusy(xstr("fuel_pump_busy")) 2474 1661 self._pump() 2475 elif self._wizard.usingSimBrief:2476 self._wizard.jumpPage(3)2477 1662 else: 2478 1663 self._wizard.nextPage() … … 2520 1705 if fuelTank is None: 2521 1706 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() 2532 1708 else: 2533 1709 currentLevel = fuelTank.currentWeight / fuelTank.capacity … … 2543 1719 currentLevel)]) 2544 1720 gobject.timeout_add(50, self._pump) 1721 1722 #----------------------------------------------------------------------------- 1723 1724 class 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) 2545 1868 2546 1869 def _notamsCallback(self, returned, result): … … 3015 2338 self._updatingMETAR = False 3016 2339 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("") 3021 2341 self._runway.set_sensitive(True) 3022 2342 self._sid.set_active(0) … … 3577 2897 self._transition.set_sensitive(True) 3578 2898 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("") 3583 2900 self._runway.set_sensitive(True) 3584 2901 … … 4261 3578 self._payloadIndex = len(self._pages) 4262 3579 self._pages.append(TimePage(self)) 3580 self._pages.append(FuelPage(self)) 4263 3581 self._routePage = RoutePage(self) 4264 3582 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))4270 3583 self._departureBriefingPage = BriefingPage(self, True) 4271 3584 self._pages.append(self._departureBriefingPage) … … 4340 3653 return self._loginResult 4341 3654 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.""" 4349 3657 assert index < len(self._pages) 4350 3658 … … 4355 3663 page.complete() 4356 3664 self.remove(page) 4357 if fromPageShift is not None:4358 fromPage -= fromPageShift4359 3665 4360 3666 self._currentPage = index … … 4435 3741 4436 3742 @property 4437 def alternate(self):4438 """Get the ICAO code of the alternate airport."""4439 return self._routePage.alternate4440 4441 @property4442 3743 def departureMETAR(self): 4443 3744 """Get the METAR of the departure airport.""" … … 4539 3840 return self._finishPage.online 4540 3841 4541 @property4542 def usingSimBrief(self):4543 """Indicate if we are using a SimBrief briefing or not."""4544 return self._usingSimBrief4545 4546 @usingSimBrief.setter4547 def usingSimBrief(self, x):4548 """Set whether we are using a SimBrief briefing or not."""4549 self._usingSimBrief = x4550 4551 3842 def nextPage(self, finalize = True): 4552 3843 """Go to the next page.""" 4553 3844 self.jumpPage(1, finalize) 4554 3845 4555 def jumpPage(self, count, finalize = True , fromPageShift = None):3846 def jumpPage(self, count, finalize = True): 4556 3847 """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) 4559 3849 4560 3850 def grabDefault(self): … … 4605 3895 self._arrivalNOTAMs = None 4606 3896 self._arrivalMETAR = None 4607 self._usingSimBrief = None4608 self.takeoffRunway = None4609 self.landingRunway = None4610 3897 4611 3898 firstPage = 0 if self._loginResult is None else 1 … … 4651 3938 metar = metar.upper() 4652 3939 if originator in [self._departureBriefingPage, self._takeoffPage]: 4653 self. departureMETARChanged(metar, originator)3940 self._departureMETARChanged(metar, originator) 4654 3941 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): 4658 3945 """Called when the departure METAR has been edited on one of the 4659 3946 pages. … … 4665 3952 page.changeMETAR(metar) 4666 3953 4667 def arrivalMETARChanged(self, metar, originator):3954 def _arrivalMETARChanged(self, metar, originator): 4668 3955 """Called when the arrival METAR has been edited on one of the 4669 3956 pages.
Note:
See TracChangeset
for help on using the changeset viewer.