Small fix for the custom sync name info message
[gpodder.git] / src / gpodder / gtkui / desktop / preferences.py
blob74e206b23d6d27f43f1426fa0c0426db01afe358
1 # -*- coding: utf-8 -*-
3 # gPodder - A media aggregator and podcast client
4 # Copyright (c) 2005-2009 Thomas Perl and the gPodder Team
6 # gPodder is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # gPodder is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import gtk
22 import gpodder
24 _ = gpodder.gettext
26 from gpodder.gtkui.interface.common import BuilderWidget
27 from gpodder.gtkui.interface.configeditor import gPodderConfigEditor
29 class gPodderPreferences(BuilderWidget):
30 def new(self):
31 if not hasattr( self, 'callback_finished'):
32 self.callback_finished = None
34 self._config.connect_gtk_editable( 'player', self.openApp)
35 self._config.connect_gtk_editable('videoplayer', self.openVideoApp)
36 self._config.connect_gtk_editable( 'custom_sync_name', self.entryCustomSyncName)
37 self._config.connect_gtk_togglebutton( 'custom_sync_name_enabled', self.cbCustomSyncName)
38 self._config.connect_gtk_togglebutton( 'update_on_startup', self.updateonstartup)
39 self._config.connect_gtk_togglebutton( 'only_sync_not_played', self.only_sync_not_played)
40 self._config.connect_gtk_togglebutton( 'fssync_channel_subfolders', self.cbChannelSubfolder)
41 self._config.connect_gtk_togglebutton( 'on_sync_mark_played', self.on_sync_mark_played)
42 self._config.connect_gtk_togglebutton( 'on_sync_delete', self.on_sync_delete)
43 self._config.connect_gtk_spinbutton('episode_old_age', self.episode_old_age)
44 self._config.connect_gtk_togglebutton('auto_remove_old_episodes', self.auto_remove_old_episodes)
45 self._config.connect_gtk_togglebutton('auto_update_feeds', self.auto_update_feeds)
46 self._config.connect_gtk_spinbutton('auto_update_frequency', self.auto_update_frequency)
47 self._config.connect_gtk_togglebutton('display_tray_icon', self.display_tray_icon)
48 self._config.connect_gtk_togglebutton('minimize_to_tray', self.minimize_to_tray)
49 self._config.connect_gtk_togglebutton('enable_notifications', self.enable_notifications)
50 self._config.connect_gtk_togglebutton('start_iconified', self.start_iconified)
51 self._config.connect_gtk_togglebutton('ipod_delete_played_from_db', self.ipod_delete_played_from_db)
52 self._config.connect_gtk_togglebutton('mp3_player_delete_played', self.delete_episodes_marked_played)
53 self._config.connect_gtk_togglebutton('disable_pre_sync_conversion', self.player_supports_ogg)
55 self.enable_notifications.set_sensitive(self.display_tray_icon.get_active())
56 self.minimize_to_tray.set_sensitive(self.display_tray_icon.get_active())
58 self.entryCustomSyncName.set_sensitive( self.cbCustomSyncName.get_active())
60 self.iPodMountpoint.set_label( self._config.ipod_mount)
61 self.filesystemMountpoint.set_label( self._config.mp3_player_folder)
62 self.chooserDownloadTo.set_current_folder(self._config.download_dir)
64 self.on_sync_delete.set_sensitive(not self.delete_episodes_marked_played.get_active())
65 self.on_sync_mark_played.set_sensitive(not self.delete_episodes_marked_played.get_active())
67 # device type
68 self.comboboxDeviceType.set_active( 0)
69 if self._config.device_type == 'ipod':
70 self.comboboxDeviceType.set_active( 1)
71 elif self._config.device_type == 'filesystem':
72 self.comboboxDeviceType.set_active( 2)
73 elif self._config.device_type == 'mtp':
74 self.comboboxDeviceType.set_active( 3)
76 # setup cell renderers
77 cellrenderer = gtk.CellRendererPixbuf()
78 self.comboAudioPlayerApp.pack_start(cellrenderer, False)
79 self.comboAudioPlayerApp.add_attribute(cellrenderer, 'pixbuf', 2)
80 cellrenderer = gtk.CellRendererText()
81 self.comboAudioPlayerApp.pack_start(cellrenderer, True)
82 self.comboAudioPlayerApp.add_attribute(cellrenderer, 'markup', 0)
84 cellrenderer = gtk.CellRendererPixbuf()
85 self.comboVideoPlayerApp.pack_start(cellrenderer, False)
86 self.comboVideoPlayerApp.add_attribute(cellrenderer, 'pixbuf', 2)
87 cellrenderer = gtk.CellRendererText()
88 self.comboVideoPlayerApp.pack_start(cellrenderer, True)
89 self.comboVideoPlayerApp.add_attribute(cellrenderer, 'markup', 0)
91 if not hasattr(self, 'user_apps_reader'):
92 self.user_apps_reader = UserAppsReader(['audio', 'video'])
94 self.comboAudioPlayerApp.set_row_separator_func(self.is_row_separator)
95 self.comboVideoPlayerApp.set_row_separator_func(self.is_row_separator)
97 self.user_apps_reader.read()
99 self.comboAudioPlayerApp.set_model(self.user_apps_reader.get_applications_as_model('audio'))
100 index = self.find_active_audio_app()
101 self.comboAudioPlayerApp.set_active(index)
102 self.comboVideoPlayerApp.set_model(self.user_apps_reader.get_applications_as_model('video'))
103 index = self.find_active_video_app()
104 self.comboVideoPlayerApp.set_active(index)
106 # auto download option
107 self.comboboxAutoDownload.set_active( 0)
108 if self._config.auto_download == 'minimized':
109 self.comboboxAutoDownload.set_active( 1)
110 elif self._config.auto_download == 'always':
111 self.comboboxAutoDownload.set_active( 2)
113 def is_row_separator(self, model, iter):
114 return model.get_value(iter, 0) == ''
116 def update_mountpoint( self, ipod):
117 if ipod is None or ipod.mount_point is None:
118 self.iPodMountpoint.set_label( '')
119 else:
120 self.iPodMountpoint.set_label( ipod.mount_point)
122 def find_active_audio_app(self):
123 index_custom = -1
124 model = self.comboAudioPlayerApp.get_model()
125 iter = model.get_iter_first()
126 index = 0
127 while iter is not None:
128 command = model.get_value(iter, 1)
129 if command == self.openApp.get_text():
130 return index
131 if index_custom < 0 and command == '':
132 index_custom = index
133 iter = model.iter_next(iter)
134 index += 1
135 # return index of custom command or first item
136 return max(0, index_custom)
138 def find_active_video_app( self):
139 index_custom = -1
140 model = self.comboVideoPlayerApp.get_model()
141 iter = model.get_iter_first()
142 index = 0
143 while iter is not None:
144 command = model.get_value(iter, 1)
145 if command == self.openVideoApp.get_text():
146 return index
147 if index_custom < 0 and command == '':
148 index_custom = index
149 iter = model.iter_next(iter)
150 index += 1
151 # return index of custom command or first item
152 return max(0, index_custom)
154 def on_auto_update_feeds_toggled( self, widget, *args):
155 self.auto_update_frequency.set_sensitive(widget.get_active())
157 def on_display_tray_icon_toggled( self, widget, *args):
158 self.enable_notifications.set_sensitive(widget.get_active())
159 self.minimize_to_tray.set_sensitive(widget.get_active())
161 def on_cbCustomSyncName_toggled( self, widget, *args):
162 self.entryCustomSyncName.set_sensitive( widget.get_active())
164 def on_only_sync_not_played_toggled( self, widget, *args):
165 self.delete_episodes_marked_played.set_sensitive( widget.get_active())
166 if not widget.get_active():
167 self.delete_episodes_marked_played.set_active(False)
169 def on_delete_episodes_marked_played_toggled( self, widget, *args):
170 if widget.get_active() and self.only_sync_not_played.get_active():
171 self.on_sync_leave.set_active(True)
172 self.on_sync_delete.set_sensitive(not widget.get_active())
173 self.on_sync_mark_played.set_sensitive(not widget.get_active())
175 def on_btnCustomSyncNameHelp_clicked( self, widget):
176 examples = [
177 '<i>{episode.title}</i> -&gt; <b>Interview with RMS</b>',
178 '<i>{episode.filename}</i> -&gt; <b>70908-interview-rms</b>',
179 '<i>{episode.published}</i> -&gt; <b>20070908</b> (for 08.09.2007)',
180 '<i>{episode.pubtime}</i> -&gt; <b>1344</b> (for 13:44)',
181 '<i>{podcast.title}</i> -&gt; <b>The Interview Podcast</b>'
184 info = [
185 _('You can specify a custom format string for the file names on your MP3 player here.'),
186 _('The format string will be used to generate a file name on your device. The file extension (e.g. ".mp3") will be added automatically.'),
187 '\n'.join( [ ' %s' % s for s in examples ])
190 self.show_message('\n\n'.join(info), _('Custom format strings'), important=True)
192 def on_gPodderPreferences_destroy(self, widget, *args):
193 self.on_btnOK_clicked( widget, *args)
195 def on_btnConfigEditor_clicked(self, widget, *args):
196 gPodderConfigEditor(self.gPodderPreferences, _config=self._config)
197 self.on_btnOK_clicked(widget, *args)
199 def on_comboAudioPlayerApp_changed(self, widget, *args):
200 # find out which one
201 iter = self.comboAudioPlayerApp.get_active_iter()
202 model = self.comboAudioPlayerApp.get_model()
203 command = model.get_value( iter, 1)
204 if command == '':
205 if self.openApp.get_text() == 'default':
206 self.openApp.set_text('')
207 self.openApp.set_sensitive( True)
208 self.openApp.show()
209 self.labelCustomCommand.show()
210 else:
211 self.openApp.set_text( command)
212 self.openApp.set_sensitive( False)
213 self.openApp.hide()
214 self.labelCustomCommand.hide()
216 def on_comboVideoPlayerApp_changed(self, widget, *args):
217 # find out which one
218 iter = self.comboVideoPlayerApp.get_active_iter()
219 model = self.comboVideoPlayerApp.get_model()
220 command = model.get_value(iter, 1)
221 if command == '':
222 if self.openVideoApp.get_text() == 'default':
223 self.openVideoApp.set_text('')
224 self.openVideoApp.set_sensitive(True)
225 self.openVideoApp.show()
226 self.labelCustomVideoCommand.show()
227 else:
228 self.openVideoApp.set_text(command)
229 self.openVideoApp.set_sensitive(False)
230 self.openVideoApp.hide()
231 self.labelCustomVideoCommand.hide()
233 def on_cbEnvironmentVariables_toggled(self, widget, *args):
234 sens = not self.cbEnvironmentVariables.get_active()
235 self.httpProxy.set_sensitive( sens)
237 def on_comboboxDeviceType_changed(self, widget, *args):
238 active_item = self.comboboxDeviceType.get_active()
240 # None
241 sync_widgets = ( self.only_sync_not_played, self.labelSyncOptions,
242 self.imageSyncOptions, self. separatorSyncOptions,
243 self.on_sync_mark_played, self.on_sync_delete,
244 self.on_sync_leave, self.label_after_sync,
245 self.delete_episodes_marked_played,
246 self.player_supports_ogg )
248 for widget in sync_widgets:
249 if active_item == 0:
250 widget.hide_all()
251 else:
252 widget.show_all()
254 # iPod
255 ipod_widgets = (self.ipodLabel, self.btn_iPodMountpoint,
256 self.ipod_delete_played_from_db)
258 for widget in ipod_widgets:
259 if active_item == 1:
260 widget.show_all()
261 else:
262 widget.hide_all()
264 # filesystem-based MP3 player
265 fs_widgets = ( self.filesystemLabel, self.btn_filesystemMountpoint,
266 self.cbChannelSubfolder, self.cbCustomSyncName,
267 self.entryCustomSyncName, self.btnCustomSyncNameHelp,
268 self.player_supports_ogg )
270 for widget in fs_widgets:
271 if active_item == 2:
272 widget.show_all()
273 else:
274 widget.hide_all()
276 def on_btn_iPodMountpoint_clicked(self, widget, *args):
277 fs = gtk.FileChooserDialog( title = _('Select iPod mountpoint'), action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
278 fs.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
279 fs.add_button( gtk.STOCK_OPEN, gtk.RESPONSE_OK)
280 fs.set_current_folder(self.iPodMountpoint.get_label())
281 if fs.run() == gtk.RESPONSE_OK:
282 self.iPodMountpoint.set_label( fs.get_filename())
283 fs.destroy()
285 def on_btn_FilesystemMountpoint_clicked(self, widget, *args):
286 fs = gtk.FileChooserDialog( title = _('Select folder for MP3 player'), action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
287 fs.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
288 fs.add_button( gtk.STOCK_OPEN, gtk.RESPONSE_OK)
289 fs.set_current_folder(self.filesystemMountpoint.get_label())
290 if fs.run() == gtk.RESPONSE_OK:
291 self.filesystemMountpoint.set_label( fs.get_filename())
292 fs.destroy()
294 def on_btnOK_clicked(self, widget, *args):
295 self._config.ipod_mount = self.iPodMountpoint.get_label()
296 self._config.mp3_player_folder = self.filesystemMountpoint.get_label()
298 # FIXME: set self._config.download_dir to self.chooserDownloadTo.get_filename() and move download folder!
300 device_type = self.comboboxDeviceType.get_active()
301 if device_type == 0:
302 self._config.device_type = 'none'
303 elif device_type == 1:
304 self._config.device_type = 'ipod'
305 elif device_type == 2:
306 self._config.device_type = 'filesystem'
307 elif device_type == 3:
308 self._config.device_type = 'mtp'
310 auto_download = self.comboboxAutoDownload.get_active()
311 if auto_download == 0:
312 self._config.auto_download = 'never'
313 elif auto_download == 1:
314 self._config.auto_download = 'minimized'
315 elif auto_download == 2:
316 self._config.auto_download = 'always'
317 self.gPodderPreferences.destroy()
318 if self.callback_finished:
319 self.callback_finished()