Index: MLXMANIFEST
===================================================================
--- MLXMANIFEST	(revision 158)
+++ MLXMANIFEST	(revision 166)
@@ -3,5 +3,5 @@
 library/encodings/euc_jis_2004.pyc	1694	e12bbd059d4fd595cf4be5440ab439c2
 library/fnmatch.pyc	3414	4d50000f78e903598af06ef1c5cfb3ef
-library/gtk/_gtk.pyc	549	324e9bf59f307c6f34abcd2e105af2a6
+library/gtk/_gtk.pyc	549	cce831fbbce661780e4aa4aee4005355
 library/encodings/cp858.pyc	7591	02054a0b8e91b9758826eb70cddf096f
 library/encodings/cp1254.pyc	2678	17ff2ac86f90886d5c73ed789f0499f3
@@ -12,5 +12,5 @@
 library/unittest/signals.pyc	2126	d574469ae3f8e3c3c6054c48e8ff6fe1
 library/pdb.pyc	41336	cca4477d622e897335b3f0cecb667ff4
-runmlx.exe	64000	8bcbc8f4c68b590c5ef010ad9580e1aa
+runmlx.exe	64000	488633e152c81c000e315cd0d74d6474
 library/xml/sax/xmlreader.pyc	17862	0362ded7016d21cdd85aea1170ebdda1
 library/encodings/latin_1.pyc	2111	52427573ccbfd06220b67d5a9dd1376e
@@ -58,6 +58,6 @@
 library/encodings/koi8_r.pyc	2700	fff1b35002b9e938b7ea6fd0fbe824ae
 library/mlx/gui/statusbar.pyc	4616	2909310114db08ca8d3162e70ef22519
-library/mlx/const.pyc	4972	de3904c521b27597d548bbc96ff14050
-library/mlx/fsuipc.pyc	53293	3e9f6032fd366882d0982f6fe4f48418
+library/mlx/const.pyc	4972	8b05e5b96077ed4c99eebd228f48db69
+library/mlx/fsuipc.pyc	53402	5c12463c240c8e90844490a9ff850168
 library/encodings/punycode.pyc	7570	335ff94e207934ae64e6f5fc07a5cacc
 library/encodings/shift_jisx0213.pyc	1710	1ec0383aafb1dcadb5f9b6afff16eb7f
@@ -95,5 +95,5 @@
 library/encodings/iso2022_jp_2004.pyc	1723	66376e788f3819e781897268c1100986
 library/encodings/cp866.pyc	8103	f36418dcf93b17b3ced63bd544f44159
-library/gio/_gio.pyc	549	b623cbe0dd5f229d582bb55841557361
+library/gio/_gio.pyc	549	014ddc5612d5ab5e06a303cfa0bcf0e9
 library/encodings/cp437.pyc	7874	63f1278c0a66129c6fb4f504d6b61b66
 library/mimetools.pyc	7837	c9accd6ef795bf71c90630be0161cadc
@@ -123,5 +123,5 @@
 library/encodings/cp864.pyc	7999	ca90afae086cb6b8f69b8419cc3cd1cb
 library/pyexpat.pyd	152576	5a82e9ec95005aca6130751e5b961cc3
-library/pyexpat.pyc	546	e0bf8ea119e513f8a72142c6d04852e7
+library/pyexpat.pyc	546	28db9f4e93d106aa021b40423032f06b
 library/unittest/loader.pyc	10884	591a785be23fba35582ce33bdd3d7acd
 library/ftplib.pyc	32043	5a1925388a0874e459aed6891f4cf0c1
@@ -130,5 +130,5 @@
 library/unittest/suite.pyc	9838	bf2c79bd4a6b6032f1ea53fa4908748f
 library/encodings/mac_arabic.pyc	7824	820deef79b02e1f7e52eb18e9be655bf
-library/mlx/gui/prefs.pyc	13030	3c3d1fe199deb11859b67dc920c0e13d
+library/mlx/gui/prefs.pyc	13053	0d5dbe8afbb8fab7b2be1840781e8db2
 library/encodings/tis_620.pyc	2748	5969b4db4f967b11ae7992cdfbf5890e
 library/encodings/cp855.pyc	8071	0a4259ba854c24186f2ce61d85883b4a
@@ -157,5 +157,5 @@
 library/encodings/iso8859_10.pyc	2693	5e6cc8f721486ddbc1c99da285e13191
 library/mlx/config.pyc	12010	7a138f5b96c513912e8e0686f5c5fbaa
-library/atk.pyc	534	fa86d691ae7b8d042fd5b3c33549cabe
+library/atk.pyc	534	fe3e307a78a9cc4bce684d7bdf816dff
 library/gio._gio.pyd	263168	acb8c95fdc391079bebdf7d8685b0dbc
 library/encodings/cp861.pyc	7868	c97a8970ce4d9f40cbafbea6576fbdca
