Great! Will the libraries appear in separate menu entries also? It would
be great if one could add a separate library for e.g audiobooks, have
that entry appear as a separate item in the menu, and rename it
'Audiobooks'...

If there are separate entries, I believe it solves some of the issues...

Mats

On Wed, 2009-03-25 at 19:01 +0100, Christian Becke wrote:
> Hi all,
> 
> currently, if you use multiple library locations, browser state for
> additional library sources is lost when rhythmbox is restarted.
> I made a patch making additional library sources preserve state across
> restarts[1].
> 
> Until now, additional library sources can only be added by editing the
> gconf key "/apps/rhythmbox/library_locations" using e.g. gconf-editor -
> so I am planing to edit the preferences dialog to allow selection of
> multiple library locations (see attached python demo).
> 
> There are some implementation details that have to be decided upon:
> 
> * If you have configured multiple library locations, and you choose to
> remove one of them, what should happen to the songs from the removed
> location? Should they be removed from the library or should they be
> kept? If they are removed, what about the metadata (play counts,
> ratings, etc.)?
> Currently, if you remove a song from the library (by right-clicking a
> song and selecting "Remove"), the removal time is recorded in RhythmDB
> and metadata is kept for a certain time (configurable via the gconf key
> "/apps/rhythmbox/grace_period"). So if you add the song again to your
> library during grace_time, metadata will still be there. Should this
> apply to songs from a removed library location as well?
> 
> * If you rip a CD using rb, where should the files be saved? Currently,
> they are put in the first library location. Should there be some ui to
> choose where to put them?
> 
> * Should there be drag and drop support, allowing to move files between
> different library sources within rb?
> 
> Please try the patch from [1] and the attached python demo of the new
> preferences dialog I have in mind, and tell me your thoughts.
> 
> 
> Regards,
> 
> Chris
> 
> [1] http://bugzilla.gnome.org/show_bug.cgi?id=523162
> plain text document attachment (library_prefs_example.py)
> #!/usr/bin/python
> 
> import gobject
> import gtk
> import gtk.glade
> import urlparse
> 
> LIBRARY_PREFS_GLADE = "library-prefs-example.glade"
> 
> COL_LIBRARY_LOCATION = 0
> COL_NEW_FILES_LOCATION = 1
> 
> class UI:
> 
>       def __init__ (self):
>               self.gladeXML = gtk.glade.XML (LIBRARY_PREFS_GLADE)
>               self.gladeXML.signal_autoconnect (self)
>               locations_tv = self.gladeXML.get_widget 
> ("library_locations_treeview")
>               self.library_locations_filechooserdialog = 
> self.gladeXML.get_widget ("library_locations_filechooserdialog")
>               self.remove_library_location_messagedialog = 
> self.gladeXML.get_widget ("remove_library_location_messagedialog")
>               self.keep_metadata_checkbutton = self.gladeXML.get_widget 
> ("keep_metadata_checkbutton")
>               
>               self.locations = gtk.ListStore (gobject.TYPE_STRING, 
> gobject.TYPE_BOOLEAN)
>               self.locations_tree_selection = locations_tv.get_selection ()
>               self.locations_tree_selection.set_mode (gtk.SELECTION_MULTIPLE)
>               locations_tv.set_model (self.locations)
>               locations_column = gtk.TreeViewColumn ("Library Locations")
>               locations_column.set_expand (True)
>               locations_tv.append_column (locations_column)
>               cr = gtk.CellRendererText ()
>               locations_column.pack_start (cr, True)
>               locations_column.add_attribute (cr, 'text', 
> COL_LIBRARY_LOCATION)
> 
>               new_files_column = gtk.TreeViewColumn ("Put new files here")
>               new_files_column.set_expand (False)
>               locations_tv.append_column (new_files_column)
>               cr = gtk.CellRendererToggle ()
>               cr.set_radio (True)
>               cr.connect ("toggled", self.on_new_files_location_toggled)
>               new_files_column.pack_start (cr, True)
>               new_files_column.add_attribute (cr, 'active', 
> COL_NEW_FILES_LOCATION)
> 
>       def run (self):
>               gtk.main ()
> 
>       def run_library_locations_filechooserdialog (self):
>               locations = []
>               resp = self.library_locations_filechooserdialog.run ()
>               if resp == gtk.RESPONSE_OK:
>                       locations = 
> self.library_locations_filechooserdialog.get_uris ()
>               self.library_locations_filechooserdialog.hide ()
>               return locations
> 
>       def new_files_location_toggled_foreach_func (self, model, path, it, 
> toggled):
>               if int (path[0]) == int (toggled):
>                       model.set_value (it, COL_NEW_FILES_LOCATION, True)
>               else:
>                       model.set_value (it, COL_NEW_FILES_LOCATION, False)
>               return False
> 
>       def on_new_files_location_toggled (self, cr, path):
>               self.locations.foreach 
> (self.new_files_location_toggled_foreach_func, path)
>               return False
> 
>       def on_quit (self, *args, **kwargs):
>               gtk.main_quit ()
>       
>       def location_is_valid_foreach_func (self, model, path, it, data):
>               loc = urlparse.urlsplit (model.get_value (it, 
> COL_LIBRARY_LOCATION))
>               new = data[0]
>               if new.scheme == loc.scheme:
>                       if new.path == loc.path or new.path.startswith 
> (loc.path) or loc.path.startswith (new.path):
>                               data[1] = False
>                               return True
>       
>       def location_is_valid (self, location):
>               data = [urlparse.urlsplit (location), True]
>               self.locations.foreach (self.location_is_valid_foreach_func, 
> data)
>               return data[1]
>               
>       def update_new_files_location_foreach_func (self, model, path, it, 
> found):
>               if model.get_value (it, COL_NEW_FILES_LOCATION):
>                       found[0] = it
>                       return False
>       
>       def update_new_files_location (self):
>               found = [None]
>               self.locations.foreach 
> (self.update_new_files_location_foreach_func, found)
>               if not found[0]:
>                       gobject.idle_add (self.on_new_files_location_toggled, 
> None, 0)
>               return False
> 
>       def on_button_add_clicked (self, button):
>               locations = self.run_library_locations_filechooserdialog ()
>               location_added = False
>               invalid_locations = []
>               for loc in locations:
>                       if self.location_is_valid (loc):
>                               self.locations.append ([loc, False])
>                               location_added = True
>                       else:
>                               invalid_locations.append (loc)
> 
>               if location_added:
>                       gobject.idle_add (self.update_new_files_location)
> 
>               if invalid_locations:
>                       dlg = gtk.MessageDialog 
> (parent=self.gladeXML.get_widget ("window1"),
>                                       flags=gtk.DIALOG_MODAL | 
> gtk.DIALOG_DESTROY_WITH_PARENT,
>                                       type=gtk.MESSAGE_ERROR,
>                                       buttons=gtk.BUTTONS_OK,
>                                       message_format="Some location(s) could 
> not be added")
>                       dlg.format_secondary_text ("The following location(s) 
> could not be added to the list of library locations:\n\n"
>                                       "%s\n\n"
>                                       "Possible reasons: either the location 
> itself, "
>                                       "one of its subfolders, or one of its 
> parent folders is already added.\n"
>                                       "Nested folders can not be added as 
> library locations." % 
>                                       "\n".join (invalid_locations))
>                       dlg.run ()
>                       dlg.destroy ()
>       
>       def on_button_remove_clicked (self, button):
>               resp = self.remove_library_location_messagedialog.run ()
>               if resp == gtk.RESPONSE_OK:
>                       keep_metadata = 
> self.keep_metadata_checkbutton.get_active ()
>                       if keep_metadata:
>                               print "Would remove songs from library, keeping 
> metadata in rhythmdb."
>                       else:
>                               print "Would remove songs from library, 
> removing metadata from rhythmdb."
>                       (model, pathlist) = 
> self.locations_tree_selection.get_selected_rows ()
>                       pathlist.reverse ()
>                       new_files_location_removed = False
>                       for path in pathlist:
>                               it = model.get_iter (path)
>                               new_files_location_removed = 
> (new_files_location_removed
>                                               or model.get_value (it, 
> COL_NEW_FILES_LOCATION))
>                               model.remove (it)
>                       if new_files_location_removed:
>                               gobject.idle_add 
> (self.update_new_files_location)
>               self.remove_library_location_messagedialog.hide ()
> 
> 
> if __name__ == '__main__':
>       ui = UI ()
>       ui.run ()
> _______________________________________________
> rhythmbox-devel mailing list
> rhythmbox-devel@gnome.org
> http://mail.gnome.org/mailman/listinfo/rhythmbox-devel

_______________________________________________
rhythmbox-devel mailing list
rhythmbox-devel@gnome.org
http://mail.gnome.org/mailman/listinfo/rhythmbox-devel

Reply via email to