source: src/mlx/gui/flightlist.py@ 858:1f655516b7ae

Last change on this file since 858:1f655516b7ae was 858:1f655516b7ae, checked in by István Váradi <ivaradi@…>, 7 years ago

The timetable can be queried, displayed and filtered (re #304)

File size: 26.0 KB
Line 
1# A widget which is a generic list of flights
2
3#-----------------------------------------------------------------------------
4
5from mlx.gui.common import *
6
7import mlx.const as const
8
9#-----------------------------------------------------------------------------
10
11class ColumnDescriptor(object):
12 """A descriptor for a column in the list."""
13 def __init__(self, attribute, heading, type = str,
14 convertFn = None, renderer = None,
15 extraColumnAttributes = None, sortable = False,
16 defaultSortable = False, defaultDescending = False,
17 cellDataFn = None):
18 """Construct the descriptor."""
19 self._attribute = attribute
20 self._heading = heading
21 self._type = type
22 self._convertFn = convertFn
23 self._renderer = \
24 gtk.CellRendererText() if renderer is None else renderer
25 self._extraColumnAttributes = extraColumnAttributes
26 self._sortable = sortable
27 self._defaultSortable = defaultSortable
28 self._defaultDescending = defaultDescending
29 self._cellDataFn = cellDataFn
30
31 @property
32 def defaultSortable(self):
33 """Determine if this column is the default sortable one."""
34 return self._defaultSortable
35
36 def appendType(self, types):
37 """Append the type of this column to the given list of types."""
38 types.append(self._type)
39
40 def getViewColumn(self, index):
41 """Get a new column object for a tree view.
42
43 @param index is the 0-based index of the column."""
44 if isinstance(self._renderer, gtk.CellRendererText):
45 column = gtk.TreeViewColumn(self._heading, self._renderer,
46 text = index)
47 elif isinstance(self._renderer, gtk.CellRendererToggle):
48 column = gtk.TreeViewColumn(self._heading, self._renderer,
49 active = index)
50 else:
51 column = gtk.TreeViewColumn(self._heading, self._renderer)
52 column.set_expand(True)
53 if self._sortable:
54 column.set_sort_column_id(index)
55 column.set_sort_indicator(True)
56
57 if self._extraColumnAttributes is not None:
58 for (key, value) in self._extraColumnAttributes.iteritems():
59 if key=="alignment":
60 self._renderer.set_alignment(value, 0.5)
61 else:
62 raise Exception("unhandled extra column attribute '" +
63 key + "'")
64 if self._cellDataFn is not None:
65 column.set_cell_data_func(self._renderer, self._cellDataFn)
66
67 return column
68
69 def getValueFrom(self, flight):
70 """Get the value from the given flight."""
71 attributes = self._attribute.split(".")
72 value = getattr(flight, attributes[0])
73 for attr in attributes[1:]:
74 value = getattr(value, attr)
75 return self._type(value) if self._convertFn is None \
76 else self._convertFn(value, flight)
77
78#-----------------------------------------------------------------------------
79
80class FlightList(gtk.Alignment):
81 """Construct the flight list.
82
83 This is a complete widget with a scroll window. It is alignment centered
84 horizontally and expandable vertically."""
85
86 defaultColumnDescriptors = [
87 ColumnDescriptor("callsign", xstr("flightsel_no")),
88 ColumnDescriptor("departureTime", xstr("flightsel_deptime"),
89 sortable = True, defaultSortable = True),
90 ColumnDescriptor("departureICAO", xstr("flightsel_from"),
91 sortable = True),
92 ColumnDescriptor("arrivalICAO", xstr("flightsel_to"), sortable = True)
93 ]
94
95 def __init__(self, columnDescriptors = defaultColumnDescriptors,
96 popupMenuProducer = None, widthRequest = None,
97 multiSelection = False):
98 """Construct the flight list with the given column descriptors."""
99
100 self._columnDescriptors = columnDescriptors
101 self._popupMenuProducer = popupMenuProducer
102 self._popupMenu = None
103
104 types = [int]
105 defaultSortableIndex = None
106 for columnDescriptor in self._columnDescriptors:
107 if columnDescriptor.defaultSortable:
108 defaultSortableIndex = len(types)
109 columnDescriptor.appendType(types)
110
111 self._model = gtk.ListStore(*types)
112 if defaultSortableIndex is not None:
113 sortOrder = SORT_DESCENDING \
114 if self._columnDescriptors[defaultSortableIndex-1]._defaultDescending \
115 else SORT_ASCENDING
116 self._model.set_sort_column_id(defaultSortableIndex, sortOrder)
117 self._view = gtk.TreeView(self._model)
118
119 flightIndexColumn = gtk.TreeViewColumn()
120 flightIndexColumn.set_visible(False)
121 self._view.append_column(flightIndexColumn)
122
123 index = 1
124 for columnDescriptor in self._columnDescriptors:
125 column = columnDescriptor.getViewColumn(index)
126 self._view.append_column(column)
127 index += 1
128
129 self._view.connect("row-activated", self._rowActivated)
130 self._view.connect("button-press-event", self._buttonPressEvent)
131
132 selection = self._view.get_selection()
133 selection.connect("changed", self._selectionChanged)
134 if multiSelection:
135 selection.set_mode(SELECTION_MULTIPLE)
136
137 scrolledWindow = gtk.ScrolledWindow()
138 scrolledWindow.add(self._view)
139 if widthRequest is not None:
140 scrolledWindow.set_size_request(widthRequest, -1)
141 # FIXME: these should be constants in common.py
142 scrolledWindow.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
143 else gtk.POLICY_AUTOMATIC,
144 gtk.PolicyType.AUTOMATIC if pygobject
145 else gtk.POLICY_AUTOMATIC)
146 scrolledWindow.set_shadow_type(gtk.ShadowType.IN if pygobject
147 else gtk.SHADOW_IN)
148
149 super(FlightList, self).__init__(xalign = 0.5, yalign = 0.0,
150 xscale = 0.0, yscale = 1.0)
151 self.add(scrolledWindow)
152
153 @property
154 def selectedIndexes(self):
155 """Get the indexes of the selected entries, if any.
156
157 The indexes are sorted."""
158 selection = self._view.get_selection()
159 (model, rows) = selection.get_selected_rows()
160
161 indexes = [self._getIndexForPath(path) for path in rows]
162 indexes.sort()
163 return indexes
164
165 @property
166 def hasFlights(self):
167 """Determine if there are any flights in the list."""
168 return self._model.get_iter_root() is not None
169
170 def clear(self):
171 """Clear the model."""
172 self._model.clear()
173
174 def addFlight(self, flight):
175 """Add the given booked flight."""
176 values = [self._model.iter_n_children(None)]
177 for columnDescriptor in self._columnDescriptors:
178 values.append(columnDescriptor.getValueFrom(flight))
179 self._model.append(values)
180
181 def removeFlights(self, indexes):
182 """Remove the flights with the given indexes."""
183 model = self._model
184 idx = 0
185 iter = model.get_iter_first()
186 while iter is not None:
187 nextIter = model.iter_next(iter)
188 if model.get_value(iter, 0) in indexes:
189 model.remove(iter)
190 else:
191 model.set_value(iter, 0, idx)
192 idx += 1
193 iter = nextIter
194
195 def _getIndexForPath(self, path):
196 """Get the index for the given path."""
197 iter = self._model.get_iter(path)
198 return self._model.get_value(iter, 0)
199
200 def _rowActivated(self, flightList, path, column):
201 """Called when a row is selected."""
202 self.emit("row-activated", self._getIndexForPath(path))
203
204 def _buttonPressEvent(self, widget, event):
205 """Called when a mouse button is pressed or released."""
206 if event.type!=EVENT_BUTTON_PRESS or event.button!=3 or \
207 self._popupMenuProducer is None:
208 return
209
210 (path, _, _, _) = self._view.get_path_at_pos(int(event.x),
211 int(event.y))
212 selection = self._view.get_selection()
213 selection.unselect_all()
214 selection.select_path(path)
215
216 if self._popupMenu is None:
217 self._popupMenu = self._popupMenuProducer()
218 menu = self._popupMenu
219 if pygobject:
220 menu.popup(None, None, None, None, event.button, event.time)
221 else:
222 menu.popup(None, None, None, event.button, event.time)
223
224 def _selectionChanged(self, selection):
225 """Called when the selection has changed."""
226 self.emit("selection-changed", self.selectedIndexes)
227
228#-------------------------------------------------------------------------------
229
230gobject.signal_new("row-activated", FlightList, gobject.SIGNAL_RUN_FIRST,
231 None, (int,))
232
233gobject.signal_new("selection-changed", FlightList, gobject.SIGNAL_RUN_FIRST,
234 None, (object,))
235
236#-----------------------------------------------------------------------------
237
238class PendingFlightsFrame(gtk.Frame):
239 """A frame for a list of pending (reported or rejected) flights.
240
241 It contains the list and the buttons available."""
242 @staticmethod
243 def getAircraft(tailNumber, bookedFlight):
244 """Get the aircraft from the given booked flight.
245
246 This is the tail number followed by the ICAO code of the aircraft's
247 type."""
248 return tailNumber + \
249 " (" + const.icaoCodes[bookedFlight.aircraftType] + ")"
250
251 def _getAcft(tailNumber, bookedFlight):
252 return PendingFlightsFrame.getAircraft(tailNumber, bookedFlight)
253
254 columnDescriptors = [
255 ColumnDescriptor("callsign", xstr("flightsel_no")),
256 ColumnDescriptor("departureTime", xstr("flightsel_deptime"),
257 sortable = True, defaultSortable = True),
258 ColumnDescriptor("departureICAO", xstr("flightsel_from"),
259 sortable = True),
260 ColumnDescriptor("arrivalICAO", xstr("flightsel_to"),
261 sortable = True),
262 ColumnDescriptor("tailNumber", xstr("pendflt_acft"),
263 convertFn = _getAcft)
264 ]
265
266 def __init__(self, which, wizard, window, pirepEditable = False):
267 """Construct the frame with the given title."""
268 super(PendingFlightsFrame, self).__init__(xstr("pendflt_title_" + which))
269
270 self._which = which
271 self._wizard = wizard
272 self._window = window
273 self._pirepEditable = pirepEditable
274
275 alignment = gtk.Alignment(xscale = 1.0, yscale = 1.0)
276 alignment.set_padding(padding_top = 2, padding_bottom = 8,
277 padding_left = 4, padding_right = 4)
278
279 hbox = gtk.HBox()
280
281 self._flights = []
282 self._flightList = FlightList(columnDescriptors =
283 PendingFlightsFrame.columnDescriptors,
284 widthRequest = 500, multiSelection = True)
285 self._flightList.connect("selection-changed", self._selectionChanged)
286
287 hbox.pack_start(self._flightList, True, True, 4)
288
289 buttonBox = gtk.VBox()
290
291 self._editButton = gtk.Button(xstr("pendflt_" +
292 ("edit" if pirepEditable else
293 "view") + "_" + which))
294 self._editButton.set_sensitive(False)
295 self._editButton.connect("clicked", self._editClicked)
296 buttonBox.pack_start(self._editButton, False, False, 2)
297
298 self._reflyButton = gtk.Button(xstr("pendflt_refly_" + which))
299 self._reflyButton.set_sensitive(False)
300 self._reflyButton.connect("clicked", self._reflyClicked)
301 buttonBox.pack_start(self._reflyButton, False, False, 2)
302
303 self._deleteButton = gtk.Button(xstr("pendflt_delete_" + which))
304 self._deleteButton.set_sensitive(False)
305 self._deleteButton.connect("clicked", self._deleteClicked)
306 buttonBox.pack_start(self._deleteButton, False, False, 2)
307
308 hbox.pack_start(buttonBox, False, False, 4)
309
310 alignment.add(hbox)
311 self.add(alignment)
312
313 @property
314 def hasFlights(self):
315 """Determine if there are any flights in the list."""
316 return self._flightList.hasFlights
317
318 def clear(self):
319 """Clear the lists."""
320 self._flights = []
321 self._flightList.clear()
322
323 def addFlight(self, flight):
324 """Add a flight to the list."""
325 self._flights.append(flight)
326 self._flightList.addFlight(flight)
327
328 def _selectionChanged(self, flightList, selectedIndexes):
329 """Called when the selection in the list has changed."""
330 self._editButton.set_sensitive(len(selectedIndexes)==1)
331 self._reflyButton.set_sensitive(len(selectedIndexes)>0)
332 self._deleteButton.set_sensitive(len(selectedIndexes)>0)
333
334 def _editClicked(self, button):
335 """Called when the Edit button is clicked."""
336 gui = self._wizard.gui
337 gui.beginBusy(xstr("pendflt_pirep_busy"))
338 self.set_sensitive(False)
339
340 indexes = self._flightList.selectedIndexes
341 assert(len(indexes)==1)
342
343 flightID = self._flights[indexes[0]].id
344 gui.webHandler.getPIREP(self._pirepResultCallback, flightID)
345
346 def _pirepResultCallback(self, returned, result):
347 """Called when the PIREP query result is available."""
348 gobject.idle_add(self._handlePIREPResult, returned, result)
349
350 def _handlePIREPResult(self, returned, result):
351 """Handle the refly result."""
352
353 self.set_sensitive(True)
354 gui = self._wizard.gui
355 gui.endBusy()
356
357 if returned:
358 if self._pirepEditable:
359 gui.editPIREP(result.pirep)
360 else:
361 gui.viewMessagedPIREP(result.pirep)
362
363 def _reflyClicked(self, button):
364 """Called when the Refly button is clicked."""
365 if askYesNo(xstr("pendflt_refly_question"), parent = self._window):
366 gui = self._wizard.gui
367 gui.beginBusy(xstr("pendflt_refly_busy"))
368 self.set_sensitive(False)
369
370 flightIDs = [self._flights[i].id
371 for i in self._flightList.selectedIndexes]
372 gui.webHandler.reflyFlights(self._reflyResultCallback, flightIDs)
373
374 def _reflyResultCallback(self, returned, result):
375 """Called when the refly result is available."""
376 gobject.idle_add(self._handleReflyResult, returned, result)
377
378 def _handleReflyResult(self, returned, result):
379 """Handle the refly result."""
380
381 self.set_sensitive(True)
382 gui = self._wizard.gui
383 gui.endBusy()
384
385 print "PendingFlightsFrame._handleReflyResult", returned, result
386
387 if returned:
388 indexes = self._flightList.selectedIndexes
389
390 flights = [self._flights[index] for index in indexes]
391
392 self._flightList.removeFlights(indexes)
393 for index in indexes[::-1]:
394 del self._flights[index]
395
396 for flight in flights:
397 self._wizard.reflyFlight(flight)
398 self._window.checkFlights()
399 else:
400 communicationErrorDialog()
401
402 def _deleteClicked(self, button):
403 """Called when the Delete button is clicked."""
404 if askYesNo(xstr("flight_delete_question"), parent = self._window):
405 gui = self._wizard.gui
406 gui.beginBusy(xstr("pendflt_refly_busy"))
407 self.set_sensitive(False)
408
409 flightIDs = [self._flights[i].id
410 for i in self._flightList.selectedIndexes]
411 gui.webHandler.deleteFlights(self._deleteResultCallback, flightIDs)
412
413 def _deleteResultCallback(self, returned, result):
414 """Called when the deletion result is available."""
415 gobject.idle_add(self._handleDeleteResult, returned, result)
416
417 def _handleDeleteResult(self, returned, result):
418 """Handle the delete result."""
419
420 self.set_sensitive(True)
421 gui = self._wizard.gui
422 gui.endBusy()
423
424 print "PendingFlightsFrame._handleDeleteResult", returned, result
425
426 if returned:
427 indexes = self._flightList.selectedIndexes
428
429 flights = [self._flights[index] for index in indexes]
430
431 self._flightList.removeFlights(indexes)
432 for index in indexes[::-1]:
433 del self._flights[index]
434
435 for flight in flights:
436 self._wizard.deleteFlight(flight)
437 self._window.checkFlights()
438 else:
439 communicationErrorDialog()
440
441#-----------------------------------------------------------------------------
442
443class PendingFlightsWindow(gtk.Window):
444 """The window to display the lists of the pending (reported or rejected)
445 flights."""
446 def __init__(self, wizard):
447 """Construct the window"""
448 super(PendingFlightsWindow, self).__init__()
449
450 gui = wizard.gui
451
452 self.set_title(WINDOW_TITLE_BASE + " - " + xstr("pendflt_title"))
453 self.set_size_request(-1, 450)
454 self.set_transient_for(gui.mainWindow)
455 self.set_modal(True)
456
457 mainAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
458 xscale = 1.0, yscale = 1.0)
459 mainAlignment.set_padding(padding_top = 0, padding_bottom = 12,
460 padding_left = 8, padding_right = 8)
461
462 vbox = gtk.VBox()
463
464 self._reportedFrame = PendingFlightsFrame("reported", wizard, self,
465 True)
466 vbox.pack_start(self._reportedFrame, True, True, 2)
467
468 self._rejectedFrame = PendingFlightsFrame("rejected", wizard, self)
469 vbox.pack_start(self._rejectedFrame, True, True, 2)
470
471 alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
472 xscale = 0.0, yscale = 0.0)
473 self._closeButton = gtk.Button(xstr("button_ok"))
474 self._closeButton.connect("clicked", self._closeClicked)
475 alignment.add(self._closeButton)
476 vbox.pack_start(alignment, False, False, 2)
477
478 mainAlignment.add(vbox)
479
480 self.add(mainAlignment)
481
482 self.connect("key-press-event", self._keyPressed)
483
484 @property
485 def hasFlights(self):
486 """Determine if the window has any flights."""
487 return self._reportedFrame.hasFlights or self._rejectedFrame.hasFlights
488
489 def clear(self):
490 """Clear the lists."""
491 self._reportedFrame.clear()
492 self._rejectedFrame.clear()
493
494 def addReportedFlight(self, flight):
495 """Add a reported flight."""
496 self._reportedFrame.addFlight(flight)
497
498 def addRejectedFlight(self, flight):
499 """Add a rejected flight."""
500 self._rejectedFrame.addFlight(flight)
501
502 def checkFlights(self):
503 """Check if there are any flights in any of the lists, and close the
504 window if not."""
505 if not self.hasFlights:
506 self.emit("delete-event", None)
507
508 def _closeClicked(self, button):
509 """Called when the Close button is clicked.
510
511 A 'delete-event' is emitted to close the window."""
512 self.emit("delete-event", None)
513
514 def _keyPressed(self, window, event):
515 """Called when a key is pressed in the window.
516
517 If the Escape key is pressed, 'delete-event' is emitted to close the
518 window."""
519 if gdk.keyval_name(event.keyval) == "Escape":
520 self.emit("delete-event", None)
521 return True
522
523#-----------------------------------------------------------------------------
524
525class AcceptedFlightsWindow(gtk.Window):
526 """A window for a list of accepted flights."""
527 def getFlightDuration(flightTimeStart, flight):
528 """Get the flight duration for the given flight."""
529 minutes = int(round((flight.flightTimeEnd - flightTimeStart)/60.0))
530 return "%02d:%02d" % (minutes/60, minutes%60)
531
532 columnDescriptors = [
533 ColumnDescriptor("bookedFlight.callsign", xstr("flightsel_no")),
534 ColumnDescriptor("bookedFlight.departureTime", xstr("flightsel_deptime"),
535 sortable = True, defaultSortable = True,
536 defaultDescending = True),
537 ColumnDescriptor("bookedFlight.departureICAO", xstr("flightsel_from"),
538 sortable = True),
539 ColumnDescriptor("bookedFlight.arrivalICAO", xstr("flightsel_to"),
540 sortable = True),
541 ColumnDescriptor("bookedFlight.tailNumber", xstr("pendflt_acft"),
542 convertFn = lambda value, flight:
543 PendingFlightsFrame.getAircraft(value,
544 flight.bookedFlight)),
545 ColumnDescriptor("flightTimeStart", xstr("acceptedflt_flight_duration"),
546 convertFn = getFlightDuration, sortable = True,
547 extraColumnAttributes =
548 { "alignment": 0.5 } ),
549 ColumnDescriptor("numPassengers", xstr("acceptedflt_num_pax"),
550 type = int, sortable = True,
551 extraColumnAttributes =
552 { "alignment": 1.0 } ),
553 ColumnDescriptor("fuelUsed", xstr("acceptedflt_fuel"),
554 type = int, sortable = True,
555 extraColumnAttributes =
556 { "alignment": 1.0 } ),
557 ColumnDescriptor("rating", xstr("acceptedflt_rating"),
558 type = float, sortable = True,
559 extraColumnAttributes =
560 { "alignment": 1.0 },
561 cellDataFn = lambda col, cell, model, iter:
562 cell.set_property("text",
563 "%.0f" %
564 (model.get(iter, 9)[0],)))
565 ]
566
567 def __init__(self, gui):
568 """Construct the window."""
569 super(AcceptedFlightsWindow, self).__init__()
570
571 self._gui = gui
572
573 self.set_title(WINDOW_TITLE_BASE + " - " + xstr("acceptedflt_title"))
574 self.set_size_request(-1, 700)
575 self.set_transient_for(gui.mainWindow)
576
577 alignment = gtk.Alignment(xscale = 1.0, yscale = 1.0)
578 alignment.set_padding(padding_top = 2, padding_bottom = 8,
579 padding_left = 4, padding_right = 4)
580
581 vbox = gtk.VBox()
582
583 hbox = gtk.HBox()
584 vbox.pack_start(hbox, True, True, 4)
585
586 self._flights = []
587 self._flightList = FlightList(columnDescriptors =
588 AcceptedFlightsWindow.columnDescriptors,
589 widthRequest = 750,
590 multiSelection = False)
591 self._flightList.connect("selection-changed", self._selectionChanged)
592
593 hbox.pack_start(self._flightList, True, True, 4)
594
595 buttonBox = gtk.VBox()
596
597 self._refreshButton = gtk.Button(xstr("acceptedflt_refresh"))
598 self._refreshButton.set_sensitive(True)
599 self._refreshButton.connect("clicked", self._refreshClicked)
600 buttonBox.pack_start(self._refreshButton, False, False, 2)
601
602 filler = gtk.Alignment(xalign = 0.0, yalign = 0.0,
603 xscale = 1.0, yscale = 1.0)
604 filler.set_size_request(-1, 4)
605 buttonBox.pack_start(filler, False, False, 0)
606
607 self._viewButton = gtk.Button(xstr("acceptedflt_view"))
608 self._viewButton.set_sensitive(False)
609 self._viewButton.connect("clicked", self._viewClicked)
610 buttonBox.pack_start(self._viewButton, False, False, 2)
611
612 hbox.pack_start(buttonBox, False, False, 4)
613
614 buttonAlignment = gtk.Alignment(xscale = 0.0, yscale = 0.0,
615 xalign = 0.5, yalign = 0.5)
616
617 self._closeButton = gtk.Button(xstr("button_ok"))
618 self._closeButton.connect("clicked", self._closeClicked)
619
620 buttonAlignment.add(self._closeButton)
621 vbox.pack_start(buttonAlignment, False, False, 2)
622
623 alignment.add(vbox)
624
625 self.add(alignment)
626
627 self.connect("key-press-event", self._keyPressed)
628
629 @property
630 def hasFlights(self):
631 """Determine if there are any flights that we know of."""
632 return len(self._flights)>0
633
634 def clear(self):
635 """Clear the flight list."""
636 self._flights = []
637 self._flightList.clear()
638
639 def addFlight(self, flight):
640 """Add the given flight."""
641 self._flights.append(flight)
642 self._flightList.addFlight(flight)
643
644 def _selectionChanged(self, flightList, selectedIndexes):
645 """Called when the selection has changed."""
646 self._viewButton.set_sensitive(len(selectedIndexes)==1)
647
648 def _refreshClicked(self, button):
649 """Called when the refresh button has been clicked."""
650 self.clear()
651 self._gui.showFlights(None)
652
653 def _viewClicked(self, button):
654 """Called when the view button has been clicked."""
655 gui = self._gui
656 gui.beginBusy(xstr("pendflt_pirep_busy"))
657 self.set_sensitive(False)
658
659 indexes = self._flightList.selectedIndexes
660 assert(len(indexes)==1)
661
662 flightID = self._flights[indexes[0]].bookedFlight.id
663 gui.webHandler.getPIREP(self._pirepResultCallback, flightID)
664
665 def _pirepResultCallback(self, returned, result):
666 """Called when the PIREP query result is available."""
667 gobject.idle_add(self._handlePIREPResult, returned, result)
668
669 def _handlePIREPResult(self, returned, result):
670 """Handle the refly result."""
671 self.set_sensitive(True)
672 gui = self._gui
673 gui.endBusy()
674
675 if returned:
676 gui.viewMessagedPIREP(result.pirep)
677
678 def _closeClicked(self, button):
679 """Called when the Close button is clicked.
680
681 A 'delete-event' is emitted to close the window."""
682 self.emit("delete-event", None)
683
684 def _keyPressed(self, window, event):
685 """Called when a key is pressed in the window.
686
687 If the Escape key is pressed, 'delete-event' is emitted to close the
688 window."""
689 if gdk.keyval_name(event.keyval) == "Escape":
690 self.emit("delete-event", None)
691 return True
692
693#-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.