source: src/mlx/gui/gui.py@ 119:0185f1446770

Last change on this file since 119:0185f1446770 was 119:0185f1446770, checked in by István Váradi <ivaradi@…>, 12 years ago

The fleet is now retrieved centrally and is updated on the Gates page all the time

File size: 25.5 KB
Line 
1# The main file for the GUI
2
3from statusicon import StatusIcon
4from statusbar import Statusbar
5from info import FlightInfo
6from update import Updater
7from mlx.gui.common import *
8from mlx.gui.flight import Wizard
9from mlx.gui.monitor import MonitorWindow
10from mlx.gui.weighthelp import WeightHelp
11from mlx.gui.gates import FleetGateStatus
12
13import mlx.const as const
14import mlx.fs as fs
15import mlx.flight as flight
16import mlx.logger as logger
17import mlx.acft as acft
18import mlx.web as web
19from mlx.i18n import xstr
20
21import time
22import threading
23import sys
24
25#------------------------------------------------------------------------------
26
27class GUI(fs.ConnectionListener):
28 """The main GUI class."""
29 @staticmethod
30 def _formatFlightLogLine(timeStr, line):
31 """Format the given line for flight logging."""
32 if timeStr is not None:
33 line = timeStr + ": " + line
34 return line + "\n"
35
36 def __init__(self, programDirectory, config):
37 """Construct the GUI."""
38 gobject.threads_init()
39
40 self._programDirectory = programDirectory
41 self.config = config
42 self._connecting = False
43 self._reconnecting = False
44 self._connected = False
45 self._logger = logger.Logger(self)
46 self._flight = None
47 self._simulator = None
48 self._monitoring = False
49 self._fleet = None
50 self._fleetCallback = None
51
52 self._stdioLock = threading.Lock()
53 self._stdioText = ""
54
55 self.webHandler = web.Handler()
56 self.webHandler.start()
57
58 self.toRestart = False
59
60 def build(self, iconDirectory):
61 """Build the GUI."""
62
63 window = gtk.Window()
64 window.set_title(WINDOW_TITLE_BASE)
65 window.set_icon_from_file(os.path.join(iconDirectory, "logo.ico"))
66 window.connect("delete-event",
67 lambda a, b: self.hideMainWindow())
68 window.connect("window-state-event", self._handleMainWindowState)
69 accelGroup = gtk.AccelGroup()
70 window.add_accel_group(accelGroup)
71
72 mainVBox = gtk.VBox()
73 window.add(mainVBox)
74
75 menuBar = self._buildMenuBar(accelGroup)
76 mainVBox.pack_start(menuBar, False, False, 0)
77
78 self._notebook = gtk.Notebook()
79 mainVBox.pack_start(self._notebook, True, True, 4)
80
81 self._wizard = Wizard(self)
82 label = gtk.Label(xstr("tab_flight"))
83 label.set_use_underline(True)
84 label.set_tooltip_text(xstr("tab_flight_tooltip"))
85 self._notebook.append_page(self._wizard, label)
86
87 self._flightInfo = FlightInfo(self)
88 label = gtk.Label(xstr("tab_flight_info"))
89 label.set_use_underline(True)
90 label.set_tooltip_text(xstr("tab_flight_info_tooltip"))
91 self._notebook.append_page(self._flightInfo, label)
92 self._flightInfo.disable()
93
94 self._weightHelp = WeightHelp(self)
95 label = gtk.Label(xstr("tab_weight_help"))
96 label.set_use_underline(True)
97 label.set_tooltip_text(xstr("tab_weight_help_tooltip"))
98 self._notebook.append_page(self._weightHelp, label)
99
100 (logWidget, self._logView) = self._buildLogWidget()
101 label = gtk.Label(xstr("tab_log"))
102 label.set_use_underline(True)
103 label.set_tooltip_text(xstr("tab_log_tooltip"))
104 self._notebook.append_page(logWidget, label)
105
106 self._fleetGateStatus = FleetGateStatus(self)
107 label = gtk.Label(xstr("tab_gates"))
108 label.set_use_underline(True)
109 label.set_tooltip_text(xstr("tab_gates_tooltip"))
110 self._notebook.append_page(self._fleetGateStatus, label)
111
112 (self._debugLogWidget, self._debugLogView) = self._buildLogWidget()
113 self._debugLogWidget.show_all()
114
115 mainVBox.pack_start(gtk.HSeparator(), False, False, 0)
116
117 self._statusbar = Statusbar()
118 mainVBox.pack_start(self._statusbar, False, False, 0)
119
120 self._notebook.connect("switch-page", self._notebookPageSwitch)
121
122 self._monitorWindow = MonitorWindow(self, iconDirectory)
123 self._monitorWindow.add_accel_group(accelGroup)
124 self._monitorWindowX = None
125 self._monitorWindowY = None
126 self._selfToggling = False
127
128 window.show_all()
129 self._wizard.grabDefault()
130 self._weightHelp.reset()
131 self._weightHelp.disable()
132
133 self._mainWindow = window
134
135 self._statusIcon = StatusIcon(iconDirectory, self)
136
137 self._busyCursor = gdk.Cursor(gdk.CursorType.WATCH if pygobject
138 else gdk.WATCH)
139
140 @property
141 def mainWindow(self):
142 """Get the main window of the GUI."""
143 return self._mainWindow
144
145 @property
146 def logger(self):
147 """Get the logger used by us."""
148 return self._logger
149
150 @property
151 def simulator(self):
152 """Get the simulator used by us."""
153 return self._simulator
154
155 @property
156 def flight(self):
157 """Get the flight being performed."""
158 return self._flight
159
160 @property
161 def bookedFlight(self):
162 """Get the booked flight selected, if any."""
163 return self._wizard.bookedFlight
164
165 @property
166 def cargoWeight(self):
167 """Get the cargo weight."""
168 return self._wizard.cargoWeight
169
170 @property
171 def zfw(self):
172 """Get Zero-Fuel Weight calculated for the current flight."""
173 return self._wizard.zfw
174
175 @property
176 def filedCruiseAltitude(self):
177 """Get cruise altitude filed for the current flight."""
178 return self._wizard.filedCruiseAltitude
179
180 @property
181 def cruiseAltitude(self):
182 """Get cruise altitude set for the current flight."""
183 return self._wizard.cruiseAltitude
184
185 @property
186 def route(self):
187 """Get the flight route."""
188 return self._wizard.route
189
190 @property
191 def departureMETAR(self):
192 """Get the METAR of the deprature airport."""
193 return self._wizard.departureMETAR
194
195 @property
196 def arrivalMETAR(self):
197 """Get the METAR of the deprature airport."""
198 return self._wizard.arrivalMETAR
199
200 @property
201 def departureRunway(self):
202 """Get the name of the departure runway."""
203 return self._wizard.departureRunway
204
205 @property
206 def sid(self):
207 """Get the SID."""
208 return self._wizard.sid
209
210 @property
211 def v1(self):
212 """Get the V1 speed calculated for the flight."""
213 return self._wizard.v1
214
215 @property
216 def vr(self):
217 """Get the Vr speed calculated for the flight."""
218 return self._wizard.vr
219
220 @property
221 def v2(self):
222 """Get the V2 speed calculated for the flight."""
223 return self._wizard.v2
224
225 @property
226 def arrivalRunway(self):
227 """Get the arrival runway."""
228 return self._wizard.arrivalRunway
229
230 @property
231 def star(self):
232 """Get the STAR."""
233 return self._wizard.star
234
235 @property
236 def transition(self):
237 """Get the transition."""
238 return self._wizard.transition
239
240 @property
241 def approachType(self):
242 """Get the approach type."""
243 return self._wizard.approachType
244
245 @property
246 def vref(self):
247 """Get the Vref speed calculated for the flight."""
248 return self._wizard.vref
249
250 @property
251 def flightType(self):
252 """Get the flight type."""
253 return self._wizard.flightType
254
255 @property
256 def online(self):
257 """Get whether the flight was online or not."""
258 return self._wizard.online
259
260 @property
261 def comments(self):
262 """Get the comments."""
263 return self._flightInfo.comments
264
265 @property
266 def flightDefects(self):
267 """Get the flight defects."""
268 return self._flightInfo.flightDefects
269
270 @property
271 def delayCodes(self):
272 """Get the delay codes."""
273 return self._flightInfo.delayCodes
274
275 def run(self):
276 """Run the GUI."""
277 if self.config.autoUpdate:
278 self._updater = Updater(self,
279 self._programDirectory,
280 self.config.updateURL,
281 self._mainWindow)
282 self._updater.start()
283
284 gtk.main()
285
286 self._disconnect()
287
288 def connected(self, fsType, descriptor):
289 """Called when we have connected to the simulator."""
290 self._connected = True
291 self._logger.untimedMessage("Connected to the simulator %s" % (descriptor,))
292 gobject.idle_add(self._handleConnected, fsType, descriptor)
293
294 def _handleConnected(self, fsType, descriptor):
295 """Called when the connection to the simulator has succeeded."""
296 self._statusbar.updateConnection(self._connecting, self._connected)
297 self.endBusy()
298 if not self._reconnecting:
299 self._wizard.connected(fsType, descriptor)
300 self._reconnecting = False
301
302 def connectionFailed(self):
303 """Called when the connection failed."""
304 self._logger.untimedMessage("Connection to the simulator failed")
305 gobject.idle_add(self._connectionFailed)
306
307 def _connectionFailed(self):
308 """Called when the connection failed."""
309 self.endBusy()
310 self._statusbar.updateConnection(self._connecting, self._connected)
311
312 dialog = gtk.MessageDialog(parent = self._mainWindow,
313 type = MESSAGETYPE_ERROR,
314 message_format = xstr("conn_failed"))
315
316 dialog.set_title(WINDOW_TITLE_BASE)
317 dialog.format_secondary_markup(xstr("conn_failed_sec"))
318
319 dialog.add_button(xstr("button_cancel"), 0)
320 dialog.add_button(xstr("button_tryagain"), 1)
321 dialog.set_default_response(1)
322
323 result = dialog.run()
324 dialog.hide()
325 if result == 1:
326 self.beginBusy(xstr("connect_busy"))
327 self._simulator.reconnect()
328 else:
329 self.reset()
330
331 def disconnected(self):
332 """Called when we have disconnected from the simulator."""
333 self._connected = False
334 self._logger.untimedMessage("Disconnected from the simulator")
335
336 gobject.idle_add(self._disconnected)
337
338 def _disconnected(self):
339 """Called when we have disconnected from the simulator unexpectedly."""
340 self._statusbar.updateConnection(self._connecting, self._connected)
341
342 dialog = gtk.MessageDialog(type = MESSAGETYPE_ERROR,
343 message_format = xstr("conn_broken"),
344 parent = self._mainWindow)
345 dialog.set_title(WINDOW_TITLE_BASE)
346 dialog.format_secondary_markup(xstr("conn_broken_sec"))
347
348 dialog.add_button(xstr("button_cancel"), 0)
349 dialog.add_button(xstr("button_reconnect"), 1)
350 dialog.set_default_response(1)
351
352 result = dialog.run()
353 dialog.hide()
354 if result == 1:
355 self.beginBusy(xstr("connect_busy"))
356 self._reconnecting = True
357 self._simulator.reconnect()
358 else:
359 self.reset()
360
361 def enableFlightInfo(self):
362 """Enable the flight info tab."""
363 self._flightInfo.enable()
364
365 def reset(self):
366 """Reset the GUI."""
367 self._disconnect()
368
369 self._flightInfo.reset()
370 self._flightInfo.disable()
371 self.resetFlightStatus()
372
373 self._weightHelp.reset()
374 self._weightHelp.disable()
375 self._wizard.reset()
376 self._notebook.set_current_page(0)
377
378 self._logView.get_buffer().set_text("")
379
380 def _disconnect(self):
381 """Disconnect from the simulator if connected."""
382 self.stopMonitoring()
383
384 if self._connected:
385 self._flight.simulator.disconnect()
386 self._connected = False
387
388 self._connecting = False
389 self._reconnecting = False
390 self._statusbar.updateConnection(False, False)
391
392 def addFlightLogLine(self, timeStr, line):
393 """Write the given message line to the log."""
394 gobject.idle_add(self._writeLog,
395 GUI._formatFlightLogLine(timeStr, line),
396 self._logView)
397
398 def updateFlightLogLine(self, index, timeStr, line):
399 """Update the line with the given index."""
400 gobject.idle_add(self._updateFlightLogLine, index,
401 GUI._formatFlightLogLine(timeStr, line))
402
403 def _updateFlightLogLine(self, index, line):
404 """Replace the contents of the given line in the log."""
405 buffer = self._logView.get_buffer()
406 startIter = buffer.get_iter_at_line(index)
407 endIter = buffer.get_iter_at_line(index + 1)
408 buffer.delete(startIter, endIter)
409 buffer.insert(startIter, line)
410 self._logView.scroll_mark_onscreen(buffer.get_insert())
411
412 def check(self, flight, aircraft, logger, oldState, state):
413 """Update the data."""
414 gobject.idle_add(self._monitorWindow.setData, state)
415 gobject.idle_add(self._statusbar.updateTime, state.timestamp)
416
417 def resetFlightStatus(self):
418 """Reset the status of the flight."""
419 self._statusbar.resetFlightStatus()
420 self._statusbar.updateTime()
421 self._statusIcon.resetFlightStatus()
422
423 def setStage(self, stage):
424 """Set the stage of the flight."""
425 gobject.idle_add(self._setStage, stage)
426
427 def _setStage(self, stage):
428 """Set the stage of the flight."""
429 self._statusbar.setStage(stage)
430 self._statusIcon.setStage(stage)
431 self._wizard.setStage(stage)
432 if stage==const.STAGE_END:
433 self._disconnect()
434
435 def setRating(self, rating):
436 """Set the rating of the flight."""
437 gobject.idle_add(self._setRating, rating)
438
439 def _setRating(self, rating):
440 """Set the rating of the flight."""
441 self._statusbar.setRating(rating)
442 self._statusIcon.setRating(rating)
443
444 def setNoGo(self, reason):
445 """Set the rating of the flight to No-Go with the given reason."""
446 gobject.idle_add(self._setNoGo, reason)
447
448 def _setNoGo(self, reason):
449 """Set the rating of the flight."""
450 self._statusbar.setNoGo(reason)
451 self._statusIcon.setNoGo(reason)
452
453 def _handleMainWindowState(self, window, event):
454 """Hande a change in the state of the window"""
455 iconified = gdk.WindowState.ICONIFIED if pygobject \
456 else gdk.WINDOW_STATE_ICONIFIED
457 if (event.changed_mask&iconified)!=0 and (event.new_window_state&iconified)!=0:
458 self.hideMainWindow(savePosition = False)
459
460 def hideMainWindow(self, savePosition = True):
461 """Hide the main window and save its position."""
462 if savePosition:
463 (self._mainWindowX, self._mainWindowY) = \
464 self._mainWindow.get_window().get_root_origin()
465 else:
466 self._mainWindowX = self._mainWindowY = None
467 self._mainWindow.hide()
468 self._statusIcon.mainWindowHidden()
469 return True
470
471 def showMainWindow(self):
472 """Show the main window at its former position."""
473 if self._mainWindowX is not None and self._mainWindowY is not None:
474 self._mainWindow.move(self._mainWindowX, self._mainWindowY)
475
476 self._mainWindow.show()
477 self._mainWindow.deiconify()
478
479 self._statusIcon.mainWindowShown()
480
481 def toggleMainWindow(self):
482 """Toggle the main window."""
483 if self._mainWindow.get_visible():
484 self.hideMainWindow()
485 else:
486 self.showMainWindow()
487
488 def hideMonitorWindow(self, savePosition = True):
489 """Hide the monitor window."""
490 if savePosition:
491 (self._monitorWindowX, self._monitorWindowY) = \
492 self._monitorWindow.get_window().get_root_origin()
493 else:
494 self._monitorWindowX = self._monitorWindowY = None
495 self._monitorWindow.hide()
496 self._statusIcon.monitorWindowHidden()
497 if self._showMonitorMenuItem.get_active():
498 self._selfToggling = True
499 self._showMonitorMenuItem.set_active(False)
500 return True
501
502 def showMonitorWindow(self):
503 """Show the monitor window."""
504 if self._monitorWindowX is not None and self._monitorWindowY is not None:
505 self._monitorWindow.move(self._monitorWindowX, self._monitorWindowY)
506 self._monitorWindow.show_all()
507 self._statusIcon.monitorWindowShown()
508 if not self._showMonitorMenuItem.get_active():
509 self._selfToggling = True
510 self._showMonitorMenuItem.set_active(True)
511
512 def _toggleMonitorWindow(self, menuItem):
513 if self._selfToggling:
514 self._selfToggling = False
515 elif self._monitorWindow.get_visible():
516 self.hideMonitorWindow()
517 else:
518 self.showMonitorWindow()
519
520 def restart(self):
521 """Quit and restart the application."""
522 self.toRestart = True
523 self._quit(force = True)
524
525 def flushStdIO(self):
526 """Flush any text to the standard error that could not be logged."""
527 if self._stdioText:
528 sys.__stderr__.write(self._stdioText)
529
530 def writeStdIO(self, text):
531 """Write the given text into standard I/O log."""
532 with self._stdioLock:
533 self._stdioText += text
534
535 gobject.idle_add(self._writeStdIO)
536
537 def beginBusy(self, message):
538 """Begin a period of background processing."""
539 self._wizard.set_sensitive(False)
540 self._weightHelp.set_sensitive(False)
541 self._mainWindow.get_window().set_cursor(self._busyCursor)
542 self._statusbar.updateBusyState(message)
543
544 def endBusy(self):
545 """End a period of background processing."""
546 self._mainWindow.get_window().set_cursor(None)
547 self._weightHelp.set_sensitive(True)
548 self._wizard.set_sensitive(True)
549 self._statusbar.updateBusyState(None)
550
551 def initializeWeightHelp(self):
552 """Initialize the weight help tab."""
553 self._weightHelp.reset()
554 self._weightHelp.enable()
555
556 def getFleet(self, callback = None, force = False):
557 """Get the fleet.
558
559 If force is False, and we already have a fleet retrieved,
560 that one will be used."""
561 if self._fleet is None or force:
562 self._fleetCallback = callback
563 self.beginBusy(xstr("fleet_busy"))
564 self.webHandler.getFleet(self._fleetResultCallback)
565 else:
566 callback(self._fleet)
567
568 def _fleetResultCallback(self, returned, result):
569 """Called when the fleet has been queried."""
570 gobject.idle_add(self._handleFleetResult, returned, result)
571
572 def _handleFleetResult(self, returned, result):
573 """Handle the fleet result."""
574 self.endBusy()
575 if returned:
576 self._fleet = result.fleet
577 else:
578 self._fleet = None
579
580 dialog = gtk.MessageDialog(parent = self.gui.mainWindow,
581 type = MESSAGETYPE_ERROR,
582 buttons = BUTTONSTYPE_OK,
583 message_format = xstr("fleet_failed"))
584 dialog.set_title(WINDOW_TITLE_BASE)
585 dialog.run()
586 dialog.hide()
587
588 if self._fleetCallback is not None:
589 self._fleetCallback(self._fleet)
590 self._fleetCallback = None
591 self._fleetGateStatus.handleFleet(self._fleet)
592
593 def _writeStdIO(self):
594 """Perform the real writing."""
595 with self._stdioLock:
596 text = self._stdioText
597 self._stdioText = ""
598 if not text: return
599
600 lines = text.splitlines()
601 if text[-1]=="\n":
602 text = ""
603 else:
604 text = lines[-1]
605 lines = lines[:-1]
606
607 for line in lines:
608 #print >> sys.__stdout__, line
609 self._writeLog(line + "\n", self._debugLogView)
610
611 if text:
612 #print >> sys.__stdout__, text,
613 self._writeLog(text, self._debugLogView)
614
615 def connectSimulator(self, aircraftType):
616 """Connect to the simulator for the first time."""
617 self._logger.reset()
618
619 self._flight = flight.Flight(self._logger, self)
620 self._flight.aircraftType = aircraftType
621 self._flight.aircraft = acft.Aircraft.create(self._flight)
622 self._flight.aircraft._checkers.append(self)
623
624 if self._simulator is None:
625 self._simulator = fs.createSimulator(const.SIM_MSFS9, self)
626
627 self._flight.simulator = self._simulator
628
629 self.beginBusy(xstr("connect_busy"))
630 self._statusbar.updateConnection(self._connecting, self._connected)
631
632 self._connecting = True
633 self._simulator.connect(self._flight.aircraft)
634
635 def startMonitoring(self):
636 """Start monitoring."""
637 if not self._monitoring:
638 self.simulator.startMonitoring()
639 self._monitoring = True
640
641 def stopMonitoring(self):
642 """Stop monitoring."""
643 if self._monitoring:
644 self.simulator.stopMonitoring()
645 self._monitoring = False
646
647 def _buildMenuBar(self, accelGroup):
648 """Build the main menu bar."""
649 menuBar = gtk.MenuBar()
650
651 fileMenuItem = gtk.MenuItem(xstr("menu_file"))
652 fileMenu = gtk.Menu()
653 fileMenuItem.set_submenu(fileMenu)
654 menuBar.append(fileMenuItem)
655
656 quitMenuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
657 quitMenuItem.set_use_stock(True)
658 quitMenuItem.set_label(xstr("menu_file_quit"))
659 quitMenuItem.add_accelerator("activate", accelGroup,
660 ord(xstr("menu_file_quit_key")),
661 CONTROL_MASK, ACCEL_VISIBLE)
662 quitMenuItem.connect("activate", self._quit)
663 fileMenu.append(quitMenuItem)
664
665
666 viewMenuItem = gtk.MenuItem(xstr("menu_view"))
667 viewMenu = gtk.Menu()
668 viewMenuItem.set_submenu(viewMenu)
669 menuBar.append(viewMenuItem)
670
671 self._showMonitorMenuItem = gtk.CheckMenuItem()
672 self._showMonitorMenuItem.set_label(xstr("menu_view_monitor"))
673 self._showMonitorMenuItem.set_use_underline(True)
674 self._showMonitorMenuItem.set_active(False)
675 self._showMonitorMenuItem.add_accelerator("activate", accelGroup,
676 ord(xstr("menu_view_monitor_key")),
677 CONTROL_MASK, ACCEL_VISIBLE)
678 self._showMonitorMenuItem.connect("toggled", self._toggleMonitorWindow)
679 viewMenu.append(self._showMonitorMenuItem)
680
681 showDebugMenuItem = gtk.CheckMenuItem()
682 showDebugMenuItem.set_label(xstr("menu_view_debug"))
683 showDebugMenuItem.set_use_underline(True)
684 showDebugMenuItem.set_active(False)
685 showDebugMenuItem.add_accelerator("activate", accelGroup,
686 ord(xstr("menu_view_debug_key")),
687 CONTROL_MASK, ACCEL_VISIBLE)
688 showDebugMenuItem.connect("toggled", self._toggleDebugLog)
689 viewMenu.append(showDebugMenuItem)
690
691 return menuBar
692
693 def _toggleDebugLog(self, menuItem):
694 """Toggle the debug log."""
695 if menuItem.get_active():
696 label = gtk.Label(xstr("tab_debug_log"))
697 label.set_use_underline(True)
698 label.set_tooltip_text(xstr("tab_debug_log_tooltip"))
699 self._debugLogPage = self._notebook.append_page(self._debugLogWidget, label)
700 self._notebook.set_current_page(self._debugLogPage)
701 else:
702 self._notebook.remove_page(self._debugLogPage)
703
704 def _buildLogWidget(self):
705 """Build the widget for the log."""
706 alignment = gtk.Alignment(xscale = 1.0, yscale = 1.0)
707
708 alignment.set_padding(padding_top = 8, padding_bottom = 8,
709 padding_left = 16, padding_right = 16)
710
711 logScroller = gtk.ScrolledWindow()
712 # FIXME: these should be constants in common
713 logScroller.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
714 else gtk.POLICY_AUTOMATIC,
715 gtk.PolicyType.AUTOMATIC if pygobject
716 else gtk.POLICY_AUTOMATIC)
717 logScroller.set_shadow_type(gtk.ShadowType.IN if pygobject
718 else gtk.SHADOW_IN)
719 logView = gtk.TextView()
720 logView.set_editable(False)
721 logScroller.add(logView)
722
723 logBox = gtk.VBox()
724 logBox.pack_start(logScroller, True, True, 0)
725 logBox.set_size_request(-1, 200)
726
727 alignment.add(logBox)
728
729 return (alignment, logView)
730
731 def _writeLog(self, msg, logView):
732 """Write the given message to the log."""
733 buffer = logView.get_buffer()
734 buffer.insert(buffer.get_end_iter(), msg)
735 logView.scroll_mark_onscreen(buffer.get_insert())
736
737 def _quit(self, what = None, force = False):
738 """Quit from the application."""
739 if force:
740 result=RESPONSETYPE_YES
741 else:
742 dialog = gtk.MessageDialog(parent = self._mainWindow,
743 type = MESSAGETYPE_QUESTION,
744 buttons = BUTTONSTYPE_YES_NO,
745 message_format = xstr("quit_question"))
746
747 dialog.set_title(WINDOW_TITLE_BASE)
748 result = dialog.run()
749 dialog.hide()
750
751 if result==RESPONSETYPE_YES:
752 self._statusIcon.destroy()
753 return gtk.main_quit()
754
755 def _notebookPageSwitch(self, notebook, page, page_num):
756 """Called when the current page of the notebook has changed."""
757 if page_num==0:
758 gobject.idle_add(self._wizard.grabDefault)
759 else:
760 self._mainWindow.set_default(None)
Note: See TracBrowser for help on using the repository browser.