source: src/mlx/gui/prefs.py@ 159:5a0078210fff

Last change on this file since 159:5a0078210fff was 151:a2584357ff6c, checked in by István Váradi <ivaradi@…>, 13 years ago

Added support for saving and loading PIREPs

File size: 16.3 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
9
10import urlparse
11
12#------------------------------------------------------------------------------
13
14class Preferences(gtk.Dialog):
15 """The preferences dialog."""
16 def __init__(self, gui):
17 """Construct the dialog."""
18 super(Preferences, self).__init__(WINDOW_TITLE_BASE + " " +
19 xstr("prefs_title"),
20 gui.mainWindow,
21 DIALOG_MODAL)
22
23 self.add_button(xstr("button_cancel"), RESPONSETYPE_REJECT)
24 self.add_button(xstr("button_ok"), RESPONSETYPE_ACCEPT)
25
26 self._gui = gui
27
28 contentArea = self.get_content_area()
29
30 notebook = gtk.Notebook()
31 contentArea.pack_start(notebook, True, True, 4)
32
33 general = self._buildGeneral()
34 label = gtk.Label(xstr("prefs_tab_general"))
35 label.set_use_underline(True)
36 label.set_tooltip_text(xstr("prefs_tab_general_tooltip"))
37 notebook.append_page(general, label)
38
39 messages = self._buildMessages()
40 label = gtk.Label(xstr("prefs_tab_messages"))
41 label.set_use_underline(True)
42 label.set_tooltip_text(xstr("prefs_tab_message_tooltip"))
43 notebook.append_page(messages, label)
44
45 advanced = self._buildAdvanced()
46 label = gtk.Label(xstr("prefs_tab_advanced"))
47 label.set_use_underline(True)
48 label.set_tooltip_text(xstr("prefs_tab_advanced_tooltip"))
49 notebook.append_page(advanced, label)
50
51 def run(self, config):
52 """Run the preferences dialog.
53
54 The dialog will be set up from data in the given configuration. If the
55 changes are accepted by the user, the configuration is updated and saved."""
56 self._fromConfig(config)
57
58 self.show_all()
59 response = super(Preferences, self).run()
60 self.hide()
61
62 if response==RESPONSETYPE_ACCEPT:
63 self._toConfig(config)
64 config.save()
65
66 def _fromConfig(self, config):
67 """Setup the dialog from the given configuration."""
68 self._setLanguage(config.language)
69 self._hideMinimizedWindow.set_active(config.hideMinimizedWindow)
70 self._onlineGateSystem.set_active(config.onlineGateSystem)
71 self._onlineACARS.set_active(config.onlineACARS)
72 self._flareTimeFromFS.set_active(config.flareTimeFromFS)
73 self._syncFSTime.set_active(config.syncFSTime)
74
75 pirepDirectory = config.pirepDirectory
76 self._pirepDirectory.set_text("" if pirepDirectory is None
77 else pirepDirectory)
78
79 for messageType in const.messageTypes:
80 level = config.getMessageTypeLevel(messageType)
81 button = self._msgFSCheckButtons[messageType]
82 button.set_active(level == const.MESSAGELEVEL_FS or
83 level == const.MESSAGELEVEL_BOTH)
84 button = self._msgSoundCheckButtons[messageType]
85 button.set_active(level == const.MESSAGELEVEL_SOUND or
86 level == const.MESSAGELEVEL_BOTH)
87
88 self._togglingAutoUpdate = True
89 self._autoUpdate.set_active(config.autoUpdate)
90 self._togglingAutoUpdate = False
91 if not config.autoUpdate:
92 self._warnedAutoUpdate = True
93
94 self._updateURL.set_text(config.updateURL)
95
96 def _toConfig(self, config):
97 """Setup the given config from the settings in the dialog."""
98 config.language = self._getLanguage()
99 config.hideMinimizedWindow = self._hideMinimizedWindow.get_active()
100 config.onlineGateSystem = self._onlineGateSystem.get_active()
101 config.onlineACARS = self._onlineACARS.get_active()
102 config.flareTimeFromFS = self._flareTimeFromFS.get_active()
103 config.syncFSTime = self._syncFSTime.get_active()
104 config.pirepDirectory = self._pirepDirectory.get_text()
105
106 for messageType in const.messageTypes:
107 fsButtonActive = self._msgFSCheckButtons[messageType].get_active()
108 soundButtonActive = self._msgSoundCheckButtons[messageType].get_active()
109 if fsButtonActive:
110 level = const.MESSAGELEVEL_BOTH if soundButtonActive \
111 else const.MESSAGELEVEL_FS
112 elif soundButtonActive:
113 level = const.MESSAGELEVEL_SOUND
114 else:
115 level = const.MESSAGELEVEL_NONE
116 config.setMessageTypeLevel(messageType, level)
117
118 config.autoUpdate = self._autoUpdate.get_active()
119 config.updateURL = self._updateURL.get_text()
120
121 def _buildGeneral(self):
122 """Build the page for the general settings."""
123 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
124 xscale = 1.0, yscale = 0.0)
125 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
126 padding_left = 4, padding_right = 4)
127 mainBox = gtk.VBox()
128 mainAlignment.add(mainBox)
129
130 languageBox = gtk.HBox()
131 mainBox.pack_start(languageBox, False, False, 4)
132
133 label = gtk.Label(xstr("prefs_language"))
134 label.set_use_underline(True)
135
136 languageBox.pack_start(label, False, False, 4)
137
138 self._languageList = gtk.ListStore(str, str)
139 for language in const.languages:
140 self._languageList.append([xstr("prefs_lang_" + language),
141 language])
142
143 self._languageComboBox = languageComboBox = \
144 gtk.ComboBox(model = self._languageList)
145 cell = gtk.CellRendererText()
146 languageComboBox.pack_start(cell, True)
147 languageComboBox.add_attribute(cell, 'text', 0)
148 languageComboBox.set_tooltip_text(xstr("prefs_language_tooltip"))
149 languageComboBox.connect("changed", self._languageChanged)
150 languageBox.pack_start(languageComboBox, False, False, 4)
151
152 label.set_mnemonic_widget(languageComboBox)
153
154 self._changingLanguage = False
155 self._warnedRestartNeeded = False
156
157 self._hideMinimizedWindow = gtk.CheckButton(xstr("prefs_hideMinimizedWindow"))
158 self._hideMinimizedWindow.set_use_underline(True)
159 self._hideMinimizedWindow.set_tooltip_text(xstr("prefs_hideMinimizedWindow_tooltip"))
160 mainBox.pack_start(self._hideMinimizedWindow, False, False, 4)
161
162 self._onlineGateSystem = gtk.CheckButton(xstr("prefs_onlineGateSystem"))
163 self._onlineGateSystem.set_use_underline(True)
164 self._onlineGateSystem.set_tooltip_text(xstr("prefs_onlineGateSystem_tooltip"))
165 mainBox.pack_start(self._onlineGateSystem, False, False, 4)
166
167 self._onlineACARS = gtk.CheckButton(xstr("prefs_onlineACARS"))
168 self._onlineACARS.set_use_underline(True)
169 self._onlineACARS.set_tooltip_text(xstr("prefs_onlineACARS_tooltip"))
170 mainBox.pack_start(self._onlineACARS, False, False, 4)
171
172 self._flareTimeFromFS = gtk.CheckButton(xstr("prefs_flaretimeFromFS"))
173 self._flareTimeFromFS.set_use_underline(True)
174 self._flareTimeFromFS.set_tooltip_text(xstr("prefs_flaretimeFromFS_tooltip"))
175 mainBox.pack_start(self._flareTimeFromFS, False, False, 4)
176
177 self._syncFSTime = gtk.CheckButton(xstr("prefs_syncFSTime"))
178 self._syncFSTime.set_use_underline(True)
179 self._syncFSTime.set_tooltip_text(xstr("prefs_syncFSTime_tooltip"))
180 mainBox.pack_start(self._syncFSTime, False, False, 4)
181
182 pirepBox = gtk.HBox()
183 mainBox.pack_start(pirepBox, False, False, 4)
184
185 label = gtk.Label(xstr("prefs_pirepDirectory"))
186 label.set_use_underline(True)
187 pirepBox.pack_start(label, False, False, 4)
188
189 self._pirepDirectory = gtk.Entry()
190 self._pirepDirectory.set_tooltip_text(xstr("prefs_pirepDirectory_tooltip"))
191 label.set_mnemonic_widget(self._pirepDirectory)
192 pirepBox.pack_start(self._pirepDirectory, True, True, 4)
193
194 self._pirepDirectoryButton = gtk.Button(xstr("button_browse"))
195 self._pirepDirectoryButton.connect("clicked",
196 self._pirepDirectoryButtonClicked)
197 pirepBox.pack_start(self._pirepDirectoryButton, False, False, 4)
198
199 return mainAlignment
200
201 def _setLanguage(self, language):
202 """Set the language to the given one."""
203 iter = self._languageList.get_iter_first()
204 while iter is not None:
205 (lang,) = self._languageList.get(iter, 1)
206 if (not language and lang=="$system") or \
207 lang==language:
208 self._changingLanguage = True
209 self._languageComboBox.set_active_iter(iter)
210 self._changingLanguage = False
211 break
212 else:
213 iter = self._languageList.iter_next(iter)
214
215 def _getLanguage(self):
216 """Get the language selected by the user."""
217 iter = self._languageComboBox.get_active_iter()
218 (lang,) = self._languageList.get(iter, 1)
219 return "" if lang=="$system" else lang
220
221 def _languageChanged(self, comboBox):
222 """Called when the language has changed."""
223 if not self._changingLanguage and not self._warnedRestartNeeded:
224 dialog = gtk.MessageDialog(parent = self,
225 type = MESSAGETYPE_INFO,
226 message_format = xstr("prefs_restart"))
227 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
228 dialog.set_title(self.get_title())
229 dialog.format_secondary_markup(xstr("prefs_language_restart_sec"))
230 dialog.run()
231 dialog.hide()
232 self._warnedRestartNeeded = True
233
234 def _pirepDirectoryButtonClicked(self, button):
235 """Called when the PIREP directory button is clicked."""
236 dialog = gtk.FileChooserDialog(title = WINDOW_TITLE_BASE + " - " +
237 xstr("prefs_pirepDirectory_browser_title"),
238 action = FILE_CHOOSER_ACTION_SELECT_FOLDER,
239 buttons = (gtk.STOCK_CANCEL, RESPONSETYPE_CANCEL,
240 gtk.STOCK_OK, RESPONSETYPE_OK),
241 parent = self)
242 dialog.set_modal(True)
243 dialog.set_transient_for(self)
244
245 directory = self._pirepDirectory.get_text()
246 if directory:
247 dialog.select_filename(directory)
248
249 result = dialog.run()
250 dialog.hide()
251
252 if result==RESPONSETYPE_OK:
253 self._pirepDirectory.set_text(dialog.get_filename())
254
255 def _buildMessages(self):
256 """Build the page for the message settings."""
257
258 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
259 xscale = 0.0, yscale = 0.0)
260 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
261 padding_left = 4, padding_right = 4)
262 mainBox = gtk.VBox()
263 mainAlignment.add(mainBox)
264
265 table = gtk.Table(len(const.messageTypes) + 1, 3)
266 table.set_row_spacings(8)
267 table.set_col_spacings(32)
268 table.set_homogeneous(False)
269 mainBox.pack_start(table, False, False, 4)
270
271 label = gtk.Label(xstr("prefs_msgs_fs"))
272 label.set_justify(JUSTIFY_CENTER)
273 label.set_alignment(0.5, 1.0)
274 table.attach(label, 1, 2, 0, 1)
275
276 label = gtk.Label(xstr("prefs_msgs_sound"))
277 label.set_justify(JUSTIFY_CENTER)
278 label.set_alignment(0.5, 1.0)
279 table.attach(label, 2, 3, 0, 1)
280
281 self._msgFSCheckButtons = {}
282 self._msgSoundCheckButtons = {}
283 row = 1
284 for messageType in const.messageTypes:
285 messageTypeStr = const.messageType2string(messageType)
286 label = gtk.Label(xstr("prefs_msgs_type_" + messageTypeStr))
287 label.set_justify(JUSTIFY_CENTER)
288 label.set_use_underline(True)
289 label.set_alignment(0.5, 0.5)
290 table.attach(label, 0, 1, row, row+1)
291
292 fsCheckButton = gtk.CheckButton()
293 alignment = gtk.Alignment(xscale = 0.0, yscale = 0.0,
294 xalign = 0.5, yalign = 0.5)
295 alignment.add(fsCheckButton)
296 table.attach(alignment, 1, 2, row, row+1)
297 self._msgFSCheckButtons[messageType] = fsCheckButton
298
299 soundCheckButton = gtk.CheckButton()
300 alignment = gtk.Alignment(xscale = 0.0, yscale = 0.0,
301 xalign = 0.5, yalign = 0.5)
302 alignment.add(soundCheckButton)
303 table.attach(alignment, 2, 3, row, row+1)
304 self._msgSoundCheckButtons[messageType] = soundCheckButton
305
306 mnemonicWidget = gtk.Label("")
307 table.attach(mnemonicWidget, 3, 4, row, row+1)
308 label.set_mnemonic_widget(mnemonicWidget)
309 mnemonicWidget.connect("mnemonic-activate",
310 self._msgLabelActivated,
311 messageType)
312
313 row += 1
314
315 return mainAlignment
316
317 def _msgLabelActivated(self, button, cycle_group, messageType):
318 """Called when the mnemonic of a label is activated.
319
320 It cycles the corresponding options."""
321 fsCheckButton = self._msgFSCheckButtons[messageType]
322 soundCheckButton = self._msgSoundCheckButtons[messageType]
323
324 num = 1 if fsCheckButton.get_active() else 0
325 num += 2 if soundCheckButton.get_active() else 0
326 num += 1
327
328 fsCheckButton.set_active((num&0x01)==0x01)
329 soundCheckButton.set_active((num&0x02)==0x02)
330
331 return True
332
333 def _buildAdvanced(self):
334 """Build the page for the advanced settings."""
335
336 mainAlignment = gtk.Alignment(xalign = 0.0, yalign = 0.0,
337 xscale = 1.0, yscale = 0.0)
338 mainAlignment.set_padding(padding_top = 16, padding_bottom = 8,
339 padding_left = 4, padding_right = 4)
340 mainBox = gtk.VBox()
341 mainAlignment.add(mainBox)
342
343 self._autoUpdate = gtk.CheckButton(xstr("prefs_update_auto"))
344 mainBox.pack_start(self._autoUpdate, False, False, 4)
345
346 self._autoUpdate.set_use_underline(True)
347 self._autoUpdate.connect("toggled", self._autoUpdateToggled)
348 self._autoUpdate.set_tooltip_text(xstr("prefs_update_auto_tooltip"))
349 self._warnedAutoUpdate = False
350 self._togglingAutoUpdate = False
351
352 updateURLBox = gtk.HBox()
353 mainBox.pack_start(updateURLBox, False, False, 4)
354 label = gtk.Label(xstr("prefs_update_url"))
355 label.set_use_underline(True)
356 updateURLBox.pack_start(label, False, False, 4)
357
358 self._updateURL = gtk.Entry()
359 label.set_mnemonic_widget(self._updateURL)
360 self._updateURL.set_width_chars(40)
361 self._updateURL.set_tooltip_text(xstr("prefs_update_url_tooltip"))
362 self._updateURL.connect("changed", self._updateURLChanged)
363 updateURLBox.pack_start(self._updateURL, True, True, 4)
364
365 return mainAlignment
366
367 def _setOKButtonSensitivity(self):
368 """Set the sensitive state of the OK button."""
369 sensitive = False
370 try:
371 result = urlparse.urlparse(self._updateURL.get_text())
372 sensitive = result.scheme!="" and (result.netloc + result.path)!=""
373 except:
374 pass
375
376 okButton = self.get_widget_for_response(RESPONSETYPE_ACCEPT)
377 okButton.set_sensitive(sensitive)
378
379 def _autoUpdateToggled(self, button):
380 """Called when the auto update check button is toggled."""
381 if not self._togglingAutoUpdate and not self._warnedAutoUpdate and \
382 not self._autoUpdate.get_active():
383 dialog = gtk.MessageDialog(parent = self,
384 type = MESSAGETYPE_INFO,
385 message_format = xstr("prefs_update_auto_warning"))
386 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK)
387 dialog.set_title(self.get_title())
388 dialog.run()
389 dialog.hide()
390 self._warnedAutoUpdate = True
391
392 def _updateURLChanged(self, entry):
393 """Called when the update URL is changed."""
394 self._setOKButtonSensitivity()
Note: See TracBrowser for help on using the repository browser.