#!/usr/bin/env python #**************************************************************************** # flydialogs.py, provides dialog classes for wp search and time entry # # FlyWay, a VFR/IFR Route Planner for Pilots # Copyright (C) 2002, Douglas W. Bell # # This is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License, Version 2. This program is # distributed in the hope that it will be useful, but WITTHOUT ANY WARRANTY. #***************************************************************************** from units import Time from tmpcontrol import SpinBoxEx import flymainwin from qt import * from xpm import * import sys class SearchDlg(QDialog): """Waypoint selection dialog after search returns multiple waypoints""" filterNames = ('Include Airports', 'Include Navaids', 'Include Fixes') wpTypes = ('A', 'N', 'F') def __init__(self, wpList, searchStr, parent=None, name=None, \ modal=0, flags=0): QDialog.__init__(self, parent, name, modal, flags) self.wpList = wpList if sys.platform == 'win32': self.setCaption('Search Results (PyQt)') else: self.setCaption('Search Results') self.setIcon(QPixmap(fly_xpm)) topLayout = QVBoxLayout(self, 5) strLayout = QHBoxLayout(topLayout) self.searchEdit = QLineEdit(searchStr, self) strLayout.addWidget(self.searchEdit) self.connect(self.searchEdit, SIGNAL('textChanged(const QString&)'), \ self.enableSearch) self.connect(self.searchEdit, SIGNAL('returnPressed()'), \ self.repeatSearch) self.searchButton = QPushButton('Search', self) strLayout.addWidget(self.searchButton) self.connect(self.searchButton, SIGNAL('clicked()'), self.repeatSearch) self.searchButton.setEnabled(0) self.filters = QHButtonGroup('Filter Waypoints', self) topLayout.addWidget(self.filters) for name in SearchDlg.filterNames: button = QCheckBox(name, self.filters) button.setChecked(1) self.connect(self.filters, SIGNAL('clicked(int)'), self.filterList) self.enableFilters() self.listView = QListView(self) topLayout.addWidget(self.listView) self.listView.addColumn('#', 40) self.listView.addColumn('ID', 60) self.listView.addColumn('Description', 300) self.listView.setSorting(0) self.connect(self.listView, SIGNAL('doubleClicked(QListViewItem*)'), \ self, SLOT('accept()')) self.connect(self.listView, SIGNAL('returnPressed(QListViewItem*)'), \ self, SLOT('accept()')) self.filterList() ctrlLayout = QHBoxLayout(topLayout) cancelButton = QPushButton('Cancel', self) ctrlLayout.addWidget(cancelButton) self.connect(cancelButton, SIGNAL('clicked()'), self, SLOT('reject()')) okButton = QPushButton('OK', self) ctrlLayout.addWidget(okButton) self.connect(okButton, SIGNAL('clicked()'), self, SLOT('accept()')) self.listView.setFocus() def result(self): """Return selected waypoint or None""" if self.listView.selectedItem(): for wp in self.wpList: if wp.ident() == str(self.listView.selectedItem().text(1)) \ and wp.description() == str(self.listView.selectedItem().\ text(2)): return wp return None def filterList(self): """Load list view with filtered waypoints""" self.listView.clear() types = [SearchDlg.wpTypes[num] for num in range(3) if \ self.filters.find(num).isChecked()] num = 1 for wp in self.wpList: if wp.wpTypeChar() in types: QListViewItem(self.listView, '%4d' % num, wp.ident(), \ wp.description()) num += 1 if self.listView.childCount(): self.listView.setSelected(self.listView.firstChild(), 1) def enableFilters(self): """Set wp type filter buttons enabled based on wp contents""" availTypes = [wp.wpTypeChar() for wp in self.wpList] for num in range(3): self.filters.find(num).setEnabled(SearchDlg.wpTypes[num] \ in availTypes) def repeatSearch(self): """Do a new search based on text entry""" text = str(self.searchEdit.text()) if text: self.wpList = flymainwin.FlyMainWin.route.findWp(text) self.enableFilters() self.filterList() self.searchButton.setEnabled(0) self.listView.setFocus() def enableSearch(self): """Activate search button based on line edit change""" self.searchButton.setEnabled( not self.searchEdit.text().isEmpty()) class TimeDlg(QDialog): """Depart time selection dialog with timezones & 12/24 hour selections""" def __init__(self, parent=None, name=None, modal=0, flags=0): QDialog.__init__(self, parent, name, modal, flags) if sys.platform == 'win32': self.setCaption('Departure Time (PyQt)') else: self.setCaption('Departure Time') self.setIcon(QPixmap(fly_xpm)) defaultTime = Time(flymainwin.FlyMainWin.option.\ intData('DepartHour', 0, 23) \ + flymainwin.FlyMainWin.option.\ intData('DepartMinute', 0, 60) / 60.0) self.is12hrClock = flymainwin.FlyMainWin.option.boolData('12hrClock') self.localClock = flymainwin.FlyMainWin.option.boolData('LocalClock') topLayout = QVBoxLayout(self, 5) horizLayout = QHBoxLayout(topLayout) typeGroup = QVButtonGroup('Type', self) QRadioButton('Local Time, 12-Hour ', typeGroup) QRadioButton('Local Time, 24-Hour ', typeGroup) QRadioButton('Zulu Time, 24-Hour ', typeGroup) if not self.localClock: typeGroup.setButton(2) elif self.is12hrClock: typeGroup.setButton(0) else: typeGroup.setButton(1) self.connect(typeGroup, SIGNAL('clicked(int)'), self.typeChange) horizLayout.addWidget(typeGroup) rightLayout = QVBoxLayout(horizLayout) self.curTimeLbl = QLabel(self) self.curTimeLbl.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.curTimeLbl.setAlignment(Qt.AlignCenter) rightLayout.addWidget(self.curTimeLbl) self.setCurrentTime() editLayout = QHBoxLayout(rightLayout) self.hourBox = SpinBoxEx(0, 23, 1, 2, self) self.hourBox.setWrapping(1) editLayout.addWidget(self.hourBox, 0, Qt.AlignLeft) self.connect(self.hourBox, PYSIGNAL('spinChange'), self.spinHour) colon = QLabel(':', self) editLayout.addWidget(colon, 0, Qt.AlignLeft) self.minuteBox = SpinBoxEx(0, 59, 5, 2, self) self.minuteBox.setWrapping(1) editLayout.addWidget(self.minuteBox, 0, Qt.AlignLeft) self.connect(self.minuteBox, PYSIGNAL('wrapped'), self.wrapMinute) self.amBox = QComboBox(0, self) self.amBox.insertItem('AM') self.amBox.insertItem('PM') editLayout.addWidget(self.amBox) editLayout.addStretch(10) self.setDefaultTime(defaultTime) ctrlLayout = QHBoxLayout(topLayout) okButton = QPushButton('OK', self) ctrlLayout.addWidget(okButton) self.connect(okButton, SIGNAL('clicked()'), self, SLOT('accept()')) cancelButton = QPushButton('Cancel', self) ctrlLayout.addWidget(cancelButton) self.connect(cancelButton, SIGNAL('clicked()'), self, SLOT('reject()')) def setDefaultTime(self, time): """Update default time setting for types""" self.hourBox.setMinValue(self.is12hrClock) self.hourBox.setMaxValue(self.is12hrClock and 12 or 23) self.hourBox.setValue(time.hourMinute(not self.is12hrClock)[0]) self.minuteBox.setValue(time.hourMinute()[1]) self.amBox.setCurrentItem(not time.isAM()) if self.is12hrClock: self.amBox.show() else: self.amBox.hide() def setCurrentTime(self): """Set dialog current time string""" text = Time().current(self.localClock).timeStr(not self.is12hrClock, \ self.is12hrClock) self.curTimeLbl.setText('Current Time:\n%s %s' % \ (text, self.localClock and 'Local' or 'Zulu')) def timeResult(self): """Return user time setting""" hour = self.hourBox.value() + self.minuteBox.value() / 60.0 if self.is12hrClock and self.amBox.currentItem == 1: hour += 12 return Time(hour) def typeChange(self, id): """Change time style based on button group signal""" timeSet = self.timeResult() if id < 2: # local self.is12hrClock = id == 0 if not self.localClock: timeSet.toLocal() self.localClock = 1 elif self.localClock: # GMT timeSet.toGMT() self.localClock = 0 self.is12hrClock = 0 self.setDefaultTime(timeSet) self.setCurrentTime() def spinHour(self, isUp, value): """Adjust AM & PM for hour spin change""" if self.is12hrClock and (isUp and value == 12) \ or (not isUp and value == 11): self.amBox.setCurrentItem(not self.amBox.currentItem()) def wrapMinute(self, isUp): """Adjust hour on minute spin change""" if isUp: self.hourBox.stepUp() else: self.hourBox.stepDown() def accept(self): """Set option from result on dialog accept signal""" timeSet = self.timeResult().hourMinute() flymainwin.FlyMainWin.option.changeData('DepartHour', `timeSet[0]`, 0) flymainwin.FlyMainWin.option.changeData('DepartMinute', `timeSet[1]`, 0) flymainwin.FlyMainWin.option.changeData('12hrClock', \ self.is12hrClock and 'yes' or 'no', 1) flymainwin.FlyMainWin.option.changeData('LocalClock', \ self.localClock and 'yes' or 'no', 1) flymainwin.FlyMainWin.option.writeChanges() QDialog.accept(self) class PasswordDlg(QDialog): """Dialog for DUAT login info""" def __init__(self, parent=None, name=None, modal=0, flags=0): QDialog.__init__(self, parent, name, modal, flags) self.user = flymainwin.FlyMainWin.option.strData('WeatherUser', 1) self.password = flymainwin.FlyMainWin.option.\ strData('WeatherPassword', 1) if sys.platform == 'win32': self.setCaption('DynCorp DUATS Login (PyQt)') else: self.setCaption('DynCorp DUATS Login') self.setIcon(QPixmap(fly_xpm)) topLayout = QVBoxLayout(self, 5) mainLayout = QGridLayout(topLayout, 3, 2) label = QLabel('Access Code:', self) mainLayout.addWidget(label, 0, 0) label = QLabel('Password:', self) mainLayout.addWidget(label, 1, 0) self.userEdit = QLineEdit(self) self.userEdit.setText(self.user) mainLayout.addWidget(self.userEdit, 0, 1) self.passEdit = QLineEdit(self) self.passEdit.setText(self.password) self.passEdit.setEchoMode(QLineEdit.Password) mainLayout.addWidget(self.passEdit, 1, 1) self.saveButton = QCheckBox('Remeber values (not secure)', self) if flymainwin.FlyMainWin.option.boolData('WeatherKeepPass'): self.saveButton.setChecked(1) mainLayout.addWidget(self.saveButton, 2, 1) ctrlLayout = QHBoxLayout(topLayout) okButton = QPushButton('OK', self) ctrlLayout.addWidget(okButton) self.connect(okButton, SIGNAL('clicked()'), self, SLOT('accept()')) cancelButton = QPushButton('Cancel', self) ctrlLayout.addWidget(cancelButton) self.connect(cancelButton, SIGNAL('clicked()'), self, SLOT('reject()')) if self.user: self.passEdit.setFocus() else: self.userEdit.setFocus() def accept(self): """Set values after OK button""" text = str(self.userEdit.text()).strip() if text and (len(text) != 8 or not text.isdigit() or not \ text.startswith('10')): QMessageBox.warning(self, 'FlyWay', \ 'Access Code does not appear to be valid') return self.user = text self.password = str(self.passEdit.text()).strip() if self.saveButton.isChecked(): flymainwin.FlyMainWin.option.changeData('WeatherUser', \ self.user, 1) flymainwin.FlyMainWin.option.changeData('WeatherPassword', \ self.password, 1) flymainwin.FlyMainWin.option.changeData('WeatherKeepPass', \ 'yes', 1) flymainwin.FlyMainWin.option.writeChanges() if self.user and self.password: QDialog.accept(self) else: QDialog.reject(self)