@@ -174,7 +174,7 @@
 library/encodings/iso8859_6.pyc	2723	c8f9aa14a6a2ebf05d977317114bc65d
 library/libpango-1.0-0.dll	333729	5a14efd93ee27cfe960220fe4a904911
-library/mlx/gui/gui.pyc	36341	6eeaa07fcbd8a89bf7e598087c666ee1
+library/mlx/gui/gui.pyc	36364	2050500c35abdb515d17daf894d29320
 library/stat.pyc	2503	d3b6dc7a54e705219f04d0be75a212de
-library/gobject/_gobject.pyc	573	a37d7d8cb4f70b0f09ab615b993ea70c
+library/gobject/_gobject.pyc	573	891881fc921b55eb6436b850d5bf668a
 library/encodings/utf_7.pyc	1747	2beeb059236527197d6c640396476ce8
 library/atexit.pyc	2083	595a09be339c73c3c02e378d99325d2a
@@ -184,8 +184,8 @@
 library/encodings/iso8859_1.pyc	2678	f09ec3b7f6a348cbd7f7286b60572bd0
 library/pangocairo.pyd	17920	5fc69a7d29a6d3127710c64de440daa4
-library/pangocairo.pyc	555	9a662f4c2634358c694d6833a0553304
+library/pangocairo.pyc	555	f23a6733ab8c9132c1c6791714240df2
 library/sre.pyc	499	92bb633daa0bab6550ec0e3677673b5b
 library/tokenize.pyc	13565	354d02cd79df187a28c1851a1e3bad96
-library/mlx/gui/flight.pyc	85395	f5ec8303901df37eedc2c0667a087c07
+library/mlx/gui/flight.pyc	85418	86f3c4ba458413deabd618aa67421374
 library/lib/gtk-2.0/2.10.0/engines/libwimp.dll	97984	a5bbbe46e1363aba9020a76f2d58e9d6
 library/email/quoprimime.pyc	8590	f6c7a8ad81d44037dd074f4871053dab
@@ -195,5 +195,5 @@
 library/gtk._gtk.pyd	1882624	bbb1d1e41bbebc6abf69bed719d50497
 library/_hashlib.pyd	287232	a1a18de0644f481749fcbcf26005eeaf
-library/_hashlib.pyc	549	b44386b428f16d1b172e6b57cbc6e8de
+library/_hashlib.pyc	549	b0f9228e2299a7272830effaa43a4377
 library/copy.pyc	11674	30d1745c5e38ab170f8a0486fbebf305
 library/unittest/result.pyc	7444	aefbb3cc79c0ff17787ce84faed7f5e8
@@ -207,5 +207,5 @@
 library/ctypes/__init__.pyc	18846	2bd183962453ae93d6887b303d3fd338
 library/mlx/acars.pyc	1690	06ac9e4ad5cc96b831a3c69868e6145a
-library/cairo/_cairo.pyc	561	5785a244ecd7cfe65c2a27738ab4de48
+library/cairo/_cairo.pyc	561	6622b2b68a65815534f741644f28467a
 library/warnings.pyc	12666	9788b5f45765e8204e04c820f2711094
 library/encodings/iso2022_jp_1.pyc	1699	faed9d5747e982cec9fa8b3ad8e1de26
@@ -225,14 +225,14 @@
 library/bz2.pyd	76800	1ca9ececd2c84b80996fe632627f857f
 library/encodings/iso8859_16.pyc	2695	85e819a29dec2b601ce978dcd5a040fc
-library/bz2.pyc	534	96169408e5e34b63e6395ee84d6400de
+library/bz2.pyc	534	2dacc1f67ce6f4b8bef18fddbc30c9de
 library/email/utils.pyc	8840	a7be428df6fddee6121cfce55382d1f8
-library/_ssl.pyc	537	daeef57719226ef9d0bc44ad8a6b06ed
+library/_ssl.pyc	537	a5ad680df66cce9aa48b31a6396e6d12
 library/encodings/cp1250.pyc	2676	c92e287a2aa6a1c924df287d826aa3b7
 library/_ssl.pyd	720896	90826a140137efd0d806038828e16f8e
-library/pango.pyc	540	1e5a976d1817680edb7c1c21ff48892d
+library/pango.pyc	540	e3fcfc3d867e92c2c7416ef6dc684d58
 library/glib/__init__.pyc	187	d44c8c2772b263a36726ac0dcfc04b42
 library/pango.pyd	111616	c934763bdf125c3dc92b56db817001d4
 library/libgobject-2.0-0.dll	341594	356d697647a480562c4e2e921b13f8ed
-mlxupdate.exe	19456	d8eadc14204f8dd84f8ac703de608f02
+mlxupdate.exe	19456	e4a2240eacdc2647c90656899310c6f8
 library/email/errors.pyc	3229	cdb78ab237e195ad69f059128bc03b1d
 library/linecache.pyc	3091	666e6f81b0ea9a7637f8068493f738d5
