- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mlx/gui/flight.py
r675 r719 1 1 2 2 from mlx.gui.common import * 3 import mlx.gui.cef as cef 3 4 4 5 import mlx.const as const … … 17 18 import time 18 19 import os 20 import tempfile 21 import threading 19 22 20 23 #----------------------------------------------------------------------------- … … 1425 1428 #----------------------------------------------------------------------------- 1426 1429 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 "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 = 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 1427 2240 class FuelTank(gtk.VBox): 1428 2241 """Widget for the fuel tank.""" … … 1660 2473 self._wizard.gui.beginBusy(xstr("fuel_pump_busy")) 1661 2474 self._pump() 2475 elif self._wizard.usingSimBrief: 2476 self._wizard.jumpPage(3) 1662 2477 else: 1663 2478 self._wizard.nextPage() … … 1705 2520 if fuelTank is None: 1706 2521 self._wizard.gui.endBusy() 1707 self._wizard.nextPage() 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) 1708 2532 else: 1709 2533 currentLevel = fuelTank.currentWeight / fuelTank.capacity … … 1719 2543 currentLevel)]) 1720 2544 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 pygobject1775 else gtk.SHADOW_IN)1776 routeWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject1777 else gtk.POLICY_AUTOMATIC,1778 gtk.PolicyType.AUTOMATIC if pygobject1779 else gtk.POLICY_AUTOMATIC)1780 1781 self._uppercasingRoute = False1782 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 @property1801 def filedCruiseLevel(self):1802 """Get the filed cruise level."""1803 return self._cruiseLevel.get_value_as_int()1804 1805 @property1806 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 01827 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 = True1844 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 = False1852 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._bookedFlight1863 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)1868 2545 1869 2546 def _notamsCallback(self, returned, result): … … 2338 3015 self._updatingMETAR = False 2339 3016 2340 self._runway.set_text("") 3017 if self._wizard.takeoffRunway is None: 3018 self._runway.set_text("") 3019 else: 3020 self._runway.set_text(self._wizard.takeoffRunway) 2341 3021 self._runway.set_sensitive(True) 2342 3022 self._sid.set_active(0) … … 2897 3577 self._transition.set_sensitive(True) 2898 3578 2899 self._runway.set_text("") 3579 if self._wizard.landingRunway is None: 3580 self._runway.set_text("") 3581 else: 3582 self._runway.set_text(self._wizard.landingRunway) 2900 3583 self._runway.set_sensitive(True) 2901 3584 … … 3578 4261 self._payloadIndex = len(self._pages) 3579 4262 self._pages.append(TimePage(self)) 3580 self._pages.append(FuelPage(self))3581 4263 self._routePage = RoutePage(self) 3582 4264 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)) 3583 4270 self._departureBriefingPage = BriefingPage(self, True) 3584 4271 self._pages.append(self._departureBriefingPage) … … 3653 4340 return self._loginResult 3654 4341 3655 def setCurrentPage(self, index, finalize = False): 3656 """Set the current page to the one with the given index.""" 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.""" 3657 4349 assert index < len(self._pages) 3658 4350 … … 3663 4355 page.complete() 3664 4356 self.remove(page) 4357 if fromPageShift is not None: 4358 fromPage -= fromPageShift 3665 4359 3666 4360 self._currentPage = index … … 3741 4435 3742 4436 @property 4437 def alternate(self): 4438 """Get the ICAO code of the alternate airport.""" 4439 return self._routePage.alternate 4440 4441 @property 3743 4442 def departureMETAR(self): 3744 4443 """Get the METAR of the departure airport.""" … … 3840 4539 return self._finishPage.online 3841 4540 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 3842 4551 def nextPage(self, finalize = True): 3843 4552 """Go to the next page.""" 3844 4553 self.jumpPage(1, finalize) 3845 4554 3846 def jumpPage(self, count, finalize = True ):4555 def jumpPage(self, count, finalize = True, fromPageShift = None): 3847 4556 """Go to the page which is 'count' pages after the current one.""" 3848 self.setCurrentPage(self._currentPage + count, finalize = finalize) 4557 self.setCurrentPage(self._currentPage + count, 4558 finalize = finalize, fromPageShift = fromPageShift) 3849 4559 3850 4560 def grabDefault(self): … … 3895 4605 self._arrivalNOTAMs = None 3896 4606 self._arrivalMETAR = None 4607 self._usingSimBrief = None 4608 self.takeoffRunway = None 4609 self.landingRunway = None 3897 4610 3898 4611 firstPage = 0 if self._loginResult is None else 1 … … 3938 4651 metar = metar.upper() 3939 4652 if originator in [self._departureBriefingPage, self._takeoffPage]: 3940 self. _departureMETARChanged(metar, originator)4653 self.departureMETARChanged(metar, originator) 3941 4654 else: 3942 self. _arrivalMETARChanged(metar, originator)3943 3944 def _departureMETARChanged(self, metar, originator):4655 self.arrivalMETARChanged(metar, originator) 4656 4657 def departureMETARChanged(self, metar, originator): 3945 4658 """Called when the departure METAR has been edited on one of the 3946 4659 pages. … … 3952 4665 page.changeMETAR(metar) 3953 4666 3954 def _arrivalMETARChanged(self, metar, originator):4667 def arrivalMETARChanged(self, metar, originator): 3955 4668 """Called when the arrival METAR has been edited on one of the 3956 4669 pages.
Note:
See TracChangeset
for help on using the changeset viewer.