Index: src/mlx/gui/common.py
===================================================================
--- src/mlx/gui/common.py	(revision 86)
+++ src/mlx/gui/common.py	(revision 93)
@@ -24,4 +24,6 @@
     BUTTONSTYPE_YES_NO = gtk.BUTTONS_YES_NO
     RESPONSETYPE_YES = gtk.RESPONSE_YES
+    ACCEL_VISIBLE = gtk.ACCEL_VISIBLE
+    CONTROL_MASK = gdk.CONTROL_MASK
 else:
     print "Using PyGObject"
@@ -39,4 +41,6 @@
     BUTTONSTYPE_YES_NO = gtk.ButtonsType.YES_NO
     RESPONSETYPE_YES = gtk.ResponseType.YES
+    ACCEL_VISIBLE = gtk.AccelFlags.VISIBLE
+    CONTROL_MASK = gdk.ModifierType.CONTROL_MASK
 
 import cairo
Index: src/mlx/gui/flight.py
===================================================================
--- src/mlx/gui/flight.py	(revision 92)
+++ src/mlx/gui/flight.py	(revision 93)
@@ -359,4 +359,7 @@
             flight = self._wizard.loginResult.flights[index]
             self._wizard._bookedFlight = flight
+            # FIXME: with PyGObject this call causes error messages to
+            # appear on the standard output
+            self._wizard.gui.enableFlightInfo()
 
             self._updateDepartureGate()
Index: src/mlx/gui/gui.py
===================================================================
--- src/mlx/gui/gui.py	(revision 92)
+++ src/mlx/gui/gui.py	(revision 93)
@@ -40,5 +40,4 @@
         self._stdioLock = threading.Lock()
         self._stdioText = ""
-        self._stdioAfterNewLine = True
 
         self.webHandler = web.Handler()
@@ -56,10 +55,15 @@
                        lambda a, b: self.hideMainWindow())
         window.connect("window-state-event", self._handleMainWindowState)
+        accelGroup = gtk.AccelGroup()
+        window.add_accel_group(accelGroup)
 
         mainVBox = gtk.VBox()
         window.add(mainVBox)
 
+        menuBar = self._buildMenuBar(accelGroup)
+        mainVBox.pack_start(menuBar, False, False, 0)
+
         self._notebook = gtk.Notebook()
-        mainVBox.add(self._notebook)
+        mainVBox.pack_start(self._notebook, True, True, 4)
 
         self._wizard = Wizard(self)
@@ -74,14 +78,14 @@
         label.set_tooltip_text("Flight information")
         self._notebook.append_page(self._flightInfo, label)
-
-        logVBox = gtk.VBox()
+        self._flightInfo.disable()
+
+        (logWidget, self._logView)  = self._buildLogWidget()
         label = gtk.Label("_Log")
         label.set_use_underline(True)
-        label.set_tooltip_text("Flight log")
-        self._notebook.append_page(logVBox, label)
-        
-        logFrame = self._buildLogFrame()
-        logFrame.set_border_width(8)
-        logVBox.pack_start(logFrame, True, True, 0)
+        label.set_tooltip_text("The log of your flight that will be sent to the MAVA website")
+        self._notebook.append_page(logWidget, label)
+
+        (self._debugLogWidget, self._debugLogView) = self._buildLogWidget()
+        self._debugLogWidget.show_all()
 
         mainVBox.pack_start(gtk.HSeparator(), False, False, 0)
@@ -93,6 +97,8 @@
 
         self._monitorWindow = MonitorWindow(self, iconDirectory)
+        self._monitorWindow.add_accel_group(accelGroup)
         self._monitorWindowX = None
         self._monitorWindowY = None
+        self._selfToggling = False
 
         window.show_all()
@@ -237,4 +243,8 @@
             self.reset()
 
+    def enableFlightInfo(self):
+        """Enable the flight info tab."""
+        self._flightInfo.enable()
+
     def reset(self):
         """Reset the GUI."""
@@ -242,4 +252,5 @@
 
         self._flightInfo.reset()
+        self._flightInfo.disable()
         self.resetFlightStatus()
 
@@ -263,5 +274,5 @@
     def write(self, msg):
         """Write the given message to the log."""