@@ -250,5 +250,5 @@
 library/encodings/mbcs.pyc	1883	2213911a7dd0deada6799b63e18b695b
 library/unicodedata.pyd	688128	c856c31a03dc892e4f2aee93d0bfee44
-library/unicodedata.pyc	558	b025c9579740ae143839a018b5da0e79
+library/unicodedata.pyc	558	4289806e666e46e891fceb60a20b894e
 library/encodings/cp1256.pyc	2675	c1bf26ed9c9b5ee0eec495138993cffb
 library/email/base64mime.pyc	5221	c536d6f0c03f029bba77f15ef6ba3d99
@@ -309,14 +309,14 @@
 library/encodings/koi8_u.pyc	2686	b7e5a52eaaaf6b340075b40dc7596f42
 library/atk.pyd	208384	ebe7f0929eac23a3205d17d69906e172
-library/_ctypes.pyc	546	9f86310b686c3061d75bdd32ec1f4ff8
+library/_ctypes.pyc	546	3b2a84ea4d020180b585c738bf78cec1
 library/mlx/update.pyc	16214	1927a43ac4580370198b6d2f091f835f
 library/subprocess.pyc	38648	c9f749db06dfc9fb32079de51d6efd01
 library/encodings/utf_16_le.pyc	1854	dfa68705c26fd303adfc7ce3322166f2
 library/_socket.pyd	38400	5d273be76603399e88cf57f2605004bf
-library/_socket.pyc	546	ba16b5802151bed5e05fe83d11f2b92c
+library/_socket.pyc	546	7b1bd8f25e4e763ce7a2163c657aa4d3
 library/encodings/hex_codec.pyc	3520	a8b8d5b7c8810379c7007bcbc253951c
 library/tempfile.pyc	18526	e2cc2d63c29e15f20ee9325e790643a3
-library/glib/_glib.pyc	555	6157f7df91d682da07475a99f05d19b2
-library/win32api.pyc	549	d33834386641fd02adce67fe64a1cd2a
+library/glib/_glib.pyc	555	b1fd18ba441a3ec8e55f93ebe9aa659a
+library/win32api.pyc	549	3228c4576e9659f1af7ff11114e2a90c
 library/encodings/iso8859_13.pyc	2696	f901ae0bbcfbb78f0c1783e89b2e2dc5
 library/zlib1.dll	100352	d90dad5eea33a178bac56fff2847d4c2
@@ -330,12 +330,12 @@
 library/xml/sax/saxutils.pyc	12382	32ed045b3b520234ebea6a508a6569fe
 library/encodings/mac_turkish.pyc	2739	1682e228ddfd2e74e3ccaee0b65e7261
-library/mlx/pyuipc_sim.pyc	43532	fe15a7610a4058a4059a09bb2e91bccf
+library/mlx/pyuipc_sim.pyc	43607	eecadfd81467b977dc4a4ae2b05c487f
 library/encodings/cp875.pyc	2636	c72faa5d1cb6105ae81c971448fea479
 library/socket.pyc	15488	35f8eb455d6d8df8e19826d1dd7193f2
-library/select.pyc	543	bde5d0dccea956e8408f692d35755f8b
+library/select.pyc	543	7c963d4085711e3cb6cb745bf936ef58
 library/encodings/iso2022_jp.pyc	1683	40c2b92127f99452f84b250c2b4b2cda
 library/libgthread-2.0-0.dll	44287	7ad6f303082b382bff7bafbab246c61f
 library/select.pyd	11776	d90bf525f9f6c9c3aa6532fa6e569b4f
-library/pyuipc.pyc	543	96b93d674c4f8ee6a8feac09af40b25f
+library/pyuipc.pyc	543	2d50c10362e28900a8761a170f9c5061
 library/pyuipc.pyd	129220	58cdce7763687f456383c93fd3404d9f
 library/encodings/johab.pyc	1638	5346c11a863ffbcfb21aba8f1d2236b7
Index: notes.txt
===================================================================
--- notes.txt	(revision 107)
+++ notes.txt	(revision 166)
@@ -41,2 +41,73 @@
         Alt+K: Kapuk
         
