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