1 /*
2  *  Copyright (C) 2004,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 of the License, or
7  *  (at your option) 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-coverselect.h"
21 #include <gtk/gtk.h>
22 #include <string.h>
23 #include <glib/gi18n.h>
24 
25 #include "ario-debug.h"
26 #include "ario-profiles.h"
27 #include "ario-util.h"
28 #include "covers/ario-cover.h"
29 #include "covers/ario-cover-handler.h"
30 #include "covers/ario-cover-manager.h"
31 #include "lib/ario-conf.h"
32 #include "lib/gtk-builder-helpers.h"
33 #include "preferences/ario-preferences.h"
34 
35 #define CURRENT_COVER_SIZE 130
36 #define MAX_COVER_SIZE 300
37 
38 static void ario_shell_coverselect_finalize (GObject *object);
39 static GObject * ario_shell_coverselect_constructor (GType type, guint n_construct_properties,
40                                                      GObjectConstructParam *construct_properties);
41 static gboolean ario_shell_coverselect_window_delete_cb (GtkWidget *window,
42                                                          GdkEventAny *event,
43                                                          ArioShellCoverselect *shell_coverselect);
44 static void ario_shell_coverselect_response_cb (GtkDialog *dialog,
45                                                 int response_id,
46                                                 ArioShellCoverselect *shell_coverselect);
47 G_MODULE_EXPORT void ario_shell_coverselect_local_open_button_cb (GtkWidget *widget,
48                                                                   ArioShellCoverselect *shell_coverselect);
49 G_MODULE_EXPORT void ario_shell_coverselect_get_covers_cb (GtkWidget *widget,
50                                                            ArioShellCoverselect *shell_coverselect);
51 static void ario_shell_coverselect_show_covers (ArioShellCoverselect *shell_coverselect);
52 static void ario_shell_coverselect_save_cover (ArioShellCoverselect *shell_coverselect);
53 static void ario_shell_coverselect_set_current_cover (ArioShellCoverselect *shell_coverselect);
54 
55 /* Tree columns */
56 enum
57 {
58         BMP_COLUMN,
59         N_COLUMN
60 };
61 
62 /* Notebook pages */
63 enum
64 {
65         GLOBAL_PAGE,
66         LOCAL_PAGE
67 };
68 
69 struct ArioShellCoverselectPrivate
70 {
71         GtkWidget *artist_entry;
72         GtkWidget *album_entry;
73 
74         GtkWidget *notebook;
75 
76         GtkWidget *artist_label;
77         GtkWidget *album_label;
78 
79         GtkWidget *get_covers_button;
80         GtkWidget *current_cover;
81 
82         GtkWidget *listview;
83         GtkListStore *liststore;
84 
85         GtkWidget *local_file_entry;
86 
87         const gchar *file_artist;
88         const gchar *file_album;
89         gchar *path;
90 
91         GArray *file_size;
92         GSList *file_contents;
93 };
94 
95 #define ARIO_SHELL_COVERSELECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_ARIO_SHELL_COVERSELECT, ArioShellCoverselectPrivate))
G_DEFINE_TYPE(ArioShellCoverselect,ario_shell_coverselect,GTK_TYPE_DIALOG)96 G_DEFINE_TYPE (ArioShellCoverselect, ario_shell_coverselect, GTK_TYPE_DIALOG)
97 
98 static void
99 ario_shell_coverselect_class_init (ArioShellCoverselectClass *klass)
100 {
101         ARIO_LOG_FUNCTION_START;
102         GObjectClass *object_class = G_OBJECT_CLASS (klass);
103 
104         /* Virtual methods */
105         object_class->finalize = ario_shell_coverselect_finalize;
106         object_class->constructor = ario_shell_coverselect_constructor;
107 
108         /* Private attributes */
109         g_type_class_add_private (klass, sizeof (ArioShellCoverselectPrivate));
110 }
111 
112 static void
ario_shell_coverselect_init(ArioShellCoverselect * shell_coverselect)113 ario_shell_coverselect_init (ArioShellCoverselect *shell_coverselect)
114 {
115         ARIO_LOG_FUNCTION_START;
116         shell_coverselect->priv = ARIO_SHELL_COVERSELECT_GET_PRIVATE (shell_coverselect);
117         shell_coverselect->priv->liststore = gtk_list_store_new (N_COLUMN, GDK_TYPE_PIXBUF);
118         shell_coverselect->priv->file_contents = NULL;
119 }
120 
121 static void
ario_shell_coverselect_finalize(GObject * object)122 ario_shell_coverselect_finalize (GObject *object)
123 {
124         ARIO_LOG_FUNCTION_START;
125         ArioShellCoverselect *shell_coverselect;
126 
127         g_return_if_fail (object != NULL);
128         g_return_if_fail (IS_ARIO_SHELL_COVERSELECT (object));
129 
130         shell_coverselect = ARIO_SHELL_COVERSELECT (object);
131 
132         g_return_if_fail (shell_coverselect->priv != NULL);
133 
134         if (shell_coverselect->priv->file_size)
135                 g_array_free (shell_coverselect->priv->file_size, TRUE);
136         g_slist_foreach (shell_coverselect->priv->file_contents, (GFunc) g_free, NULL);
137         g_slist_free (shell_coverselect->priv->file_contents);
138         g_free (shell_coverselect->priv->path);
139 
140         G_OBJECT_CLASS (ario_shell_coverselect_parent_class)->finalize (object);
141 }
142 
143 static void
ario_shell_coverselect_drag_leave_cb(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * data,guint info,guint time,ArioShellCoverselect * shell_coverselect)144 ario_shell_coverselect_drag_leave_cb (GtkWidget *widget,
145                                       GdkDragContext *context,
146                                       gint x, gint y,
147                                       GtkSelectionData *data,
148                                       guint info,
149                                       guint time,
150                                       ArioShellCoverselect *shell_coverselect)
151 {
152         ARIO_LOG_FUNCTION_START;
153         gchar *url;
154         gchar *contents;
155         gsize length;
156 
157         if (info == 1) {
158                 /* Drag of image */
159                 printf ("image  DND : TODO\n");
160         } else if (info == 2) {
161                 const guchar *udata = gtk_selection_data_get_data (data);
162                 /* Remove 'file://' */
163                 url = g_strndup ((gchar *) udata + 7, gtk_selection_data_get_length (data) - 2 - 7);
164                 if (ario_util_uri_exists (url)) {
165                         /* Get file content */
166                         if (ario_file_get_contents (url,
167                                                     &contents,
168                                                     &length,
169                                                     NULL)) {
170                                 /* Save cover */
171                                 ario_cover_save_cover (shell_coverselect->priv->file_artist,
172                                                        shell_coverselect->priv->file_album,
173                                                        contents, length,
174                                                        OVERWRITE_MODE_REPLACE);
175                                 g_free (contents);
176                                 ario_cover_handler_force_reload ();
177                                 /* Change cover in dialog */
178                                 ario_shell_coverselect_set_current_cover (shell_coverselect);
179                         }
180                 }
181                 g_free (url);
182         }
183 
184         /* Finish the drag */
185         gtk_drag_finish (context, TRUE, FALSE, time);
186 }
187 
188 static GObject *
ario_shell_coverselect_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)189 ario_shell_coverselect_constructor (GType type, guint n_construct_properties,
190                                     GObjectConstructParam *construct_properties)
191 {
192         ARIO_LOG_FUNCTION_START;
193         ArioShellCoverselect *shell_coverselect;
194         ArioShellCoverselectClass *klass;
195         GObjectClass *parent_class;
196         GtkBuilder *builder;
197         GtkWidget *vbox;
198         GtkTargetList *targets;
199         GtkTargetEntry *target_entry;
200         gint n_elem;
201 
202         /* Call parent constructor */
203         klass = ARIO_SHELL_COVERSELECT_CLASS (g_type_class_peek (TYPE_ARIO_SHELL_COVERSELECT));
204         parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
205         shell_coverselect = ARIO_SHELL_COVERSELECT (parent_class->constructor (type, n_construct_properties,
206                                                                                construct_properties));
207 
208         /* Create UI using GtkBuilder */
209         builder = gtk_builder_helpers_new (UI_PATH "cover-select.ui",
210                                            shell_coverselect);
211 
212         /* Get pointers to various widgets */
213         vbox = GTK_WIDGET (gtk_builder_get_object (builder, "vbox"));
214         shell_coverselect->priv->artist_label =
215                 GTK_WIDGET (gtk_builder_get_object (builder, "artist_label"));
216         shell_coverselect->priv->album_label =
217                 GTK_WIDGET (gtk_builder_get_object (builder, "album_label"));
218         shell_coverselect->priv->notebook =
219                 GTK_WIDGET (gtk_builder_get_object (builder, "notebook"));
220         shell_coverselect->priv->artist_entry =
221                 GTK_WIDGET (gtk_builder_get_object (builder, "artist_entry"));
222         shell_coverselect->priv->album_entry =
223                 GTK_WIDGET (gtk_builder_get_object (builder, "album_entry"));
224         shell_coverselect->priv->get_covers_button =
225                 GTK_WIDGET (gtk_builder_get_object (builder, "search_button"));
226         shell_coverselect->priv->current_cover =
227                 GTK_WIDGET (gtk_builder_get_object (builder, "current_cover"));
228         shell_coverselect->priv->listview =
229                 GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
230         shell_coverselect->priv->local_file_entry =
231                 GTK_WIDGET (gtk_builder_get_object (builder, "local_file_entry"));
232         shell_coverselect->priv->liststore =
233                 GTK_LIST_STORE (gtk_builder_get_object (builder, "liststore"));
234 
235         gtk_builder_helpers_boldify_label (builder, "static_artist_label");
236         gtk_builder_helpers_boldify_label (builder, "static_album_label");
237 
238         gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (shell_coverselect))),
239                            vbox);
240 
241         /* Set window properties */
242         gtk_window_set_title (GTK_WINDOW (shell_coverselect), _("Cover Download"));
243         gtk_window_set_default_size (GTK_WINDOW (shell_coverselect), 520, 620);
244         gtk_dialog_add_button (GTK_DIALOG (shell_coverselect),
245                                _("_Cancel"),
246                                GTK_RESPONSE_CANCEL);
247         gtk_dialog_add_button (GTK_DIALOG (shell_coverselect),
248                                _("_OK"),
249                                GTK_RESPONSE_OK);
250         gtk_dialog_set_default_response (GTK_DIALOG (shell_coverselect),
251                                          GTK_RESPONSE_OK);
252 
253         /* Connect signals for user actions */
254         g_signal_connect (shell_coverselect,
255                           "delete_event",
256                           G_CALLBACK (ario_shell_coverselect_window_delete_cb),
257                           shell_coverselect);
258         g_signal_connect (shell_coverselect,
259                           "response",
260                           G_CALLBACK (ario_shell_coverselect_response_cb),
261                           shell_coverselect);
262 
263         /* Set drag and drop target */
264         targets = gtk_target_list_new (NULL, 0);
265         gtk_target_list_add_image_targets (targets, 1, TRUE);
266         gtk_target_list_add_uri_targets (targets, 2);
267         target_entry = gtk_target_table_new_from_list (targets, &n_elem);
268         gtk_target_list_unref (targets);
269 
270         gtk_drag_dest_set (shell_coverselect->priv->current_cover,
271                            GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
272                            target_entry, n_elem,
273                            GDK_ACTION_COPY);
274         gtk_target_table_free (target_entry, n_elem);
275 
276         g_signal_connect (shell_coverselect->priv->current_cover,
277                           "drag_data_received",
278                           G_CALLBACK (ario_shell_coverselect_drag_leave_cb),
279                           shell_coverselect);
280 
281         g_object_unref (builder);
282 
283         return G_OBJECT (shell_coverselect);
284 }
285 
286 GtkWidget *
ario_shell_coverselect_new(ArioServerAlbum * server_album)287 ario_shell_coverselect_new (ArioServerAlbum *server_album)
288 {
289         ARIO_LOG_FUNCTION_START;
290         ArioShellCoverselect *shell_coverselect;
291 
292         shell_coverselect = g_object_new (TYPE_ARIO_SHELL_COVERSELECT,
293                                           NULL);
294 
295         /* Remember info about album */
296         shell_coverselect->priv->file_artist = server_album->artist;
297         shell_coverselect->priv->file_album = server_album->album;
298         shell_coverselect->priv->path = g_path_get_dirname (server_album->path);
299 
300         /* Fill widgets with album data */
301         ario_shell_coverselect_set_current_cover (shell_coverselect);
302 
303         gtk_entry_set_text (GTK_ENTRY (shell_coverselect->priv->artist_entry),
304                             shell_coverselect->priv->file_artist);
305         gtk_entry_set_text (GTK_ENTRY (shell_coverselect->priv->album_entry),
306                             shell_coverselect->priv->file_album);
307 
308         gtk_label_set_label (GTK_LABEL (shell_coverselect->priv->artist_label),
309                              shell_coverselect->priv->file_artist);
310         gtk_label_set_label (GTK_LABEL (shell_coverselect->priv->album_label),
311                              shell_coverselect->priv->file_album);
312 
313         g_return_val_if_fail (shell_coverselect->priv != NULL, NULL);
314 
315         return GTK_WIDGET (shell_coverselect);
316 }
317 
318 static gboolean
ario_shell_coverselect_window_delete_cb(GtkWidget * window,GdkEventAny * event,ArioShellCoverselect * shell_coverselect)319 ario_shell_coverselect_window_delete_cb (GtkWidget *window,
320                                          GdkEventAny *event,
321                                          ArioShellCoverselect *shell_coverselect)
322 {
323         ARIO_LOG_FUNCTION_START;
324         gtk_widget_hide (GTK_WIDGET (shell_coverselect));
325         return FALSE;
326 }
327 
328 static void
ario_shell_coverselect_response_cb(GtkDialog * dialog,int response_id,ArioShellCoverselect * shell_coverselect)329 ario_shell_coverselect_response_cb (GtkDialog *dialog,
330                                     int response_id,
331                                     ArioShellCoverselect *shell_coverselect)
332 {
333         ARIO_LOG_FUNCTION_START;
334         if (response_id == GTK_RESPONSE_OK) {
335                 /* Save cover */
336                 ario_shell_coverselect_save_cover (shell_coverselect);
337                 gtk_widget_hide (GTK_WIDGET (shell_coverselect));
338         }
339 
340         if (response_id == GTK_RESPONSE_CANCEL)
341                 gtk_widget_hide (GTK_WIDGET (shell_coverselect));
342 }
343 
344 void
ario_shell_coverselect_local_open_button_cb(GtkWidget * widget,ArioShellCoverselect * shell_coverselect)345 ario_shell_coverselect_local_open_button_cb (GtkWidget *widget,
346                                              ArioShellCoverselect *shell_coverselect)
347 {
348         ARIO_LOG_FUNCTION_START;
349         GtkWidget *dialog;
350         gchar *musicdir;
351         gchar *path;
352 
353         /* Create dialog to choose file on disk */
354         dialog = gtk_file_chooser_dialog_new (NULL,
355                                               NULL,
356                                               GTK_FILE_CHOOSER_ACTION_OPEN,
357                                               _("_Cancel"),
358                                               GTK_RESPONSE_CANCEL,
359                                               _("_Open"),
360                                               GTK_RESPONSE_ACCEPT,
361                                               NULL);
362 
363         /* Set folder to the album folder if possible */
364         musicdir = ario_profiles_get_current (ario_profiles_get ())->musicdir;
365         if (musicdir) {
366                 path = g_build_filename (musicdir, shell_coverselect->priv->path, NULL);
367 
368                 if (ario_util_uri_exists (path))
369                         gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path);
370 
371                 g_free (path);
372         }
373 
374         /* Launch dialog */
375         if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
376                 char *filename;
377 
378                 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
379                 if (filename) {
380                         /* Fill text entry with selected file */
381                         gtk_entry_set_text (GTK_ENTRY (shell_coverselect->priv->local_file_entry),
382                                             filename);
383                         g_free (filename);
384                 }
385         }
386 
387         gtk_widget_destroy (dialog);
388 }
389 
390 static void
ario_shell_coverselect_set_sensitive(ArioShellCoverselect * shell_coverselect,gboolean sensitive)391 ario_shell_coverselect_set_sensitive (ArioShellCoverselect *shell_coverselect,
392                                       gboolean sensitive)
393 {
394         ARIO_LOG_FUNCTION_START;
395         /* Change widgets sensitivity */
396         gtk_dialog_set_response_sensitive (GTK_DIALOG (shell_coverselect),
397                                            GTK_RESPONSE_CLOSE,
398                                            sensitive);
399         gtk_widget_set_sensitive (GTK_WIDGET (shell_coverselect->priv->artist_entry), sensitive);
400         gtk_widget_set_sensitive (GTK_WIDGET (shell_coverselect->priv->album_entry), sensitive);
401         gtk_widget_set_sensitive (GTK_WIDGET (shell_coverselect->priv->get_covers_button), sensitive);
402         gtk_widget_set_sensitive (GTK_WIDGET (shell_coverselect->priv->listview), sensitive);
403 
404         /* Wait for UI to refresh */
405         while (gtk_events_pending ())
406                 gtk_main_iteration ();
407 }
408 
409 void
ario_shell_coverselect_get_covers_cb(GtkWidget * widget,ArioShellCoverselect * shell_coverselect)410 ario_shell_coverselect_get_covers_cb (GtkWidget *widget,
411                                       ArioShellCoverselect *shell_coverselect)
412 {
413         ARIO_LOG_FUNCTION_START;
414         const gchar *artist;
415         const gchar *album;
416 
417         /* Set widgets insensitive during cover download */
418         ario_shell_coverselect_set_sensitive (shell_coverselect, FALSE);
419 
420         artist = gtk_entry_get_text (GTK_ENTRY (shell_coverselect->priv->artist_entry));
421         album = gtk_entry_get_text (GTK_ENTRY (shell_coverselect->priv->album_entry));
422 
423         /* Free previous data */
424         if (shell_coverselect->priv->file_size)
425                 g_array_free (shell_coverselect->priv->file_size, TRUE);
426         g_slist_foreach (shell_coverselect->priv->file_contents, (GFunc) g_free, NULL);
427         g_slist_free (shell_coverselect->priv->file_contents);
428         shell_coverselect->priv->file_contents = NULL;
429 
430         /* Get covers */
431         shell_coverselect->priv->file_size = g_array_new (TRUE, TRUE, sizeof (int));
432 
433         ario_cover_manager_get_covers (ario_cover_manager_get_instance (),
434                                        artist,
435                                        album,
436                                        shell_coverselect->priv->path,
437                                        &shell_coverselect->priv->file_size,
438                                        &shell_coverselect->priv->file_contents,
439                                        GET_ALL_COVERS);
440 
441         /* Show downloaded covers */
442         ario_shell_coverselect_show_covers (shell_coverselect);
443 
444         /* Reset widgets sensitive */
445         ario_shell_coverselect_set_sensitive (shell_coverselect, TRUE);
446 }
447 
448 static void
ario_shell_coverselect_show_covers(ArioShellCoverselect * shell_coverselect)449 ario_shell_coverselect_show_covers (ArioShellCoverselect *shell_coverselect)
450 {
451         ARIO_LOG_FUNCTION_START;
452         GtkTreeIter iter;
453         int i = 0;
454         GSList *temp;
455         GdkPixbuf *pixbuf, *tmp_pixbuf;
456         GdkPixbufLoader *loader;
457         int height, width;
458 
459         /* Empty list */
460         gtk_list_store_clear (shell_coverselect->priv->liststore);
461 
462         if (!shell_coverselect->priv->file_contents)
463                 return;
464 
465         /* For each downloaded cover */
466         temp = shell_coverselect->priv->file_contents;
467         while (g_array_index (shell_coverselect->priv->file_size, int, i) != 0) {
468                 /* Get a pixbuf from downloaded data */
469                 loader = gdk_pixbuf_loader_new ();
470                 if (gdk_pixbuf_loader_write (loader,
471                                              temp->data,
472                                              g_array_index (shell_coverselect->priv->file_size, int, i),
473                                              NULL)) {
474                         gdk_pixbuf_loader_close (loader, NULL);
475                         pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
476 
477                         /* Resize cover */
478                         height = gdk_pixbuf_get_height (pixbuf);
479                         width = gdk_pixbuf_get_width (pixbuf);
480                         if (height > MAX_COVER_SIZE || width > MAX_COVER_SIZE) {
481                                 tmp_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
482                                                                       MAX_COVER_SIZE,
483                                                                       height * MAX_COVER_SIZE / width,
484                                                                       GDK_INTERP_BILINEAR);
485                                 g_object_unref (G_OBJECT (pixbuf));
486                                 pixbuf = tmp_pixbuf;
487                         }
488 
489                         /* Append cover so list */
490                         gtk_list_store_append(shell_coverselect->priv->liststore,
491                                               &iter);
492                         gtk_list_store_set (shell_coverselect->priv->liststore,
493                                             &iter,
494                                             BMP_COLUMN,
495                                             pixbuf, -1);
496 
497                         g_object_unref (G_OBJECT (pixbuf));
498                 }
499                 temp = g_slist_next (temp);
500                 ++i;
501         }
502 
503         /* Select first item in list */
504         if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (shell_coverselect->priv->liststore), &iter))
505                 gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (shell_coverselect->priv->listview)), &iter);
506 }
507 
508 static void
ario_shell_coverselect_save_cover(ArioShellCoverselect * shell_coverselect)509 ario_shell_coverselect_save_cover (ArioShellCoverselect *shell_coverselect)
510 {
511         ARIO_LOG_FUNCTION_START;
512         GtkWidget *dialog;
513 
514         GtkTreeSelection *selection;
515         GtkTreeIter iter;
516         GtkTreePath *tree_path;
517         gint *indice;
518         gchar *data;
519         const gchar *local_file;
520         gsize size;
521         gboolean ret;
522 
523         switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (shell_coverselect->priv->notebook))) {
524         case GLOBAL_PAGE:
525                 /* Get selected cover */
526                 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (shell_coverselect->priv->listview));
527 
528                 if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
529                         return;
530                 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (shell_coverselect->priv->liststore),
531                                                      &iter);
532 
533                 indice = gtk_tree_path_get_indices (tree_path);
534 
535                 /* Save cover */
536                 ret = ario_cover_save_cover (shell_coverselect->priv->file_artist,
537                                              shell_coverselect->priv->file_album,
538                                              g_slist_nth_data (shell_coverselect->priv->file_contents, indice[0]),
539                                              g_array_index (shell_coverselect->priv->file_size, int, indice[0]),
540                                              OVERWRITE_MODE_ASK);
541                 gtk_tree_path_free (tree_path);
542                 break;
543         case LOCAL_PAGE:
544                 /* Cover file on disk */
545                 local_file = gtk_entry_get_text (GTK_ENTRY (shell_coverselect->priv->local_file_entry));
546                 if (!local_file || !strcmp (local_file, ""))
547                         return;
548 
549                 /* Get cover file content */
550                 ret = ario_file_get_contents (local_file,
551                                               &data,
552                                               &size,
553                                               NULL);
554                 if (!ret) {
555                         /* Error */
556                         dialog = gtk_message_dialog_new(NULL,
557                                                         GTK_DIALOG_MODAL,
558                                                         GTK_MESSAGE_ERROR,
559                                                         GTK_BUTTONS_OK,
560                                                         _("Error reading file"));
561                         gtk_dialog_run (GTK_DIALOG (dialog));
562                         gtk_widget_destroy (dialog);
563                         return;
564                 }
565 
566                 /* Save cover */
567                 ret = ario_cover_save_cover (shell_coverselect->priv->file_artist,
568                                              shell_coverselect->priv->file_album,
569                                              data,
570                                              size,
571                                              OVERWRITE_MODE_ASK);
572                 g_free (data);
573                 break;
574         default:
575                 return;
576                 break;
577         }
578 
579         if (!ret) {
580                 /* Error */
581                 dialog = gtk_message_dialog_new(NULL,
582                                                 GTK_DIALOG_MODAL,
583                                                 GTK_MESSAGE_ERROR,
584                                                 GTK_BUTTONS_OK,
585                                                 _("Error saving file"));
586                 gtk_dialog_run(GTK_DIALOG(dialog));
587                 gtk_widget_destroy(dialog);
588         }
589         /* Reload current cover */
590         ario_cover_handler_force_reload();
591 }
592 
593 static void
ario_shell_coverselect_set_current_cover(ArioShellCoverselect * shell_coverselect)594 ario_shell_coverselect_set_current_cover (ArioShellCoverselect *shell_coverselect)
595 {
596         ARIO_LOG_FUNCTION_START;
597         GdkPixbuf *pixbuf;
598         gchar *ario_cover_path;
599 
600         if (ario_cover_cover_exists (shell_coverselect->priv->file_artist, shell_coverselect->priv->file_album)) {
601                 /* Get cover path */
602                 ario_cover_path = ario_cover_make_cover_path (shell_coverselect->priv->file_artist,
603                                                               shell_coverselect->priv->file_album,
604                                                               NORMAL_COVER);
605                 /* Display cover in cover widget */
606                 gtk_widget_show_all (shell_coverselect->priv->current_cover);
607                 pixbuf = gdk_pixbuf_new_from_file_at_size (ario_cover_path, CURRENT_COVER_SIZE, CURRENT_COVER_SIZE, NULL);
608                 g_free (ario_cover_path);
609                 gtk_image_set_from_pixbuf (GTK_IMAGE (shell_coverselect->priv->current_cover),
610                                            pixbuf);
611                 g_object_unref (pixbuf);
612         } else {
613                 /* No cover, hide cover widget */
614                 gtk_widget_hide (shell_coverselect->priv->current_cover);
615         }
616 }
617