source: src/mlx/gui/prefs.py@ 194:daa841678660

Last change on this file since 194:daa841678660 was 186:a808eda90d15, checked in by István Váradi <ivaradi@…>, 13 years ago

Attempted to make the General tab of the Preferences dialog better looking

File size: 30.4 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 self._usingFS2Crew.set_active(config.usingFS2Crew)
231
232 pirepDirectory = config.pirepDirectory
233 self._pirepDirectory.set_text("" if pirepDirectory is None
234 else pirepDirectory)
235
236 for messageType in const.messageTypes:
237 level = config.getMessageTypeLevel(messageType)
238 button = self._msgFSCheckButtons[messageType]
239 button.set_active(level == const.MESSAGELEVEL_FS or
240 level == const.MESSAGELEVEL_BOTH)
241 button = self._msgSoundCheckButtons[messageType]
242 button.set_active(level == const.MESSAGELEVEL_SOUND or
243 level == const.MESSAGELEVEL_BOTH)
244
245 self._enableSounds.set_active(config.enableSounds)
246 self._pilotControlsSounds.set_active(config.pilotControlsSounds)
247 self._pilotHotkey.set(config.pilotHotkey)
248 #self._approachCallOuts.set_active(config.approachCallOuts)
249 self._speedbrakeAtTD.set_active(config.speedbrakeAtTD)
250
251 self._enableChecklists.set_active(config.enableChecklists)
252 self._checklistHotkey.set(config.checklistHotkey)
253
254 self._autoUpdate.set_active(config.autoUpdate)
255 if not config.autoUpdate:
256 self._warnedAutoUpdate = True
257
258 self._updateURL.set_text(config.updateURL)
259
260 self._settingFromConfig = False
261
262 def _toConfig(self, config):
263 """Setup the given config from the settings in the dialog."""
264 config.language = self._getLanguage()
265 config.hideMinimizedWindow = self._hideMinimizedWindow.get_active()
266 config.onlineGateSystem = self._onlineGateSystem.get_active()
267 config.onlineACARS = self._onlineACARS.get_active()
268 config.flareTimeFromFS = self._flareTimeFromFS.get_active()
269 config.syncFSTime = self._syncFSTime.get_active()
270 config.usingFS2Crew = self._usingFS2Crew.get_active()
271 config.pirepDirectory = text2unicode(self._pirepDirectory.get_text())
272
273 for messageType in const.messageTypes:
274 fsButtonActive = self._msgFSCheckButtons[messageType].get_active()
275 soundButtonActive = self._msgSoundCheckButtons[messageType].get_active()
276 if fsButtonActive:
277 level = const.MESSAGELEVEL_BOTH if soundButtonActive \
278 else const.MESSAGELEVEL_FS
279 elif soundButtonActive:
280 level = const.MESSAGELEVEL_SOUND
281 else:
282 level = const.MESSAGELEVEL_NONE
283 config.setMessageTypeLevel(messageType, level)
284
285 config.enableSounds = self._enableSounds.get_active()
286 config.pilotControlsSounds = self._pilotControlsSounds.get_active()
287 config.pilotHotkey = self._pilotHotkey.get()
288 #config.approachCallOuts = self._approachCallOuts.get_active()
289 config.speedbrakeAtTD = self._speedbrakeAtTD.get_active()
290
291 config.enableChecklists = self._enableChecklists.get_active()
292 config.checklistHotkey = self._checklistHotkey.get()
293
294 config.autoUpdate = self._autoUpdate.get_active()
295 config.updateURL = self._updateURL.get_text()
296
297 def _buildGeneral(self):
298 """Build the page for the general settings."""
299 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
300 xscale = 1.0, yscale = 0.0)
301 mainAlignment.set_padding(padding_top = 0, padding_bottom = 8,
302 padding_left = 4, padding_right = 4)
303 mainBox = gtk.VBox()
304 mainAlignment.add(mainBox)
305
306 guiBox = self._createFrame(mainBox, xstr("prefs_frame_gui"))
307
308 languageBox = gtk.HBox()
309 guiBox.pack_start(languageBox, False, False, 4)
310
311 label = gtk.Label(xstr("prefs_language"))
312 label.set_use_underline(True)
313
314 languageBox.pack_start(label, False, False, 4)
315
316 self._languageList = gtk.ListStore(str, str)
317 for language in const.languages:
318 self._languageList.append([xstr("prefs_lang_" + language),
319 language])
320
321 self._languageComboBox = languageComboBox = \
322 gtk.ComboBox(model = self._languageList)
323 cell = gtk.CellRendererText()
324 languageComboBox.pack_start(cell, True)
325 languageComboBox.add_attribute(cell, 'text', 0)
326 languageComboBox.set_tooltip_text(xstr("prefs_language_tooltip"))
327 languageComboBox.connect("changed", self._languageChanged)
328 languageBox.pack_start(languageComboBox, False, False, 4)
329
330 label.set_mnemonic_widget(languageComboBox)
331
332 self._changingLanguage = False
333 self._warnedRestartNeeded = False
334
335 self._hideMinimizedWindow = gtk.CheckButton(xstr("prefs_hideMinimizedWindow"))
336 self._hideMinimizedWindow.set_use_underline(True)
337 self._hideMinimizedWindow.set_tooltip_text(xstr("prefs_hideMinimizedWindow_tooltip"))
338 guiBox.pack_start(self._hideMinimizedWindow, False, False, 4)
339
340 onlineBox = self._createFrame(mainBox, xstr("prefs_frame_online"))
341
342 self._onlineGateSystem = gtk.CheckButton(xstr("prefs_onlineGateSystem"))
343 self._onlineGateSystem.set_use_underline(True)
344 self._onlineGateSystem.set_tooltip_text(xstr("prefs_onlineGateSystem_tooltip"))
345 onlineBox.pack_start(self._onlineGateSystem, False, False, 4)
346
347 self._onlineACARS = gtk.CheckButton(xstr("prefs_onlineACARS"))
348 self._onlineACARS.set_use_underline(True)
349 self._onlineACARS.set_tooltip_text(xstr("prefs_onlineACARS_tooltip"))
350 onlineBox.pack_start(self._onlineACARS, False, False, 4)
351
352 simulatorBox = self._createFrame(mainBox, xstr("prefs_frame_simulator"))
353
354 self._flareTimeFromFS = gtk.CheckButton(xstr("prefs_flaretimeFromFS"))
355 self._flareTimeFromFS.set_use_underline(True)
356 self._flareTimeFromFS.set_tooltip_text(xstr("prefs_flaretimeFromFS_tooltip"))
357 simulatorBox.pack_start(self._flareTimeFromFS, False, False, 4)
358
359 self._syncFSTime = gtk.CheckButton(xstr("prefs_syncFSTime"))
360 self._syncFSTime.set_use_underline(True)
361 self._syncFSTime.set_tooltip_text(xstr("prefs_syncFSTime_tooltip"))
362 simulatorBox.pack_start(self._syncFSTime, False, False, 4)
363
364 self._usingFS2Crew = gtk.CheckButton(xstr("prefs_usingFS2Crew"))
365 self._usingFS2Crew.set_use_underline(True)
366 self._usingFS2Crew.set_tooltip_text(xstr("prefs_usingFS2Crew_tooltip"))
367 simulatorBox.pack_start(self._usingFS2Crew, False, False, 4)
368
369 pirepBox = gtk.HBox()
370 mainBox.pack_start(pirepBox, False, False, 8)
371
372 label = gtk.Label(xstr("prefs_pirepDirectory"))
373 label.set_use_underline(True)
374 pirepBox.pack_start(label, False, False, 4)
375
376 self._pirepDirectory = gtk.Entry()
377 self._pirepDirectory.set_tooltip_text(xstr("prefs_pirepDirectory_tooltip"))
378 label.set_mnemonic_widget(self._pirepDirectory)
379 pirepBox.pack_start(self._pirepDirectory, True, True, 4)
380
381 self._pirepDirectoryButton = gtk.Button(xstr("button_browse"))
382 self._pirepDirectoryButton.connect("clicked",
383 self._pirepDirectoryButtonClicked)
384 pirepBox.pack_start(self._pirepDirectoryButton, False, False, 4)
385
386 return mainAlignment
387
388 def _createFrame(self, mainBox, label):
389 """Create a frame with an inner alignment and VBox.
390
391 Return the vbox."""
392 frame = gtk.Frame(label = label)
393 mainBox.pack_start(frame, False, False, 4)
394 alignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
395 xscale = 1.0, yscale = 0.0)
396 alignment.set_padding(padding_top = 4, padding_bottom = 0,
397 padding_left = 0, padding_right = 0)
398 frame.add(alignment)
399 vbox = gtk.VBox()
400 alignment.add(vbox)
401
402 return vbox
403
404 def _setLanguage(self, language):
405 """Set the language to the given one."""
406 iter = self._languageList.get_iter_first()
407 while iter is not None:
408 (lang,) = self._languageList.get(iter, 1)
409 if (not language and lang=="$system") or \
410 lang==language:
411 self._changingLanguage = True
412 self._languageComboBox.set_active_iter(iter)
413 self._changingLanguage = False
414 break
415 else:
416 iter = self._languageList.iter_next(iter)
417
418 def _getLanguage(self):
419 """Get the language selected by the user."""
420 iter = self._languageComboBox.get_active_iter()
421 (lang,) = self._languageList.get(iter, 1)
422 return "" if lang=="$system" else lang
423
424 def _languageChanged(self, comboBox):
425 """Called when the language has changed."""
426 if not self._changingLanguage and not self._warnedRestartNeeded:
427 dialog = gtk.MessageDialog(parent = self,
428 type = MESSAGETYPE_INFO,
429 message_format = xstr("prefs_restart"))
430 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
431 dialog.set_title(self.get_title())
432 dialog.format_secondary_markup(xstr("prefs_language_restart_sec"))
433 dialog.run()
434 dialog.hide()
435 self._warnedRestartNeeded = True
436
437 def _pirepDirectoryButtonClicked(self, button):
438 """Called when the PIREP directory button is clicked."""
439 dialog = gtk.FileChooserDialog(title = WINDOW_TITLE_BASE + " - " +
440 xstr("prefs_pirepDirectory_browser_title"),
441 action = FILE_CHOOSER_ACTION_SELECT_FOLDER,
442 buttons = (gtk.STOCK_CANCEL, RESPONSETYPE_CANCEL,
443 gtk.STOCK_OK, RESPONSETYPE_OK),
444 parent = self)
445 dialog.set_modal(True)
446 dialog.set_transient_for(self)
447
448 directory = self._pirepDirectory.get_text()
449 if directory:
450 dialog.select_filename(directory)
451
452 result = dialog.run()
453 dialog.hide()
454
455 if result==RESPONSETYPE_OK:
456 self._pirepDirectory.set_text(dialog.get_filename())
457
458 def _buildMessages(self):
459 """Build the page for the message settings."""
460
461 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
462 xscale = 0.0, yscale = 0.0)
463 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
464 padding_left = 4, padding_right = 4)
465 mainBox = gtk.VBox()
466 mainAlignment.add(mainBox)
467
468 table = gtk.Table(len(const.messageTypes) + 1, 3)
469 table.set_row_spacings(8)
470 table.set_col_spacings(32)
471 table.set_homogeneous(False)
472 mainBox.pack_start(table, False, False, 4)
473
474 label = gtk.Label(xstr("prefs_msgs_fs"))
475 label.set_justify(JUSTIFY_CENTER)
476 label.set_alignment(0.5, 1.0)
477 table.attach(label, 1, 2, 0, 1)
478
479 label = gtk.Label(xstr("prefs_msgs_sound"))
480 label.set_justify(JUSTIFY_CENTER)
481 label.set_alignment(0.5, 1.0)
482 table.attach(label, 2, 3, 0, 1)
483
484 self._msgFSCheckButtons = {}
485 self._msgSoundCheckButtons = {}
486 row = 1
487 for messageType in const.messageTypes:
488 messageTypeStr = const.messageType2string(messageType)
489 label = gtk.Label(xstr("prefs_msgs_type_" + messageTypeStr))
490 label.set_justify(JUSTIFY_CENTER)
491 label.set_use_underline(True)
492 label.set_alignment(0.5, 0.5)
493 table.attach(label, 0, 1, row, row+1)
494
495 fsCheckButton = gtk.CheckButton()
496 alignment = gtk.Alignment(xscale = 0.0, yscale = 0.0,
497 xalign = 0.5, yalign = 0.5)
498 alignment.add(fsCheckButton)
499 table.attach(alignment, 1, 2, row, row+1)
500 self._msgFSCheckButtons[messageType] = fsCheckButton
501
502 soundCheckButton = gtk.CheckButton()
503 alignment = gtk.Alignment(xscale = 0.0, yscale = 0.0,
504 xalign = 0.5, yalign = 0.5)
505 alignment.add(soundCheckButton)
506 table.attach(alignment, 2, 3, row, row+1)
507 self._msgSoundCheckButtons[messageType] = soundCheckButton
508
509 mnemonicWidget = gtk.Label("")
510 table.attach(mnemonicWidget, 3, 4, row, row+1)
511 label.set_mnemonic_widget(mnemonicWidget)
512 mnemonicWidget.connect("mnemonic-activate",
513 self._msgLabelActivated,
514 messageType)
515
516 row += 1
517
518 return mainAlignment
519
520 def _msgLabelActivated(self, button, cycle_group, messageType):
521 """Called when the mnemonic of a label is activated.
522
523 It cycles the corresponding options."""
524 fsCheckButton = self._msgFSCheckButtons[messageType]
525 soundCheckButton = self._msgSoundCheckButtons[messageType]
526
527 num = 1 if fsCheckButton.get_active() else 0
528 num += 2 if soundCheckButton.get_active() else 0
529 num += 1
530
531 fsCheckButton.set_active((num&0x01)==0x01)
532 soundCheckButton.set_active((num&0x02)==0x02)
533
534 return True
535
536 def _buildSounds(self):
537 """Build the page for the sounds."""
538 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
539 xscale = 1.0, yscale = 1.0)
540 mainAlignment.set_padding(padding_top = 8, padding_bottom = 8,
541 padding_left = 4, padding_right = 4)
542
543 mainBox = gtk.VBox()
544 mainAlignment.add(mainBox)
545
546 backgroundFrame = gtk.Frame(label = xstr("prefs_sounds_frame_bg"))
547 mainBox.pack_start(backgroundFrame, False, False, 4)
548
549 backgroundAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
550 xscale = 1.0, yscale = 0.0)
551 backgroundAlignment.set_padding(padding_top = 4, padding_bottom = 4,
552 padding_left = 4, padding_right = 4)
553 backgroundFrame.add(backgroundAlignment)
554
555 backgroundBox = gtk.VBox()
556 backgroundAlignment.add(backgroundBox)
557
558 self._enableSounds = gtk.CheckButton(xstr("prefs_sounds_enable"))
559 self._enableSounds.set_use_underline(True)
560 self._enableSounds.set_tooltip_text(xstr("prefs_sounds_enable_tooltip"))
561 self._enableSounds.connect("toggled", self._enableSoundsToggled)
562 alignment = gtk.Alignment(xalign = 0.0, yalign = 0.5,
563 xscale = 1.0, yscale = 0.0)
564 alignment.add(self._enableSounds)
565 backgroundBox.pack_start(alignment, False, False, 4)
566
567 self._pilotControlsSounds = gtk.CheckButton(xstr("prefs_sounds_pilotControls"))
568 self._pilotControlsSounds.set_use_underline(True)
569 self._pilotControlsSounds.set_tooltip_text(xstr("prefs_sounds_pilotControls_tooltip"))
570 self._pilotControlsSounds.connect("toggled", self._pilotControlsSoundsToggled)
571 backgroundBox.pack_start(self._pilotControlsSounds, False, False, 4)
572
573 self._pilotHotkey = Hotkey(xstr("prefs_sounds_pilotHotkey"),
574 [xstr("prefs_sounds_pilotHotkey_tooltip"),
575 xstr("prefs_sounds_pilotHotkeyCtrl_tooltip"),
576 xstr("prefs_sounds_pilotHotkeyShift_tooltip")])
577
578 backgroundBox.pack_start(self._pilotHotkey, False, False, 4)
579
580 # self._approachCallOuts = gtk.CheckButton(xstr("prefs_sounds_approachCallOuts"))
581 # self._approachCallOuts.set_use_underline(True)
582 # self._approachCallOuts.set_tooltip_text(xstr("prefs_sounds_approachCallOuts_tooltip"))
583 # backgroundBox.pack_start(self._approachCallOuts, False, False, 4)
584
585 self._speedbrakeAtTD = gtk.CheckButton(xstr("prefs_sounds_speedbrakeAtTD"))
586 self._speedbrakeAtTD.set_use_underline(True)
587 self._speedbrakeAtTD.set_tooltip_text(xstr("prefs_sounds_speedbrakeAtTD_tooltip"))
588 backgroundBox.pack_start(self._speedbrakeAtTD, False, False, 4)
589
590 checklistFrame = gtk.Frame(label = xstr("prefs_sounds_frame_checklists"))
591 mainBox.pack_start(checklistFrame, False, False, 4)
592
593 checklistAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
594 xscale = 1.0, yscale = 0.0)
595 checklistAlignment.set_padding(padding_top = 4, padding_bottom = 4,
596 padding_left = 4, padding_right = 4)
597 checklistFrame.add(checklistAlignment)
598
599 checklistBox = gtk.VBox()
600 checklistAlignment.add(checklistBox)
601
602 self._enableChecklists = gtk.CheckButton(xstr("prefs_sounds_enableChecklists"))
603 self._enableChecklists.set_use_underline(True)
604 self._enableChecklists.set_tooltip_text(xstr("prefs_sounds_enableChecklists_tooltip"))
605 self._enableChecklists.connect("toggled", self._enableChecklistsToggled)
606 checklistBox.pack_start(self._enableChecklists, False, False, 4)
607
608 self._checklistHotkey = Hotkey(xstr("prefs_sounds_checklistHotkey"),
609 [xstr("prefs_sounds_checklistHotkey_tooltip"),
610 xstr("prefs_sounds_checklistHotkeyCtrl_tooltip"),
611 xstr("prefs_sounds_checklistHotkeyShift_tooltip")])
612
613 checklistBox.pack_start(self._checklistHotkey, False, False, 4)
614
615 self._enableSoundsToggled(self._enableSounds)
616 self._enableChecklistsToggled(self._enableChecklists)
617
618 self._pilotHotkey.connect("hotkey-changed", self._reconcileHotkeys,
619 self._checklistHotkey)
620 self._checklistHotkey.connect("hotkey-changed", self._reconcileHotkeys,
621 self._pilotHotkey)
622
623 return mainAlignment
624
625 def _enableSoundsToggled(self, button):
626 """Called when the enable sounds button is toggled."""
627 active = button.get_active()
628 self._pilotControlsSounds.set_sensitive(active)
629 self._pilotControlsSoundsToggled(self._pilotControlsSounds)
630 #self._approachCallOuts.set_sensitive(active)
631 self._speedbrakeAtTD.set_sensitive(active)
632
633 def _pilotControlsSoundsToggled(self, button):
634 """Called when the enable sounds button is toggled."""
635 active = button.get_active() and self._enableSounds.get_active()
636 self._pilotHotkey.set_sensitive(active)
637 if active and self._checklistHotkey.get_sensitive():
638 self._reconcileHotkeys(self._checklistHotkey, Hotkey.CHANGED_SHIFT,
639 self._pilotHotkey)
640
641 def _enableChecklistsToggled(self, button):
642 """Called when the enable checklists button is toggled."""
643 active = button.get_active()
644 self._checklistHotkey.set_sensitive(active)
645 if active and self._pilotHotkey.get_sensitive():
646 self._reconcileHotkeys(self._pilotHotkey, Hotkey.CHANGED_SHIFT,
647 self._checklistHotkey)
648
649 def _reconcileHotkeys(self, changedHotkey, what, otherHotkey):
650 """Reconcile the given hotkeys so that they are different.
651
652 changedHotkey is the hotkey that has changed. what is one of the
653 Hotkey.CHANGED_XXX constants denoting what has changed. otherHotkey is
654 the other hotkey that must be reconciled.
655
656 If the other hotkey is not sensitive or is not equal to the changed
657 one, nothing happens.
658
659 Otherwise, if the status of the Ctrl modifier has changed, the status
660 of the Ctrl modifier on the other hotkey will be negated. Similarly, if
661 the Shift modifier has changed. If the key has changed, the Shift
662 modifier is negated in the other hotkey."""
663 if otherHotkey.get_sensitive() and changedHotkey==otherHotkey:
664 if what==Hotkey.CHANGED_CTRL:
665 otherHotkey.ctrl = not changedHotkey.ctrl
666 elif what==Hotkey.CHANGED_SHIFT or what==Hotkey.CHANGED_KEY:
667 otherHotkey.shift = not changedHotkey.shift
668
669 def _buildAdvanced(self):
670 """Build the page for the advanced settings."""
671
672 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
673 xscale = 1.0, yscale = 0.0)
674 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
675 padding_left = 4, padding_right = 4)
676 mainBox = gtk.VBox()
677 mainAlignment.add(mainBox)
678
679 self._autoUpdate = gtk.CheckButton(xstr("prefs_update_auto"))
680 mainBox.pack_start(self._autoUpdate, False, False, 4)
681
682 self._autoUpdate.set_use_underline(True)
683 self._autoUpdate.connect("toggled", self._autoUpdateToggled)
684 self._autoUpdate.set_tooltip_text(xstr("prefs_update_auto_tooltip"))
685 self._warnedAutoUpdate = False
686
687 updateURLBox = gtk.HBox()
688 mainBox.pack_start(updateURLBox, False, False, 4)
689 label = gtk.Label(xstr("prefs_update_url"))
690 label.set_use_underline(True)
691 updateURLBox.pack_start(label, False, False, 4)
692
693 self._updateURL = gtk.Entry()
694 label.set_mnemonic_widget(self._updateURL)
695 self._updateURL.set_width_chars(40)
696 self._updateURL.set_tooltip_text(xstr("prefs_update_url_tooltip"))
697 self._updateURL.connect("changed", self._updateURLChanged)
698 updateURLBox.pack_start(self._updateURL, True, True, 4)
699
700 return mainAlignment
701
702 def _setOKButtonSensitivity(self):
703 """Set the sensitive state of the OK button."""
704 sensitive = False
705 try:
706 result = urlparse.urlparse(self._updateURL.get_text())
707 sensitive = result.scheme!="" and (result.netloc + result.path)!=""
708 except:
709 pass
710
711 okButton = self.get_widget_for_response(RESPONSETYPE_ACCEPT)
712 okButton.set_sensitive(sensitive)
713
714 def _autoUpdateToggled(self, button):
715 """Called when the auto update check button is toggled."""
716 if not self._settingFromConfig and not self._warnedAutoUpdate and \
717 not self._autoUpdate.get_active():
718 dialog = gtk.MessageDialog(parent = self,
719 type = MESSAGETYPE_INFO,
720 message_format = xstr("prefs_update_auto_warning"))
721 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
722 dialog.set_title(self.get_title())
723 dialog.run()
724 dialog.hide()
725 self._warnedAutoUpdate = True
726
727 def _updateURLChanged(self, entry):
728 """Called when the update URL is changed."""
729 self._setOKButtonSensitivity()
730
Note: See TracBrowser for help on using the repository browser.