source: src/mlx/gui/prefs.py@ 167:db7becb14f9e

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

Added code to reconcile the hotkeys if they are equal

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