source: src/mlx/gui/prefs.py@ 180:a126eca82a37

Last change on this file since 180:a126eca82a37 was 174:94ca17c4e4af, checked in by István Váradi <ivaradi@…>, 13 years ago

The label's mnemonic widget is set correctly

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