[gnome-music/wip/mschraal/renamepl] playlist: Add the possibility to rename a playlist
- From: Marinus Schraal <mschraal src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/mschraal/renamepl] playlist: Add the possibility to rename a playlist
- Date: Tue, 19 Dec 2017 08:30:56 +0000 (UTC)
commit 9f6e386ccc3a36fedfecb32367036b997bcf3c03
Author: Jean Felder <jean felder gmail com>
Date: Tue Dec 19 00:10:50 2017 +0100
playlist: Add the possibility to rename a playlist
https://bugzilla.gnome.org/show_bug.cgi?id=744822
data/PlaylistControls.ui | 68 +++++++++++++++++++++++++++++++++-------
gnomemusic/playlists.py | 22 +++++++++++++
gnomemusic/query.py | 25 +++++++++++++++
gnomemusic/views/playlistview.py | 66 +++++++++++++++++++++++++++++++++++++-
gnomemusic/window.py | 9 +++++-
5 files changed, 177 insertions(+), 13 deletions(-)
---
diff --git a/data/PlaylistControls.ui b/data/PlaylistControls.ui
index 8f064fc..6d09bd4 100644
--- a/data/PlaylistControls.ui
+++ b/data/PlaylistControls.ui
@@ -10,6 +10,10 @@
<attribute name="label" translatable="yes">_Delete</attribute>
<attribute name="action">win.playlist_delete</attribute>
</item>
+ <item>
+ <attribute name="label" translatable="yes">_Rename...</attribute>
+ <attribute name="action">win.playlist_rename</attribute>
+ </item>
</menu>
<object class="GtkGrid" id="grid">
<property name="visible">True</property>
@@ -19,17 +23,59 @@
<property name="margin_top">18</property>
<property name="margin_bottom">18</property>
<child>
- <object class="GtkLabel" id="playlist_name">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Playlist Name</property>
- <property name="ellipsize">middle</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- <attribute name="scale" value="1.5"/>
- </attributes>
+ <object class="GtkStack" id="stack">
+ <child>
+ <object class="GtkLabel" id="playlist_name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Playlist Name</property>
+ <property name="ellipsize">middle</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="1.5"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkEntry" id="playlist_rename_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="is_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="playlist_rename_done_button">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">_Done</property>
+ <property name="use_underline">True</property>
+ <property name="valign">center</property>
+ <property name="sensitive">True</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="name">renaming_dialog</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="left_attach">0</property>
diff --git a/gnomemusic/playlists.py b/gnomemusic/playlists.py
index d39011b..3952255 100644
--- a/gnomemusic/playlists.py
+++ b/gnomemusic/playlists.py
@@ -117,6 +117,9 @@ class Playlists(GObject.GObject):
'playlist-updated': (
GObject.SignalFlags.RUN_FIRST, None, (int,)
),
+ 'playlist-renamed': (
+ GObject.SignalFlags.RUN_FIRST, None, (Grl.Media,)
+ ),
'song-added-to-playlist': (
GObject.SignalFlags.RUN_FIRST, None, (Grl.Media, Grl.Media)
),
@@ -348,6 +351,25 @@ class Playlists(GObject.GObject):
)
@log
+ def rename(self, item, new_name):
+ """Rename a playlist
+
+ :param item: playlist to rename
+ :param new_name: new playlist name
+ :type item: Grl.Media
+ :type new_name: str
+ :return: None
+ :rtype: None
+ """
+ def update_callback(conn, res, data):
+ conn.update_finish(res)
+ self.emit('playlist-renamed', item)
+
+ self.tracker.update_async(
+ Query.rename_playlist(item.get_id(), new_name), GLib.PRIORITY_LOW,
+ None, update_callback, None)
+
+ @log
def delete_playlist(self, item):
def update_callback(conn, res, data):
conn.update_finish(res)
diff --git a/gnomemusic/query.py b/gnomemusic/query.py
index e70cfa7..c4ff40c 100644
--- a/gnomemusic/query.py
+++ b/gnomemusic/query.py
@@ -473,6 +473,31 @@ class Query():
return query
@staticmethod
+ def rename_playlist(playlist_id, new_name):
+ query = """
+ INSERT OR REPLACE {
+ ?playlist
+ nie:title "%(title)s"
+ }
+ WHERE {
+ ?playlist
+ a nmm:Playlist ;
+ a nfo:MediaList .
+ OPTIONAL {
+ ?playlist
+ nfo:hasMediaFileListEntry ?entry .
+ }
+ FILTER (
+ tracker:id(?playlist) = %(playlist_id)s
+ )
+ }
+ """.replace("\n", " ").strip() % {
+ 'title': new_name,
+ 'playlist_id': playlist_id
+ }
+ return query
+
+ @staticmethod
def add_song_to_playlist(playlist_id, song_uri):
query = """
INSERT OR REPLACE {
diff --git a/gnomemusic/views/playlistview.py b/gnomemusic/views/playlistview.py
index 36c270c..37c140d 100644
--- a/gnomemusic/views/playlistview.py
+++ b/gnomemusic/views/playlistview.py
@@ -70,7 +70,12 @@ class PlaylistView(BaseView):
builder = Gtk.Builder()
builder.add_from_resource('/org/gnome/Music/PlaylistControls.ui')
headerbar = builder.get_object('grid')
+ self._name_stack = builder.get_object('stack')
self._name_label = builder.get_object('playlist_name')
+ self._rename_entry = builder.get_object('playlist_rename_entry')
+ self._rename_entry.connect('changed', self._on_rename_entry_changed)
+ self._rename_done_button = builder.get_object(
+ 'playlist_rename_done_button')
self._songs_count_label = builder.get_object('songs_count')
self._menubutton = builder.get_object('playlist_menubutton')
@@ -83,6 +88,11 @@ class PlaylistView(BaseView):
self._playlist_delete_action.connect('activate',
self._on_delete_activate)
self._window.add_action(self._playlist_delete_action)
+ self._playlist_rename_action = Gio.SimpleAction.new(
+ 'playlist_rename', None)
+ self._playlist_rename_action.connect(
+ 'activate', self._on_rename_activate)
+ self._window.add_action(self._playlist_rename_action)
self._grid.insert_row(0)
self._grid.attach(headerbar, 1, 0, 1, 1)
@@ -125,6 +135,8 @@ class PlaylistView(BaseView):
self.pl_todelete = None
self._pl_todelete_index = None
self._songs_count = 0
+ self._handler_rename_done_button = 0
+ self._handler_rename_entry = 0
self._update_songs_count()
@@ -375,6 +387,9 @@ class PlaylistView(BaseView):
playlist_name = self._playlists_model[_iter][2]
playlist = self._playlists_model[_iter][5]
+ if self.rename_active:
+ self.disable_rename_playlist()
+
self.current_playlist = playlist
self._name_label.set_text(playlist_name)
self._current_playlist_index = int(path.to_string())
@@ -386,11 +401,12 @@ class PlaylistView(BaseView):
self._songs_count = 0
grilo.populate_playlist_songs(playlist, self._add_item)
- # disable delete button if current playlist is a smart playlist
if self._current_playlist_is_protected():
self._playlist_delete_action.set_enabled(False)
+ self._playlist_rename_action.set_enabled(False)
else:
self._playlist_delete_action.set_enabled(True)
+ self._playlist_rename_action.set_enabled(True)
@log
def _add_item(self, source, param, item, remaining=0, data=None):
@@ -479,6 +495,54 @@ class PlaylistView(BaseView):
self._stage_playlist_for_deletion()
@log
+ @property
+ def rename_active(self):
+ """Indicate if renaming dialog is active"""
+ return self._name_stack.get_visible_child_name() == 'renaming_dialog'
+
+ @log
+ def _on_rename_entry_changed(self, selection):
+ if selection.get_text_length() > 0:
+ self._rename_done_button.set_sensitive(True)
+ else:
+ self._rename_done_button.set_sensitive(False)
+
+ @log
+ def disable_rename_playlist(self):
+ """disables rename button and entry"""
+ self._name_stack.set_visible_child(self._name_label)
+ self._rename_done_button.disconnect(self._handler_rename_done_button)
+ self._rename_entry.disconnect(self._handler_rename_entry)
+
+ @log
+ def _stage_playlist_for_renaming(self):
+ _iter = self._pl_generic_view.get_selection().get_selected()[1]
+ pl_torename = self._playlists_model[_iter][5]
+
+ def playlist_renamed_callback(widget):
+ new_name = self._rename_entry.get_text()
+ if not new_name:
+ return
+
+ self._playlists_model[_iter][2] = new_name
+ pl_torename.set_title(new_name)
+ playlists.rename(pl_torename, new_name)
+ self._name_label.set_text(new_name)
+ self.disable_rename_playlist()
+
+ self._name_stack.set_visible_child_name('renaming_dialog')
+ self._rename_entry.set_text(utils.get_media_title(pl_torename))
+ self._rename_entry.grab_focus()
+ self._handler_rename_entry = self._rename_entry.connect(
+ 'activate', playlist_renamed_callback)
+ self._handler_rename_done_button = self._rename_done_button.connect(
+ 'clicked', playlist_renamed_callback)
+
+ @log
+ def _on_rename_activate(self, menuitem, data=None):
+ self._stage_playlist_for_renaming()
+
+ @log
def _on_playlist_created(self, playlists, item):
self._add_playlist_item_to_model(item)
if self._playlists_model.iter_n_children(None) == 1:
diff --git a/gnomemusic/window.py b/gnomemusic/window.py
index 5a3f585..25e261a 100644
--- a/gnomemusic/window.py
+++ b/gnomemusic/window.py
@@ -471,7 +471,8 @@ class Window(Gtk.ApplicationWindow):
and not event.keyval == Gdk.KEY_space)
and GLib.unichar_isprint(chr(key_unic))
and (event_and_modifiers == Gdk.ModifierType.SHIFT_MASK
- or event_and_modifiers == 0)):
+ or event_and_modifiers == 0)
+ and not self.views[3].rename_active):
self.toolbar.searchbar.show_bar(True)
@log
@@ -502,6 +503,12 @@ class Window(Gtk.ApplicationWindow):
self.toolbar._select_button.set_sensitive(
not self.toolbar._select_button.get_sensitive())
+ # Disable renaming playlist if it was active when leaving
+ # Playlist view
+ if (self.prev_view == self.views[3]
+ and self.views[3].rename_active):
+ self.views[3].disable_rename_playlist()
+
@log
def _toggle_view(self, btn, i):
self._stack.set_visible_child(self.views[i])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]