Index: src/mlx/gui/flight.py
===================================================================
--- src/mlx/gui/flight.py	(revision 208)
+++ src/mlx/gui/flight.py	(revision 214)
@@ -375,4 +375,10 @@
         self.setMainWidget(alignment)
 
+        self._saveButton = self.addButton(xstr("flightsel_save"),
+                                          sensitive = False,
+                                          clicked = self._saveClicked,
+                                          tooltip = xstr("flightsel_save_tooltip"))
+        self._saveDialog = None
+
         self._refreshButton = self.addButton(xstr("flightsel_refresh"),
                                              sensitive = True,
@@ -419,4 +425,37 @@
                                 flight.arrivalICAO])
 
+    def _saveClicked(self, button):
+        """Called when the Save flight button is clicked."""
+        flight = self._getSelectedFlight()
+        date = flight.departureTime.date()
+        name = "%04d-%02d-%02d %s %s-%s.vaflight" % \
+               (date.year, date.month, date.day, flight.callsign,
+                flight.departureICAO, flight.arrivalICAO)
+
+        dialog = self._getSaveDialog()
+        dialog.set_current_name(name)
+        dialog.show_all()
+        response = dialog.run()
+        dialog.hide()
+
+        if response==RESPONSETYPE_OK:
+            fileName = dialog.get_filename()
+            print "Saving", fileName
+            try:
+                with open(fileName, "wt") as f:
+                    flight.writeIntoFile(f)
+            except Exception, e:
+                print "Failed to save flight:", str(e)
+                dialog = gtk.MessageDialog(parent = self._wizard.gui.mainWindow,
+                                           type = MESSAGETYPE_ERROR,
+                                           message_format =
+                                           xstr("flightsel_save_failed"))
+                dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
+                dialog.set_title(WINDOW_TITLE_BASE)
+                secondary = xstr("flightsel_save_failed_sec")
+                dialog.format_secondary_markup(secondary)
+                dialog.run()
+                dialog.hide()
+                
     def _refreshClicked(self, button):
         """Called when the refresh button is clicked."""
@@ -430,5 +469,7 @@
     def _selectionChanged(self, selection):
         """Called when the selection is changed."""
-        self._button.set_sensitive(selection.count_selected_rows()==1)
+        selected = selection.count_selected_rows()==1
+        self._saveButton.set_sensitive(selected)
+        self._button.set_sensitive(selected)
 
     def _loadButtonClicked(self, loadButton):
@@ -465,14 +506,18 @@
             self._wizard.jumpPage(self._nextDistance, finalize = False)
         else:
-            selection = self._flightList.get_selection()
-            (listStore, iter) = selection.get_selected()
-            path = listStore.get_path(iter)
-            [index] = path.get_indices() if pygobject else path
-
-            flight = self._flights[index]
+            flight = self._getSelectedFlight()
             self._wizard._bookedFlight = flight
             self._wizard.gui.enableFlightInfo()
 
             self._updateDepartureGate()
+
+    def _getSelectedFlight(self):
+        """Get the currently selected flight."""
+        selection = self._flightList.get_selection()
+        (listStore, iter) = selection.get_selected()
+        path = listStore.get_path(iter)
+        [index] = path.get_indices() if pygobject else path
+        
+        return self._flights[index]
         
     def _updateDepartureGate(self):
@@ -515,4 +560,34 @@
         self._wizard.jumpPage(2)
 
+    def _getSaveDialog(self):
+        """Get the dialog to load a flight file."""
+        if self._saveDialog is not None:
+            return self._saveDialog
+        
+        gui = self._wizard.gui
+        dialog = gtk.FileChooserDialog(title = WINDOW_TITLE_BASE + " - " +
+                                       xstr("flightsel_save_title"),
+                                       action = FILE_CHOOSER_ACTION_SAVE,
+                                       buttons = (gtk.STOCK_CANCEL,
+                                                  RESPONSETYPE_CANCEL,
+                                                  gtk.STOCK_OK, RESPONSETYPE_OK),
+                                       parent = gui.mainWindow)
+        dialog.set_modal(True)            
+        dialog.set_do_overwrite_confirmation(True)
+
+        filter = gtk.FileFilter()
+        filter.set_name(xstr("flightsel_filter_flights"))
+        filter.add_pattern("*.vaflight")
+        dialog.add_filter(filter)
+            
+        filter = gtk.FileFilter()
+        filter.set_name(xstr("file_filter_all"))
+        filter.add_pattern("*.*")
+        dialog.add_filter(filter)
+
+        self._saveDialog = dialog
+        
+        return dialog        
+    
     def _getLoadDialog(self):
         """Get the dialog to load a flight file."""
Index: src/mlx/i18n.py
===================================================================
--- src/mlx/i18n.py	(revision 208)
+++ src/mlx/i18n.py	(revision 214)
@@ -274,4 +274,13 @@
         self.add("flightsel_from", "From")
         self.add("flightsel_to", "To")
+        self.add("flightsel_save", "_Save flight")
+        self.add("flightsel_save_tooltip",
+                 "Click here to save the currently selected flight into "
+                 "a file that can be loaded later.")
+        self.add("flightsel_save_title", "Save a flight into a file")
+        self.add("flightsel_save_failed",
+                 "Could not save the flight into a file.")
+        self.add("flightsel_save_failed_sec",
+                 "Check the debug log for more details.")
         self.add("flightsel_refresh", "_Refresh flights")
         self.add("flightsel_refresh_tooltip",
Index: src/mlx/web.py
===================================================================
--- src/mlx/web.py	(revision 208)
+++ src/mlx/web.py	(revision 214)
@@ -151,5 +151,6 @@
                     elif key=="departure_time": departureTime = value
                     elif key=="arrival_time": arrivalTime = value
-                    elif key=="foglalas_id": pass
+                    elif key=="foglalas_id":
+                        self.id = None if value=="0" else value
                     elif key=="planetype": pass
                     else: lineOK = False
@@ -178,4 +179,28 @@
                 raise Exception("Attribute %s could not be read" % (attribute,))
             
+    def writeIntoFile(self, f):
+        """Write the flight into a file."""
+        print >> f, "callsign=%s" % (self.callsign,)
+        date = self.departureTime.date()
+        print >> f, "date=%04d-%02d-%0d" % (date.year, date.month, date.day)
+        print >> f, "dep_airport=%s" % (self.departureICAO,)
+        print >> f, "dest_airport=%s" % (self.arrivalICAO,)
+        print >> f, "planecode=%s" % \
+              (BookedFlight.TYPE2TYPECODE[self.aircraftType],)
+        print >> f, "tail_nr=%s" % (self.tailNumber,)
+        print >> f, "passenger=%d" % (self.numPassengers,)
+        print >> f, "crew=%d" % (self.numCrew,)
+        print >> f, "bag=%d" % (self.bagWeight,)
+        print >> f, "cargo=%d" % (self.cargoWeight,)
+        print >> f, "mail=%d" % (self.mailWeight,)
+        print >> f, "flight_route=%s" % (self.route,)
+        departureTime = self.departureTime
+        print >> f, "departure_time=%02d\\:%02d\\:%02d" % \
+              (departureTime.hour, departureTime.minute, departureTime.second)
+        arrivalTime = self.arrivalTime
+        print >> f, "arrival_time=%02d\\:%02d\\:%02d" % \
+              (arrivalTime.hour, arrivalTime.minute, arrivalTime.second)
+        print >> f, "foglalas_id=%s" % ("0" if self.id is None else self.id,)
+
     def _readAircraftType(self, f):
         """Read the aircraft type from the given file."""