+-------------------------------------------------------------------------------
+
+Sounds
+------
+
+- sikoly.mp3: vs<-6000 | vs>6000, and is not playing
+
+- board.mp3: stage==BOARDING, not played yet, and pilot either pressed
+  hot key, or !pilotControlsSounds and 10s after the start of the boarding
+
+- malev.mp3: stage==PUSHANDTAXI, pilotControlsSounds && hotkey || 
+  !pilotControlsSounds && gs>5,
+  played only when board.mp3 was finished (if started at all), 
+  followed by XXXtaxi.mp3, when finished
+
+- cpt_takeoff.mp3: stage==TAKEOFF && (langingLights on || gs>80)
+
+- TOC.mp3: stage==CRUISE && (pilotControlsSounds && hotkey || 
+                             !pilotControlsSounds)
+
+- TOD.mp3: stage==DESCEND && (pilotControlsSounds && hotkey ||
+                              !pilotControlsSounds && altitude<15000)
+
+- TaxiAfterLand.mp3: stage==TAXIAFTERLAND && (pilotControlsSounds && hotkey ||
+                                              !pilotControlsSounds && timeSinceStage>10)
+
+- (notnormal.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+                   gs<40 && flown distance<0.404
+
+- (2500.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+              radioAltitude<2500
+
+- (700.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+              radioAltitude<700
+
+- (1200.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+              radioAltitude<1200
+
+- (1800.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+              radioAltitude<1800
+
+- (500.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+             radioAltitude<500
+
+- (200.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+             radioAltitude<200
+
+- (20.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+            radioAltitude<500
+
+- (atTD.mp3): approachCallouts && stage in [DESCEND, LANDING, TAXIAFTERLAND] &&
+              isOnTheGround
+
+- taps.mp3: 2 sec after touchdown, if T/D rate<150
+
+- cpt_landing.mp3: ????
+
+- notam.mp3: when the briefing window is displayed for the first time
+
+- notify.wav: for VISIBILITY message if sounds are enabled for that
+
+- speed.mp3: stage==LANDING, spoiler moves, speedbrake sound selected
+
+- Checklists:
+  - there are directories named checklist_<type>
+  - each directory contains a file named checklist.txt which is a list of
+    the sound files comprising the check list
+  - if a check list set is enabled and selected, its items are played
+    on-by-one as the second hot key is pressed
+
+  
Index: src/mlx/config.py
===================================================================
--- src/mlx/config.py	(revision 156)
+++ src/mlx/config.py	(revision 166)
@@ -20,4 +20,33 @@
     _languageMap = { "en_GB" : "eng",
                      "hu_HU" : "hun" }
+
+#-------------------------------------------------------------------------------
+
+class Hotkey(object):
+    """A hotkey."""
+    def __init__(self, ctrl = False, shift = False, key = "0"):
+        """Construct the hotkey."""
+        self.ctrl = ctrl
+        self.shift = shift
+        self.key = key
+
+    def set(self, s):
+        """Set the hotkey from the given string."""
+        self.ctrl = "C" in s[:-1]
+        self.shift = "S" in s[:-1]
+        self.key = s[-1]
+
+    def __eq__(self, other):
+        """Check if the given hotkey is equal to the other one."""
+        return self.ctrl == other.ctrl and self.shift == other.shift and \
+               self.key == other.key
+
+    def __str__(self):
+        """Construct the hotkey to a string."""
+        s = ""
+        if self.ctrl: s += "C"
+        if self.shift: s += "S"
+        s += self.key
+        return s
 
 #-------------------------------------------------------------------------------
@@ -44,5 +73,16 @@
 
         self._pirepDirectory = None
-        
+
+        self._enableSounds = True
+
+        self._pilotControlsSounds = True
+        self._pilotHotkey = Hotkey(ctrl = True, shift = False, key = "0")
+
+        #self._approachCallOuts = False
+        self._speedbrakeAtTD = True
+
+        self._enableChecklists = False
+        self._checklistHotkey = Hotkey(ctrl = True, shift = True, key = "0")
+                
         self._autoUpdate = True        
         self._updateURL = Config.DEFAULT_UPDATE_URL
@@ -196,4 +236,88 @@
            self._messageTypeLevels[messageType]!=level:
             self._messageTypeLevels[messageType] = level
+            self._modified = True
+
+    @property
+    def enableSounds(self):
+        """Get whether background sounds are enabled."""
+        return self._enableSounds
+
+    @enableSounds.setter
+    def enableSounds(self, enableSounds):
+        """Set whether background sounds are enabled."""
+        if enableSounds!=self._enableSounds:
+            self._enableSounds = enableSounds
+            self._modified = True
+
+    @property 
+    def pilotControlsSounds(self):
+        """Get whether the pilot controls the background sounds."""
+        return self._pilotControlsSounds
+
+    @pilotControlsSounds.setter
+    def pilotControlsSounds(self, pilotControlsSounds):
+        """Set whether the pilot controls the background sounds."""
+        if pilotControlsSounds!=self._pilotControlsSounds:
+            self._pilotControlsSounds = pilotControlsSounds
+            self._modified = True
+
+    @property
+    def pilotHotkey(self):
+        """Get the pilot's hotkey."""
+        return self._pilotHotkey
+
+    @pilotHotkey.setter
+    def pilotHotkey(self, pilotHotkey):
+        """Set the pilot's hotkey."""
+        if pilotHotkey!=self._pilotHotkey:
+            self._pilotHotkey = pilotHotkey
+            self._modified = True
+
+    # @property
+    # def approachCallOuts(self):
+    #     """Get whether the approach callouts should be played."""
+    #     return self._approachCallOuts
+
+    # @approachCallOuts.setter
+    # def approachCallOuts(self, approachCallOuts):
+    #     """Set whether the approach callouts should be played."""
+    #     if approachCallOuts!=self._approachCallOuts:
+    #         self._approachCallOuts = approachCallOuts
+    #         self._modified = True
+
+    @property
+    def speedbrakeAtTD(self):
+        """Get whether the speedbrake sounds should be played at touchdown."""
+        return self._speedbrakeAtTD
+
+    @speedbrakeAtTD.setter
+    def speedbrakeAtTD(self, speedbrakeAtTD):
+        """Set whether the speedbrake sounds should be played at touchdown."""
+        if speedbrakeAtTD!=self._speedbrakeAtTD:
+            self._speedbrakeAtTD = speedbrakeAtTD
+            self._modified = True
+        
+    @property
+    def enableChecklists(self):
+        """Get whether aircraft-specific checklists should be played."""
+        return self._enableChecklists
+
+    @enableChecklists.setter
+    def enableChecklists(self, enableChecklists):
+        """Get whether aircraft-specific checklists should be played."""
+        if enableChecklists!=self._enableChecklists:
+            self._enableChecklists = enableChecklists
+            self._modified = True
+
+    @property
+    def checklistHotkey(self):
+        """Get the checklist hotkey."""
+        return self._checklistHotkey
+
+    @checklistHotkey.setter
+    def checklistHotkey(self, checklistHotkey):
+        """Set the checklist hotkey."""
+        if checklistHotkey!=self._checklistHotkey:
+            self._checklistHotkey = checklistHotkey
             self._modified = True
 
@@ -254,4 +378,20 @@
             self._messageTypeLevels[messageType] = \
                 self._getMessageTypeLevel(config, messageType)
+
+        self._enableSounds = self._getBoolean(config, "sounds",
+                                              "enable", True)
+        self._pilotControlsSounds = self._getBoolean(config, "sounds",
+                                                     "pilotControls", True)
+        self._pilotHotkey.set(self._get(config, "sounds",
+                                        "pilotHotkey", "C0"))
+        #self._approachCallOuts = self._getBoolean(config, "sounds",
+        #                                          "approachCallOuts", False)
+        self._speedbrakeAtTD = self._getBoolean(config, "sounds",
+                                                "speedbrakeAtTD", True)
+
+        self._enableChecklists = self._getBoolean(config, "sounds",
+                                                  "enableChecklists", False)
+        self._checklistHotkey.set(self._get(config, "sounds",
+                                            "checklistHotkey", "CS0"))
             
         self._autoUpdate = self._getBoolean(config, "update", "auto", True)
@@ -298,4 +438,20 @@
                 config.set(Config._messageTypesSection, option,
                            const.messageLevel2string(level))
+
+        config.add_section("sounds")
+        config.set("sounds", "enable",
+                   "yes" if self._enableSounds else "no")
+        config.set("sounds", "pilotControls",
+                   "yes" if self._pilotControlsSounds else "no")
+        config.set("sounds", "pilotHotkey", str(self._pilotHotkey))
+        #config.set("sounds", "approachCallOuts",
+        #           "yes" if self._approachCallOuts else "no")
+        config.set("sounds", "speedbrakeAtTD",
+                   "yes" if self._speedbrakeAtTD else "no")
+
+        config.set("sounds", "enableChecklists",
+                   "yes" if self._enableChecklists else "no")
+        config.set("sounds", "checklistHotkey",
+                   str(self._checklistHotkey))
         
         config.add_section("update")
Index: src/mlx/gui/prefs.py
===================================================================
--- src/mlx/gui/prefs.py	(revision 164)
+++ src/mlx/gui/prefs.py	(revision 166)
@@ -7,6 +7,79 @@
 from mlx.i18n import xstr
 import mlx.const as const
+import mlx.config as config
 
 import urlparse
+
+#------------------------------------------------------------------------------
+
+class Hotkey(gtk.HBox):
+    """A widget to handle a hotkey."""
+    def __init__(self, labelText, tooltips):
+        """Construct the hotkey widget.
+
+        labelText is the text for the label before the hotkey.
+
+        The tooltips parameter is an array of the tooltips for:
+        - the hotkey combo box,
+        - the control check box, and
+        - the shift check box."""
+        super(Hotkey, self).__init__()
+        
+        label = gtk.Label(labelText)
+        label.set_use_underline(True)
+        labelAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
+                                       xscale = 0.0, yscale = 0.0)
+        labelAlignment.add(label)
+        self.pack_start(labelAlignment, False, False, 8)
+
+        self._ctrl = gtk.CheckButton("Ctrl")
+        self._ctrl.set_tooltip_text(tooltips[1])
+        self.pack_start(self._ctrl, False, False, 4)
+            
+        self._shift = gtk.CheckButton("Shift")
+        self._shift.set_tooltip_text(tooltips[2])
+        self.pack_start(self._shift, False, False, 4)
+
+        self._hotkeyModel = gtk.ListStore(str)
+        for keyCode in range(ord("0"), ord("9")) + range(ord("A"), ord("Z")):
+            self._hotkeyModel.append([chr(keyCode)])
+
+        self._hotkey = gtk.ComboBox(model = self._hotkeyModel)
+        cell = gtk.CellRendererText()
+        self._hotkey.pack_start(cell, True)
+        self._hotkey.add_attribute(cell, 'text', 0)
+        self._hotkey.set_tooltip_text(tooltips[0])
+        self.pack_start(self._hotkey, False, False, 4)
+
+        self._setting = False
+
+    def set(self, hotkey):
+        """Set the hotkey widget from the given hotkey."""
+        self._setting = True
+
+        self._ctrl.set_active(hotkey.ctrl)
+        self._shift.set_active(hotkey.shift)
+
+        hotkeyModel = self._hotkeyModel
+        iter = hotkeyModel.get_iter_first()
+        while iter is not None and \
+              hotkeyModel.get_value(iter, 0)!=hotkey.key:
+            iter = hotkeyModel.iter_next(iter)
+
+        if iter is None:
+            iter = hotkeyModel.get_iter_first()
+
+        self._hotkey.set_active_iter(iter)            
+        
+        self._setting = False
+
+    def get(self):
+        """Get a hotkey corresponding to the settings in the widghet."""
+
+        key = self._hotkeyModel.get_value(self._hotkey.get_active_iter(), 0)
+
+        return config.Hotkey(ctrl = self._ctrl.get_active(),
+                             shift = self._shift.get_active(),
+                             key = key)
 
 #------------------------------------------------------------------------------
@@ -25,4 +98,5 @@
         
         self._gui = gui
+        self._settingFromConfig = False
 
         contentArea = self.get_content_area()
@@ -42,4 +116,10 @@
         label.set_tooltip_text(xstr("prefs_tab_message_tooltip"))
         notebook.append_page(messages, label)
+
+        sounds = self._buildSounds()
+        label = gtk.Label(xstr("prefs_tab_sounds"))
+        label.set_use_underline(True)
+        label.set_tooltip_text(xstr("prefs_tab_sounds_tooltip"))
+        notebook.append_page(sounds, label)
 
         advanced = self._buildAdvanced()
@@ -66,4 +146,6 @@
     def _fromConfig(self, config):
         """Setup the dialog from the given configuration."""
+        self._settingFromConfig = True
+
         self._setLanguage(config.language)
         self._hideMinimizedWindow.set_active(config.hideMinimizedWindow)
@@ -86,11 +168,20 @@
                               level == const.MESSAGELEVEL_BOTH)
 
-        self._togglingAutoUpdate = True
+        self._enableSounds.set_active(config.enableSounds)
+        self._pilotControlsSounds.set_active(config.pilotControlsSounds)
+        self._pilotHotkey.set(config.pilotHotkey)
+        #self._approachCallOuts.set_active(config.approachCallOuts)
+        self._speedbrakeAtTD.set_active(config.speedbrakeAtTD)
+
+        self._enableChecklists.set_active(config.enableChecklists)        
+        self._checklistHotkey.set(config.checklistHotkey)
+
         self._autoUpdate.set_active(config.autoUpdate)
-        self._togglingAutoUpdate = False
         if not config.autoUpdate:
             self._warnedAutoUpdate = True
 
         self._updateURL.set_text(config.updateURL)
+
+        self._settingFromConfig = False
 
     def _toConfig(self, config):
@@ -115,4 +206,13 @@
                 level = const.MESSAGELEVEL_NONE
             config.setMessageTypeLevel(messageType, level)
+
+        config.enableSounds = self._enableSounds.get_active()
+        config.pilotControlsSounds = self._pilotControlsSounds.get_active()
+        config.pilotHotkey = self._pilotHotkey.get()
+        #config.approachCallOuts = self._approachCallOuts.get_active()
+        config.speedbrakeAtTD = self._speedbrakeAtTD.get_active()
+
+        config.enableChecklists = self._enableChecklists.get_active()
+        config.checklistHotkey = self._checklistHotkey.get()
 
         config.autoUpdate = self._autoUpdate.get_active()
@@ -330,5 +430,101 @@
 
         return True
-            
+
+    def _buildSounds(self):
+        """Build the page for the sounds."""
+        mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
+                                      xscale = 1.0, yscale = 1.0)
+        mainAlignment.set_padding(padding_top = 8, padding_bottom = 8,
+                                  padding_left = 4, padding_right = 4)
+
+        mainBox = gtk.VBox()
+        mainAlignment.add(mainBox)
+
+        backgroundFrame = gtk.Frame(label = xstr("prefs_sounds_frame_bg"))
+        mainBox.pack_start(backgroundFrame, False, False, 4)
+
+        backgroundAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
+                                            xscale = 1.0, yscale = 0.0)
+        backgroundAlignment.set_padding(padding_top = 4, padding_bottom = 4,
+                                        padding_left = 4, padding_right = 4)
+        backgroundFrame.add(backgroundAlignment)
+
+        backgroundBox = gtk.VBox()
+        backgroundAlignment.add(backgroundBox)
+
+        self._enableSounds = gtk.CheckButton(xstr("prefs_sounds_enable"))
+        self._enableSounds.set_use_underline(True)
+        self._enableSounds.set_tooltip_text(xstr("prefs_sounds_enable_tooltip"))
+        self._enableSounds.connect("toggled", self._enableSoundsToggled)
+        alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
+                                  xscale = 1.0, yscale = 0.0)
+        alignment.add(self._enableSounds)
+        backgroundBox.pack_start(alignment, False, False, 4)
+
+        self._pilotControlsSounds = gtk.CheckButton(xstr("prefs_sounds_pilotControls"))
+        self._pilotControlsSounds.set_use_underline(True)
+        self._pilotControlsSounds.set_tooltip_text(xstr("prefs_sounds_pilotControls_tooltip"))
+        backgroundBox.pack_start(self._pilotControlsSounds, False, False, 4)
+
+        self._pilotHotkey = Hotkey(xstr("prefs_sounds_pilotHotkey"),
+                                   [xstr("prefs_sounds_pilotHotkey_tooltip"),
+                                    xstr("prefs_sounds_pilotHotkeyCtrl_tooltip"),
+                                    xstr("prefs_sounds_pilotHotkeyShift_tooltip")])
+        
+        backgroundBox.pack_start(self._pilotHotkey, False, False, 4)
+
+        # self._approachCallOuts = gtk.CheckButton(xstr("prefs_sounds_approachCallOuts"))
+        # self._approachCallOuts.set_use_underline(True)
+        # self._approachCallOuts.set_tooltip_text(xstr("prefs_sounds_approachCallOuts_tooltip"))
+        # backgroundBox.pack_start(self._approachCallOuts, False, False, 4)
+        
+        self._speedbrakeAtTD = gtk.CheckButton(xstr("prefs_sounds_speedbrakeAtTD"))
+        self._speedbrakeAtTD.set_use_underline(True)
+        self._speedbrakeAtTD.set_tooltip_text(xstr("prefs_sounds_speedbrakeAtTD_tooltip"))
+        backgroundBox.pack_start(self._speedbrakeAtTD, False, False, 4)
+
+        checklistFrame = gtk.Frame(label = xstr("prefs_sounds_frame_checklists"))
+        mainBox.pack_start(checklistFrame, False, False, 4)
+
+        checklistAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
+                                           xscale = 1.0, yscale = 0.0)
+        checklistAlignment.set_padding(padding_top = 4, padding_bottom = 4,
+                                       padding_left = 4, padding_right = 4)
+        checklistFrame.add(checklistAlignment)
+
+        checklistBox = gtk.VBox()
+        checklistAlignment.add(checklistBox)
+        
+        self._enableChecklists = gtk.CheckButton(xstr("prefs_sounds_enableChecklists"))
+        self._enableChecklists.set_use_underline(True)
+        self._enableChecklists.set_tooltip_text(xstr("prefs_sounds_enableChecklists_tooltip"))
+        self._enableChecklists.connect("toggled", self._enableChecklistsToggled)
+        checklistBox.pack_start(self._enableChecklists, False, False, 4)
+
+        self._checklistHotkey = Hotkey(xstr("prefs_sounds_checklistHotkey"),
+                                       [xstr("prefs_sounds_checklistHotkey_tooltip"),
+                                        xstr("prefs_sounds_checklistHotkeyCtrl_tooltip"),
+                                        xstr("prefs_sounds_checklistHotkeyShift_tooltip")])
+
+        checklistBox.pack_start(self._checklistHotkey, False, False, 4)
+
+        self._enableSoundsToggled(self._enableSounds)
+        self._enableChecklistsToggled(self._enableChecklists)
+
+        return mainAlignment
+
+    def _enableSoundsToggled(self, button):
+        """Called when the enable sounds button is toggled."""
+        active = button.get_active()
+        self._pilotControlsSounds.set_sensitive(active)
+        self._pilotHotkey.set_sensitive(active)
+        #self._approachCallOuts.set_sensitive(active)
+        self._speedbrakeAtTD.set_sensitive(active)
+
+    def _enableChecklistsToggled(self, button):
+        """Called when the enable checklists button is toggled."""
+        active = button.get_active()
+        self._checklistHotkey.set_sensitive(active)
+
     def _buildAdvanced(self):
         """Build the page for the advanced settings."""
@@ -348,5 +544,4 @@
         self._autoUpdate.set_tooltip_text(xstr("prefs_update_auto_tooltip"))
         self._warnedAutoUpdate = False
-        self._togglingAutoUpdate = False
         
         updateURLBox = gtk.HBox()
@@ -379,5 +574,5 @@
     def _autoUpdateToggled(self, button):
         """Called when the auto update check button is toggled."""
-        if not self._togglingAutoUpdate and not self._warnedAutoUpdate and \
+        if not self._settingFromConfig and not self._warnedAutoUpdate and \
            not self._autoUpdate.get_active():
             dialog = gtk.MessageDialog(parent = self,
Index: src/mlx/i18n.py
===================================================================
--- src/mlx/i18n.py	(revision 155)
+++ src/mlx/i18n.py	(revision 166)
@@ -568,4 +568,7 @@
         self.add("prefs_tab_message_tooltip",
                  "Enable/disable message notifications in FS and/or by sound")
+        self.add("prefs_tab_sounds", "_Sounds")
+        self.add("prefs_tab_sounds_tooltip",
+                 "Preferences regarding what sounds should be played during the various flight stages")
         self.add("prefs_tab_advanced", "_Advanced")
         self.add("prefs_tab_advanced_tooltip",
@@ -604,5 +607,5 @@
                  "from timestamps returned by the simulator.")
         self.add("prefs_syncFSTime",
-                 "_Synchronize the time in FS with the computer's clock")
+                 "S_ynchronize the time in FS with the computer's clock")
         self.add("prefs_syncFSTime_tooltip",
                  "If this is checked the flight simulator's internal clock "
@@ -615,4 +618,58 @@
         self.add("prefs_pirepDirectory_browser_title",
                  "Select PIREP directory")
+
+        self.add("prefs_sounds_frame_bg", "Background")
+        self.add("prefs_sounds_enable",
+                 "_Enable background sounds")
+        self.add("prefs_sounds_enable_tooltip",
+                 "If the background sounds are enabled, the logger "
+                 "can play different pre-recorded sounds during the "
+                 "various stages of the flight.")
+        self.add("prefs_sounds_pilotControls",
+                 "_Pilot controls the sounds")
+        self.add("prefs_sounds_pilotControls_tooltip",
+                 "If checked, the background sounds can be started by the "
+                 "pilot by pressing the hotkey specified below. Otherwise "
+                 "the sounds will start automatically when certain "
+                 "conditions hold.")
+        self.add("prefs_sounds_pilotHotkey",
+                 "_Hotkey:")
+        self.add("prefs_sounds_pilotHotkey_tooltip",
+                 "The key to press possibly together with modifiers to play "
+                 "the sound relevant to the current flight status.")
+        self.add("prefs_sounds_pilotHotkeyCtrl_tooltip",
+                 "If checked, the Ctrl key should be pressed together with the "
+                 "main key.")
+        self.add("prefs_sounds_pilotHotkeyShift_tooltip",
+                 "If checked, the Shift key should be pressed together with the "
+                 "main key.")
+        self.add("prefs_sounds_approachCallOuts",
+                 "Enable approach callouts")
+        self.add("prefs_sounds_approachCallOuts_tooltip",
+                 "If checked, the approach callouts will be played at "
+                 "certain altitudes.")
+        self.add("prefs_sounds_speedbrakeAtTD",
+                 "Enable speed_brake sound at touchdown")
+        self.add("prefs_sounds_speedbrakeAtTD_tooltip",
+                 "If checked, a speedbrake sound will be played after "
+                 "touchdown, when the speedbrakes deploy.")
+        self.add("prefs_sounds_frame_checklists", "Checklists")
+        self.add("prefs_sounds_enableChecklists",
+                 "E_nable aircraft-specific checklists")
+        self.add("prefs_sounds_enableChecklists_tooltip",
+                 "If checked, the program will play back pre-recorded "
+                 "aircraft-specific checklists at the pilot's discretion.")
+        self.add("prefs_sounds_checklistHotkey",
+                 "Checklist hot_key:")
+        self.add("prefs_sounds_checklistHotkey_tooltip",
+                 "The key to press possibly together with modifiers to play the next "
+                 "checklist item.")
+        self.add("prefs_sounds_checklistHotkeyCtrl_tooltip",
+                 "If checked, the Ctrl key should be pressed together with the "
+                 "main key.")
+        self.add("prefs_sounds_checklistHotkeyShift_tooltip",
+                 "If checked, the Shift key should be pressed together with the "
+                 "main key.")
+        
         self.add("prefs_update_auto", "Update the program auto_matically")
         self.add("prefs_update_auto_tooltip",
