source: src/mlx/gui/prefs.py@ 168:71af690e0c26

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

The hotkey handling works

File size: 28.8 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 backgroundBox.pack_start(self._pilotControlsSounds, False, False, 4)
540
541 self._pilotHotkey = Hotkey(xstr("prefs_sounds_pilotHotkey"),
542 [xstr("prefs_sounds_pilotHotkey_tooltip"),
543 xstr("prefs_sounds_pilotHotkeyCtrl_tooltip"),
544 xstr("prefs_sounds_pilotHotkeyShift_tooltip")])
545
546 backgroundBox.pack_start(self._pilotHotkey, False, False, 4)
547
548 # self._approachCallOuts = gtk.CheckButton(xstr("prefs_sounds_approachCallOuts"))
549 # self._approachCallOuts.set_use_underline(True)
550 # self._approachCallOuts.set_tooltip_text(xstr("prefs_sounds_approachCallOuts_tooltip"))
551 # backgroundBox.pack_start(self._approachCallOuts, False, False, 4)
552
553 self._speedbrakeAtTD = gtk.CheckButton(xstr("prefs_sounds_speedbrakeAtTD"))
554 self._speedbrakeAtTD.set_use_underline(True)
555 self._speedbrakeAtTD.set_tooltip_text(xstr("prefs_sounds_speedbrakeAtTD_tooltip"))
556 backgroundBox.pack_start(self._speedbrakeAtTD, False, False, 4)
557
558 checklistFrame = gtk.Frame(label = xstr("prefs_sounds_frame_checklists"))
559 mainBox.pack_start(checklistFrame, False, False, 4)
560
561 checklistAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
562 xscale = 1.0, yscale = 0.0)
563 checklistAlignment.set_padding(padding_top = 4, padding_bottom = 4,
564 padding_left = 4, padding_right = 4)
565 checklistFrame.add(checklistAlignment)
566
567 checklistBox = gtk.VBox()
568 checklistAlignment.add(checklistBox)
569
570 self._enableChecklists = gtk.CheckButton(xstr("prefs_sounds_enableChecklists"))
571 self._enableChecklists.set_use_underline(True)
572 self._enableChecklists.set_tooltip_text(xstr("prefs_sounds_enableChecklists_tooltip"))
573 self._enableChecklists.connect("toggled", self._enableChecklistsToggled)
574 checklistBox.pack_start(self._enableChecklists, False, False, 4)
575
576 self._checklistHotkey = Hotkey(xstr("prefs_sounds_checklistHotkey"),
577 [xstr("prefs_sounds_checklistHotkey_tooltip"),
578 xstr("prefs_sounds_checklistHotkeyCtrl_tooltip"),
579 xstr("prefs_sounds_checklistHotkeyShift_tooltip")])
580
581 checklistBox.pack_start(self._checklistHotkey, False, False, 4)
582
583 self._enableSoundsToggled(self._enableSounds)
584 self._enableChecklistsToggled(self._enableChecklists)
585
586 self._pilotHotkey.connect("hotkey-changed", self._reconcileHotkeys,
587 self._checklistHotkey)
588 self._checklistHotkey.connect("hotkey-changed", self._reconcileHotkeys,
589 self._pilotHotkey)
590
591 return mainAlignment
592
593 def _enableSoundsToggled(self, button):
594 """Called when the enable sounds button is toggled."""
595 active = button.get_active()
596 self._pilotControlsSounds.set_sensitive(active)
597 self._pilotHotkey.set_sensitive(active)
598 if active and self._checklistHotkey.get_sensitive():
599 self._reconcileHotkeys(self._checklistHotkey, Hotkey.CHANGED_SHIFT,
600 self._pilotHotkey)
601 #self._approachCallOuts.set_sensitive(active)
602 self._speedbrakeAtTD.set_sensitive(active)
603
604 def _enableChecklistsToggled(self, button):
605 """Called when the enable checklists button is toggled."""
606 active = button.get_active()
607 self._checklistHotkey.set_sensitive(active)
608 if active and self._pilotHotkey.get_sensitive():
609 self._reconcileHotkeys(self._pilotHotkey, Hotkey.CHANGED_SHIFT,
610 self._checklistHotkey)
611
612 def _reconcileHotkeys(self, changedHotkey, what, otherHotkey):
613 """Reconcile the given hotkeys so that they are different.
614
615 changedHotkey is the hotkey that has changed. what is one of the
616 Hotkey.CHANGED_XXX constants denoting what has changed. otherHotkey is
617 the other hotkey that must be reconciled.
618
619 If the other hotkey is not sensitive or is not equal to the changed
620 one, nothing happens.
621
622 Otherwise, if the status of the Ctrl modifier has changed, the status
623 of the Ctrl modifier on the other hotkey will be negated. Similarly, if
624 the Shift modifier has changed. If the key has changed, the Shift
625 modifier is negated in the other hotkey."""
626 if otherHotkey.get_sensitive() and changedHotkey==otherHotkey:
627 if what==Hotkey.CHANGED_CTRL:
628 otherHotkey.ctrl = not changedHotkey.ctrl
629 elif what==Hotkey.CHANGED_SHIFT or what==Hotkey.CHANGED_KEY:
630 otherHotkey.shift = not changedHotkey.shift
631
632 def _buildAdvanced(self):
633 """Build the page for the advanced settings."""
634
635 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
636 xscale = 1.0, yscale = 0.0)
637 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
638 padding_left = 4, padding_right = 4)
639 mainBox = gtk.VBox()
640 mainAlignment.add(mainBox)
641
642 self._autoUpdate = gtk.CheckButton(xstr("prefs_update_auto"))
643 mainBox.pack_start(self._autoUpdate, False, False, 4)
644
645 self._autoUpdate.set_use_underline(True)
646 self._autoUpdate.connect("toggled", self._autoUpdateToggled)
647 self._autoUpdate.set_tooltip_text(xstr("prefs_update_auto_tooltip"))
648 self._warnedAutoUpdate = False
649
650 updateURLBox = gtk.HBox()
651 mainBox.pack_start(updateURLBox, False, False, 4)
652 label = gtk.Label(xstr("prefs_update_url"))
653 label.set_use_underline(True)
654 updateURLBox.pack_start(label, False, False, 4)
655
656 self._updateURL = gtk.Entry()
657 label.set_mnemonic_widget(self._updateURL)
658 self._updateURL.set_width_chars(40)
659 self._updateURL.set_tooltip_text(xstr("prefs_update_url_tooltip"))
660 self._updateURL.connect("changed", self._updateURLChanged)
661 updateURLBox.pack_start(self._updateURL, True, True, 4)
662
663 return mainAlignment
664
665 def _setOKButtonSensitivity(self):
666 """Set the sensitive state of the OK button."""
667 sensitive = False
668 try:
669 result = urlparse.urlparse(self._updateURL.get_text())
670 sensitive = result.scheme!="" and (result.netloc + result.path)!=""
671 except:
672 pass
673
674 okButton = self.get_widget_for_response(RESPONSETYPE_ACCEPT)
675 okButton.set_sensitive(sensitive)
676
677 def _autoUpdateToggled(self, button):
678 """Called when the auto update check button is toggled."""
679 if not self._settingFromConfig and not self._warnedAutoUpdate and \
680 not self._autoUpdate.get_active():
681 dialog = gtk.MessageDialog(parent = self,
682 type = MESSAGETYPE_INFO,
683 message_format = xstr("prefs_update_auto_warning"))
684 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
685 dialog.set_title(self.get_title())
686 dialog.run()
687 dialog.hide()
688 self._warnedAutoUpdate = True
689
690 def _updateURLChanged(self, entry):
691 """Called when the update URL is changed."""
692 self._setOKButtonSensitivity()
693
Note: See TracBrowser for help on using the repository browser.