-        gobject.idle_add(self._writeLog, msg)
+        gobject.idle_add(self._writeLog, msg, self._logView)
         
     def check(self, flight, aircraft, logger, oldState, state):
@@ -350,4 +361,7 @@
         self._monitorWindow.hide()
         self._statusIcon.monitorWindowHidden()
+        if self._showMonitorMenuItem.get_active():
+            self._selfToggling = True
+            self._showMonitorMenuItem.set_active(False)
         return True
 
@@ -358,4 +372,15 @@
         self._monitorWindow.show_all()
         self._statusIcon.monitorWindowShown()
+        if not self._showMonitorMenuItem.get_active():
+            self._selfToggling = True
+            self._showMonitorMenuItem.set_active(True)
+
+    def _toggleMonitorWindow(self, menuItem):
+        if self._selfToggling:
+            self._selfToggling = False
+        elif self._monitorWindow.get_visible():
+            self.hideMonitorWindow()
+        else:
+            self.showMonitorWindow()
 
     def restart(self):
@@ -378,4 +403,5 @@
     def beginBusy(self, message):
         """Begin a period of background processing."""
+        self._wizard.set_sensitive(False)
         self._mainWindow.get_window().set_cursor(self._busyCursor)
         self._statusbar.updateBusyState(message)
@@ -384,4 +410,5 @@
         """End a period of background processing."""
         self._mainWindow.get_window().set_cursor(None)
+        self._wizard.set_sensitive(True)
         self._statusbar.updateBusyState(None)
 
@@ -401,14 +428,10 @@
             
         for line in lines:
-            if self._stdioAfterNewLine:
-                line = "[STDIO] " + line
-            self._writeLog(line + "\n")
-            self._stdioAfterNewLine = True
+            print >> sys.__stdout__, line
+            self._writeLog(line + "\n", self._debugLogView)
 
         if text:
-            if self._stdioAfterNewLine:
-                text = "[STDIO] " + text
-            self._writeLog(text)
-            self._stdioAfterNewLine = False
+            print >> sys.__stdout__, line,
+            self._writeLog(text, self._debugLogView)
 
     def connectSimulator(self, aircraftType):
@@ -444,19 +467,78 @@
             self._monitoring = False
 
-    def _buildLogFrame(self):
-        """Build the frame for the log."""
-        logFrame = gtk.Frame(label = "Log")
-
-        frameAlignment = gtk.Alignment(xscale = 1.0, yscale = 1.0)
-
-        frameAlignment.set_padding(padding_top = 4, padding_bottom = 10,
-                                   padding_left = 16, padding_right = 16)
-
-        logFrame.add(frameAlignment)
+    def _buildMenuBar(self, accelGroup):
+        """Build the main menu bar."""
+        menuBar = gtk.MenuBar()
+        
+        fileMenuItem = gtk.MenuItem("File")
+        fileMenu = gtk.Menu()
+        fileMenuItem.set_submenu(fileMenu)
+        menuBar.append(fileMenuItem)
+
+        quitMenuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+        quitMenuItem.set_use_stock(True)
+        quitMenuItem.add_accelerator("activate", accelGroup,
+                                     ord("q"), CONTROL_MASK,
+                                     ACCEL_VISIBLE)
+        quitMenuItem.connect("activate", self._quit)
+        fileMenu.append(quitMenuItem)
+
+
+        viewMenuItem = gtk.MenuItem("View")
+        viewMenu = gtk.Menu()
+        viewMenuItem.set_submenu(viewMenu)
+        menuBar.append(viewMenuItem)
+
+        self._showMonitorMenuItem = gtk.CheckMenuItem()
+        self._showMonitorMenuItem.set_label("Show _monitor window")
+        self._showMonitorMenuItem.set_use_underline(True)
+        self._showMonitorMenuItem.set_active(False)
+        self._showMonitorMenuItem.add_accelerator("activate", accelGroup,
+                                                  ord("m"), CONTROL_MASK,
+                                                  ACCEL_VISIBLE)
+        self._showMonitorMenuItem.connect("toggled", self._toggleMonitorWindow)
+        viewMenu.append(self._showMonitorMenuItem)
+
+        showDebugMenuItem = gtk.CheckMenuItem()
+        showDebugMenuItem.set_label("Show _debug log")
+        showDebugMenuItem.set_use_underline(True)
+        showDebugMenuItem.set_active(False)
+        showDebugMenuItem.add_accelerator("activate", accelGroup,
+                                          ord("d"), CONTROL_MASK,
+                                          ACCEL_VISIBLE)
+        showDebugMenuItem.connect("toggled", self._toggleDebugLog)
+        viewMenu.append(showDebugMenuItem)
+
+        return menuBar
+
+    def _toggleDebugLog(self, menuItem):
+        """Toggle the debug log."""
+        if menuItem.get_active():
+            label = gtk.Label("_Debug log")
+            label.set_use_underline(True)
+            label.set_tooltip_text("Log with debugging information.")        
+            self._debugLogPage = self._notebook.append_page(self._debugLogWidget, label)
+            self._notebook.set_current_page(self._debugLogPage)
+        else:
+            self._notebook.remove_page(self._debugLogPage)
+
+    def _buildLogWidget(self):
+        """Build the widget for the log."""
+        alignment = gtk.Alignment(xscale = 1.0, yscale = 1.0)
+
+        alignment.set_padding(padding_top = 8, padding_bottom = 8,
+                              padding_left = 16, padding_right = 16)
 
         logScroller = gtk.ScrolledWindow()
