[gnome-music/wip/jfelder/musicbrainz-tageditordialog] tageditordialog: Initial songs support
- From: Jean Felder <jfelder src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/jfelder/musicbrainz-tageditordialog] tageditordialog: Initial songs support
- Date: Thu, 8 Nov 2018 18:49:27 +0000 (UTC)
commit b6c0b984a02ec9fff667db5ce0a06b72007d2bb8
Author: Jean Felder <jfelder src gnome org>
Date: Tue Aug 21 00:59:11 2018 +0200
tageditordialog: Initial songs support
data/org.gnome.Music.gresource.xml | 1 +
data/ui/SelectionToolbar.ui | 12 +
data/ui/TagEditorDialog.ui | 847 +++++++++++++++++++++++++++++++++
gnomemusic/utils.py | 2 +-
gnomemusic/widgets/selectiontoolbar.py | 23 +-
gnomemusic/widgets/tageditordialog.py | 124 +++++
gnomemusic/window.py | 22 +-
po/POTFILES.in | 2 +
8 files changed, 1025 insertions(+), 8 deletions(-)
---
diff --git a/data/org.gnome.Music.gresource.xml b/data/org.gnome.Music.gresource.xml
index 200159ae..6b8b5212 100644
--- a/data/org.gnome.Music.gresource.xml
+++ b/data/org.gnome.Music.gresource.xml
@@ -24,6 +24,7 @@
<file preprocess="xml-stripblanks">ui/SelectionToolbar.ui</file>
<file preprocess="xml-stripblanks">ui/SidebarRow.ui</file>
<file preprocess="xml-stripblanks">ui/SongWidget.ui</file>
+ <file preprocess="xml-stripblanks">ui/TagEditorDialog.ui</file>
<file preprocess="xml-stripblanks">ui/TwoLineTip.ui</file>
</gresource>
</gresources>
diff --git a/data/ui/SelectionToolbar.ui b/data/ui/SelectionToolbar.ui
index ec64876c..577f9d88 100644
--- a/data/ui/SelectionToolbar.ui
+++ b/data/ui/SelectionToolbar.ui
@@ -17,5 +17,17 @@
</style>
</object>
</child>
+ <child>
+ <object class="GtkButton" id="_edit_details_button">
+ <property name="label" translatable="yes">Edit Details</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <signal name="clicked" handler="_on_edit_tags_button_clicked" swapped="no"/>
+ <style>
+ <class name="text-button"/>
+ </style>
+ </object>
+</child>
</template>
</interface>
diff --git a/data/ui/TagEditorDialog.ui b/data/ui/TagEditorDialog.ui
new file mode 100644
index 00000000..3608c8ca
--- /dev/null
+++ b/data/ui/TagEditorDialog.ui
@@ -0,0 +1,847 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+ <requires lib="gtk+" version="3.16"/>
+ <template class="TagEditorDialog" parent="GtkDialog">
+ <property name="can_focus">False</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog_vbox">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkOverlay" id="overlay">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox" id="media_details">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">12</property>
+ <property name="margin_right">12</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">18</property>
+ <property name="spacing">24</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkButton" id="_coverart_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="relief">none</property>
+ <signal name="clicked" handler="_choose_cover" swapped="no"/>
+ <child>
+ <object class="CoverStack" id="_cover_stack">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ </object>
+ </child>
+ <style>
+ <class name="album-cover"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox">
+ <property name="width_request">260</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">36</property>
+ <property name="label" translatable="yes">Title</property>
+ <property name="xalign">1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_title_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_title_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="album">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">36</property>
+ <property name="label" translatable="yes">Album</property>
+ <property name="xalign">1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_album_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_album_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="artist">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">36</property>
+ <property name="label" translatable="yes">Artist</property>
+ <property name="xalign">1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_artist_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_artist_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="composer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">36</property>
+ <property name="label" translatable="yes">Composer</property>
+ <property name="xalign">1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_composer_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_composer_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="genre">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">36</property>
+ <property name="label" translatable="yes">Genre</property>
+ <property name="xalign">1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_genre_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_genre_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="track">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Song</property>
+ <property name="xalign">1</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_track_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_track_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="width_chars">8</property>
+ <property name="max_width_chars">2</property>
+ <property name="input_purpose">number</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="disc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Disc</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_disc_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_disc_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">2</property>
+ <property name="width_chars">8</property>
+ <property name="max_width_chars">2</property>
+ <property name="input_purpose">number</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="year">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Year</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_year_suggestion">
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_right">2</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="_year_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="max_length">4</property>
+ <property name="width_chars">10</property>
+ <property name="max_width_chars">4</property>
+ <property name="input_purpose">number</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="index">-1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="margin_right">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">end</property>
+ <property name="spacing">6</property>
+ <property name="baseline_position">bottom</property>
+ <child>
+ <object class="GtkSpinner" id="_spinner">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="active">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="_spinner_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Fetching metadata...</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">go-next-symbolic-rtl</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">go-next-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <style>
+ <class name="linked"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="_use_suggestion_button">
+ <property name="label" translatable="yes">Use Suggestions</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkHeaderBar" id="_title_bar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Edit Details</property>
+ <property name="show_close_button">True</property>
+ </object>
+</interface>
diff --git a/gnomemusic/utils.py b/gnomemusic/utils.py
index 504878fe..82bba3bc 100644
--- a/gnomemusic/utils.py
+++ b/gnomemusic/utils.py
@@ -175,4 +175,4 @@ fields = {
'title': get_media_title,
'track': get_media_track_nr,
'year': get_media_year
- }
+}
diff --git a/gnomemusic/widgets/selectiontoolbar.py b/gnomemusic/widgets/selectiontoolbar.py
index 1d2b775a..517d0faf 100644
--- a/gnomemusic/widgets/selectiontoolbar.py
+++ b/gnomemusic/widgets/selectiontoolbar.py
@@ -33,9 +33,11 @@ class SelectionToolbar(Gtk.ActionBar):
__gtype_name__ = 'SelectionToolbar'
_add_to_playlist_button = Gtk.Template.Child()
+ _edit_details_button = Gtk.Template.Child()
__gsignals__ = {
- 'add-to-playlist': (GObject.SignalFlags.RUN_FIRST, None, ())
+ 'add-to-playlist': (GObject.SignalFlags.RUN_FIRST, None, ()),
+ 'edit-details': (GObject.SignalFlags.RUN_FIRST, None, ())
}
selected_items_count = GObject.Property(type=int, default=0, minimum=0)
@@ -44,9 +46,10 @@ class SelectionToolbar(Gtk.ActionBar):
return '<SelectionToolbar>'
@log
- def __init__(self):
+ def __init__(self, window):
super().__init__()
+ self._headerbar = window._headerbar
self.connect(
'notify::selected-items-count', self._on_item_selection_changed)
@@ -55,9 +58,17 @@ class SelectionToolbar(Gtk.ActionBar):
def _on_add_to_playlist_button_clicked(self, widget):
self.emit('add-to-playlist')
+ @Gtk.Template.Callback()
+ @log
+ def _on_edit_tags_button_clicked(self, widget):
+ self.emit('edit-details')
+
@log
def _on_item_selection_changed(self, widget, data):
- if self.props.selected_items_count > 0:
- self._add_to_playlist_button.props.sensitive = True
- else:
- self._add_to_playlist_button.props.sensitive = False
+ stack = self._headerbar.props.stack
+ songs_view_visible = (stack.props.visible_child_name == 'songs')
+ selection_size = self.props.selected_items_count
+
+ self._add_to_playlist_button.props.sensitive = (selection_size > 0)
+ self._edit_details_button.props.sensitive = (selection_size == 1
+ and songs_view_visible)
diff --git a/gnomemusic/widgets/tageditordialog.py b/gnomemusic/widgets/tageditordialog.py
new file mode 100644
index 00000000..c0119caf
--- /dev/null
+++ b/gnomemusic/widgets/tageditordialog.py
@@ -0,0 +1,124 @@
+# Copyright 2018 The GNOME Music Developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+import logging
+from gettext import gettext as _
+
+from gi.repository import Grl, Gtk
+
+from gnomemusic import log
+from gnomemusic.albumartcache import Art
+from gnomemusic.grilo import grilo
+import gnomemusic.utils as utils
+
+logger = logging.getLogger(__name__)
+
+
+@Gtk.Template(resource_path="/org/gnome/Music/ui/TagEditorDialog.ui")
+class TagEditorDialog(Gtk.Dialog):
+ """Tag editor widget
+ A tag editor dialog box that allows storing metadata for music files
+ through editing entries manually or applying automatic fetched tags.
+ """
+
+ __gtype_name__ = 'TagEditorDialog'
+
+ _cover_stack = Gtk.Template.Child()
+ _spinner = Gtk.Template.Child()
+ _spinner_label = Gtk.Template.Child()
+ _title_bar = Gtk.Template.Child()
+
+ # tags entries and labels
+ _album_entry = Gtk.Template.Child()
+ _album_suggestion = Gtk.Template.Child()
+ _artist_entry = Gtk.Template.Child()
+ _artist_suggestion = Gtk.Template.Child()
+ _composer_entry = Gtk.Template.Child()
+ _composer_suggestion = Gtk.Template.Child()
+ _disc_entry = Gtk.Template.Child()
+ _disc_suggestion = Gtk.Template.Child()
+ _genre_entry = Gtk.Template.Child()
+ _genre_suggestion = Gtk.Template.Child()
+ _title_entry = Gtk.Template.Child()
+ _title_suggestion = Gtk.Template.Child()
+ _track_entry = Gtk.Template.Child()
+ _track_suggestion = Gtk.Template.Child()
+ _year_entry = Gtk.Template.Child()
+ _year_suggestion = Gtk.Template.Child()
+
+ def __repr__(self):
+ return '<TagEditorDialog>'
+
+ @log
+ def __init__(self, parent, selected_song):
+ """Initialize the tag editor
+ :param parent: The parent widget calling the editor dialog box
+ :param selected_song: The current selected track which is being edited
+ """
+ super().__init__()
+
+ self.props.transient_for = parent
+ self.set_titlebar(self._title_bar)
+
+ self._cover_stack.props.size = Art.Size.MEDIUM
+ self._cover_stack.update(selected_song)
+
+ self._initial_song = selected_song
+ self._init_labels()
+ self._search_tags()
+
+ @log
+ def _init_labels(self):
+ for field in utils.fields:
+ entry = getattr(self, '_' + field + '_entry')
+ value = utils.fields[field](self._initial_song)
+ if value:
+ entry.props.text = value
+
+ @log
+ def _start_spinner(self, text):
+ self._spinner.start()
+ self._spinner_label.props.label = text
+
+ @log
+ def _stop_spinner(self):
+ self._spinner.stop()
+ self._spinner_label.props.label = ""
+
+ @log
+ def _search_tags(self):
+ self._start_spinner(_("Fetching metadata…"))
+ new_media = Grl.Media.audio_new()
+ new_media.set_url(self._initial_song.get_url())
+ grilo.get_tags_from_musicbrainz(new_media, self._tags_found)
+
+ @log
+ def _tags_found(self, media):
+ for field in utils.fields:
+ suggestion = getattr(self, '_' + field + '_suggestion')
+ value = utils.fields[field](media)
+ if value:
+ suggestion.props.label = value
+ suggestion.props.visible = True
+ self._stop_spinner()
diff --git a/gnomemusic/window.py b/gnomemusic/window.py
index 82dfba5d..8422a2ea 100644
--- a/gnomemusic/window.py
+++ b/gnomemusic/window.py
@@ -49,6 +49,7 @@ from gnomemusic.widgets.playertoolbar import PlayerToolbar
from gnomemusic.widgets.playlistdialog import PlaylistDialog
from gnomemusic.widgets.searchbar import Searchbar
from gnomemusic.widgets.selectiontoolbar import SelectionToolbar
+from gnomemusic.widgets.tageditordialog import TagEditorDialog
from gnomemusic.windowplacement import WindowPlacement
from gnomemusic.playlists import Playlists
from gnomemusic.grilo import grilo
@@ -122,7 +123,7 @@ class Window(Gtk.ApplicationWindow):
self._searchbar = Searchbar()
self._player = Player(self)
self._player_toolbar = PlayerToolbar(self._player, self)
- selection_toolbar = SelectionToolbar()
+ selection_toolbar = SelectionToolbar(self)
self.views = [None] * len(View)
self._stack = Gtk.Stack(
transition_type=Gtk.StackTransitionType.CROSSFADE,
@@ -178,6 +179,7 @@ class Window(Gtk.ApplicationWindow):
'toggled', self._on_search_toggled)
selection_toolbar.connect(
'add-to-playlist', self._on_add_to_playlist)
+ selection_toolbar.connect('edit-details', self._on_edit_tags)
self._headerbar.props.state = HeaderBar.State.MAIN
self._headerbar.show()
@@ -506,6 +508,24 @@ class Window(Gtk.ApplicationWindow):
self._stack.get_visible_child().get_selected_songs(callback)
+ @log
+ def _on_edit_tags(self, widget):
+ if self._stack.get_visible_child() == self.views[View.PLAYLIST]:
+ return
+
+ def callback(selected_songs):
+ if len(selected_songs) < 1:
+ return
+
+ tags_editor_dialog = TagEditorDialog(self, selected_songs[0])
+ if tags_editor_dialog.run() == Gtk.ResponseType.ACCEPT:
+ return
+
+ self.props.selection_mode = False
+ tags_editor_dialog.destroy()
+
+ self._stack.get_visible_child().get_selected_songs(callback)
+
@log
def set_player_visible(self, visible):
"""Set PlayWidget action visibility
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 15aaaf14..c11863bd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,6 +14,7 @@ data/ui/PlaylistControls.ui
data/ui/PlaylistDialog.ui
data/ui/SelectionBarMenuButton.ui
data/ui/SelectionToolbar.ui
+data/ui/TagEditorDialog.ui
gnomemusic/__init__.py
gnomemusic/albumartcache.py
gnomemusic/application.py
@@ -40,4 +41,5 @@ gnomemusic/widgets/playlistcontrols.py
gnomemusic/widgets/playlistdialog.py
gnomemusic/widgets/searchbar.py
gnomemusic/widgets/starhandlerwidget.py
+gnomemusic/widgets/tageditordialog.py
gnomemusic/window.py
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]