1 /*************************************************************************/
2 /* Copyright (C) 2007-2009 sujith <m.sujith@gmail.com>                   */
3 /* Copyright (C) 2009-2013 matias <mati86dl@gmail.com>                   */
4 /*                                                                       */
5 /* This program is free software: you can redistribute it and/or modify  */
6 /* it under the terms of the GNU General Public License as published by  */
7 /* the Free Software Foundation, either version 3 of the License, or     */
8 /* (at your option) any later version.                                   */
9 /*                                                                       */
10 /* This program is distributed in the hope that it will be useful,       */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of        */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
13 /* GNU General Public License for more details.                          */
14 /*                                                                       */
15 /* You should have received a copy of the GNU General Public License     */
16 /* along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17 /*************************************************************************/
18 
19 #if HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 
23 #include "pragha-tags-dialog.h"
24 
25 #if defined(GETTEXT_PACKAGE)
26 #include <glib/gi18n-lib.h>
27 #else
28 #include <glib/gi18n.h>
29 #endif
30 
31 #include "pragha-hig.h"
32 #include "pragha-utils.h"
33 #include "pragha-musicobject-mgmt.h"
34 
35 static void     pragha_tags_dialog_dispose            (GObject *object);
36 static void     pragha_tags_dialog_finalize           (GObject *object);
37 
38 static void     pragha_tag_entry_change               (GtkEntry *entry, GtkCheckButton *check);
39 static void     pragha_tag_entry_clear_pressed        (GtkEntry *entry, gint position, GdkEventButton *event);
40 static void     pragha_tag_entry_directory_pressed    (GtkEntry *entry, gint position, GdkEventButton *event, gpointer user_data);
41 static gboolean pragha_tag_entry_select_text_on_click (GtkWidget *widget, GdkEvent  *event, gpointer user_data);
42 static void     pragha_file_entry_populate_menu       (GtkEntry *entry, GtkMenu *menu, gpointer user_data);
43 
44 GtkEntryCompletion *pragha_tags_get_entry_completion_from_table (const gchar *table);
45 
46 struct _PraghaTagsDialogClass {
47 	GtkDialogClass __parent__;
48 };
49 
50 struct _PraghaTagsDialog {
51 	GtkDialog __parent__;
52 
53 	GtkWidget         *title_entry;
54 	GtkWidget         *artist_entry;
55 	GtkWidget         *album_entry;
56 	GtkWidget         *genre_entry;
57 	GtkWidget         *track_no_entry;
58 	GtkWidget         *year_entry;
59 	GtkWidget         *comment_entry;
60 	GtkWidget         *file_entry;
61 
62 	GtkWidget         *title_check_change;
63 	GtkWidget         *artist_check_change;
64 	GtkWidget         *album_check_change;
65 	GtkWidget         *genre_check_change;
66 	GtkWidget         *track_no_check_change;
67 	GtkWidget         *year_check_change;
68 	GtkWidget         *comment_check_change;
69 
70 	PraghaMusicobject *mobj;
71 };
72 
73 G_DEFINE_TYPE (PraghaTagsDialog, pragha_tags_dialog, GTK_TYPE_DIALOG);
74 
75 static void
pragha_tags_dialog_class_init(PraghaTagsDialogClass * klass)76 pragha_tags_dialog_class_init (PraghaTagsDialogClass *klass)
77 {
78   GObjectClass   *gobject_class;
79 
80   gobject_class = G_OBJECT_CLASS (klass);
81   gobject_class->dispose = pragha_tags_dialog_dispose;
82   gobject_class->finalize = pragha_tags_dialog_finalize;
83 }
84 
85 static void
pragha_tags_dialog_init(PraghaTagsDialog * dialog)86 pragha_tags_dialog_init (PraghaTagsDialog *dialog)
87 {
88 	GtkWidget *tag_table;
89 	GtkWidget *label_title, *label_artist, *label_album, *label_genre, *label_tno, *label_year, *label_comment, *label_file;
90 	GtkWidget *chk_title, *chk_artist, *chk_album, *chk_genre, *chk_tno, *chk_year, *chk_comment;
91 	GtkWidget *entry_title, *entry_artist, *entry_album, *entry_genre,  *entry_tno, *entry_year, *entry_comment, *entry_file;
92 	GtkWidget *hbox_title, *hbox_artist, *hbox_album, *hbox_genre, *hbox_tno, *hbox_year, *hbox_comment;
93 	GtkWidget *hbox_spins, *comment_view_scroll, *chk_alignment;
94 	GtkEntryCompletion *completion;
95 
96 	/* Set dialog properties */
97 
98 	gtk_window_set_title (GTK_WINDOW (dialog), _("Edit tags"));
99 	gtk_window_set_default_size(GTK_WINDOW (dialog), 450, 300);
100 	gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL);
101 	gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Ok"), GTK_RESPONSE_OK);
102 	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
103 
104 	/* Create table */
105 
106 	tag_table = gtk_grid_new ();
107 
108 	gtk_grid_set_row_spacing (GTK_GRID(tag_table), 5);
109 	gtk_grid_set_column_spacing (GTK_GRID(tag_table), 5);
110 
111 	gtk_container_set_border_width (GTK_CONTAINER(tag_table), 5);
112 
113 	/* Create labels */
114 
115 	label_title = gtk_label_new(_("Title"));
116 	label_artist = gtk_label_new(_("Artist"));
117 	label_album = gtk_label_new(_("Album"));
118 	label_genre = gtk_label_new(_("Genre"));
119 	label_tno = gtk_label_new(_("Track No"));
120 	label_year = gtk_label_new(_("Year"));
121 	label_comment = gtk_label_new(_("Comment"));
122 	label_file = gtk_label_new(_("File"));
123 
124 	gtk_misc_set_alignment(GTK_MISC (label_title), 1, 0.5);
125 	gtk_misc_set_alignment(GTK_MISC (label_artist), 1, 0.5);
126 	gtk_misc_set_alignment(GTK_MISC (label_album), 1, 0.5);
127 	gtk_misc_set_alignment(GTK_MISC (label_genre), 1, 0.5);
128 	gtk_misc_set_alignment(GTK_MISC (label_tno), 1, 0.5);
129 	gtk_misc_set_alignment(GTK_MISC (label_year), 1, 0.5);
130 	gtk_misc_set_alignment(GTK_MISC (label_comment), 1, 0);
131 	gtk_misc_set_alignment(GTK_MISC (label_file), 1, 0.5);
132 
133 	gtk_label_set_attribute_bold(GTK_LABEL(label_title));
134 	gtk_label_set_attribute_bold(GTK_LABEL(label_artist));
135 	gtk_label_set_attribute_bold(GTK_LABEL(label_album));
136 	gtk_label_set_attribute_bold(GTK_LABEL(label_genre));
137 	gtk_label_set_attribute_bold(GTK_LABEL(label_tno));
138 	gtk_label_set_attribute_bold(GTK_LABEL(label_year));
139 	gtk_label_set_attribute_bold(GTK_LABEL(label_comment));
140 	gtk_label_set_attribute_bold(GTK_LABEL(label_file));
141 
142 	/* Create entry fields */
143 
144 	entry_title = gtk_entry_new();
145 	entry_artist = gtk_entry_new();
146 	entry_album = gtk_entry_new();
147 	entry_genre = gtk_entry_new();
148 
149 	entry_tno = gtk_spin_button_new_with_range (0, 2030, 1);
150 	entry_year = gtk_spin_button_new_with_range (0, 2030, 1);
151 
152 	entry_comment = gtk_text_view_new();
153 	gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (entry_comment), FALSE);
154 	gtk_widget_set_hexpand (entry_comment, TRUE);
155 	gtk_widget_set_vexpand (entry_comment, TRUE);
156 
157 	entry_file = gtk_entry_new();
158 
159 	gtk_entry_set_max_length(GTK_ENTRY(entry_title), TAG_MAX_LEN);
160 	gtk_entry_set_max_length(GTK_ENTRY(entry_artist), TAG_MAX_LEN);
161 	gtk_entry_set_max_length(GTK_ENTRY(entry_album), TAG_MAX_LEN);
162 	gtk_entry_set_max_length(GTK_ENTRY(entry_genre), TAG_MAX_LEN);
163 
164 	completion = pragha_tags_get_entry_completion_from_table ("ARTIST");
165 	gtk_entry_set_completion(GTK_ENTRY(entry_artist), completion);
166 	g_object_unref (completion);
167 
168 	completion = pragha_tags_get_entry_completion_from_table ("ALBUM");
169 	gtk_entry_set_completion(GTK_ENTRY(entry_album), completion);
170 	g_object_unref (completion);
171 
172 	completion = pragha_tags_get_entry_completion_from_table ("GENRE");
173 	gtk_entry_set_completion(GTK_ENTRY(entry_genre), completion);
174 	g_object_unref (completion);
175 
176 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_title), GTK_ENTRY_ICON_SECONDARY, "edit-clear");
177 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_artist), GTK_ENTRY_ICON_SECONDARY, "edit-clear");
178 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_album), GTK_ENTRY_ICON_SECONDARY, "edit-clear");
179 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_genre), GTK_ENTRY_ICON_SECONDARY, "edit-clear");
180 
181 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_file), GTK_ENTRY_ICON_PRIMARY, "folder");
182 	gtk_entry_set_icon_from_icon_name (GTK_ENTRY(entry_file), GTK_ENTRY_ICON_SECONDARY, "go-jump");
183 
184 	gtk_editable_set_editable (GTK_EDITABLE(entry_file), FALSE);
185 
186 	/* Create checkboxes. */
187 
188 	chk_title = gtk_check_button_new();
189 	chk_artist = gtk_check_button_new();
190 	chk_album = gtk_check_button_new();
191 	chk_genre = gtk_check_button_new();
192 	chk_year = gtk_check_button_new();
193 	chk_tno = gtk_check_button_new();
194 	chk_comment = gtk_check_button_new();
195 
196 	/* Connect signals. */
197 
198 	g_signal_connect(G_OBJECT(entry_title),
199 	                 "changed",
200 	                 G_CALLBACK(pragha_tag_entry_change), chk_title);
201 	g_signal_connect(G_OBJECT(entry_artist),
202 	                 "changed",
203 	                 G_CALLBACK(pragha_tag_entry_change), chk_artist);
204 	g_signal_connect(G_OBJECT(entry_album),
205 	                 "changed",
206 	                 G_CALLBACK(pragha_tag_entry_change), chk_album);
207 	g_signal_connect(G_OBJECT(entry_genre),
208 	                 "changed",
209 	                 G_CALLBACK(pragha_tag_entry_change), chk_genre);
210 	g_signal_connect(G_OBJECT(entry_tno),
211 	                 "changed",
212 	                 G_CALLBACK(pragha_tag_entry_change), chk_tno);
213 	g_signal_connect(G_OBJECT(entry_year),
214 	                 "changed",
215 	                 G_CALLBACK(pragha_tag_entry_change), chk_year);
216 	g_signal_connect(G_OBJECT(gtk_text_view_get_buffer (GTK_TEXT_VIEW (entry_comment))),
217 	                 "changed",
218 	                 G_CALLBACK(pragha_tag_entry_change), chk_comment);
219 
220 	g_signal_connect(G_OBJECT(entry_title),
221 	                 "icon-press",
222 	                 G_CALLBACK(pragha_tag_entry_clear_pressed), NULL);
223 	g_signal_connect(G_OBJECT(entry_artist),
224 	                 "icon-press",
225 	                 G_CALLBACK(pragha_tag_entry_clear_pressed), NULL);
226 	g_signal_connect(G_OBJECT(entry_album),
227 	                 "icon-press",
228 	                 G_CALLBACK(pragha_tag_entry_clear_pressed), NULL);
229 	g_signal_connect(G_OBJECT(entry_genre),
230 	                 "icon-press",
231 	                 G_CALLBACK(pragha_tag_entry_clear_pressed), NULL);
232 	g_signal_connect(G_OBJECT(entry_file),
233 	                 "icon-press",
234 	                 G_CALLBACK(pragha_tag_entry_directory_pressed), dialog);
235 
236 	g_signal_connect(G_OBJECT(entry_tno),
237 	                 "button-release-event",
238 	                 G_CALLBACK(pragha_tag_entry_select_text_on_click), NULL);
239 	g_signal_connect(G_OBJECT(entry_year),
240 	                 "button-release-event",
241 	                 G_CALLBACK(pragha_tag_entry_select_text_on_click), NULL);
242 
243 	g_signal_connect (G_OBJECT(entry_file),
244 	                  "populate-popup",
245 	                  G_CALLBACK (pragha_file_entry_populate_menu), dialog);
246 
247 	/* Create boxs and package all. */
248 
249 	hbox_title = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
250 	hbox_artist = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
251 	hbox_album = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
252 	hbox_genre = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
253 	hbox_year = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
254 	hbox_tno = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
255 	hbox_comment = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
256 
257 	hbox_spins = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
258 
259 	/* Create hobxs(ENTRY CHECHK) and attach in table */
260 
261 	gtk_box_pack_start (GTK_BOX(hbox_title), entry_title, TRUE, TRUE, 0);
262 	gtk_box_pack_start (GTK_BOX(hbox_title), chk_title, FALSE, FALSE, 0);
263 	gtk_widget_set_hexpand (hbox_title, TRUE);
264 
265 	gtk_grid_attach (GTK_GRID(tag_table), label_title, 0, 0, 1, 1);
266 	gtk_grid_attach (GTK_GRID(tag_table), hbox_title, 1, 0, 1, 1);
267 
268 	gtk_box_pack_start(GTK_BOX(hbox_artist), entry_artist, TRUE, TRUE, 0);
269 	gtk_box_pack_start(GTK_BOX(hbox_artist), chk_artist, FALSE, FALSE, 0);
270 	gtk_widget_set_hexpand (hbox_artist, TRUE);
271 
272 	gtk_grid_attach (GTK_GRID(tag_table), label_artist, 0, 1, 1, 1);
273 	gtk_grid_attach (GTK_GRID(tag_table), hbox_artist, 1, 1, 1, 1);
274 
275 	gtk_box_pack_start (GTK_BOX(hbox_album), entry_album, TRUE, TRUE, 0);
276 	gtk_box_pack_start (GTK_BOX(hbox_album), chk_album, FALSE, FALSE, 0);
277 	gtk_widget_set_hexpand (hbox_album, TRUE);
278 
279 	gtk_grid_attach (GTK_GRID(tag_table), label_album, 0, 2, 1, 1);
280 	gtk_grid_attach (GTK_GRID(tag_table), hbox_album, 1, 2, 1, 1);
281 
282 	gtk_box_pack_start (GTK_BOX(hbox_genre), entry_genre, TRUE, TRUE, 0);
283 	gtk_box_pack_start (GTK_BOX(hbox_genre), chk_genre, FALSE, FALSE, 0);
284 	gtk_widget_set_hexpand (hbox_genre, TRUE);
285 
286 	gtk_grid_attach (GTK_GRID(tag_table), label_genre, 0, 3, 1, 1);
287 	gtk_grid_attach (GTK_GRID(tag_table), hbox_genre, 1, 3, 1, 1);
288 
289 	gtk_box_pack_start (GTK_BOX(hbox_tno), entry_tno, TRUE, TRUE, 0);
290 	gtk_box_pack_start(GTK_BOX(hbox_tno), chk_tno, FALSE, FALSE, 0);
291 
292 	gtk_box_pack_start (GTK_BOX(hbox_year), label_year, FALSE, FALSE, 5);
293 	gtk_box_pack_start (GTK_BOX(hbox_year), entry_year, TRUE, TRUE, 0);
294 	gtk_box_pack_start (GTK_BOX(hbox_year), chk_year, FALSE, FALSE, 0);
295 
296 	gtk_box_pack_start (GTK_BOX(hbox_spins), hbox_tno, TRUE, TRUE, 0);
297 	gtk_box_pack_start (GTK_BOX(hbox_spins), hbox_year, TRUE, TRUE, 0);
298 	gtk_widget_set_hexpand (hbox_spins, TRUE);
299 
300 	gtk_grid_attach (GTK_GRID(tag_table), label_tno, 0, 4, 1, 1);
301 	gtk_grid_attach (GTK_GRID(tag_table), hbox_spins, 1, 4, 1, 1);
302 
303 	comment_view_scroll = gtk_scrolled_window_new(NULL, NULL);
304 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(comment_view_scroll),
305 	                               GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
306 	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(comment_view_scroll),
307 	                                    GTK_SHADOW_IN);
308 	gtk_container_add(GTK_CONTAINER(comment_view_scroll), entry_comment);
309 
310 	chk_alignment = gtk_alignment_new(0.5, 0, 0, 0);
311 	gtk_container_add(GTK_CONTAINER(chk_alignment), chk_comment);
312 
313 	gtk_box_pack_start (GTK_BOX(hbox_comment), comment_view_scroll, TRUE, TRUE, 0);
314 	gtk_box_pack_start (GTK_BOX(hbox_comment), chk_alignment, FALSE, FALSE, 0);
315 	gtk_widget_set_hexpand (hbox_comment, TRUE);
316 
317 	gtk_grid_attach (GTK_GRID(tag_table), label_comment, 0, 5, 1, 1);
318 	gtk_grid_attach (GTK_GRID(tag_table), hbox_comment, 1, 5, 1, 2);
319 
320 	gtk_widget_set_hexpand (entry_file, TRUE);
321 
322 	gtk_grid_attach (GTK_GRID(tag_table), label_file, 0, 7, 1, 1);
323 	gtk_grid_attach (GTK_GRID(tag_table), entry_file, 1, 7, 1, 1);
324 
325 	/* Save changes when press enter. */
326 
327 	gtk_entry_set_activates_default (GTK_ENTRY(entry_title), TRUE);
328 	gtk_entry_set_activates_default (GTK_ENTRY(entry_artist), TRUE);
329 	gtk_entry_set_activates_default (GTK_ENTRY(entry_album), TRUE);
330 	gtk_entry_set_activates_default (GTK_ENTRY(entry_genre), TRUE);
331 	gtk_entry_set_activates_default (GTK_ENTRY(entry_tno), TRUE);
332 	gtk_entry_set_activates_default (GTK_ENTRY(entry_year), TRUE);
333 
334 	/* Storage widgets and its to dialog. */
335 
336 	dialog->title_entry = entry_title;
337 	dialog->artist_entry = entry_artist;
338 	dialog->album_entry = entry_album;
339 	dialog->genre_entry = entry_genre;
340 	dialog->track_no_entry = entry_tno;
341 	dialog->year_entry = entry_year;
342 	dialog->comment_entry = entry_comment;
343 	dialog->file_entry = entry_file;
344 
345 	dialog->title_check_change = chk_title;
346 	dialog->artist_check_change = chk_artist;
347 	dialog->album_check_change = chk_album;
348 	dialog->genre_check_change = chk_genre;
349 	dialog->track_no_check_change = chk_tno;
350 	dialog->year_check_change = chk_year;
351 	dialog->comment_check_change = chk_comment;
352 
353 	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), tag_table, TRUE, TRUE, 0);
354 	gtk_widget_show_all(tag_table);
355 
356 	/* Init flags */
357 	dialog->mobj = pragha_musicobject_new();
358 }
359 
360 void
pragha_tags_dialog_set_changed(PraghaTagsDialog * dialog,gint changed)361 pragha_tags_dialog_set_changed(PraghaTagsDialog *dialog, gint changed)
362 {
363 	if(changed & TAG_TNO_CHANGED)
364 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->track_no_check_change), TRUE);
365 	if(changed & TAG_TITLE_CHANGED)
366 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->title_check_change), TRUE);
367 	if(changed & TAG_ARTIST_CHANGED)
368 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->artist_check_change), TRUE);
369 	if(changed & TAG_ALBUM_CHANGED)
370 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->album_check_change), TRUE);
371 	if(changed & TAG_GENRE_CHANGED)
372 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->genre_check_change), TRUE);
373 	if(changed & TAG_YEAR_CHANGED)
374 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->year_check_change), TRUE);
375 	if(changed & TAG_COMMENT_CHANGED)
376 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->comment_check_change), TRUE);
377 }
378 
379 gint
pragha_tags_dialog_get_changed(PraghaTagsDialog * dialog)380 pragha_tags_dialog_get_changed(PraghaTagsDialog *dialog)
381 {
382 	gint changed = 0;
383 
384 	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->track_no_check_change)))
385 		changed |= TAG_TNO_CHANGED;
386 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->title_check_change)))
387 		changed |= TAG_TITLE_CHANGED;
388 	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->artist_check_change)))
389 		changed |= TAG_ARTIST_CHANGED;
390 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->album_check_change)))
391 		changed |= TAG_ALBUM_CHANGED;
392 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->genre_check_change)))
393 		changed |= TAG_GENRE_CHANGED;
394 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->year_check_change)))
395 		changed |= TAG_YEAR_CHANGED;
396 	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->comment_check_change)))
397 		changed |= TAG_COMMENT_CHANGED;
398 
399 	return changed;
400 }
401 
402 void
pragha_tags_dialog_set_musicobject(PraghaTagsDialog * dialog,PraghaMusicobject * mobj)403 pragha_tags_dialog_set_musicobject(PraghaTagsDialog *dialog, PraghaMusicobject *mobj)
404 {
405 	const gchar *title, *artist, *album, *genre, *comment, *file;
406 	gint track_no, year;
407 	GtkTextBuffer *buffer;
408 
409 	g_object_unref(dialog->mobj);
410 	dialog->mobj = pragha_musicobject_dup (mobj);
411 
412 	title = pragha_musicobject_get_title(mobj);
413 	artist = pragha_musicobject_get_artist(mobj);
414 	album = pragha_musicobject_get_album(mobj);
415 	genre = pragha_musicobject_get_genre(mobj);
416 	track_no = pragha_musicobject_get_track_no(mobj);
417 	year = pragha_musicobject_get_year(mobj);
418 	comment = pragha_musicobject_get_comment(mobj);
419 	file = pragha_musicobject_get_file(mobj);
420 
421 	/* Block changed signal, and force text. */
422 
423 	g_signal_handlers_block_by_func(G_OBJECT(dialog->title_entry), pragha_tag_entry_change, dialog->title_check_change);
424 	gtk_entry_set_text(GTK_ENTRY(dialog->title_entry), title);
425 	g_signal_handlers_unblock_by_func(G_OBJECT(dialog->title_entry), pragha_tag_entry_change, dialog->title_check_change);
426 
427 	g_signal_handlers_block_by_func(G_OBJECT(dialog->artist_entry), pragha_tag_entry_change, dialog->artist_check_change);
428 	gtk_entry_set_text(GTK_ENTRY(dialog->artist_entry), artist);
429 	g_signal_handlers_unblock_by_func(G_OBJECT(dialog->artist_entry), pragha_tag_entry_change, dialog->artist_check_change);
430 
431 	g_signal_handlers_block_by_func(G_OBJECT(dialog->album_entry), pragha_tag_entry_change, dialog->album_check_change);
432 	gtk_entry_set_text(GTK_ENTRY(dialog->album_entry), album);
433 	g_signal_handlers_unblock_by_func(G_OBJECT(dialog->album_entry), pragha_tag_entry_change, dialog->album_check_change);
434 
435 	g_signal_handlers_block_by_func(G_OBJECT(dialog->genre_entry), pragha_tag_entry_change, dialog->genre_check_change);
436 	gtk_entry_set_text(GTK_ENTRY(dialog->genre_entry), genre);
437 	g_signal_handlers_unblock_by_func(G_OBJECT(dialog->genre_entry), pragha_tag_entry_change, dialog->genre_check_change);
438 
439 	g_signal_handlers_block_by_func(G_OBJECT(dialog->track_no_entry), pragha_tag_entry_change, dialog->track_no_check_change);
440 	gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->track_no_entry), track_no);
441 	g_signal_handlers_unblock_by_func(G_OBJECT(dialog->track_no_entry), pragha_tag_entry_change, dialog->track_no_check_change);
442 
443 	g_signal_handlers_block_by_func(G_OBJECT(dialog->year_entry), pragha_tag_entry_change, dialog->year_check_change);
444 	gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->year_entry), year);
445 	g_signal_handlers_unblock_by_func(G_OBJECT(dialog->year_entry), pragha_tag_entry_change, dialog->year_check_change);
446 
447 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->comment_entry));
448 	g_signal_handlers_block_by_func(G_OBJECT(buffer), pragha_tag_entry_change, dialog->comment_check_change);
449 	gtk_text_buffer_set_text (buffer, comment, -1);
450 	g_signal_handlers_unblock_by_func(G_OBJECT(buffer), pragha_tag_entry_change, dialog->comment_check_change);
451 
452 	if (string_is_empty(file))
453 		gtk_widget_set_sensitive(GTK_WIDGET(dialog->file_entry), FALSE);
454 	else {
455 		gtk_entry_set_text(GTK_ENTRY(dialog->file_entry), file);
456 		gtk_editable_set_position(GTK_EDITABLE(dialog->file_entry), g_utf8_strlen(file, -1));
457 		gtk_dialog_add_button(GTK_DIALOG(dialog), _("Details"), GTK_RESPONSE_HELP);
458 	}
459 }
460 
461 PraghaMusicobject *
pragha_tags_dialog_get_musicobject(PraghaTagsDialog * dialog)462 pragha_tags_dialog_get_musicobject(PraghaTagsDialog *dialog)
463 {
464 	GtkTextBuffer *buffer;
465 	GtkTextIter start, end;
466 
467 	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->track_no_check_change)))
468 		pragha_musicobject_set_track_no(dialog->mobj,
469 		                                gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(dialog->track_no_entry)));
470 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->title_check_change)))
471 		pragha_musicobject_set_title(dialog->mobj,
472 		                             gtk_entry_get_text (GTK_ENTRY(dialog->title_entry)));
473 	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->artist_check_change)))
474 		pragha_musicobject_set_artist(dialog->mobj,
475 		                              gtk_entry_get_text (GTK_ENTRY(dialog->artist_entry)));
476 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->album_check_change)))
477 		pragha_musicobject_set_album(dialog->mobj,
478 		                             gtk_entry_get_text (GTK_ENTRY(dialog->album_entry)));
479 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->genre_check_change)))
480 		pragha_musicobject_set_genre(dialog->mobj,
481 		                             gtk_entry_get_text (GTK_ENTRY(dialog->genre_entry)));
482 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->year_check_change)))
483 		pragha_musicobject_set_year(dialog->mobj,
484 		                            gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(dialog->year_entry)));
485 	if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->comment_check_change))) {
486 		buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->comment_entry));
487 		gtk_text_buffer_get_start_iter (buffer, &start);
488 		gtk_text_buffer_get_end_iter (buffer, &end);
489 		pragha_musicobject_set_comment(dialog->mobj,
490 		                               gtk_text_buffer_get_text (buffer, &start, &end, FALSE));
491 	}
492 
493 	return dialog->mobj;
494 }
495 
496 static void
pragha_tags_dialog_dispose(GObject * object)497 pragha_tags_dialog_dispose (GObject *object)
498 {
499 	PraghaTagsDialog *dialog = PRAGHA_TAGS_DIALOG (object);
500 
501 	if(dialog->mobj) {
502 		g_object_unref(dialog->mobj);
503 		dialog->mobj = NULL;
504 	}
505 
506 	(*G_OBJECT_CLASS (pragha_tags_dialog_parent_class)->dispose) (object);
507 }
508 
509 static void
pragha_tags_dialog_finalize(GObject * object)510 pragha_tags_dialog_finalize (GObject *object)
511 {
512 	//PraghaTagsDialog *dialog = PRAGHA_TAGS_DIALOG (object);
513 
514 	/*
515 	 * Need free dialog->loc_arr or dialog->rlist?
516 	 */
517 
518 	(*G_OBJECT_CLASS (pragha_tags_dialog_parent_class)->finalize) (object);
519 }
520 
521 GtkWidget *
pragha_tags_dialog_new(void)522 pragha_tags_dialog_new (void)
523 {
524   return g_object_new (PRAGHA_TYPE_TAGS_DIALOG, NULL);
525 }
526 
527 
528 /*
529  * Track properties dialog
530  */
531 
532 static void
pragha_track_properties_response(GtkDialog * dialog,gint response,gpointer data)533 pragha_track_properties_response(GtkDialog *dialog,
534                                  gint response,
535                                  gpointer data)
536 {
537 	gtk_widget_destroy(GTK_WIDGET(dialog));
538 }
539 
540 void
pragha_track_properties_dialog(PraghaMusicobject * mobj,GtkWidget * parent)541 pragha_track_properties_dialog(PraghaMusicobject *mobj,
542                                GtkWidget *parent)
543 {
544 	GtkWidget *dialog;
545 	GtkWidget *properties_table;
546 	GtkWidget *label_length, *label_bitrate, *label_channels, *label_samplerate, *label_folder, *label_filename, *label_mimetype;
547 	GtkWidget *info_length, *info_bitrate, *info_channels, *info_samplerate, *info_folder, *info_filename, *info_mimetype;
548 
549 	gchar *length = NULL, *bitrate = NULL, *channels = NULL, *samplerate = NULL, *folder = NULL, *filename = NULL;
550 	const gchar *mimetype = NULL;
551 
552 	if(!mobj)
553 		return;
554 
555 	gint channels_n = pragha_musicobject_get_channels(mobj);
556 
557 	length = convert_length_str(pragha_musicobject_get_length(mobj));
558 	bitrate = g_strdup_printf("%d kbps", pragha_musicobject_get_bitrate(mobj));
559 	channels = g_strdup_printf("%d %s", channels_n, ngettext("channel", "channels", channels_n));
560 	samplerate = g_strdup_printf("%d Hz", pragha_musicobject_get_samplerate(mobj));
561 	folder = get_display_filename(pragha_musicobject_get_file(mobj), TRUE);
562 	filename = get_display_name(mobj);
563 	mimetype = pragha_musicobject_get_mime_type(mobj);
564 
565 	/* Create table */
566 
567 	properties_table = gtk_grid_new ();
568 
569 	gtk_grid_set_row_spacing (GTK_GRID(properties_table), 5);
570 	gtk_grid_set_column_spacing (GTK_GRID(properties_table), 5);
571 
572 	gtk_container_set_border_width (GTK_CONTAINER(properties_table), 5);
573 
574 	/* Create labels */
575 
576 	label_length = gtk_label_new(_("Length"));
577 	label_bitrate = gtk_label_new(_("Bitrate"));
578 	label_channels = gtk_label_new(_("Channels"));
579 	label_samplerate = gtk_label_new(_("Samplerate"));
580 	label_folder = gtk_label_new(_("Folder"));
581 	label_filename = gtk_label_new(_("Filename"));
582 	label_mimetype = gtk_label_new(_("Mimetype"));
583 
584 	gtk_misc_set_alignment(GTK_MISC (label_length), 1, 0);
585 	gtk_misc_set_alignment(GTK_MISC (label_bitrate), 1, 0);
586 	gtk_misc_set_alignment(GTK_MISC (label_channels), 1, 0);
587 	gtk_misc_set_alignment(GTK_MISC (label_samplerate), 1, 0);
588 	gtk_misc_set_alignment(GTK_MISC (label_folder), 1, 0);
589 	gtk_misc_set_alignment(GTK_MISC (label_filename), 1, 0);
590 	gtk_misc_set_alignment(GTK_MISC (label_mimetype), 1, 0);
591 
592 	gtk_label_set_attribute_bold(GTK_LABEL(label_length));
593 	gtk_label_set_attribute_bold(GTK_LABEL(label_bitrate));
594 	gtk_label_set_attribute_bold(GTK_LABEL(label_channels));
595 	gtk_label_set_attribute_bold(GTK_LABEL(label_samplerate));
596 	gtk_label_set_attribute_bold(GTK_LABEL(label_folder));
597 	gtk_label_set_attribute_bold(GTK_LABEL(label_filename));
598 	gtk_label_set_attribute_bold(GTK_LABEL(label_mimetype));
599 
600 	/* Create info labels */
601 
602 	info_length = gtk_label_new(length);
603 	info_bitrate = gtk_label_new(bitrate);
604 	info_channels = gtk_label_new(channels);
605 	info_samplerate = gtk_label_new(samplerate);
606 	info_folder = gtk_label_new(folder);
607 	info_filename = gtk_label_new(filename);
608 	info_mimetype = gtk_label_new(mimetype);
609 
610 	gtk_misc_set_alignment(GTK_MISC (info_length), 0, 0);
611 	gtk_misc_set_alignment(GTK_MISC (info_bitrate), 0, 0);
612 	gtk_misc_set_alignment(GTK_MISC (info_channels), 0, 0);
613 	gtk_misc_set_alignment(GTK_MISC (info_samplerate), 0, 0);
614 	gtk_misc_set_alignment(GTK_MISC (info_folder), 0, 0);
615 	gtk_misc_set_alignment(GTK_MISC (info_filename), 0, 0);
616 	gtk_misc_set_alignment(GTK_MISC (info_mimetype), 0, 0);
617 
618 	gtk_label_set_selectable(GTK_LABEL(info_length), TRUE);
619 	gtk_label_set_selectable(GTK_LABEL(info_bitrate), TRUE);
620 	gtk_label_set_selectable(GTK_LABEL(info_channels), TRUE);
621 	gtk_label_set_selectable(GTK_LABEL(info_samplerate), TRUE);
622 	gtk_label_set_selectable(GTK_LABEL(info_folder), TRUE);
623 	gtk_label_set_selectable(GTK_LABEL(info_filename), TRUE);
624 	gtk_label_set_selectable(GTK_LABEL(info_mimetype), TRUE);
625 
626 	gtk_widget_set_hexpand (GTK_WIDGET(info_length), TRUE);
627 	gtk_widget_set_hexpand (GTK_WIDGET(info_bitrate), TRUE);
628 	gtk_widget_set_hexpand (GTK_WIDGET(info_channels), TRUE);
629 	gtk_widget_set_hexpand (GTK_WIDGET(info_samplerate), TRUE);
630 	gtk_widget_set_hexpand (GTK_WIDGET(info_folder), TRUE);
631 	gtk_widget_set_hexpand (GTK_WIDGET(info_filename), TRUE);
632 	gtk_widget_set_hexpand (GTK_WIDGET(info_mimetype), TRUE);
633 
634 	/* Attach labels */
635 
636 	gtk_grid_attach (GTK_GRID(properties_table), label_length, 0, 0, 1, 1);
637 	gtk_grid_attach (GTK_GRID(properties_table), info_length, 1, 0, 1, 1);
638 
639 	gtk_grid_attach (GTK_GRID(properties_table), label_bitrate, 0, 1, 1, 1);
640 	gtk_grid_attach (GTK_GRID(properties_table), info_bitrate, 1, 1, 1, 1);
641 
642 	gtk_grid_attach (GTK_GRID(properties_table), label_channels, 0, 2, 1, 1);
643 	gtk_grid_attach (GTK_GRID(properties_table), info_channels, 1, 2, 1, 1);
644 
645 	gtk_grid_attach (GTK_GRID(properties_table), label_samplerate, 0, 3, 1, 1);
646 	gtk_grid_attach (GTK_GRID(properties_table), info_samplerate, 1, 3, 1, 1);
647 
648 	gtk_grid_attach (GTK_GRID(properties_table), label_folder, 0, 4, 1, 1);
649 	gtk_grid_attach (GTK_GRID(properties_table), info_folder, 1, 4, 1, 1);
650 
651 	gtk_grid_attach (GTK_GRID(properties_table), label_filename, 0, 5, 1, 1);
652 	gtk_grid_attach (GTK_GRID(properties_table), info_filename, 1, 5, 1, 1);
653 
654 	gtk_grid_attach (GTK_GRID(properties_table), label_mimetype, 0, 6, 1, 1);
655 	gtk_grid_attach (GTK_GRID(properties_table), info_mimetype, 1, 6, 1, 1);
656 
657 	/* The main edit dialog */
658 
659 	dialog = gtk_dialog_new_with_buttons (_("Details"),
660 	                                      GTK_WINDOW(parent),
661 	                                      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
662 	                                      _("_Ok"), GTK_RESPONSE_OK,
663 	                                      NULL);
664 
665 	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), properties_table);
666 
667 	g_signal_connect(G_OBJECT(dialog), "response",
668 			G_CALLBACK(pragha_track_properties_response), NULL);
669 
670 	gtk_widget_show_all(dialog);
671 
672 	g_free(length);
673 	g_free(bitrate);
674 	g_free(channels);
675 	g_free(samplerate);
676 	g_free(folder);
677 	g_free(filename);
678 }
679 
680 /*
681  * Track tags editing dialog.
682  */
683 
684 static void
pragha_tag_entry_change(GtkEntry * entry,GtkCheckButton * check)685 pragha_tag_entry_change (GtkEntry *entry, GtkCheckButton *check)
686 {
687 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
688 }
689 
690 static void
pragha_tag_entry_clear_pressed(GtkEntry * entry,gint position,GdkEventButton * event)691 pragha_tag_entry_clear_pressed (GtkEntry       *entry,
692                                 gint            position,
693                                 GdkEventButton *event)
694 {
695 	if (position == GTK_ENTRY_ICON_SECONDARY) {
696 		gtk_entry_set_text (entry, "");
697 		gtk_widget_grab_focus(GTK_WIDGET(entry));
698 	}
699 }
700 
701 static void
pragha_tag_entry_directory_pressed(GtkEntry * entry,gint position,GdkEventButton * event,gpointer user_data)702 pragha_tag_entry_directory_pressed (GtkEntry       *entry,
703                                     gint            position,
704                                     GdkEventButton *event,
705                                     gpointer        user_data)
706 {
707 	PraghaMusicobject *mobj;
708 	GtkWidget *toplevel;
709 
710 	PraghaTagsDialog *dialog = user_data;
711 
712 	if (position == GTK_ENTRY_ICON_SECONDARY) {
713 		mobj = pragha_tags_dialog_get_musicobject(dialog);
714 		toplevel = gtk_widget_get_toplevel(GTK_WIDGET(entry));
715 
716 		gchar *uri = path_get_dir_as_uri (pragha_musicobject_get_file(mobj));
717 		open_url(uri, toplevel);
718 		g_free (uri);
719 	}
720 }
721 
722 static gboolean
pragha_tag_entry_select_text_on_click(GtkWidget * widget,GdkEvent * event,gpointer user_data)723 pragha_tag_entry_select_text_on_click (GtkWidget *widget,
724                                        GdkEvent  *event,
725                                        gpointer   user_data)
726 {
727 	gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
728 
729 	return FALSE;
730 }
731 
732 gchar *
pragha_tag_entry_get_selected_text(GtkWidget * entry)733 pragha_tag_entry_get_selected_text(GtkWidget *entry)
734 {
735 	gint start_sel, end_sel;
736 
737 	if (!gtk_editable_get_selection_bounds (GTK_EDITABLE(entry), &start_sel, &end_sel))
738 		return NULL;
739 
740 	return gtk_editable_get_chars (GTK_EDITABLE(entry), start_sel, end_sel);
741 }
742 
743 static void
pragha_tag_entry_set_text(GtkWidget * entry,const gchar * text)744 pragha_tag_entry_set_text(GtkWidget *entry, const gchar *text)
745 {
746 	gtk_entry_set_text(GTK_ENTRY(entry), text);
747 	gtk_widget_grab_focus(GTK_WIDGET(entry));
748 }
749 
750 static void
pragha_file_entry_open_folder(GtkMenuItem * menuitem,PraghaTagsDialog * dialog)751 pragha_file_entry_open_folder (GtkMenuItem *menuitem, PraghaTagsDialog *dialog)
752 {
753 	GtkWidget *toplevel;
754 	const gchar *file;
755 	gchar *uri;
756 
757 	file = gtk_entry_get_text (GTK_ENTRY(dialog->file_entry));
758 	toplevel = gtk_widget_get_toplevel(GTK_WIDGET(dialog->file_entry));
759 
760 	uri = path_get_dir_as_uri (file);
761 	open_url(uri, toplevel);
762 	g_free (uri);
763 }
764 
765 static void
pragha_file_entry_selection_to_title(GtkMenuItem * menuitem,PraghaTagsDialog * dialog)766 pragha_file_entry_selection_to_title (GtkMenuItem *menuitem,PraghaTagsDialog *dialog)
767 {
768 	gchar *text = pragha_tag_entry_get_selected_text(dialog->file_entry);
769 	if(text) {
770 		pragha_tag_entry_set_text(dialog->title_entry, text);
771 		g_free(text);
772 	}
773 }
774 
775 static void
pragha_file_entry_selection_to_artist(GtkMenuItem * menuitem,PraghaTagsDialog * dialog)776 pragha_file_entry_selection_to_artist (GtkMenuItem *menuitem, PraghaTagsDialog *dialog)
777 {
778 	gchar *text = pragha_tag_entry_get_selected_text(dialog->file_entry);
779 	if(text) {
780 		pragha_tag_entry_set_text(dialog->artist_entry, text);
781 		g_free(text);
782 	}
783 }
784 
785 static void
pragha_file_entry_selection_to_album(GtkMenuItem * menuitem,PraghaTagsDialog * dialog)786 pragha_file_entry_selection_to_album (GtkMenuItem *menuitem, PraghaTagsDialog *dialog)
787 {
788 	gchar *text = pragha_tag_entry_get_selected_text(dialog->file_entry);
789 	if(text) {
790 		pragha_tag_entry_set_text(dialog->album_entry, text);
791 		g_free(text);
792 	}
793 }
794 
795 static void
pragha_file_entry_selection_to_genre(GtkMenuItem * menuitem,PraghaTagsDialog * dialog)796 pragha_file_entry_selection_to_genre (GtkMenuItem *menuitem, PraghaTagsDialog *dialog)
797 {
798 	gchar *text = pragha_tag_entry_get_selected_text(dialog->file_entry);
799 	if(text) {
800 		pragha_tag_entry_set_text(dialog->genre_entry, text);
801 		g_free(text);
802 	}
803 }
804 
805 static void
pragha_file_entry_selection_to_comment(GtkMenuItem * menuitem,PraghaTagsDialog * dialog)806 pragha_file_entry_selection_to_comment (GtkMenuItem *menuitem, PraghaTagsDialog *dialog)
807 {
808 	GtkTextBuffer *buffer;
809 
810 	gchar *text = pragha_tag_entry_get_selected_text(dialog->file_entry);
811 	if(text) {
812 		buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->comment_entry));
813 		gtk_text_buffer_set_text (buffer, text, -1);
814 		g_free(text);
815 	}
816 }
817 
818 static void
pragha_file_entry_populate_menu(GtkEntry * entry,GtkMenu * menu,gpointer user_data)819 pragha_file_entry_populate_menu (GtkEntry *entry, GtkMenu *menu, gpointer user_data)
820 {
821 	GtkWidget *submenu, *item;
822 
823 	PraghaTagsDialog *dialog = user_data;
824 
825 	item = gtk_separator_menu_item_new ();
826 	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
827 	gtk_widget_show (item);
828 
829 	item = gtk_menu_item_new_with_mnemonic (_("Selection to"));
830 	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
831 	gtk_widget_show (item);
832 
833 	submenu = gtk_menu_new ();
834 	gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
835 
836 	item = gtk_menu_item_new_with_label (_("Title"));
837 	g_signal_connect (G_OBJECT (item),
838 	                  "activate",
839 	                  G_CALLBACK (pragha_file_entry_selection_to_title), dialog);
840 	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
841 	item = gtk_menu_item_new_with_label (_("Artist"));
842 	g_signal_connect (G_OBJECT (item),
843 	                  "activate",
844 	                  G_CALLBACK (pragha_file_entry_selection_to_artist), dialog);
845 	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
846 	item = gtk_menu_item_new_with_label (_("Album"));
847 	g_signal_connect (G_OBJECT (item),
848 	                  "activate",
849 	                  G_CALLBACK (pragha_file_entry_selection_to_album), dialog);
850 	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
851 	item = gtk_menu_item_new_with_label (_("Genre"));
852 	g_signal_connect (G_OBJECT (item),
853 	                  "activate",
854 	                  G_CALLBACK (pragha_file_entry_selection_to_genre), dialog);
855 	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
856 	item = gtk_menu_item_new_with_label (_("Comment"));
857 	g_signal_connect (G_OBJECT (item),
858 	                  "activate",
859 	                  G_CALLBACK (pragha_file_entry_selection_to_comment), dialog);
860 	gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item);
861 
862 	gtk_widget_show_all (submenu);
863 
864 	if (!gtk_editable_get_selection_bounds (GTK_EDITABLE(dialog->file_entry), NULL, NULL))
865 		gtk_widget_set_sensitive (submenu, FALSE);
866 
867 	item = gtk_menu_item_new_with_mnemonic (_("Open folder"));
868 	g_signal_connect (G_OBJECT (item),
869 	                  "activate",
870 	                  G_CALLBACK (pragha_file_entry_open_folder), dialog);
871 	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
872 	gtk_widget_show (item);
873 }
874 
875 GtkEntryCompletion *
pragha_tags_get_entry_completion_from_table(const gchar * table)876 pragha_tags_get_entry_completion_from_table(const gchar *table)
877 {
878 	PraghaDatabase *cdbase;
879 	PraghaPreparedStatement *statement;
880 	gchar *sql;
881 	GtkEntryCompletion *completion;
882 	GtkListStore *model;
883 	GtkTreeIter iter;
884 
885 	cdbase = pragha_database_get ();
886 
887 	model = gtk_list_store_new(1, G_TYPE_STRING);
888 
889 	sql = g_strdup_printf("SELECT name FROM %s ORDER BY name DESC", table);
890 	statement = pragha_database_create_statement (cdbase, sql);
891 	while (pragha_prepared_statement_step (statement)) {
892 		const gchar *name = pragha_prepared_statement_get_string (statement, 0);
893 		gtk_list_store_insert_with_values (GTK_LIST_STORE(model), &iter, 0, 0, name, -1);
894 	}
895 	pragha_prepared_statement_free (statement);
896 	g_object_unref(G_OBJECT(cdbase));
897 	g_free(sql);
898 
899 	completion = gtk_entry_completion_new();
900 	gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(model));
901 	gtk_entry_completion_set_text_column(completion, 0);
902 	g_object_unref(model);
903 
904 	return completion;
905 }
906