source: src/mlx/config.py@ 377:72893c2b24d9

Last change on this file since 377:72893c2b24d9 was 373:cf2b6b8a3973, checked in by István Váradi <ivaradi@…>, 12 years ago

Added support for a secondary instance (#157)

File size: 31.1 KB
Line 
1# -*- encoding: utf-8 -*-
2
3import const
4from util import secondaryInstallation
5
6import os
7import sys
8import traceback
9import ConfigParser
10
11## @package mlx.config
12#
13# The handling of the configuration.
14#
15# The \ref Config class contains the main configuration and is capable of
16# loading and saving the configuration. It contains getters and setters for the
17# configuration options.
18#
19# Some parts of the configuration are not simple data items, like strings or
20# booleans, but more complicated data. These have their own class, like \ref
21# ApproachCallouts or \ref Checklist.
22
23#-------------------------------------------------------------------------------
24
25configPath = os.path.join(os.path.expanduser("~"),
26 "mlx.config" if os.name=="nt" else ".mlxrc") + \
27 ("-secondary" if secondaryInstallation else "")
28
29#-------------------------------------------------------------------------------
30
31if os.name=="nt":
32 _languageMap = { "en_GB" : "eng",
33 "hu_HU" : "hun" }
34
35#-------------------------------------------------------------------------------
36
37class Hotkey(object):
38 """A hotkey."""
39 def __init__(self, ctrl = False, shift = False, key = "0"):
40 """Construct the hotkey."""
41 self.ctrl = ctrl
42 self.shift = shift
43 self.key = key
44
45 def set(self, s):
46 """Set the hotkey from the given string."""
47 self.ctrl = "C" in s[:-1]
48 self.shift = "S" in s[:-1]
49 self.key = s[-1]
50
51 def __eq__(self, other):
52 """Check if the given hotkey is equal to the other one."""
53 return self.ctrl == other.ctrl and self.shift == other.shift and \
54 self.key == other.key
55
56 def __ne__(self, other):
57 """Check if the given hotkey is not equal to the other one."""
58 return not self==other
59
60 def __str__(self):
61 """Construct the hotkey to a string."""
62 s = ""
63 if self.ctrl: s += "C"
64 if self.shift: s += "S"
65 s += self.key
66 return s
67
68#-------------------------------------------------------------------------------
69
70class Checklist(object):
71 """A checklist for a certain aircraft type."""
72 # The name of the section of the checklists
73 SECTION="checklists"
74
75 @staticmethod
76 def fromConfig(config, aircraftType):
77 """Create a checklist for the given aircraft type from the given
78 config."""
79 baseName = "checklist." + const.icaoCodes[aircraftType] + "."
80 fileList = []
81 while True:
82 option = baseName + str(len(fileList))
83 if config.has_option(Checklist.SECTION, option):
84 fileList.append(config.get(Checklist.SECTION, option))
85 else:
86 break
87
88 return Checklist(fileList)
89
90 def __init__(self, fileList = None):
91 """Construct the check list with the given file list."""
92 self._fileList = [] if fileList is None else fileList[:]
93
94 def clone(self):
95 """Clone the checklist."""
96 return Checklist(self._fileList)
97
98 def toConfig(self, config, aircraftType):
99 """Add this checklist to the given config."""
100 baseName = "checklist." + const.icaoCodes[aircraftType] + "."
101 for index in range(0, len(self._fileList)):
102 option = baseName + str(index)
103 config.set(Checklist.SECTION, option,
104 self._fileList[index])
105
106 def __eq__(self, other):
107 """Determine if the checklist is equal to the given other one."""
108 return self._fileList == other._fileList
109
110 def __ne__(self, other):
111 """Determine if the checklist is not equal to the given other one."""
112 return not self==other
113
114 def __len__(self):
115 """Get the length of the file list."""
116 return len(self._fileList)
117
118 def __getitem__(self, index):
119 """Get the file with the given index."""
120 return self._fileList[index]
121
122 def __iter__(self):
123 """Iterate over the files."""
124 return iter(self._fileList)
125
126#-------------------------------------------------------------------------------
127
128class ApproachCallouts(object):
129 """The approach callouts for a certain aircraft type."""
130 # The name of the section of the approach callouts
131 SECTION="callouts"
132
133 @staticmethod
134 def fromConfig(config, aircraftType):
135 """Create a checklist for the given aircraft type from the given
136 config."""
137 baseName = "callouts." + const.icaoCodes[aircraftType] + "."
138 mapping = {}
139 while True:
140 option = baseName + str(len(mapping))
141 if config.has_option(ApproachCallouts.SECTION, option):
142 value = config.get(ApproachCallouts.SECTION, option)
143 (altitude, path) = value.split(",")
144 altitude = int(altitude.strip())
145 path = path.strip()
146 mapping[altitude] = path
147 else:
148 break
149
150 return ApproachCallouts(mapping)
151
152 def __init__(self, mapping = None):
153 """Construct the check list with the given mapping of altitudes to
154 files."""
155 self._mapping = {} if mapping is None else mapping.copy()
156
157 def clone(self):
158 """Clone the callout information."""
159 return ApproachCallouts(self._mapping)
160
161 def toConfig(self, config, aircraftType):
162 """Add this checklist to the given config."""
163 baseName = "callouts." + const.icaoCodes[aircraftType] + "."
164 index = 0
165 for (altitude, path) in self._mapping.iteritems():
166 option = baseName + str(index)
167 config.set(ApproachCallouts.SECTION, option,
168 "%d, %s" % (altitude, path))
169 index += 1
170
171 def getAltitudes(self, descending = True):
172 """Get the altitudes in decreasing order by default."""
173 altitudes = self._mapping.keys()
174 altitudes.sort(reverse = descending)
175 return altitudes
176
177 def __nonzero__(self):
178 """Return if there is anything in the mapping."""
179 return not not self._mapping
180
181 def __eq__(self, other):
182 """Determine if the approach callout mapping is equal to the given
183 other one."""
184 return self._mapping == other._mapping
185
186 def __ne__(self, other):
187 """Determine if the approach callout mapping is not equal to the given
188 other one."""
189 return not self==other
190
191 def __len__(self):
192 """Get the number of elements in the mapping."""
193 return len(self._mapping)
194
195 def __getitem__(self, altitude):
196 """Get the file that is associated with the given altitude.
197
198 If no such file found, return None."""
199 return self._mapping[altitude] if altitude in self._mapping else None
200
201 def __iter__(self):
202 """Iterate over the pairs of altitudes and paths in decreasing order of
203 the altitude."""
204 altitudes = self.getAltitudes()
205
206 for altitude in altitudes:
207 yield (altitude, self._mapping[altitude])
208
209#-------------------------------------------------------------------------------
210
211class Config(object):
212 """Our configuration."""
213 DEFAULT_UPDATE_URL = "http://mlx.varadiistvan.hu/update"
214
215 _messageTypesSection = "messageTypes"
216
217 def __init__(self):
218 """Construct the configuration with default values."""
219
220 self._pilotID = ""
221 self._password = ""
222 self._rememberPassword = False
223
224 self._language = ""
225 self._hideMinimizedWindow = True
226 self._quitOnClose = False
227 self._onlineGateSystem = not secondaryInstallation
228 self._onlineACARS = not secondaryInstallation
229 self._flareTimeFromFS = False
230 self._syncFSTime = False
231 self._usingFS2Crew = False
232 self._iasSmoothingLength = -2
233 self._vsSmoothingLength = -2
234
235 self._pirepDirectory = None
236
237 self._enableSounds = not secondaryInstallation
238
239 self._pilotControlsSounds = True
240 self._pilotHotkey = Hotkey(ctrl = True, shift = False, key = "0")
241
242 self._enableApproachCallouts = False
243 self._speedbrakeAtTD = True
244
245 self._enableChecklists = False
246 self._checklistHotkey = Hotkey(ctrl = True, shift = True, key = "0")
247
248 self._autoUpdate = True
249 self._updateURL = Config.DEFAULT_UPDATE_URL
250 if secondaryInstallation:
251 self._updateURL += "/exp"
252
253 self._messageTypeLevels = {}
254
255 self._checklists = {}
256 self._approachCallouts = {}
257 for aircraftType in const.aircraftTypes:
258 self._checklists[aircraftType] = Checklist()
259 self._approachCallouts[aircraftType] = ApproachCallouts()
260
261 self._modified = False
262
263 @property
264 def pilotID(self):
265 """Get the pilot ID."""
266 return self._pilotID
267
268 @pilotID.setter
269 def pilotID(self, pilotID):
270 """Set the pilot ID."""
271 if pilotID!=self._pilotID:
272 self._pilotID = pilotID
273 self._modified = True
274
275 @property
276 def password(self):
277 """Get the password."""
278 return self._password
279
280 @password.setter
281 def password(self, password):
282 """Set the password."""
283 if password!=self._password:
284 self._password = password
285 self._modified = True
286
287 @property
288 def rememberPassword(self):
289 """Get if we should remember the password."""
290 return self._rememberPassword
291
292 @rememberPassword.setter
293 def rememberPassword(self, rememberPassword):
294 """Set if we should remember the password."""
295 if rememberPassword!=self._rememberPassword:
296 self._rememberPassword = rememberPassword
297 self._modified = True
298
299 @property
300 def language(self):
301 """Get the language to use."""
302 return self._language
303
304 @language.setter
305 def language(self, language):
306 """Set the language to use."""
307 if language!=self._language:
308 self._language = language
309 self._modified = True
310
311 @property
312 def hideMinimizedWindow(self):
313 """Get whether a minimized window should be hidden."""
314 return self._hideMinimizedWindow
315
316 @hideMinimizedWindow.setter
317 def hideMinimizedWindow(self, hideMinimizedWindow):
318 """Set whether a minimized window should be hidden."""
319 if hideMinimizedWindow!=self._hideMinimizedWindow:
320 self._hideMinimizedWindow = hideMinimizedWindow
321 self._modified = True
322
323 @property
324 def quitOnClose(self):
325 """Get whether the application should quit when the close button is
326 clicked."""
327 return self._quitOnClose
328
329 @quitOnClose.setter
330 def quitOnClose(self, quitOnClose):
331 """Set whether the application should quit when the close button is
332 clicked."""
333 if quitOnClose!=self._quitOnClose:
334 self._quitOnClose = quitOnClose
335 self._modified = True
336
337 @property
338 def onlineGateSystem(self):
339 """Get whether the online gate system should be used."""
340 return self._onlineGateSystem
341
342 @onlineGateSystem.setter
343 def onlineGateSystem(self, onlineGateSystem):
344 """Set whether the online gate system should be used."""
345 if onlineGateSystem!=self._onlineGateSystem:
346 self._onlineGateSystem = onlineGateSystem
347 self._modified = True
348
349 @property
350 def onlineACARS(self):
351 """Get whether the online ACARS system should be used."""
352 return self._onlineACARS
353
354 @onlineACARS.setter
355 def onlineACARS(self, onlineACARS):
356 """Set whether the online ACARS system should be used."""
357 if onlineACARS!=self._onlineACARS:
358 self._onlineACARS = onlineACARS
359 self._modified = True
360
361 @property
362 def flareTimeFromFS(self):
363 """Get whether the flare time should be calculated from the time values
364 returned by the simulator."""
365 return self._flareTimeFromFS
366
367 @flareTimeFromFS.setter
368 def flareTimeFromFS(self, flareTimeFromFS):
369 """Set whether the flare time should be calculated from the time values
370 returned by the simulator."""
371 if flareTimeFromFS!=self._flareTimeFromFS:
372 self._flareTimeFromFS = flareTimeFromFS
373 self._modified = True
374
375 @property
376 def syncFSTime(self):
377 """Get whether the simulator's time should be synchronized with the
378 machine's clock."""
379 return self._syncFSTime
380
381 @syncFSTime.setter
382 def syncFSTime(self, syncFSTime):
383 """Set whether the simulator's time should be synchronized with the
384 machine's clock."""
385 if syncFSTime!=self._syncFSTime:
386 self._syncFSTime = syncFSTime
387 self._modified = True
388
389 @property
390 def usingFS2Crew(self):
391 """Get whether the FS2Crew addon is being used."""
392 return self._usingFS2Crew
393
394 @usingFS2Crew.setter
395 def usingFS2Crew(self, usingFS2Crew):
396 """Set whether the FS2Crew addon is being used."""
397 if usingFS2Crew!=self._usingFS2Crew:
398 self._usingFS2Crew = usingFS2Crew
399 self._modified = True
400
401 @property
402 def iasSmoothingLength(self):
403 """Get the number of samples over which the IAS is averaged for the
404 smoothed IAS calculation. It may be negative, in which case smoothing
405 is disabled, but we nevertheless store the number of seconds in case it
406 may become useful later."""
407 return self._iasSmoothingLength
408
409 @property
410 def realIASSmoothingLength(self):
411 """Get the real smoothing length of IAS."""
412 return max(self._iasSmoothingLength, 1)
413
414 @iasSmoothingLength.setter
415 def iasSmoothingLength(self, iasSmoothingLength):
416 """Set the number of samples over which the IAS is averaged for the
417 smoothed IAS calculation."""
418 if iasSmoothingLength!=self._iasSmoothingLength:
419 self._iasSmoothingLength = iasSmoothingLength
420 self._modified = True
421
422 @property
423 def vsSmoothingLength(self):
424 """Get the number of samples over which the VS is averaged for the
425 smoothed VS calculation. It may be negative, in which case smoothing
426 is disabled, but we nevertheless store the number of seconds in case it
427 may become useful later."""
428 return self._vsSmoothingLength
429
430 @property
431 def realVSSmoothingLength(self):
432 """Get the real smoothing length of VS."""
433 return max(self._vsSmoothingLength, 1)
434
435 @vsSmoothingLength.setter
436 def vsSmoothingLength(self, vsSmoothingLength):
437 """Set the number of samples over which the VS is averaged for the
438 smoothed VS calculation."""
439 if vsSmoothingLength!=self._vsSmoothingLength:
440 self._vsSmoothingLength = vsSmoothingLength
441 self._modified = True
442
443 @property
444 def pirepDirectory(self):
445 """Get the directory offered by default when saving a PIREP."""
446 return self._pirepDirectory
447
448 @pirepDirectory.setter
449 def pirepDirectory(self, pirepDirectory):
450 """Get the directory offered by default when saving a PIREP."""
451 if pirepDirectory!=self._pirepDirectory and \
452 (pirepDirectory!="" or self._pirepDirectory is not None):
453 self._pirepDirectory = None if pirepDirectory=="" \
454 else pirepDirectory
455 self._modified = True
456
457 def getMessageTypeLevel(self, messageType):
458 """Get the level for the given message type."""
459 return self._messageTypeLevels[messageType] \
460 if messageType in self._messageTypeLevels \
461 else const.MESSAGELEVEL_NONE
462
463 def isMessageTypeFS(self, messageType):
464 """Determine if the given message type is displayed in the
465 simulator."""
466 level = self.getMessageTypeLevel(messageType)
467 return level==const.MESSAGELEVEL_FS or \
468 level==const.MESSAGELEVEL_BOTH
469
470 def setMessageTypeLevel(self, messageType, level):
471 """Set the level of the given message type."""
472 if messageType not in self._messageTypeLevels or \
473 self._messageTypeLevels[messageType]!=level:
474 self._messageTypeLevels[messageType] = level
475 self._modified = True
476
477 @property
478 def enableSounds(self):
479 """Get whether background sounds are enabled."""
480 return self._enableSounds
481
482 @enableSounds.setter
483 def enableSounds(self, enableSounds):
484 """Set whether background sounds are enabled."""
485 if enableSounds!=self._enableSounds:
486 self._enableSounds = enableSounds
487 self._modified = True
488
489 @property
490 def pilotControlsSounds(self):
491 """Get whether the pilot controls the background sounds."""
492 return self._pilotControlsSounds
493
494 @pilotControlsSounds.setter
495 def pilotControlsSounds(self, pilotControlsSounds):
496 """Set whether the pilot controls the background sounds."""
497 if pilotControlsSounds!=self._pilotControlsSounds:
498 self._pilotControlsSounds = pilotControlsSounds
499 self._modified = True
500
501 @property
502 def pilotHotkey(self):
503 """Get the pilot's hotkey."""
504 return self._pilotHotkey
505
506 @pilotHotkey.setter
507 def pilotHotkey(self, pilotHotkey):
508 """Set the pilot's hotkey."""
509 if pilotHotkey!=self._pilotHotkey:
510 self._pilotHotkey = pilotHotkey
511 self._modified = True
512
513 @property
514 def enableApproachCallouts(self):
515 """Get whether the approach callouts should be played."""
516 return self._enableApproachCallouts
517
518 @enableApproachCallouts.setter
519 def enableApproachCallouts(self, enableApproachCallouts):
520 """Set whether the approach callouts should be played."""
521 if enableApproachCallouts!=self._enableApproachCallouts:
522 self._enableApproachCallouts = enableApproachCallouts
523 self._modified = True
524
525 @property
526 def speedbrakeAtTD(self):
527 """Get whether the speedbrake sounds should be played at touchdown."""
528 return self._speedbrakeAtTD
529
530 @speedbrakeAtTD.setter
531 def speedbrakeAtTD(self, speedbrakeAtTD):
532 """Set whether the speedbrake sounds should be played at touchdown."""
533 if speedbrakeAtTD!=self._speedbrakeAtTD:
534 self._speedbrakeAtTD = speedbrakeAtTD
535 self._modified = True
536
537 @property
538 def enableChecklists(self):
539 """Get whether aircraft-specific checklists should be played."""
540 return self._enableChecklists
541
542 @enableChecklists.setter
543 def enableChecklists(self, enableChecklists):
544 """Get whether aircraft-specific checklists should be played."""
545 if enableChecklists!=self._enableChecklists:
546 self._enableChecklists = enableChecklists
547 self._modified = True
548
549 @property
550 def checklistHotkey(self):
551 """Get the checklist hotkey."""
552 return self._checklistHotkey
553
554 @checklistHotkey.setter
555 def checklistHotkey(self, checklistHotkey):
556 """Set the checklist hotkey."""
557 if checklistHotkey!=self._checklistHotkey:
558 self._checklistHotkey = checklistHotkey
559 self._modified = True
560
561 @property
562 def autoUpdate(self):
563 """Get if an automatic update is needed."""
564 return self._autoUpdate
565
566 @autoUpdate.setter
567 def autoUpdate(self, autoUpdate):
568 """Set if an automatic update is needed."""
569 if autoUpdate!=self._autoUpdate:
570 self._autoUpdate = autoUpdate
571 self._modified = True
572
573 @property
574 def updateURL(self):
575 """Get the update URL."""
576 return self._updateURL
577
578 @updateURL.setter
579 def updateURL(self, updateURL):
580 """Set the update URL."""
581 if updateURL!=self._updateURL:
582 self._updateURL = updateURL
583 self._modified = True
584
585 def getChecklist(self, aircraftType):
586 """Get the checklist for the given aircraft type."""
587 return self._checklists[aircraftType]
588
589 def setChecklist(self, aircraftType, checklist):
590 """Set the checklist for the given aircraft type."""
591 if checklist!=self._checklists[aircraftType]:
592 self._checklists[aircraftType] = checklist.clone()
593 self._modified = True
594
595 def getApproachCallouts(self, aircraftType):
596 """Get the approach callouts for the given aircraft type."""
597 return self._approachCallouts[aircraftType]
598
599 def setApproachCallouts(self, aircraftType, approachCallouts):
600 """Set the approach callouts for the given aircraft type."""
601 if not approachCallouts==self._approachCallouts[aircraftType]:
602 self._approachCallouts[aircraftType] = approachCallouts.clone()
603 self._modified = True
604
605 def load(self):
606 """Load the configuration from its default location."""
607 try:
608 config = ConfigParser.RawConfigParser()
609 config.read(configPath)
610 except:
611 traceback.print_exc()
612 return
613
614 self._pilotID = self._get(config, "login", "id", "")
615 self._password = self._get(config, "login", "password", "")
616 self._rememberPassword = self._getBoolean(config, "login",
617 "rememberPassword", False)
618
619 self._language = self._get(config, "general", "language", "")
620
621 self._hideMinimizedWindow = self._getBoolean(config, "general",
622 "hideMinimizedWindow",
623 True)
624 self._quitOnClose = self._getBoolean(config, "general",
625 "quitOnClose", False)
626
627 self._onlineGateSystem = self._getBoolean(config, "general",
628 "onlineGateSystem",
629 not secondaryInstallation)
630 self._onlineACARS = self._getBoolean(config, "general",
631 "onlineACARS",
632 not secondaryInstallation)
633 self._flareTimeFromFS = self._getBoolean(config, "general",
634 "flareTimeFromFS",
635 False)
636 self._syncFSTime = self._getBoolean(config, "general",
637 "syncFSTime",
638 False)
639 self._usingFS2Crew = self._getBoolean(config, "general",
640 "usingFS2Crew",
641 False)
642 self._iasSmoothingLength = int(self._get(config, "general",
643 "iasSmoothingLength",
644 -2))
645 self._vsSmoothingLength = int(self._get(config, "general",
646 "vsSmoothingLength",
647 -2))
648 self._pirepDirectory = self._get(config, "general",
649 "pirepDirectory", None)
650
651 self._messageTypeLevels = {}
652 for messageType in const.messageTypes:
653 self._messageTypeLevels[messageType] = \
654 self._getMessageTypeLevel(config, messageType)
655
656 self._enableSounds = self._getBoolean(config, "sounds", "enable",
657 not secondaryInstallation)
658 self._pilotControlsSounds = self._getBoolean(config, "sounds",
659 "pilotControls", True)
660 self._pilotHotkey.set(self._get(config, "sounds",
661 "pilotHotkey", "C0"))
662 self._enableApproachCallouts = \
663 self._getBoolean(config, "sounds", "enableApproachCallouts", False)
664 self._speedbrakeAtTD = self._getBoolean(config, "sounds",
665 "speedbrakeAtTD", True)
666
667 self._enableChecklists = self._getBoolean(config, "sounds",
668 "enableChecklists", False)
669 self._checklistHotkey.set(self._get(config, "sounds",
670 "checklistHotkey", "CS0"))
671
672 self._autoUpdate = self._getBoolean(config, "update", "auto", True)
673 self._updateURL = self._get(config, "update", "url",
674 Config.DEFAULT_UPDATE_URL +
675 ("/exp" if secondaryInstallation else ""))
676
677 for aircraftType in const.aircraftTypes:
678 self._checklists[aircraftType] = \
679 Checklist.fromConfig(config, aircraftType)
680 self._approachCallouts[aircraftType] = \
681 ApproachCallouts.fromConfig(config, aircraftType)
682
683 self._modified = False
684
685 def save(self):
686 """Save the configuration file if it has been modified."""
687 if not self._modified:
688 return
689
690 config = ConfigParser.RawConfigParser()
691
692 config.add_section("login")
693 config.set("login", "id", self._pilotID)
694 config.set("login", "password", self._password)
695 config.set("login", "rememberPassword",
696 "yes" if self._rememberPassword else "no")
697
698 config.add_section("general")
699 if self._language:
700 config.set("general", "language", self._language)
701 config.set("general", "hideMinimizedWindow",
702 "yes" if self._hideMinimizedWindow else "no")
703 config.set("general", "quitOnClose",
704 "yes" if self._quitOnClose else "no")
705 config.set("general", "onlineGateSystem",
706 "yes" if self._onlineGateSystem else "no")
707 config.set("general", "onlineACARS",
708 "yes" if self._onlineACARS else "no")
709 config.set("general", "flareTimeFromFS",
710 "yes" if self._flareTimeFromFS else "no")
711 config.set("general", "syncFSTime",
712 "yes" if self._syncFSTime else "no")
713 config.set("general", "usingFS2Crew",
714 "yes" if self._usingFS2Crew else "no")
715 config.set("general", "iasSmoothingLength",
716 str(self._iasSmoothingLength))
717 config.set("general", "vsSmoothingLength",
718 str(self._vsSmoothingLength))
719
720 if self._pirepDirectory is not None:
721 config.set("general", "pirepDirectory", self._pirepDirectory)
722
723 config.add_section(Config._messageTypesSection)
724 for messageType in const.messageTypes:
725 if messageType in self._messageTypeLevels:
726 option = self._getMessageTypeLevelOptionName(messageType)
727 level = self._messageTypeLevels[messageType]
728 config.set(Config._messageTypesSection, option,
729 const.messageLevel2string(level))
730
731 config.add_section("sounds")
732 config.set("sounds", "enable",
733 "yes" if self._enableSounds else "no")
734 config.set("sounds", "pilotControls",
735 "yes" if self._pilotControlsSounds else "no")
736 config.set("sounds", "pilotHotkey", str(self._pilotHotkey))
737 config.set("sounds", "enableApproachCallouts",
738 "yes" if self._enableApproachCallouts else "no")
739 config.set("sounds", "speedbrakeAtTD",
740 "yes" if self._speedbrakeAtTD else "no")
741
742 config.set("sounds", "enableChecklists",
743 "yes" if self._enableChecklists else "no")
744 config.set("sounds", "checklistHotkey",
745 str(self._checklistHotkey))
746
747 config.add_section("update")
748 config.set("update", "auto",
749 "yes" if self._autoUpdate else "no")
750 config.set("update", "url", self._updateURL)
751
752 config.add_section(Checklist.SECTION)
753 config.add_section(ApproachCallouts.SECTION)
754 for aircraftType in const.aircraftTypes:
755 self._checklists[aircraftType].toConfig(config, aircraftType)
756 self._approachCallouts[aircraftType].toConfig(config, aircraftType)
757
758 try:
759 fd = os.open(configPath, os.O_CREAT|os.O_TRUNC|os.O_WRONLY,
760 0600)
761 with os.fdopen(fd, "wt") as f:
762 config.write(f)
763 self._modified = False
764 except Exception, e:
765 print >> sys.stderr, "Failed to update config: " + str(e)
766
767 def _getBoolean(self, config, section, option, default):
768 """Get the given option as a boolean, if found in the given config,
769 otherwise the default."""
770 return config.getboolean(section, option) \
771 if config.has_option(section, option) \
772 else default
773
774 def _get(self, config, section, option, default):
775 """Get the given option as a string, if found in the given config,
776 otherwise the default."""
777 return config.get(section, option) \
778 if config.has_option(section, option) \
779 else default
780
781 def _getMessageTypeLevel(self, config, messageType):
782 """Get the message type level for the given message type."""
783 option = self._getMessageTypeLevelOptionName(messageType)
784 if config.has_option(Config._messageTypesSection, option):
785 value = config.get(Config._messageTypesSection, option)
786 return const.string2messageLevel(value)
787 elif secondaryInstallation:
788 return const.MESSAGELEVEL_NONE
789 elif messageType in [const.MESSAGETYPE_LOGGER_ERROR,
790 const.MESSAGETYPE_FAULT,
791 const.MESSAGETYPE_NOGO,
792 const.MESSAGETYPE_GATE_SYSTEM,
793 const.MESSAGETYPE_HELP]:
794 return const.MESSAGELEVEL_BOTH
795 else:
796 return const.MESSAGELEVEL_FS
797
798 def _getMessageTypeLevelOptionName(self, messageType):
799 """Get the option name for the given message type level."""
800 return const.messageType2string(messageType)
801
802 def setupLocale(self):
803 """Setup the locale based on the language set.
804
805 Return True if a specific language was set, False otherwise."""
806 import locale
807 if self._language:
808 print "Setting up locale for", self._language
809 os.environ["LANGUAGE"] = self._language
810 langAndEncoding = self._language + "." + locale.getpreferredencoding()
811 os.environ["LANG"] = langAndEncoding
812 os.environ["LC_MESSAGES"] = langAndEncoding
813 os.environ["LC_COLLATE"] = langAndEncoding
814 os.environ["LC_CTYPE"] = langAndEncoding
815 os.environ["LC_MONETARY"] = langAndEncoding
816 os.environ["LC_NUMERIC"] = langAndEncoding
817 os.environ["LC_TIME"] = langAndEncoding
818 return True
819 else:
820 return False
821
822 def getLanguage(self):
823 """Get the language to be used."""
824 import locale
825 if self._language:
826 if os.name=="nt":
827 if self._language in _languageMap:
828 locale.setlocale(locale.LC_ALL, _languageMap[self._language])
829 else:
830 locale.setlocale(locale.LC_ALL, "")
831 else:
832 locale.setlocale(locale.LC_ALL, (self._language,
833 locale.getpreferredencoding()))
834 return self._language
835 else:
836 locale.setlocale(locale.LC_ALL, "")
837 return locale.getdefaultlocale()[0]
838
839#-------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.