230
230
self.hscale_expiration.set_value(0)
232
self._config.connect_gtk_togglebutton('auto_remove_unplayed_episodes', self.checkbutton_expiration_unplayed)
233
self._config.connect_gtk_togglebutton('auto_remove_unfinished_episodes', self.checkbutton_expiration_unfinished)
232
self._config.connect_gtk_togglebutton('auto_remove_unplayed_episodes',
233
self.checkbutton_expiration_unplayed)
234
self._config.connect_gtk_togglebutton('auto_remove_unfinished_episodes',
235
self.checkbutton_expiration_unfinished)
235
237
self.device_type_model = DeviceTypeActionList(self._config)
236
238
self.combobox_device_type.set_model(self.device_type_model)
237
239
cellrenderer = gtk.CellRendererText()
238
240
self.combobox_device_type.pack_start(cellrenderer, True)
239
self.combobox_device_type.add_attribute(cellrenderer, 'text', DeviceTypeActionList.C_CAPTION)
241
self.combobox_device_type.add_attribute(cellrenderer, 'text',
242
DeviceTypeActionList.C_CAPTION)
240
243
self.combobox_device_type.set_active(self.device_type_model.get_index())
242
245
self.on_sync_model = OnSyncActionList(self._config)
246
249
self.combobox_on_sync.add_attribute(cellrenderer, 'text', OnSyncActionList.C_CAPTION)
247
250
self.combobox_on_sync.set_active(self.on_sync_model.get_index())
249
self._config.connect_gtk_togglebutton('device_sync.skip_played_episodes', self.checkbutton_skip_played_episodes)
252
self._config.connect_gtk_togglebutton('device_sync.skip_played_episodes',
253
self.checkbutton_skip_played_episodes)
254
self._config.connect_gtk_togglebutton('device_sync.playlists.create',
255
self.checkbutton_create_playlists)
256
self._config.connect_gtk_togglebutton('device_sync.playlists.two_way_sync',
257
self.checkbutton_delete_using_playlists)
251
259
# Have to do this before calling set_active on checkbutton_enable
252
260
self._enable_mygpo = self._config.mygpo.enabled
266
274
# Configure the extensions manager GUI
267
275
self.set_extension_preferences()
269
def set_extension_preferences(self):
277
def set_extension_preferences(self):
278
def search_equal_func(model, column, key, it):
279
label = model.get_value(it, self.C_LABEL)
280
if key.lower() in label.lower():
281
# from http://www.pygtk.org/docs/pygtk/class-gtktreeview.html:
282
# "func should return False to indicate that the row matches
283
# the search criteria."
287
self.treeviewExtensions.set_search_equal_func(search_equal_func)
270
289
toggle_cell = gtk.CellRendererToggle()
271
toggle_cell.connect('toggled', self.on_extensions_cell_toggled)
290
toggle_cell.connect('toggled', self.on_extensions_cell_toggled)
291
toggle_column = gtk.TreeViewColumn('')
292
toggle_column.pack_start(toggle_cell, True)
293
toggle_column.add_attribute(toggle_cell, 'active', self.C_TOGGLE)
294
toggle_column.add_attribute(toggle_cell, 'visible', self.C_SHOW_TOGGLE)
295
toggle_column.set_property('min-width', 32)
296
self.treeviewExtensions.append_column(toggle_column)
273
298
name_cell = gtk.CellRendererText()
274
299
name_cell.set_property('ellipsize', pango.ELLIPSIZE_END)
276
300
extension_column = gtk.TreeViewColumn(_('Name'))
277
extension_column.pack_start(toggle_cell, False)
278
extension_column.add_attribute(toggle_cell, 'active', self.C_TOGGLE)
279
extension_column.add_attribute(toggle_cell, 'visible', self.C_SHOW_TOGGLE)
280
301
extension_column.pack_start(name_cell, True)
281
302
extension_column.add_attribute(name_cell, 'markup', self.C_LABEL)
282
extension_column.set_clickable(False)
283
extension_column.set_resizable(True)
284
303
extension_column.set_expand(True)
285
304
self.treeviewExtensions.append_column(extension_column)
287
306
self.extensions_model = gtk.ListStore(bool, str, object, bool)
289
308
def key_func(pair):
290
309
category, container = pair
291
310
return (category, container.metadata.title)
293
312
def convert(extensions):
294
313
for container in extensions:
295
314
yield (container.metadata.category, container)
297
316
old_category = None
298
317
for category, container in sorted(convert(gpodder.user_extensions.get_extensions()), key=key_func):
299
318
if old_category != category:
300
319
label = '<span weight="bold">%s</span>' % cgi.escape(category)
301
320
self.extensions_model.append((None, label, None, False))
302
321
old_category = category
304
323
label = '%s\n<small>%s</small>' % (
305
324
cgi.escape(container.metadata.title),
306
325
cgi.escape(container.metadata.description))
364
382
self.show_message(container.error.message,
365
383
_('Extension cannot be activated'), important=True)
366
384
model.set_value(it, self.C_TOGGLE, False)
368
def on_treeview_button_press_event(self, treeview, event):
369
if event.button != 3:
374
path, _, _, _ = treeview.get_path_at_pos(x, y)
386
def on_treeview_extensions_row_activated(self, treeview, path, column):
375
387
model = treeview.get_model()
376
388
container = model.get_value(model.get_iter(path), self.C_EXTENSION)
377
389
self.show_extension_info(model, container)
380
392
if not container or not model:
383
# This is one ugly hack, but it displays the attributes of
395
# This is one ugly hack, but it displays the attributes of
384
396
# the metadata object of the container..
385
397
info = '\n'.join('<b>%s:</b> %s' %
386
398
tuple(map(cgi.escape, map(str, (key, value))))
501
513
index = self.combobox_on_sync.get_active()
502
514
self.on_sync_model.set_index(index)
516
def on_checkbutton_create_playlists_toggled(self, widget,device_type_changed=False):
517
if not widget.get_active():
518
self._config.device_sync.playlists.create=False
519
self.toggle_playlist_interface(False)
520
#need to read value of checkbutton from interface,
521
#rather than value of parameter
523
self._config.device_sync.playlists.create=True
524
self.toggle_playlist_interface(True)
526
def toggle_playlist_interface(self, enabled):
527
if enabled and self._config.device_sync.device_type != 'none':
528
self.btn_playlistfolder.set_sensitive(True)
529
self.btn_playlistfolder.set_label(self._config.device_sync.playlists.folder)
530
self.checkbutton_delete_using_playlists.set_sensitive(True)
531
children = self.btn_playlistfolder.get_children()
533
label = children.pop()
534
label.set_alignment(0., .5)
536
self.btn_playlistfolder.set_sensitive(False)
537
self.btn_playlistfolder.set_label('')
538
self.checkbutton_delete_using_playlists.set_sensitive(False)
504
541
def on_combobox_device_type_changed(self, widget):
505
542
index = self.combobox_device_type.get_active()
506
543
self.device_type_model.set_index(index)
508
545
if device_type == 'none':
509
546
self.btn_filesystemMountpoint.set_label('')
510
547
self.btn_filesystemMountpoint.set_sensitive(False)
548
self.checkbutton_create_playlists.set_sensitive(False)
549
self.toggle_playlist_interface(False)
550
self.checkbutton_delete_using_playlists.set_sensitive(False)
551
self.combobox_on_sync.set_sensitive(False)
552
self.checkbutton_skip_played_episodes.set_sensitive(False)
511
553
elif device_type == 'filesystem':
512
554
self.btn_filesystemMountpoint.set_label(self._config.device_sync.device_folder)
513
555
self.btn_filesystemMountpoint.set_sensitive(True)
556
self.checkbutton_create_playlists.set_sensitive(True)
557
children = self.btn_filesystemMountpoint.get_children()
559
label = children.pop()
560
label.set_alignment(0., .5)
561
self.toggle_playlist_interface(self._config.device_sync.playlists.create)
562
self.combobox_on_sync.set_sensitive(True)
563
self.checkbutton_skip_played_episodes.set_sensitive(True)
515
565
# TODO: Add support for iPod and MTP devices
518
children = self.btn_filesystemMountpoint.get_children()
520
label = children.pop()
521
label.set_alignment(0., .5)
523
568
def on_btn_device_mountpoint_clicked(self, widget):
524
569
fs = gtk.FileChooserDialog(title=_('Select folder for mount point'),
525
570
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
530
575
filename = fs.get_filename()
531
576
if self._config.device_sync.device_type == 'filesystem':
532
577
self._config.device_sync.device_folder = filename
534
578
# Request an update of the mountpoint button
535
579
self.on_combobox_device_type_changed(None)
583
def on_btn_playlist_folder_clicked(self, widget):
584
fs = gtk.FileChooserDialog(title=_('Select folder for playlists'),
585
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
586
fs.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
587
fs.add_button(gtk.STOCK_OPEN, gtk.RESPONSE_OK)
588
fs.set_current_folder(self.btn_playlistfolder.get_label())
589
if fs.run() == gtk.RESPONSE_OK:
590
filename = util.relpath(self._config.device_sync.device_folder,
592
if self._config.device_sync.device_type == 'filesystem':
593
self._config.device_sync.playlists.folder = filename
594
self.btn_playlistfolder.set_label(filename)
595
children = self.btn_playlistfolder.get_children()
597
label = children.pop()
598
label.set_alignment(0., .5)