-        self._logView = gtk.TextView()
-        self._logView.set_editable(False)
-        logScroller.add(self._logView)
+        # FIXME: these should be constants in common
+        logScroller.set_policy(gtk.PolicyType.AUTOMATIC if pygobject
+                               else gtk.POLICY_AUTOMATIC,
+                               gtk.PolicyType.AUTOMATIC if pygobject
+                               else gtk.POLICY_AUTOMATIC)
+        logScroller.set_shadow_type(gtk.ShadowType.IN if pygobject
+                                    else gtk.SHADOW_IN)
+        logView = gtk.TextView()
+        logView.set_editable(False)
+        logScroller.add(logView)
 
         logBox = gtk.VBox()
@@ -464,13 +546,13 @@
         logBox.set_size_request(-1, 200)
 
-        frameAlignment.add(logBox)
-
-        return logFrame
-
-    def _writeLog(self, msg):
+        alignment.add(logBox)
+
+        return (alignment, logView)
+
+    def _writeLog(self, msg, logView):
         """Write the given message to the log."""
-        buffer = self._logView.get_buffer()
+        buffer = logView.get_buffer()
         buffer.insert(buffer.get_end_iter(), msg)
-        self._logView.scroll_mark_onscreen(buffer.get_insert())
+        logView.scroll_mark_onscreen(buffer.get_insert())
 
     def _quit(self, what = None, force = False):
Index: src/mlx/gui/info.py
===================================================================
--- src/mlx/gui/info.py	(revision 90)
+++ src/mlx/gui/info.py	(revision 93)
@@ -43,4 +43,6 @@
         self._gui = gui
 
+        self._commentsAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
+                                                xscale = 1.0, yscale = 1.0)
         commentsBox = gtk.HBox()
 
@@ -51,5 +53,6 @@
         commentsBox.pack_start(frame, True, True, 8)
 
-        self.pack_start(commentsBox, True, True, 8)
+        self._commentsAlignment.add(commentsBox)
+        self.pack_start(self._commentsAlignment, True, True, 8)
 
         frame = gtk.Frame(label = "Delay codes")
@@ -108,9 +111,21 @@
         frame.add(alignment)
 
-        alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
-                                  xscale = 0.0, yscale = 0.0)
-        alignment.add(frame)
+        self._delayAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,
+                                             xscale = 0.0, yscale = 0.0)
+        self._delayAlignment.add(frame)
 
-        self.pack_start(alignment, False, False, 8)
+        self.pack_start(self._delayAlignment, False, False, 8)
+
+    def enable(self):
+        """Enable the flight info tab."""
+        #gobject.idle_add(self.set_sensitive, True)
+        self._commentsAlignment.set_sensitive(True)
+        self._delayAlignment.set_sensitive(True)
+        
+    def disable(self):
+        """Enable the flight info tab."""
+        #gobject.idle_add(self.set_sensitive, False)
+        self._commentsAlignment.set_sensitive(False)
+        self._delayAlignment.set_sensitive(False)
 
     def reset(self):
