source: src/mlx/gui/prefs.py@ 169:eccafedbf55c

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

Fixed the sensitivity of the pilot hotkey

File size: 29.2 KB
Line 
1# Module for the preferences dialog
2
3#------------------------------------------------------------------------------
4
5from common import *
6
7from mlx.i18n import xstr
8import mlx.const as const
9import mlx.config as config
10
11import urlparse
12
13#------------------------------------------------------------------------------
14
15class Hotkey(gtk.HBox):
16 """A widget to handle a hotkey."""
17
18 # Constant to denote that the status of the Ctrl modifier is changed
19 CHANGED_CTRL = 1
20
21 # Constant to denote that the status of the Shift modifier is changed
22 CHANGED_SHIFT = 2
23
24 # Constant to denote that the value of the key is changed
25 CHANGED_KEY = 3
26
27 def __init__(self, labelText, tooltips):
28 """Construct the hotkey widget.
29
30 labelText is the text for the label before the hotkey.
31
32 The tooltips parameter is an array of the tooltips for:
33 - the hotkey combo box,
34 - the control check box, and
35 - the shift check box."""
36 super(Hotkey, self).__init__()
37
38 label = gtk.Label(labelText)
39 label.set_use_underline(True)
40 labelAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
41 xscale = 0.0, yscale = 0.0)
42 labelAlignment.set_padding(padding_top = 0, padding_bottom = 0,
43 padding_left = 0, padding_right = 4)
44 labelAlignment.add(label)
45 self.pack_start(labelAlignment, False, False, 0)
46
47 self._ctrl = gtk.CheckButton("Ctrl")
48 self._ctrl.set_tooltip_text(tooltips[1])
49 self._ctrl.connect("toggled", self._ctrlToggled)
50 self.pack_start(self._ctrl, False, False, 4)
51
52 self._shift = gtk.CheckButton("Shift")
53 self._shift.set_tooltip_text(tooltips[2])
54 self._shift.connect("toggled", self._shiftToggled)
55 self.pack_start(self._shift, False, False, 4)
56
57 self._hotkeyModel = gtk.ListStore(str)
58 for keyCode in range(ord("0"), ord("9")+1) + range(ord("A"), ord("Z")+1):
59 self._hotkeyModel.append([chr(keyCode)])
60
61 self._hotkey = gtk.ComboBox(model = self._hotkeyModel)
62 cell = gtk.CellRendererText()
63 self._hotkey.pack_start(cell, True)
64 self._hotkey.add_attribute(cell, 'text', 0)
65 self._hotkey.set_tooltip_text(tooltips[0])
66 self._hotkey.connect("changed", self._keyChanged)
67 self.pack_start(self._hotkey, False, False, 4)
68
69 self._setting = False
70
71 @property
72 def ctrl(self):
73 """Get whether the Ctrl modifier is selected."""
74 return self._ctrl.get_active()
75
76 @ctrl.setter
77 def ctrl(self, ctrl):
78 """Get whether the Ctrl modifier is selected."""
79 self._setting = True
80 self._ctrl.set_active(ctrl)
81 self._setting = False
82
83 @property
84 def shift(self):
85 """Get whether the Shift modifier is selected."""
86 return self._shift.get_active()
87
88 @shift.setter
89 def shift(self, shift):
90 """Get whether the Shift modifier is selected."""
91 self._setting = True
92 self._shift.set_active(shift)
93 self._setting = False
94
95 @property
96 def key(self):
97 """Get the value of the key."""
98 return self._hotkeyModel.get_value(self._hotkey.get_active_iter(), 0)
99
100 @key.setter
101 def key(self, key):
102 """Set the value of the key."""
103 self._setting = True
104
105 hotkeyModel = self._hotkeyModel
106 iter = hotkeyModel.get_iter_first()
107 while iter is not None and \
108 hotkeyModel.get_value(iter, 0)!=key:
109 iter = hotkeyModel.iter_next(iter)
110
111 if iter is None:
112 iter = hotkeyModel.get_iter_first()
113
114 self._hotkey.set_active_iter(iter)
115
116 self._setting = False
117
118 def set(self, hotkey):
119 """Set the hotkey widget from the given hotkey."""
120 self.ctrl = hotkey.ctrl
121 self.shift = hotkey.shift
122 self.key = hotkey.key
123
124 def get(self):
125 """Get a hotkey corresponding to the settings in the widghet."""
126
127 key = self._hotkeyModel.get_value(self._hotkey.get_active_iter(), 0)
128
129 return config.Hotkey(ctrl = self.ctrl, shift = self.shift,
130 key = self.key)
131
132 def _ctrlToggled(self, checkButton):
133 """Called when the status of the Ctrl modifier has changed."""
134 if not self._setting:
135 self.emit("hotkey-changed", Hotkey.CHANGED_CTRL)
136
137 def _shiftToggled(self, checkButton):
138 """Called when the status of the Shift modifier has changed."""
139 if not self._setting:
140 self.emit("hotkey-changed", Hotkey.CHANGED_SHIFT)
141
142 def _keyChanged(self, comboBox):
143 """Called when the value of the key has changed."""
144 if not self._setting:
145 self.emit("hotkey-changed", Hotkey.CHANGED_KEY)
146
147 def __eq__(self, other):
148 """Determine if the two hotkeys are equal."""
149 return self.ctrl==other.ctrl and self.shift==other.shift and \
150 self.key==other.key
151
152#------------------------------------------------------------------------------
153
154gobject.signal_new("hotkey-changed", Hotkey, gobject.SIGNAL_RUN_FIRST,
155 None, (int,))
156
157#------------------------------------------------------------------------------
158
159class Preferences(gtk.Dialog):
160 """The preferences dialog."""
161 def __init__(self, gui):
162 """Construct the dialog."""
163 super(Preferences, self).__init__(WINDOW_TITLE_BASE + " " +
164 xstr("prefs_title"),
165 gui.mainWindow,
166 DIALOG_MODAL)
167
168 self.add_button(xstr("button_cancel"), RESPONSETYPE_REJECT)
169 self.add_button(xstr("button_ok"), RESPONSETYPE_ACCEPT)
170
171 self._gui = gui
172 self._settingFromConfig = False
173
174 contentArea = self.get_content_area()
175
176 notebook = gtk.Notebook()
177 contentArea.pack_start(notebook, True, True, 4)
178
179 general = self._buildGeneral()
180 label = gtk.Label(xstr("prefs_tab_general"))
181 label.set_use_underline(True)
182 label.set_tooltip_text(xstr("prefs_tab_general_tooltip"))
183 notebook.append_page(general, label)
184
185 messages = self._buildMessages()
186 label = gtk.Label(xstr("prefs_tab_messages"))
187 label.set_use_underline(True)
188 label.set_tooltip_text(xstr("prefs_tab_message_tooltip"))
189 notebook.append_page(messages, label)
190
191 sounds = self._buildSounds()
192 label = gtk.Label(xstr("prefs_tab_sounds"))
193 label.set_use_underline(True)
194 label.set_tooltip_text(xstr("prefs_tab_sounds_tooltip"))
195 notebook.append_page(sounds, label)
196
197 advanced = self._buildAdvanced()
198 label = gtk.Label(xstr("prefs_tab_advanced"))
199 label.set_use_underline(True)
200 label.set_tooltip_text(xstr("prefs_tab_advanced_tooltip"))
201 notebook.append_page(advanced, label)
202
203 def run(self, config):
204 """Run the preferences dialog.
205
206 The dialog will be set up from data in the given configuration. If the
207 changes are accepted by the user, the configuration is updated and saved."""
208 self._fromConfig(config)
209
210 self.show_all()
211 response = super(Preferences, self).run()
212 self.hide()
213
214 if response==RESPONSETYPE_ACCEPT:
215 self._toConfig(config)
216 config.save()
217
218 def _fromConfig(self, config):
219 """Setup the dialog from the given configuration."""
220 self._settingFromConfig = True
221
222 self._setLanguage(config.language)
223 self._hideMinimizedWindow.set_active(config.hideMinimizedWindow)
224 self._onlineGateSystem.set_active(config.onlineGateSystem)
225 self._onlineACARS.set_active(config.onlineACARS)
226 self._flareTimeFromFS.set_active(config.flareTimeFromFS)
227 self._syncFSTime.set_active(config.syncFSTime)
228
229 pirepDirectory = config.pirepDirectory
230 self._pirepDirectory.set_text("" if pirepDirectory is None
231 else pirepDirectory)
232
233 for messageType in const.messageTypes:
234 level = config.getMessageTypeLevel(messageType)
235 button = self._msgFSCheckButtons[messageType]
236 button.set_active(level == const.MESSAGELEVEL_FS or
237 level == const.MESSAGELEVEL_BOTH)
238 button = self._msgSoundCheckButtons[messageType]
239 button.set_active(level == const.MESSAGELEVEL_SOUND or
240 level == const.MESSAGELEVEL_BOTH)
241
242 self._enableSounds.set_active(config.enableSounds)
243 self._pilotControlsSounds.set_active(config.pilotControlsSounds)
244 self._pilotHotkey.set(config.pilotHotkey)
245 #self._approachCallOuts.set_active(config.approachCallOuts)
246 self._speedbrakeAtTD.set_active(config.speedbrakeAtTD)
247
248 self._enableChecklists.set_active(config.enableChecklists)
249 self._checklistHotkey.set(config.checklistHotkey)
250
251 self._autoUpdate.set_active(config.autoUpdate)
252 if not config.autoUpdate:
253 self._warnedAutoUpdate = True
254
255 self._updateURL.set_text(config.updateURL)
256
257 self._settingFromConfig = False
258
259 def _toConfig(self, config):
260 """Setup the given config from the settings in the dialog."""
261 config.language = self._getLanguage()
262 config.hideMinimizedWindow = self._hideMinimizedWindow.get_active()
263 config.onlineGateSystem = self._onlineGateSystem.get_active()
264 config.onlineACARS = self._onlineACARS.get_active()
265 config.flareTimeFromFS = self._flareTimeFromFS.get_active()
266 config.syncFSTime = self._syncFSTime.get_active()
267 config.pirepDirectory = text2unicode(self._pirepDirectory.get_text())
268
269 for messageType in const.messageTypes:
270 fsButtonActive = self._msgFSCheckButtons[messageType].get_active()
271 soundButtonActive = self._msgSoundCheckButtons[messageType].get_active()
272 if fsButtonActive:
273 level = const.MESSAGELEVEL_BOTH if soundButtonActive \
274 else const.MESSAGELEVEL_FS
275 elif soundButtonActive:
276 level = const.MESSAGELEVEL_SOUND
277 else:
278 level = const.MESSAGELEVEL_NONE
279 config.setMessageTypeLevel(messageType, level)
280
281 config.enableSounds = self._enableSounds.get_active()
282 config.pilotControlsSounds = self._pilotControlsSounds.get_active()
283 config.pilotHotkey = self._pilotHotkey.get()
284 #config.approachCallOuts = self._approachCallOuts.get_active()
285 config.speedbrakeAtTD = self._speedbrakeAtTD.get_active()
286
287 config.enableChecklists = self._enableChecklists.get_active()
288 config.checklistHotkey = self._checklistHotkey.get()
289
290 config.autoUpdate = self._autoUpdate.get_active()
291 config.updateURL = self._updateURL.get_text()
292
293 def _buildGeneral(self):
294 """Build the page for the general settings."""
295 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
296 xscale = 1.0, yscale = 0.0)
297 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
298 padding_left = 4, padding_right = 4)
299 mainBox = gtk.VBox()
300 mainAlignment.add(mainBox)
301
302 languageBox = gtk.HBox()
303 mainBox.pack_start(languageBox, False, False, 4)
304
305 label = gtk.Label(xstr("prefs_language"))
306 label.set_use_underline(True)
307
308 languageBox.pack_start(label, False, False, 4)
309
310 self._languageList = gtk.ListStore(str, str)
311 for language in const.languages:
312 self._languageList.append([xstr("prefs_lang_" + language),
313 language])
314
315 self._languageComboBox = languageComboBox = \
316 gtk.ComboBox(model = self._languageList)
317 cell = gtk.CellRendererText()
318 languageComboBox.pack_start(cell, True)
319 languageComboBox.add_attribute(cell, 'text', 0)
320 languageComboBox.set_tooltip_text(xstr("prefs_language_tooltip"))
321 languageComboBox.connect("changed", self._languageChanged)
322 languageBox.pack_start(languageComboBox, False, False, 4)
323
324 label.set_mnemonic_widget(languageComboBox)
325
326 self._changingLanguage = False
327 self._warnedRestartNeeded = False
328
329 self._hideMinimizedWindow = gtk.CheckButton(xstr("prefs_hideMinimizedWindow"))
330 self._hideMinimizedWindow.set_use_underline(True)
331 self._hideMinimizedWindow.set_tooltip_text(xstr("prefs_hideMinimizedWindow_tooltip"))
332 mainBox.pack_start(self._hideMinimizedWindow, False, False, 4)
333
334 self._onlineGateSystem = gtk.CheckButton(xstr("prefs_onlineGateSystem"))
335 self._onlineGateSystem.set_use_underline(True)
336 self._onlineGateSystem.set_tooltip_text(xstr("prefs_onlineGateSystem_tooltip"))
337 mainBox.pack_start(self._onlineGateSystem, False, False, 4)
338
339 self._onlineACARS = gtk.CheckButton(xstr("prefs_onlineACARS"))
340 self._onlineACARS.set_use_underline(True)
341 self._onlineACARS.set_tooltip_text(xstr("prefs_onlineACARS_tooltip"))
342 mainBox.pack_start(self._onlineACARS, False, False, 4)
343
344 self._flareTimeFromFS = gtk.CheckButton(xstr("prefs_flaretimeFromFS"))
345 self._flareTimeFromFS.set_use_underline(True)
346 self._flareTimeFromFS.set_tooltip_text(xstr("prefs_flaretimeFromFS_tooltip"))
347 mainBox.pack_start(self._flareTimeFromFS, False, False, 4)
348
349 self._syncFSTime = gtk.CheckButton(xstr("prefs_syncFSTime"))
350 self._syncFSTime.set_use_underline(True)
351 self._syncFSTime.set_tooltip_text(xstr("prefs_syncFSTime_tooltip"))
352 mainBox.pack_start(self._syncFSTime, False, False, 4)
353
354 pirepBox = gtk.HBox()
355 mainBox.pack_start(pirepBox, False, False, 4)
356
357 label = gtk.Label(xstr("prefs_pirepDirectory"))
358 label.set_use_underline(True)
359 pirepBox.pack_start(label, False, False, 4)
360
361 self._pirepDirectory = gtk.Entry()
362 self._pirepDirectory.set_tooltip_text(xstr("prefs_pirepDirectory_tooltip"))
363 label.set_mnemonic_widget(self._pirepDirectory)
364 pirepBox.pack_start(self._pirepDirectory, True, True, 4)
365
366 self._pirepDirectoryButton = gtk.Button(xstr("button_browse"))
367 self._pirepDirectoryButton.connect("clicked",
368 self._pirepDirectoryButtonClicked)
369 pirepBox.pack_start(self._pirepDirectoryButton, False, False, 4)
370
371 return mainAlignment
372
373 def _setLanguage(self, language):
374 """Set the language to the given one."""
375 iter = self._languageList.get_iter_first()
376 while iter is not None:
377 (lang,) = self._languageList.get(iter, 1)
378 if (not language and lang=="$system") or \
379 lang==language:
380 self._changingLanguage = True
381 self._languageComboBox.set_active_iter(iter)
382 self._changingLanguage = False
383 break
384 else:
385 iter = self._languageList.iter_next(iter)
386
387 def _getLanguage(self):
388 """Get the language selected by the user."""
389 iter = self._languageComboBox.get_active_iter()
390 (lang,) = self._languageList.get(iter, 1)
391 return "" if lang=="$system" else lang
392
393 def _languageChanged(self, comboBox):
394 """Called when the language has changed."""
395 if not self._changingLanguage and not self._warnedRestartNeeded:
396 dialog = gtk.MessageDialog(parent = self,
397 type = MESSAGETYPE_INFO,
398 message_format = xstr("prefs_restart"))
399 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
400 dialog.set_title(self.get_title())
401 dialog.format_secondary_markup(xstr("prefs_language_restart_sec"))
402 dialog.run()
403 dialog.hide()
404 self._warnedRestartNeeded = True
405
406 def _pirepDirectoryButtonClicked(self, button):
407 """Called when the PIREP directory button is clicked."""
408 dialog = gtk.FileChooserDialog(title = WINDOW_TITLE_BASE + " - " +
409 xstr("prefs_pirepDirectory_browser_title"),
410 action = FILE_CHOOSER_ACTION_SELECT_FOLDER,
411 buttons = (gtk.STOCK_CANCEL, RESPONSETYPE_CANCEL,
412 gtk.STOCK_OK, RESPONSETYPE_OK),
413 parent = self)
414 dialog.set_modal(True)
415 dialog.set_transient_for(self)
416
417 directory = self._pirepDirectory.get_text()
418 if directory:
419 dialog.select_filename(directory)
420
421 result = dialog.run()
422 dialog.hide()
423
424 if result==RESPONSETYPE_OK:
425 self._pirepDirectory.set_text(dialog.get_filename())
426
427 def _buildMessages(self):
428 """Build the page for the message settings."""
429
430 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
431 xscale = 0.0, yscale = 0.0)
432 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
433 padding_left = 4, padding_right = 4)
434 mainBox = gtk.VBox()
435 mainAlignment.add(mainBox)
436
437 table = gtk.Table(len(const.messageTypes) + 1, 3)
438 table.set_row_spacings(8)
439 table.set_col_spacings(32)
440 table.set_homogeneous(False)
441 mainBox.pack_start(table, False, False, 4)
442
443 label = gtk.Label(xstr("prefs_msgs_fs"))
444 label.set_justify(JUSTIFY_CENTER)
445 label.set_alignment(0.5, 1.0)
446 table.attach(label, 1, 2, 0, 1)
447
448 label = gtk.Label(xstr("prefs_msgs_sound"))
449 label.set_justify(JUSTIFY_CENTER)
450 label.set_alignment(0.5, 1.0)
451 table.attach(label, 2, 3, 0, 1)
452
453 self._msgFSCheckButtons = {}
454 self._msgSoundCheckButtons = {}
455 row = 1
456 for messageType in const.messageTypes:
457 messageTypeStr = const.messageType2string(messageType)
458 label = gtk.Label(xstr("prefs_msgs_type_" + messageTypeStr))
459 label.set_justify(JUSTIFY_CENTER)
460 label.set_use_underline(True)
461 label.set_alignment(0.5, 0.5)
462 table.attach(label, 0, 1, row, row+1)
463
464 fsCheckButton = gtk.CheckButton()
465 alignment = gtk.Alignment(xscale = 0.0, yscale = 0.0,
466 xalign = 0.5, yalign = 0.5)
467 alignment.add(fsCheckButton)
468 table.attach(alignment, 1, 2, row, row+1)
469 self._msgFSCheckButtons[messageType] = fsCheckButton
470
471 soundCheckButton = gtk.CheckButton()
472 alignment = gtk.Alignment(xscale = 0.0, yscale = 0.0,
473 xalign = 0.5, yalign = 0.5)
474 alignment.add(soundCheckButton)
475 table.attach(alignment, 2, 3, row, row+1)
476 self._msgSoundCheckButtons[messageType] = soundCheckButton
477
478 mnemonicWidget = gtk.Label("")
479 table.attach(mnemonicWidget, 3, 4, row, row+1)
480 label.set_mnemonic_widget(mnemonicWidget)
481 mnemonicWidget.connect("mnemonic-activate",
482 self._msgLabelActivated,
483 messageType)
484
485 row += 1
486
487 return mainAlignment
488
489 def _msgLabelActivated(self, button, cycle_group, messageType):
490 """Called when the mnemonic of a label is activated.
491
492 It cycles the corresponding options."""
493 fsCheckButton = self._msgFSCheckButtons[messageType]
494 soundCheckButton = self._msgSoundCheckButtons[messageType]
495
496 num = 1 if fsCheckButton.get_active() else 0
497 num += 2 if soundCheckButton.get_active() else 0
498 num += 1
499
500 fsCheckButton.set_active((num&0x01)==0x01)
501 soundCheckButton.set_active((num&0x02)==0x02)
502
503 return True
504
505 def _buildSounds(self):
506 """Build the page for the sounds."""
507 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
508 xscale = 1.0, yscale = 1.0)
509 mainAlignment.set_padding(padding_top = 8, padding_bottom = 8,
510 padding_left = 4, padding_right = 4)
511
512 mainBox = gtk.VBox()
513 mainAlignment.add(mainBox)
514
515 backgroundFrame = gtk.Frame(label = xstr("prefs_sounds_frame_bg"))
516 mainBox.pack_start(backgroundFrame, False, False, 4)
517
518 backgroundAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
519 xscale = 1.0, yscale = 0.0)
520 backgroundAlignment.set_padding(padding_top = 4, padding_bottom = 4,
521 padding_left = 4, padding_right = 4)
522 backgroundFrame.add(backgroundAlignment)
523
524 backgroundBox = gtk.VBox()
525 backgroundAlignment.add(backgroundBox)
526
527 self._enableSounds = gtk.CheckButton(xstr("prefs_sounds_enable"))
528 self._enableSounds.set_use_underline(True)
529 self._enableSounds.set_tooltip_text(xstr("prefs_sounds_enable_tooltip"))
530 self._enableSounds.connect("toggled", self._enableSoundsToggled)
531 alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
532 xscale = 1.0, yscale = 0.0)
533 alignment.add(self._enableSounds)
534 backgroundBox.pack_start(alignment, False, False, 4)
535
536 self._pilotControlsSounds = gtk.CheckButton(xstr("prefs_sounds_pilotControls"))
537 self._pilotControlsSounds.set_use_underline(True)
538 self._pilotControlsSounds.set_tooltip_text(xstr("prefs_sounds_pilotControls_tooltip"))
539 self._pilotControlsSounds.connect("toggled", self._pilotControlsSoundsToggled)
540 backgroundBox.pack_start(self._pilotControlsSounds, False, False, 4)
541
542 self._pilotHotkey = Hotkey(xstr("prefs_sounds_pilotHotkey"),
543 [xstr("prefs_sounds_pilotHotkey_tooltip"),
544 xstr("prefs_sounds_pilotHotkeyCtrl_tooltip"),
545 xstr("prefs_sounds_pilotHotkeyShift_tooltip")])
546
547 backgroundBox.pack_start(self._pilotHotkey, False, False, 4)
548
549 # self._approachCallOuts = gtk.CheckButton(xstr("prefs_sounds_approachCallOuts"))
550 # self._approachCallOuts.set_use_underline(True)
551 # self._approachCallOuts.set_tooltip_text(xstr("prefs_sounds_approachCallOuts_tooltip"))
552 # backgroundBox.pack_start(self._approachCallOuts, False, False, 4)
553
554 self._speedbrakeAtTD = gtk.CheckButton(xstr("prefs_sounds_speedbrakeAtTD"))
555 self._speedbrakeAtTD.set_use_underline(True)
556 self._speedbrakeAtTD.set_tooltip_text(xstr("prefs_sounds_speedbrakeAtTD_tooltip"))
557 backgroundBox.pack_start(self._speedbrakeAtTD, False, False, 4)
558
559 checklistFrame = gtk.Frame(label = xstr("prefs_sounds_frame_checklists"))
560 mainBox.pack_start(checklistFrame, False, False, 4)
561
562 checklistAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
563 xscale = 1.0, yscale = 0.0)
564 checklistAlignment.set_padding(padding_top = 4, padding_bottom = 4,
565 padding_left = 4, padding_right = 4)
566 checklistFrame.add(checklistAlignment)
567
568 checklistBox = gtk.VBox()
569 checklistAlignment.add(checklistBox)
570
571 self._enableChecklists = gtk.CheckButton(xstr("prefs_sounds_enableChecklists"))
572 self._enableChecklists.set_use_underline(True)
573 self._enableChecklists.set_tooltip_text(xstr("prefs_sounds_enableChecklists_tooltip"))
574 self._enableChecklists.connect("toggled", self._enableChecklistsToggled)
575 checklistBox.pack_start(self._enableChecklists, False, False, 4)
576
577 self._checklistHotkey = Hotkey(xstr("prefs_sounds_checklistHotkey"),
578 [xstr("prefs_sounds_checklistHotkey_tooltip"),
579 xstr("prefs_sounds_checklistHotkeyCtrl_tooltip"),
580 xstr("prefs_sounds_checklistHotkeyShift_tooltip")])
581
582 checklistBox.pack_start(self._checklistHotkey, False, False, 4)
583
584 self._enableSoundsToggled(self._enableSounds)
585 self._enableChecklistsToggled(self._enableChecklists)
586
587 self._pilotHotkey.connect("hotkey-changed", self._reconcileHotkeys,
588 self._checklistHotkey)
589 self._checklistHotkey.connect("hotkey-changed", self._reconcileHotkeys,
590 self._pilotHotkey)
591
592 return mainAlignment
593
594 def _enableSoundsToggled(self, button):
595 """Called when the enable sounds button is toggled."""
596 active = button.get_active()
597 self._pilotControlsSounds.set_sensitive(active)
598 self._pilotControlsSoundsToggled(self._pilotControlsSounds)
599 #self._approachCallOuts.set_sensitive(active)
600 self._speedbrakeAtTD.set_sensitive(active)
601
602 def _pilotControlsSoundsToggled(self, button):
603 """Called when the enable sounds button is toggled."""
604 active = button.get_active() and self._enableSounds.get_active()
605 self._pilotHotkey.set_sensitive(active)
606 if active and self._checklistHotkey.get_sensitive():
607 self._reconcileHotkeys(self._checklistHotkey, Hotkey.CHANGED_SHIFT,
608 self._pilotHotkey)
609
610 def _enableChecklistsToggled(self, button):
611 """Called when the enable checklists button is toggled."""
612 active = button.get_active()
613 self._checklistHotkey.set_sensitive(active)
614 if active and self._pilotHotkey.get_sensitive():
615 self._reconcileHotkeys(self._pilotHotkey, Hotkey.CHANGED_SHIFT,
616 self._checklistHotkey)
617
618 def _reconcileHotkeys(self, changedHotkey, what, otherHotkey):
619 """Reconcile the given hotkeys so that they are different.
620
621 changedHotkey is the hotkey that has changed. what is one of the
622 Hotkey.CHANGED_XXX constants denoting what has changed. otherHotkey is
623 the other hotkey that must be reconciled.
624
625 If the other hotkey is not sensitive or is not equal to the changed
626 one, nothing happens.
627
628 Otherwise, if the status of the Ctrl modifier has changed, the status
629 of the Ctrl modifier on the other hotkey will be negated. Similarly, if
630 the Shift modifier has changed. If the key has changed, the Shift
631 modifier is negated in the other hotkey."""
632 if otherHotkey.get_sensitive() and changedHotkey==otherHotkey:
633 if what==Hotkey.CHANGED_CTRL:
634 otherHotkey.ctrl = not changedHotkey.ctrl
635 elif what==Hotkey.CHANGED_SHIFT or what==Hotkey.CHANGED_KEY:
636 otherHotkey.shift = not changedHotkey.shift
637
638 def _buildAdvanced(self):
639 """Build the page for the advanced settings."""
640
641 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
642 xscale = 1.0, yscale = 0.0)
643 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
644 padding_left = 4, padding_right = 4)
645 mainBox = gtk.VBox()
646 mainAlignment.add(mainBox)
647
648 self._autoUpdate = gtk.CheckButton(xstr("prefs_update_auto"))
649 mainBox.pack_start(self._autoUpdate, False, False, 4)
650
651 self._autoUpdate.set_use_underline(True)
652 self._autoUpdate.connect("toggled", self._autoUpdateToggled)
653 self._autoUpdate.set_tooltip_text(xstr("prefs_update_auto_tooltip"))
654 self._warnedAutoUpdate = False
655
656 updateURLBox = gtk.HBox()
657 mainBox.pack_start(updateURLBox, False, False, 4)
658 label = gtk.Label(xstr("prefs_update_url"))
659 label.set_use_underline(True)
660 updateURLBox.pack_start(label, False, False, 4)
661
662 self._updateURL = gtk.Entry()
663 label.set_mnemonic_widget(self._updateURL)
664 self._updateURL.set_width_chars(40)
665 self._updateURL.set_tooltip_text(xstr("prefs_update_url_tooltip"))
666 self._updateURL.connect("changed", self._updateURLChanged)
667 updateURLBox.pack_start(self._updateURL, True, True, 4)
668
669 return mainAlignment
670
671 def _setOKButtonSensitivity(self):
672 """Set the sensitive state of the OK button."""
673 sensitive = False
674 try:
675 result = urlparse.urlparse(self._updateURL.get_text())
676 sensitive = result.scheme!="" and (result.netloc + result.path)!=""
677 except:
678 pass
679
680 okButton = self.get_widget_for_response(RESPONSETYPE_ACCEPT)
681 okButton.set_sensitive(sensitive)
682
683 def _autoUpdateToggled(self, button):
684 """Called when the auto update check button is toggled."""
685 if not self._settingFromConfig and not self._warnedAutoUpdate and \
686 not self._autoUpdate.get_active():
687 dialog = gtk.MessageDialog(parent = self,
688 type = MESSAGETYPE_INFO,
689 message_format = xstr("prefs_update_auto_warning"))
690 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
691 dialog.set_title(self.get_title())
692 dialog.run()
693 dialog.hide()
694 self._warnedAutoUpdate = True
695
696 def _updateURLChanged(self, entry):
697 """Called when the update URL is changed."""
698 self._setOKButtonSensitivity()
699
Note: See TracBrowser for help on using the repository browser.