1 /*
2  *  Copyright (C) 2005 Marc Pavot <marc.pavot@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2, or (at your option)
7  *  any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  */
19 
20 #include "shell/ario-shell-songinfos.h"
21 #include <config.h>
22 #include <gtk/gtk.h>
23 #include <glib/gi18n.h>
24 #include <stdlib.h>
25 #ifdef ENABLE_TAGLIB
26 #include "taglib/tag_c.h"
27 #endif
28 
29 #include "ario-debug.h"
30 #include "ario-profiles.h"
31 #include "ario-util.h"
32 #include "lib/gtk-builder-helpers.h"
33 #include "widgets/ario-lyrics-editor.h"
34 
35 #define ARIO_PREVIOUS 987
36 #define ARIO_NEXT 998
37 #define ARIO_SAVE 999
38 
39 #define VALUE(b) b ? b : ""
40 
41 static void ario_shell_songinfos_finalize (GObject *object);
42 static gboolean ario_shell_songinfos_window_delete_cb (GtkWidget *window,
43                                                        GdkEventAny *event,
44                                                        ArioShellSonginfos *shell_songinfos);
45 static void ario_shell_songinfos_response_cb (GtkDialog *dial,
46                                               int response_id,
47                                               ArioShellSonginfos *shell_songinfos);
48 static void ario_shell_songinfos_set_current_song (ArioShellSonginfos *shell_songinfos);
49 G_MODULE_EXPORT void ario_shell_songinfos_text_changed_cb (GtkWidget *widget,
50                                                            ArioShellSonginfos *shell_songinfos);
51 
52 /* Private attributes */
53 struct ArioShellSonginfosPrivate
54 {
55         GtkWidget *notebook;
56 
57         GList *songs;
58 
59         GtkWidget *title_entry;
60         GtkWidget *artist_entry;
61         GtkWidget *album_entry;
62         GtkWidget *album_artist_entry;
63         GtkWidget *track_entry;
64         GtkWidget *date_entry;
65         GtkWidget *genre_entry;
66         GtkWidget *comment_entry;
67         GtkWidget *file_entry;
68         GtkWidget *length_entry;
69         GtkWidget *composer_entry;
70         GtkWidget *performer_entry;
71         GtkWidget *disc_entry;
72 
73         GtkWidget *lyrics_editor;
74 
75         GtkWidget *previous_button;
76         GtkWidget *next_button;
77         GtkWidget *save_button;
78 };
79 
80 #define ARIO_SHELL_SONGINFOS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_ARIO_SHELL_SONGINFOS, ArioShellSonginfosPrivate))
G_DEFINE_TYPE(ArioShellSonginfos,ario_shell_songinfos,GTK_TYPE_DIALOG)81 G_DEFINE_TYPE (ArioShellSonginfos, ario_shell_songinfos, GTK_TYPE_DIALOG)
82 
83 static void
84 ario_shell_songinfos_class_init (ArioShellSonginfosClass *klass)
85 {
86         ARIO_LOG_FUNCTION_START;
87         GObjectClass *object_class = G_OBJECT_CLASS (klass);
88 
89         /* Virtual methods */
90         object_class->finalize = ario_shell_songinfos_finalize;
91 
92         /* Private attributes */
93         g_type_class_add_private (klass, sizeof (ArioShellSonginfosPrivate));
94 }
95 
96 static void
ario_shell_songinfos_init(ArioShellSonginfos * shell_songinfos)97 ario_shell_songinfos_init (ArioShellSonginfos *shell_songinfos)
98 {
99         ARIO_LOG_FUNCTION_START;
100         shell_songinfos->priv = ARIO_SHELL_SONGINFOS_GET_PRIVATE (shell_songinfos);
101 }
102 
103 static gboolean
ario_shell_songinfos_can_edit_tags(void)104 ario_shell_songinfos_can_edit_tags (void)
105 {
106         ARIO_LOG_FUNCTION_START;
107 #ifdef ENABLE_TAGLIB
108         /* User can edit tags only if TABGLIB is enabled and Ario is on the same
109          * computer as music server and music directory is filled
110          */
111         return (ario_profiles_get_current (ario_profiles_get ())->local
112                         && ario_profiles_get_current (ario_profiles_get ())->musicdir);
113 #else
114         return FALSE;
115 #endif
116 }
117 
118 static void
ario_shell_songinfos_fill_tags(ArioServerSong * song)119 ario_shell_songinfos_fill_tags (ArioServerSong *song)
120 {
121         ARIO_LOG_FUNCTION_START;
122 #ifdef ENABLE_TAGLIB
123         gchar *filename;
124         TagLib_File *file;
125         TagLib_Tag *tag;
126         const TagLib_AudioProperties *properties;
127 
128         /* Get song full path */
129         filename = g_strconcat (ario_profiles_get_current (ario_profiles_get ())->musicdir, "/", song->file, NULL);
130 
131         /* Get taglib file */
132         file = taglib_file_new (filename);
133         g_free (filename);
134 
135         if (file && taglib_file_is_valid (file)) {
136                 /* Replace ArioServerSong tags by 'real' tags from taglib */
137                 tag = taglib_file_tag (file);
138                 properties = taglib_file_audioproperties (file);
139                 if (tag) {
140                         g_free (song->title);
141                         song->title = g_strdup (taglib_tag_title (tag));
142                         g_free (song->artist);
143                         song->artist = g_strdup (taglib_tag_artist (tag));
144                         g_free (song->album);
145                         song->album = g_strdup (taglib_tag_album (tag));
146                         g_free (song->track);
147                         song->track = g_strdup_printf ("%i", taglib_tag_track (tag));
148                         g_free (song->date);
149                         song->date = g_strdup_printf ("%i", taglib_tag_year (tag));
150                         g_free (song->genre);
151                         song->genre = g_strdup (taglib_tag_genre (tag));
152                         g_free (song->comment);
153                         song->comment = g_strdup (taglib_tag_comment (tag));
154                 }
155 
156                 if (properties)
157                         song->time = taglib_audioproperties_length (properties);
158 
159                 taglib_tag_free_strings ();
160                 taglib_file_free (file);
161         }
162 #endif
163 }
164 
165 GtkWidget *
ario_shell_songinfos_new(GSList * paths)166 ario_shell_songinfos_new (GSList *paths)
167 {
168         ARIO_LOG_FUNCTION_START;
169         ArioShellSonginfos *shell_songinfos;
170         GtkWidget *widget;
171         GtkBuilder *builder;
172         GList *tmp;
173 
174         shell_songinfos = g_object_new (TYPE_ARIO_SHELL_SONGINFOS, NULL);
175 
176         g_return_val_if_fail (shell_songinfos->priv != NULL, NULL);
177 
178         /* Build UI using GtkBuilder */
179         builder = gtk_builder_helpers_new (UI_PATH "song-infos.ui",
180                                            shell_songinfos);
181 
182         /* Get pointers to various widgets */
183         widget = GTK_WIDGET (gtk_builder_get_object (builder, "vbox"));
184         shell_songinfos->priv->title_entry =
185                 GTK_WIDGET (gtk_builder_get_object (builder, "title_entry"));
186         shell_songinfos->priv->artist_entry =
187                 GTK_WIDGET (gtk_builder_get_object (builder, "artist_entry"));
188         shell_songinfos->priv->album_entry =
189                 GTK_WIDGET (gtk_builder_get_object (builder, "album_entry"));
190         shell_songinfos->priv->album_artist_entry =
191                 GTK_WIDGET (gtk_builder_get_object (builder, "album_artist_entry"));
192         shell_songinfos->priv->track_entry =
193                 GTK_WIDGET (gtk_builder_get_object (builder, "track_entry"));
194         shell_songinfos->priv->length_entry =
195                 GTK_WIDGET (gtk_builder_get_object (builder, "length_entry"));
196         shell_songinfos->priv->date_entry =
197                 GTK_WIDGET (gtk_builder_get_object (builder, "date_entry"));
198         shell_songinfos->priv->file_entry =
199                 GTK_WIDGET (gtk_builder_get_object (builder, "file_entry"));
200         shell_songinfos->priv->genre_entry =
201                 GTK_WIDGET (gtk_builder_get_object (builder, "genre_entry"));
202         shell_songinfos->priv->composer_entry =
203                 GTK_WIDGET (gtk_builder_get_object (builder, "composer_entry"));
204         shell_songinfos->priv->performer_entry =
205                 GTK_WIDGET (gtk_builder_get_object (builder, "performer_entry"));
206         shell_songinfos->priv->disc_entry =
207                 GTK_WIDGET (gtk_builder_get_object (builder, "disc_entry"));
208         shell_songinfos->priv->comment_entry =
209                 GTK_WIDGET (gtk_builder_get_object (builder, "comment_entry"));
210 
211         /* Disable not editable text boxes */
212         gtk_widget_set_sensitive (shell_songinfos->priv->album_artist_entry, FALSE);
213         gtk_widget_set_sensitive (shell_songinfos->priv->length_entry, FALSE);
214         gtk_widget_set_sensitive (shell_songinfos->priv->file_entry, FALSE);
215         gtk_widget_set_sensitive (shell_songinfos->priv->composer_entry, FALSE);
216         gtk_widget_set_sensitive (shell_songinfos->priv->performer_entry, FALSE);
217         gtk_widget_set_sensitive (shell_songinfos->priv->disc_entry, FALSE);
218 
219         /* Change style of a labels */
220         gtk_builder_helpers_boldify_label (builder, "frame_label");
221         gtk_builder_helpers_boldify_label (builder, "title_const_label");
222         gtk_builder_helpers_boldify_label (builder, "artist_const_label");
223         gtk_builder_helpers_boldify_label (builder, "album_const_label");
224         gtk_builder_helpers_boldify_label (builder, "album_artist_const_label");
225         gtk_builder_helpers_boldify_label (builder, "track_const_label");
226         gtk_builder_helpers_boldify_label (builder, "length_const_label");
227         gtk_builder_helpers_boldify_label (builder, "date_const_label");
228         gtk_builder_helpers_boldify_label (builder, "file_const_label");
229         gtk_builder_helpers_boldify_label (builder, "genre_const_label");
230         gtk_builder_helpers_boldify_label (builder, "composer_const_label");
231         gtk_builder_helpers_boldify_label (builder, "performer_const_label");
232         gtk_builder_helpers_boldify_label (builder, "disc_const_label");
233         gtk_builder_helpers_boldify_label (builder, "comment_const_label");
234 
235         gtk_widget_set_size_request(shell_songinfos->priv->artist_entry, 280, -1);
236         gtk_widget_set_size_request(shell_songinfos->priv->album_entry, 280, -1);
237         gtk_widget_set_size_request(shell_songinfos->priv->album_artist_entry, 280, -1);
238         gtk_widget_set_size_request(shell_songinfos->priv->track_entry, 280, -1);
239         gtk_widget_set_size_request(shell_songinfos->priv->length_entry, 280, -1);
240         gtk_widget_set_size_request(shell_songinfos->priv->date_entry, 280, -1);
241         gtk_widget_set_size_request(shell_songinfos->priv->file_entry, 280, -1);
242         gtk_widget_set_size_request(shell_songinfos->priv->genre_entry, 280, -1);
243         gtk_widget_set_size_request(shell_songinfos->priv->composer_entry, 280, -1);
244         gtk_widget_set_size_request(shell_songinfos->priv->performer_entry, 280, -1);
245         gtk_widget_set_size_request(shell_songinfos->priv->disc_entry, 280, -1);
246         gtk_widget_set_size_request(shell_songinfos->priv->comment_entry, 280, -1);
247 
248         /* Set window properties */
249         gtk_window_set_title (GTK_WINDOW (shell_songinfos), _("Song Properties"));
250         gtk_window_set_resizable (GTK_WINDOW (shell_songinfos), TRUE);
251         gtk_window_set_default_size (GTK_WINDOW (shell_songinfos), 450, 350);
252 
253         /* Create notebook */
254         shell_songinfos->priv->notebook = GTK_WIDGET (gtk_notebook_new ());
255         gtk_container_set_border_width (GTK_CONTAINER (shell_songinfos->priv->notebook), 5);
256         gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (shell_songinfos))),
257                            shell_songinfos->priv->notebook);
258 
259         /* Set songinfos properties */
260         gtk_container_set_border_width (GTK_CONTAINER (shell_songinfos), 5);
261         gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (shell_songinfos))), 2);
262 
263         /* Append tags page to notebook */
264         gtk_notebook_append_page (GTK_NOTEBOOK (shell_songinfos->priv->notebook),
265                                   widget,
266                                   gtk_label_new (_("Song Properties")));
267 
268         /* Append lyrics page to notebook */
269         shell_songinfos->priv->lyrics_editor = ario_lyrics_editor_new ();
270         gtk_notebook_append_page (GTK_NOTEBOOK (shell_songinfos->priv->notebook),
271                                   shell_songinfos->priv->lyrics_editor,
272                                   gtk_label_new (_("Lyrics")));
273 
274         /* Connect signals for window deletion */
275         g_signal_connect (shell_songinfos,
276                           "delete_event",
277                           G_CALLBACK (ario_shell_songinfos_window_delete_cb),
278                           shell_songinfos);
279         g_signal_connect (shell_songinfos,
280                           "response",
281                           G_CALLBACK (ario_shell_songinfos_response_cb),
282                           shell_songinfos);
283 
284         shell_songinfos->priv->songs = ario_server_get_songs_info (paths);
285         if (ario_shell_songinfos_can_edit_tags ()) {
286                 /* Activate edition of text boxes */
287                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->title_entry), TRUE);
288                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->artist_entry), TRUE);
289                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->album_entry), TRUE);
290                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->track_entry), TRUE);
291                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->date_entry), TRUE);
292                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->genre_entry), TRUE);
293                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->comment_entry), TRUE);
294 
295                 /* Add save button */
296                 shell_songinfos->priv->save_button = gtk_button_new_from_icon_name ("document-save", GTK_ICON_SIZE_BUTTON);
297                 gtk_dialog_add_action_widget (GTK_DIALOG (shell_songinfos),
298                                               shell_songinfos->priv->save_button,
299                                               ARIO_SAVE);
300 
301                 /* Fill tags of all songs with 'real' tags from tablib */
302                 for (tmp = shell_songinfos->priv->songs; tmp; tmp = g_list_next (tmp)) {
303                         ario_shell_songinfos_fill_tags (tmp->data);
304                 }
305         } else {
306                 /* Deactivate edition of text boxes */
307                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->title_entry), FALSE);
308                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->artist_entry), FALSE);
309                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->album_entry), FALSE);
310                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->track_entry), FALSE);
311                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->date_entry), FALSE);
312                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->genre_entry), FALSE);
313                 gtk_editable_set_editable (GTK_EDITABLE (shell_songinfos->priv->comment_entry), FALSE);
314         }
315 
316         /* Add previous button */
317         shell_songinfos->priv->previous_button = gtk_button_new_from_icon_name ("go-previous", GTK_ICON_SIZE_BUTTON);
318         gtk_dialog_add_action_widget (GTK_DIALOG (shell_songinfos),
319                                       shell_songinfos->priv->previous_button,
320                                       ARIO_PREVIOUS);
321 
322         /* Add next button */
323         shell_songinfos->priv->next_button = gtk_button_new_from_icon_name ("go-next", GTK_ICON_SIZE_BUTTON);
324         gtk_dialog_add_action_widget (GTK_DIALOG (shell_songinfos),
325                                       shell_songinfos->priv->next_button,
326                                       ARIO_NEXT);
327 
328         /* Add close button */
329         gtk_dialog_add_button (GTK_DIALOG (shell_songinfos),
330                                "window-close",
331                                GTK_RESPONSE_CLOSE);
332 
333         gtk_dialog_set_default_response (GTK_DIALOG (shell_songinfos),
334                                          GTK_RESPONSE_CLOSE);
335 
336         /* Display first song */
337         ario_shell_songinfos_set_current_song (shell_songinfos);
338 
339         g_object_unref (builder);
340 
341         return GTK_WIDGET (shell_songinfos);
342 }
343 
344 static void
ario_shell_songinfos_finalize(GObject * object)345 ario_shell_songinfos_finalize (GObject *object)
346 {
347         ARIO_LOG_FUNCTION_START;
348         ArioShellSonginfos *shell_songinfos;
349 
350         g_return_if_fail (object != NULL);
351         g_return_if_fail (IS_ARIO_SHELL_SONGINFOS (object));
352 
353         shell_songinfos = ARIO_SHELL_SONGINFOS (object);
354 
355         g_return_if_fail (shell_songinfos->priv != NULL);
356 
357         /* Delete songs list */
358         shell_songinfos->priv->songs = g_list_first (shell_songinfos->priv->songs);
359         g_list_foreach (shell_songinfos->priv->songs, (GFunc) ario_server_free_song, NULL);
360         g_list_free (shell_songinfos->priv->songs);
361 
362         G_OBJECT_CLASS (ario_shell_songinfos_parent_class)->finalize (object);
363 }
364 
365 static gboolean
ario_shell_songinfos_window_delete_cb(GtkWidget * window,GdkEventAny * event,ArioShellSonginfos * shell_songinfos)366 ario_shell_songinfos_window_delete_cb (GtkWidget *window,
367                                        GdkEventAny *event,
368                                        ArioShellSonginfos *shell_songinfos)
369 {
370         ARIO_LOG_FUNCTION_START;
371         gtk_widget_hide (GTK_WIDGET (shell_songinfos));
372         gtk_widget_destroy (GTK_WIDGET (shell_songinfos));
373 
374         return TRUE;
375 }
376 
377 static void
ario_shell_songinfos_response_cb(GtkDialog * dial,int response_id,ArioShellSonginfos * shell_songinfos)378 ario_shell_songinfos_response_cb (GtkDialog *dial,
379                                   int response_id,
380                                   ArioShellSonginfos *shell_songinfos)
381 {
382         ARIO_LOG_FUNCTION_START;
383 #ifdef ENABLE_TAGLIB
384         gchar *filename;
385         TagLib_File *file;
386         TagLib_Tag *tag;
387         GtkWidget *dialog;
388         gboolean success;
389         ArioServerSong *song;
390 #endif
391 
392         switch (response_id) {
393         case GTK_RESPONSE_CLOSE:
394                 /* Destroy window */
395                 gtk_widget_hide (GTK_WIDGET (shell_songinfos));
396                 gtk_widget_destroy (GTK_WIDGET (shell_songinfos));
397                 break;
398 #ifdef ENABLE_TAGLIB
399         case ARIO_SAVE:
400                 /* Save tags */
401                 success = FALSE;
402                 g_return_if_fail (shell_songinfos->priv->songs);
403                 song = shell_songinfos->priv->songs->data;
404 
405                 /* Get full file path */
406                 filename = g_strconcat (ario_profiles_get_current (ario_profiles_get ())->musicdir, "/", song->file, NULL);
407 
408                 file = taglib_file_new (filename);
409                 if (file && taglib_file_is_valid (file)) {
410                         /* Fill taglib taglib tags with text boxes value */
411                         tag = taglib_file_tag (file);
412                         if (tag) {
413                                 taglib_tag_set_title (tag, gtk_entry_get_text (GTK_ENTRY (shell_songinfos->priv->title_entry)));
414                                 taglib_tag_set_artist (tag, gtk_entry_get_text (GTK_ENTRY (shell_songinfos->priv->artist_entry)));
415                                 taglib_tag_set_album (tag, gtk_entry_get_text (GTK_ENTRY (shell_songinfos->priv->album_entry)));
416                                 taglib_tag_set_track (tag, atoi (gtk_entry_get_text (GTK_ENTRY (shell_songinfos->priv->track_entry))));
417                                 taglib_tag_set_year (tag, atoi (gtk_entry_get_text (GTK_ENTRY (shell_songinfos->priv->date_entry))));
418                                 taglib_tag_set_genre (tag, gtk_entry_get_text (GTK_ENTRY (shell_songinfos->priv->genre_entry)));
419                                 taglib_tag_set_comment (tag, gtk_entry_get_text (GTK_ENTRY (shell_songinfos->priv->comment_entry)));
420                         }
421 
422                         /* Save tags in file */
423                         if (taglib_file_save (file)) {
424                                 /* Update song values with 'real' tags from taglib */
425                                 success = TRUE;
426                                 g_free (song->title);
427                                 song->title = g_strdup (taglib_tag_title (tag));
428                                 g_free (song->artist);
429                                 song->artist = g_strdup (taglib_tag_artist (tag));
430                                 g_free (song->album);
431                                 song->album = g_strdup (taglib_tag_album (tag));
432                                 g_free (song->track);
433                                 song->track = g_strdup_printf ("%i", taglib_tag_track (tag));
434                                 g_free (song->date);
435                                 song->date = g_strdup_printf ("%i", taglib_tag_year (tag));
436                                 g_free (song->genre);
437                                 song->genre = g_strdup (taglib_tag_genre (tag));
438                                 g_free (song->comment);
439                                 song->comment = g_strdup (taglib_tag_comment (tag));
440 
441                                 /* Update server database */
442                                 ario_server_update_db (song->file);
443                         }
444 
445                         taglib_tag_free_strings ();
446                         taglib_file_free (file);
447                 }
448                 if (!success) {
449                         /* Run error dialog */
450                         dialog = gtk_message_dialog_new (GTK_WINDOW (shell_songinfos),
451                                                          GTK_DIALOG_MODAL,
452                                                          GTK_MESSAGE_ERROR,
453                                                          GTK_BUTTONS_OK,
454                                                          "%s %s",
455                                                          _("Error saving tags of file:"), filename);
456                         gtk_dialog_run (GTK_DIALOG (dialog));
457                         gtk_widget_destroy (dialog);
458                 } else if (shell_songinfos->priv->save_button) {
459                         /* Deactivate save button until next tag modification */
460                         gtk_widget_set_sensitive (GTK_WIDGET (shell_songinfos->priv->save_button), FALSE);
461                 }
462 
463                 g_free (filename);
464                 break;
465 #endif
466         case ARIO_PREVIOUS:
467                 if (g_list_previous (shell_songinfos->priv->songs)) {
468                         /* Display previous song */
469                         shell_songinfos->priv->songs = g_list_previous (shell_songinfos->priv->songs);
470                         ario_shell_songinfos_set_current_song (shell_songinfos);
471                 }
472                 break;
473         case ARIO_NEXT:
474                 if (g_list_next (shell_songinfos->priv->songs)) {
475                         /* Display next song */
476                         shell_songinfos->priv->songs = g_list_next (shell_songinfos->priv->songs);
477                         ario_shell_songinfos_set_current_song (shell_songinfos);
478                 }
479                 break;
480         }
481 }
482 
483 static void
ario_shell_songinfos_set_current_song(ArioShellSonginfos * shell_songinfos)484 ario_shell_songinfos_set_current_song (ArioShellSonginfos *shell_songinfos)
485 {
486         ARIO_LOG_FUNCTION_START;
487         ArioServerSong *song;
488         gchar *length;
489         gchar *window_title;
490         ArioLyricsEditorData *data;
491         gboolean can_edit = ario_shell_songinfos_can_edit_tags ();
492 
493         if (!shell_songinfos->priv->songs)
494                 return;
495 
496         /* Get current song */
497         song = shell_songinfos->priv->songs->data;
498         if (!song)
499                 return;
500 
501         /* Fill text boxes with song tags */
502         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->title_entry), VALUE (song->title));
503         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->artist_entry), VALUE (song->artist));
504         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->album_entry), VALUE (song->album));
505         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->album_artist_entry), VALUE (song->album_artist));
506         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->track_entry), VALUE (song->track));
507         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->date_entry), VALUE (song->date));
508         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->genre_entry), VALUE (song->genre));
509         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->comment_entry), VALUE (song->comment));
510         length = ario_util_format_time (song->time);
511         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->length_entry), VALUE (length));
512         g_free (length);
513         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->file_entry), VALUE (song->file));
514         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->composer_entry), VALUE (song->composer));
515         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->performer_entry), VALUE (song->performer));
516         gtk_entry_set_text (GTK_ENTRY (shell_songinfos->priv->disc_entry), VALUE (song->disc));
517 
518         /* Set text boxes sensitivity */
519         gtk_widget_set_sensitive (shell_songinfos->priv->title_entry, can_edit);
520         gtk_widget_set_sensitive (shell_songinfos->priv->artist_entry, can_edit);
521         gtk_widget_set_sensitive (shell_songinfos->priv->album_entry, can_edit);
522         gtk_widget_set_sensitive (shell_songinfos->priv->track_entry, can_edit);
523         gtk_widget_set_sensitive (shell_songinfos->priv->date_entry, can_edit);
524         gtk_widget_set_sensitive (shell_songinfos->priv->genre_entry, can_edit);
525         gtk_widget_set_sensitive (shell_songinfos->priv->comment_entry, can_edit);
526 
527         /* Deactivate save button until next tag modification */
528         if (shell_songinfos->priv->save_button)
529                 gtk_widget_set_sensitive (GTK_WIDGET (shell_songinfos->priv->save_button), FALSE);
530 
531         /* Deactivate previous button if first song is displayed */
532         gtk_widget_set_sensitive (shell_songinfos->priv->previous_button, g_list_previous (shell_songinfos->priv->songs) != NULL);
533 
534         /* Deactivate next button if last song is displayed */
535         gtk_widget_set_sensitive (shell_songinfos->priv->next_button, g_list_next (shell_songinfos->priv->songs) != NULL);
536 
537         /* Get song lyrics */
538         data = (ArioLyricsEditorData *) g_malloc0 (sizeof (ArioLyricsEditorData));
539         data->artist = g_strdup (song->artist);
540         data->title = g_strdup (ario_util_format_title (song));
541         ario_lyrics_editor_push (ARIO_LYRICS_EDITOR (shell_songinfos->priv->lyrics_editor), data);
542 
543         /* Set window title */
544         window_title = g_strdup_printf ("%s - %s", _("Song Properties"), data->title);
545         gtk_window_set_title (GTK_WINDOW (shell_songinfos), window_title);
546 
547         g_free (window_title);
548 }
549 
550 void
ario_shell_songinfos_text_changed_cb(GtkWidget * widget,ArioShellSonginfos * shell_songinfos)551 ario_shell_songinfos_text_changed_cb (GtkWidget *widget,
552                                       ArioShellSonginfos *shell_songinfos)
553 {
554         ARIO_LOG_FUNCTION_START;
555         /* One tag has been modified, activate save button */
556         if (shell_songinfos->priv->save_button)
557                 gtk_widget_set_sensitive (GTK_WIDGET (shell_songinfos->priv->save_button), TRUE);
558 }
559 
560