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-lyricsselect.h"
21 #include <gtk/gtk.h>
22 #include <string.h>
23 
24 #include <glib/gi18n.h>
25 #include "lyrics/ario-lyrics-manager.h"
26 #include "lib/gtk-builder-helpers.h"
27 #include "ario-debug.h"
28 
29 #define CURRENT_LYRICS_SIZE 130
30 
31 static void ario_shell_lyricsselect_finalize (GObject *object);
32 static GObject * ario_shell_lyricsselect_constructor (GType type, guint n_construct_properties,
33                                                       GObjectConstructParam *construct_properties);
34 static gboolean ario_shell_lyricsselect_window_delete_cb (GtkWidget *window,
35                                                           GdkEventAny *event,
36                                                           ArioShellLyricsselect *shell_lyricsselect);
37 static void ario_shell_lyricsselect_search_cb (GtkWidget *widget,
38                                                ArioShellLyricsselect *shell_lyricsselect);
39 static void ario_shell_lyricsselect_show_lyrics (ArioShellLyricsselect *shell_lyricsselect);
40 
41 enum
42 {
43         ARTIST_COLUMN,
44         TITLE_COLUMN,
45         PROVIDER_COLUMN,
46         CANDIDATE_COLUMN,
47         N_COLUMN
48 };
49 
50 struct ArioShellLyricsselectPrivate
51 {
52         GtkWidget *artist_entry;
53         GtkWidget *title_entry;
54 
55         GtkWidget *artist_label;
56         GtkWidget *title_label;
57 
58         GtkWidget *search_button;
59 
60         GtkWidget *treeview;
61         GtkListStore *liststore;
62 
63         const gchar *file_artist;
64         const gchar *file_title;
65 
66         GSList *lyrics;
67 };
68 
69 #define ARIO_SHELL_LYRICSSELECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_ARIO_SHELL_LYRICSSELECT, ArioShellLyricsselectPrivate))
G_DEFINE_TYPE(ArioShellLyricsselect,ario_shell_lyricsselect,GTK_TYPE_DIALOG)70 G_DEFINE_TYPE (ArioShellLyricsselect, ario_shell_lyricsselect, GTK_TYPE_DIALOG)
71 
72 static void
73 ario_shell_lyricsselect_class_init (ArioShellLyricsselectClass *klass)
74 {
75         ARIO_LOG_FUNCTION_START;
76         GObjectClass *object_class = G_OBJECT_CLASS (klass);
77 
78         object_class->finalize = ario_shell_lyricsselect_finalize;
79         object_class->constructor = ario_shell_lyricsselect_constructor;
80 
81         g_type_class_add_private (klass, sizeof (ArioShellLyricsselectPrivate));
82 }
83 
84 static void
ario_shell_lyricsselect_init(ArioShellLyricsselect * shell_lyricsselect)85 ario_shell_lyricsselect_init (ArioShellLyricsselect *shell_lyricsselect)
86 {
87         ARIO_LOG_FUNCTION_START;
88         shell_lyricsselect->priv = ARIO_SHELL_LYRICSSELECT_GET_PRIVATE (shell_lyricsselect);
89         shell_lyricsselect->priv->lyrics = NULL;
90 }
91 
92 static void
ario_shell_lyricsselect_finalize(GObject * object)93 ario_shell_lyricsselect_finalize (GObject *object)
94 {
95         ARIO_LOG_FUNCTION_START;
96         ArioShellLyricsselect *shell_lyricsselect;
97 
98         g_return_if_fail (object != NULL);
99         g_return_if_fail (IS_ARIO_SHELL_LYRICSSELECT (object));
100 
101         shell_lyricsselect = ARIO_SHELL_LYRICSSELECT (object);
102 
103         g_return_if_fail (shell_lyricsselect->priv != NULL);
104 
105         g_slist_foreach (shell_lyricsselect->priv->lyrics, (GFunc) ario_lyrics_candidate_free, NULL);
106         g_slist_free (shell_lyricsselect->priv->lyrics);
107 
108         G_OBJECT_CLASS (ario_shell_lyricsselect_parent_class)->finalize (object);
109 }
110 
111 static GObject *
ario_shell_lyricsselect_constructor(GType type,guint n_construct_properties,GObjectConstructParam * construct_properties)112 ario_shell_lyricsselect_constructor (GType type, guint n_construct_properties,
113                                      GObjectConstructParam *construct_properties)
114 {
115         ARIO_LOG_FUNCTION_START;
116         ArioShellLyricsselect *shell_lyricsselect;
117         ArioShellLyricsselectClass *klass;
118         GObjectClass *parent_class;
119         GtkBuilder *builder;
120         GtkWidget *vbox;
121 
122         klass = ARIO_SHELL_LYRICSSELECT_CLASS (g_type_class_peek (TYPE_ARIO_SHELL_LYRICSSELECT));
123 
124         parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
125         shell_lyricsselect = ARIO_SHELL_LYRICSSELECT (parent_class->constructor (type, n_construct_properties,
126                                                                                  construct_properties));
127 
128         builder = gtk_builder_helpers_new (UI_PATH "lyrics-select.ui",
129                                            NULL);
130         vbox = GTK_WIDGET (gtk_builder_get_object (builder, "vbox"));
131         shell_lyricsselect->priv->artist_label =
132                 GTK_WIDGET (gtk_builder_get_object (builder, "artist_label"));
133         shell_lyricsselect->priv->title_label =
134                 GTK_WIDGET (gtk_builder_get_object (builder, "title_label"));
135         shell_lyricsselect->priv->artist_entry =
136                 GTK_WIDGET (gtk_builder_get_object (builder, "artist_entry"));
137         shell_lyricsselect->priv->title_entry =
138                 GTK_WIDGET (gtk_builder_get_object (builder, "title_entry"));
139         shell_lyricsselect->priv->search_button =
140                 GTK_WIDGET (gtk_builder_get_object (builder, "search_button"));
141         shell_lyricsselect->priv->treeview =
142                 GTK_WIDGET (gtk_builder_get_object (builder, "treeview"));
143         shell_lyricsselect->priv->liststore =
144                 GTK_LIST_STORE (gtk_builder_get_object (builder, "liststore"));
145 
146         gtk_builder_helpers_boldify_label (builder, "static_artist_label");
147         gtk_builder_helpers_boldify_label (builder, "static_title_label");
148 
149         gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (shell_lyricsselect))),
150                            vbox);
151 
152         gtk_window_set_title (GTK_WINDOW (shell_lyricsselect), _("Lyrics Download"));
153         gtk_window_set_default_size (GTK_WINDOW (shell_lyricsselect), 520, 350);
154         gtk_dialog_add_button (GTK_DIALOG (shell_lyricsselect),
155                                _("_Cancel"),
156                                GTK_RESPONSE_CANCEL);
157         gtk_dialog_add_button (GTK_DIALOG (shell_lyricsselect),
158                                _("_OK"),
159                                GTK_RESPONSE_OK);
160         gtk_dialog_set_default_response (GTK_DIALOG (shell_lyricsselect),
161                                          GTK_RESPONSE_OK);
162 
163         g_signal_connect (shell_lyricsselect,
164                           "delete_event",
165                           G_CALLBACK (ario_shell_lyricsselect_window_delete_cb),
166                           shell_lyricsselect);
167         g_signal_connect (shell_lyricsselect->priv->search_button,
168                           "clicked", G_CALLBACK (ario_shell_lyricsselect_search_cb),
169                           shell_lyricsselect);
170 
171         g_object_unref (builder);
172 
173         return G_OBJECT (shell_lyricsselect);
174 }
175 
176 GtkWidget *
ario_shell_lyricsselect_new(const char * artist,const char * title)177 ario_shell_lyricsselect_new (const char *artist,
178                              const char *title)
179 {
180         ARIO_LOG_FUNCTION_START;
181         ArioShellLyricsselect *shell_lyricsselect;
182 
183         shell_lyricsselect = g_object_new (TYPE_ARIO_SHELL_LYRICSSELECT,
184                                            NULL);
185 
186         shell_lyricsselect->priv->file_artist = artist;
187         shell_lyricsselect->priv->file_title = title;
188 
189         gtk_entry_set_text (GTK_ENTRY (shell_lyricsselect->priv->artist_entry),
190                             shell_lyricsselect->priv->file_artist);
191         gtk_entry_set_text (GTK_ENTRY (shell_lyricsselect->priv->title_entry),
192                             shell_lyricsselect->priv->file_title);
193 
194         gtk_label_set_label (GTK_LABEL (shell_lyricsselect->priv->artist_label),
195                              shell_lyricsselect->priv->file_artist);
196         gtk_label_set_label (GTK_LABEL (shell_lyricsselect->priv->title_label),
197                              shell_lyricsselect->priv->file_title);
198 
199         g_return_val_if_fail (shell_lyricsselect->priv != NULL, NULL);
200 
201         return GTK_WIDGET (shell_lyricsselect);
202 }
203 
204 static gboolean
ario_shell_lyricsselect_window_delete_cb(GtkWidget * window,GdkEventAny * event,ArioShellLyricsselect * shell_lyricsselect)205 ario_shell_lyricsselect_window_delete_cb (GtkWidget *window,
206                                           GdkEventAny *event,
207                                           ArioShellLyricsselect *shell_lyricsselect)
208 {
209         ARIO_LOG_FUNCTION_START;
210         gtk_widget_hide (GTK_WIDGET (shell_lyricsselect));
211         return FALSE;
212 }
213 
214 static void
ario_shell_lyricsselect_set_sensitive(ArioShellLyricsselect * shell_lyricsselect,gboolean sensitive)215 ario_shell_lyricsselect_set_sensitive (ArioShellLyricsselect *shell_lyricsselect,
216                                        gboolean sensitive)
217 {
218         ARIO_LOG_FUNCTION_START;
219         gtk_dialog_set_response_sensitive (GTK_DIALOG (shell_lyricsselect),
220                                            GTK_RESPONSE_CLOSE,
221                                            sensitive);
222         gtk_widget_set_sensitive (GTK_WIDGET (shell_lyricsselect->priv->artist_entry), sensitive);
223         gtk_widget_set_sensitive (GTK_WIDGET (shell_lyricsselect->priv->title_entry), sensitive);
224         gtk_widget_set_sensitive (GTK_WIDGET (shell_lyricsselect->priv->search_button), sensitive);
225         gtk_widget_set_sensitive (GTK_WIDGET (shell_lyricsselect->priv->treeview), sensitive);
226 
227         while (gtk_events_pending ())
228                 gtk_main_iteration ();
229 }
230 
231 static void
ario_shell_lyricsselect_search_cb(GtkWidget * widget,ArioShellLyricsselect * shell_lyricsselect)232 ario_shell_lyricsselect_search_cb (GtkWidget *widget,
233                                    ArioShellLyricsselect *shell_lyricsselect)
234 {
235         ARIO_LOG_FUNCTION_START;
236         const gchar *artist;
237         const gchar *title;
238 
239         ario_shell_lyricsselect_set_sensitive (shell_lyricsselect, FALSE);
240 
241         artist = gtk_entry_get_text (GTK_ENTRY (shell_lyricsselect->priv->artist_entry));
242         title = gtk_entry_get_text (GTK_ENTRY (shell_lyricsselect->priv->title_entry));
243 
244         g_slist_foreach (shell_lyricsselect->priv->lyrics, (GFunc) ario_lyrics_candidate_free, NULL);
245         g_slist_free (shell_lyricsselect->priv->lyrics);
246         shell_lyricsselect->priv->lyrics = NULL;
247 
248         ario_lyrics_manager_get_lyrics_candidates (ario_lyrics_manager_get_instance(),
249                                                    artist, title,
250                                                    &shell_lyricsselect->priv->lyrics);
251 
252         ario_shell_lyricsselect_show_lyrics (shell_lyricsselect);
253 
254         ario_shell_lyricsselect_set_sensitive (shell_lyricsselect, TRUE);
255 }
256 
257 static void
ario_shell_lyricsselect_show_lyrics(ArioShellLyricsselect * shell_lyricsselect)258 ario_shell_lyricsselect_show_lyrics (ArioShellLyricsselect *shell_lyricsselect)
259 {
260         ARIO_LOG_FUNCTION_START;
261         GtkTreeIter iter;
262         GSList *tmp;
263         ArioLyricsCandidate *candidate;
264 
265         gtk_list_store_clear (shell_lyricsselect->priv->liststore);
266 
267         for (tmp = shell_lyricsselect->priv->lyrics; tmp; tmp = g_slist_next (tmp)) {
268                 candidate = (ArioLyricsCandidate *) tmp->data;
269                 gtk_list_store_append(shell_lyricsselect->priv->liststore,
270                                       &iter);
271                 gtk_list_store_set (shell_lyricsselect->priv->liststore,
272                                     &iter,
273                                     ARTIST_COLUMN,
274                                     candidate->artist,
275                                     TITLE_COLUMN,
276                                     candidate->title,
277                                     PROVIDER_COLUMN,
278                                     ario_lyrics_provider_get_name (candidate->lyrics_provider),
279                                     CANDIDATE_COLUMN,
280                                     candidate, -1);
281         }
282 
283         /* Select first item in list */
284         if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (shell_lyricsselect->priv->liststore), &iter))
285                 gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (shell_lyricsselect->priv->treeview)), &iter);
286 }
287 
288 ArioLyricsCandidate *
ario_shell_lyricsselect_get_lyrics_candidate(ArioShellLyricsselect * shell_lyricsselect)289 ario_shell_lyricsselect_get_lyrics_candidate (ArioShellLyricsselect *shell_lyricsselect)
290 {
291         ARIO_LOG_FUNCTION_START;
292         GList* paths;
293         GtkTreeIter iter;
294         ArioLyricsCandidate *candidate;
295         GtkTreeModel *tree_model = GTK_TREE_MODEL (shell_lyricsselect->priv->liststore);
296         GtkTreePath *path;
297         GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (shell_lyricsselect->priv->treeview));
298 
299         paths = gtk_tree_selection_get_selected_rows (selection,
300                                                       &tree_model);
301         if (!paths)
302                 return NULL;
303 
304         path = g_list_first(paths)->data;
305         if (!path)
306                 return NULL;
307 
308         gtk_tree_model_get_iter (tree_model,
309                                  &iter,
310                                  path);
311         gtk_tree_model_get (tree_model, &iter, CANDIDATE_COLUMN, &candidate, -1);
312 
313         return ario_lyrics_candidate_copy (candidate);
314 }
315 
316