1 /* $Id$ */
2 /*-
3 * Copyright (c) 2006 Jannis Pohlmann <jannis@xfce.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * 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, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #ifdef HAVE_MEMORY_H
26 #include <memory.h>
27 #endif
28 #ifdef HAVE_STRING_H
29 #include <string.h>
30 #endif
31
32 #include <taglib/tag_c.h>
33
34 #include <exo/exo.h>
35
36 #include <tag-renamer.h>
37 #include <audio-tags-page.h>
38 #include <media-tags-provider.h>
39
40
41
42 static GType tag_renamer_format_type;
43
44
45
46 GType
tag_renamer_format_get_type(void)47 tag_renamer_format_get_type (void)
48 {
49 return tag_renamer_format_type;
50 }
51
52
53
54 void
tag_renamer_register_enum_types(ThunarxProviderPlugin * plugin)55 tag_renamer_register_enum_types (ThunarxProviderPlugin *plugin)
56 {
57 static const GEnumValue tag_renamer_format_values[] =
58 {
59 { TAG_RENAMER_FORMAT_TITLE, "TAG_RENAMER_FORMAT_TITLE", N_ ("Title"), },
60 { TAG_RENAMER_FORMAT_ARTIST_TITLE, "TAG_RENAMER_FORMAT_ARTIST_TITLE", N_ ("Artist - Title"), },
61 { TAG_RENAMER_FORMAT_TRACK_TITLE, "TAG_RENAMER_FORMAT_TRACK_TITLE", N_ ("Track - Title"), },
62 { TAG_RENAMER_FORMAT_TRACK_ARTIST_TITLE, "TAG_RENAMER_FORMAT_TRACK_ARTIST_TITLE", N_ ("Track - Artist - Title"), },
63 { TAG_RENAMER_FORMAT_TRACK_DOT_TITLE, "TAG_RENAMER_FORMAT_TRACK_DOT_TITLE", N_ ("Track. Title"), },
64 { TAG_RENAMER_FORMAT_TRACK_DOT_ARTIST_TITLE, "TAG_RENAMER_FORMAT_TRACK_DOT_ARTIST_TITLE", N_ ("Track. Artist - Title"), },
65 { TAG_RENAMER_FORMAT_ARTIST_TRACK_TITLE, "TAG_RENAMER_FORMAT_ARTIST_TRACK_TITLE", N_ ("Artist - Track - Title"), },
66 { TAG_RENAMER_FORMAT_SEPARATOR, "TAG_RENAMER_FORMAT_SEPARATOR", " ", },
67 { TAG_RENAMER_FORMAT_CUSTOM, "TAG_RENAMER_FORMAT_CUSTOM", N_ ("Custom"), },
68 { 0, NULL, NULL, },
69 };
70
71 tag_renamer_format_type = thunarx_provider_plugin_register_enum (plugin, "TagRenamerFormat", tag_renamer_format_values);
72 }
73
74
75
76 enum
77 {
78 COLUMN_TEXT,
79 COLUMN_NUMBER,
80 N_COLUMNS
81 };
82
83
84
85 /* Property identifiers */
86 enum
87 {
88 PROP_0,
89 PROP_FORMAT,
90 PROP_TEXT,
91 PROP_REPLACE_SPACES,
92 PROP_LOWERCASE,
93 };
94
95
96
97 static void tag_renamer_finalize (GObject *object);
98 static void tag_renamer_get_property (GObject *object,
99 guint prop_id,
100 GValue *value,
101 GParamSpec *pspec);
102 static void tag_renamer_set_property (GObject *object,
103 guint prop_id,
104 const GValue *value,
105 GParamSpec *pspec);
106 static gchar *tag_renamer_process (ThunarxRenamer *renamer,
107 ThunarxFileInfo *file,
108 const gchar *text,
109 guint index);
110 static GList *tag_renamer_get_menu_items (ThunarxRenamer *renamer,
111 GtkWindow *window,
112 GList *files);
113 static void tag_renamer_help_clicked (GtkWidget *button);
114 static gboolean tag_renamer_combo_separator_func (GtkTreeModel *model,
115 GtkTreeIter *iter,
116 gpointer user_data);
117 static void tag_renamer_combo_changed (GtkComboBox *combo_box,
118 GtkWidget *entry);
119 static void tag_renamer_edit_tags_activated (ThunarxMenuItem *item,
120 ThunarxFileInfo *file);
121
122
123
124 struct _TagRenamerClass
125 {
126 ThunarxRenamerClass __parent__;
127 };
128
129 struct _TagRenamer
130 {
131 ThunarxRenamer __parent__;
132
133 /* Properties */
134 TagRenamerFormat format;
135 gchar *text;
136 gboolean replace_spaces;
137 gboolean lowercase;
138 };
139
140
141
142 THUNARX_DEFINE_TYPE (TagRenamer, tag_renamer, THUNARX_TYPE_RENAMER);
143
144
145
146 static void
tag_renamer_class_init(TagRenamerClass * klass)147 tag_renamer_class_init (TagRenamerClass *klass)
148 {
149 ThunarxRenamerClass *thunarxrenamer_class;
150 GObjectClass *gobject_class;
151
152 gobject_class = G_OBJECT_CLASS (klass);
153 gobject_class->finalize = tag_renamer_finalize;
154 gobject_class->get_property = tag_renamer_get_property;
155 gobject_class->set_property = tag_renamer_set_property;
156
157 thunarxrenamer_class = THUNARX_RENAMER_CLASS (klass);
158 thunarxrenamer_class->process = tag_renamer_process;
159 thunarxrenamer_class->get_menu_items = tag_renamer_get_menu_items;
160
161 /**
162 * TagRenamer:format:
163 *
164 * Naming format used for renaming the selected files.
165 **/
166 g_object_class_install_property (gobject_class,
167 PROP_FORMAT,
168 g_param_spec_enum ("format",
169 "format",
170 "format",
171 TYPE_TAG_RENAMER_FORMAT,
172 TAG_RENAMER_FORMAT_TRACK_TITLE,
173 G_PARAM_READWRITE));
174
175 /**
176 * TagRenamer:text:
177 *
178 * Custom format from the user.
179 **/
180 g_object_class_install_property (gobject_class,
181 PROP_TEXT,
182 g_param_spec_string ("text",
183 "text",
184 "text",
185 NULL,
186 G_PARAM_READWRITE));
187
188 /**
189 * TagRenamer:replace-spaces:
190 *
191 * Whether spaces should be replaced with _ or not
192 **/
193 g_object_class_install_property (gobject_class,
194 PROP_REPLACE_SPACES,
195 g_param_spec_boolean ("replace-spaces",
196 "replace-spaces",
197 "replace-spaces",
198 FALSE,
199 G_PARAM_READWRITE));
200
201 /**
202 * TagRenamer:lowercase:
203 *
204 * Whether all chars will be converted to lowercase.
205 **/
206 g_object_class_install_property (gobject_class,
207 PROP_LOWERCASE,
208 g_param_spec_boolean ("lowercase",
209 "lowercase",
210 "lowercase",
211 FALSE,
212 G_PARAM_READWRITE));
213
214 }
215
216
217
218 static void
tag_renamer_init(TagRenamer * tag_renamer)219 tag_renamer_init (TagRenamer *tag_renamer)
220 {
221 AtkRelationSet *relations;
222 AtkRelation *relation;
223 AtkObject *object;
224 GtkWidget *grid;
225 GtkWidget *label;
226 GtkWidget *combo;
227 GtkWidget *image;
228 GtkWidget *button;
229 GtkWidget *entry;
230 GEnumClass *klass;
231 GtkListStore *store;
232 GtkCellRenderer *cell;
233 GtkTreeIter iter;
234 guint n;
235
236 grid = gtk_grid_new ();
237 gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
238 gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
239 gtk_box_pack_start (GTK_BOX (tag_renamer), grid, FALSE, FALSE, 0);
240 gtk_widget_show (grid);
241
242 /* Custom format */
243 label = gtk_label_new_with_mnemonic (_("Cust_om format:"));
244 gtk_label_set_xalign (GTK_LABEL (label), 1.0f);
245 gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
246 gtk_widget_show (label);
247
248 entry = gtk_entry_new ();
249 gtk_widget_set_hexpand (entry, TRUE);
250 gtk_grid_attach (GTK_GRID (grid), entry, 1, 1, 1, 1);
251 exo_mutual_binding_new (G_OBJECT (entry), "text", G_OBJECT (tag_renamer), "text");
252 gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
253 gtk_widget_show (entry);
254
255 button = gtk_button_new ();
256 gtk_grid_attach (GTK_GRID (grid), button, 2, 1, 1, 1);
257 g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (tag_renamer_help_clicked), NULL);
258 gtk_widget_show (button);
259
260 image = gtk_image_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_MENU);
261 gtk_container_add (GTK_CONTAINER (button), image);
262 gtk_widget_show (image);
263
264 /* Set Atk label relation for the entry */
265 object = gtk_widget_get_accessible (entry);
266 relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label));
267 relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR);
268 atk_relation_set_add (relations, relation);
269 g_object_unref (G_OBJECT (relation));
270
271 /* Format label */
272 label = gtk_label_new_with_mnemonic (_("_Format:"));
273 gtk_label_set_xalign (GTK_LABEL (label), 1.0f);
274 gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
275 gtk_widget_show (label);
276
277 /* Create combo box store */
278 store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
279
280 /* Format combo box */
281 combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
282 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), tag_renamer_combo_separator_func, NULL, NULL);
283 g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (tag_renamer_combo_changed), entry);
284
285 /* Text renderer for the combo box */
286 cell = gtk_cell_renderer_text_new ();
287 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
288 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, "text", COLUMN_TEXT, NULL);
289
290 /* Insert items */
291 klass = g_type_class_ref (TYPE_TAG_RENAMER_FORMAT);
292 for (n = 0; n < klass->n_values; ++n)
293 {
294 gtk_list_store_append (store, &iter);
295 gtk_list_store_set (store, &iter, COLUMN_TEXT, _(klass->values[n].value_nick), COLUMN_NUMBER, n, -1);
296 }
297 g_type_class_unref (klass);
298 exo_mutual_binding_new (G_OBJECT (tag_renamer), "format", G_OBJECT (combo), "active");
299 gtk_widget_set_hexpand (combo, TRUE);
300 gtk_grid_attach (GTK_GRID (grid), combo, 1, 0, 2, 1);
301 gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
302 gtk_widget_show (combo);
303
304 /* Release the store */
305 g_object_unref (G_OBJECT (store));
306
307 /* Set Atk label relation for the combo box */
308 object = gtk_widget_get_accessible (combo);
309 relations = atk_object_ref_relation_set (gtk_widget_get_accessible (label));
310 relation = atk_relation_new (&object, 1, ATK_RELATION_LABEL_FOR);
311 atk_relation_set_add (relations, relation);
312 g_object_unref (G_OBJECT (relation));
313
314 button = gtk_check_button_new_with_mnemonic (_("_Underscores"));
315 exo_mutual_binding_new (G_OBJECT (button), "active", G_OBJECT (tag_renamer), "replace-spaces");
316 gtk_widget_set_tooltip_text (GTK_WIDGET (button), _("Activating this option will replace all spaces in the target filename "
317 "with underscores."));
318 gtk_grid_attach (GTK_GRID (grid), button, 3, 0, 1, 1);
319 gtk_widget_show (button);
320
321 button = gtk_check_button_new_with_mnemonic (_("_Lowercase"));
322 exo_mutual_binding_new (G_OBJECT (button), "active", G_OBJECT (tag_renamer), "lowercase");
323 gtk_widget_set_tooltip_text (GTK_WIDGET (button), _("If you activate this, the resulting filename will only contain lowercase letters."));
324 gtk_grid_attach (GTK_GRID (grid), button, 3, 1, 1, 1);
325 gtk_widget_show (button);
326 }
327
328
329
330
331
332 static void
tag_renamer_finalize(GObject * object)333 tag_renamer_finalize (GObject *object)
334 {
335 TagRenamer *tag_renamer = TAG_RENAMER (object);
336
337 /* Free string */
338 g_free (tag_renamer->text);
339
340 (*G_OBJECT_CLASS (tag_renamer_parent_class)->finalize) (object);
341 }
342
343
344
345 static void
tag_renamer_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)346 tag_renamer_get_property (GObject *object,
347 guint prop_id,
348 GValue *value,
349 GParamSpec *pspec)
350 {
351 TagRenamer *tag_renamer = TAG_RENAMER (object);
352
353 switch (prop_id)
354 {
355 case PROP_FORMAT:
356 g_value_set_enum (value, tag_renamer_get_format (tag_renamer));
357 break;
358
359 case PROP_TEXT:
360 g_value_set_string (value, tag_renamer_get_text (tag_renamer));
361 break;
362
363 case PROP_REPLACE_SPACES:
364 g_value_set_boolean (value, tag_renamer_get_replace_spaces (tag_renamer));
365 break;
366
367 case PROP_LOWERCASE:
368 g_value_set_boolean (value, tag_renamer_get_lowercase (tag_renamer));
369 break;
370
371 default:
372 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
373 break;
374 }
375 }
376
377
378
379 static void
tag_renamer_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)380 tag_renamer_set_property (GObject *object,
381 guint prop_id,
382 const GValue *value,
383 GParamSpec *pspec)
384 {
385 TagRenamer *tag_renamer = TAG_RENAMER (object);
386
387 switch (prop_id)
388 {
389 case PROP_FORMAT:
390 tag_renamer_set_format (tag_renamer, g_value_get_enum (value));
391 break;
392
393 case PROP_TEXT:
394 tag_renamer_set_text (tag_renamer, g_value_get_string (value));
395 break;
396
397 case PROP_REPLACE_SPACES:
398 tag_renamer_set_replace_spaces (tag_renamer, g_value_get_boolean (value));
399 break;
400
401 case PROP_LOWERCASE:
402 tag_renamer_set_lowercase (tag_renamer, g_value_get_boolean (value));
403 break;
404
405 default:
406 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
407 break;
408 }
409 }
410
411
412
413 static gchar *
tag_renamer_process_format(TagRenamer * tag_renamer,ThunarxFileInfo * file,const gchar * format)414 tag_renamer_process_format (TagRenamer *tag_renamer,
415 ThunarxFileInfo *file,
416 const gchar *format)
417 {
418 TagLib_File *taglib_file;
419 TagLib_Tag *taglib_tag;
420 const gchar *value;
421 guint integer;
422 gchar *uri, *filename;
423 gchar *string, *tmp;
424 GString *result;
425 const gchar *p;
426
427 /* Get the file uri, return on fail */
428 uri = thunarx_file_info_get_uri (file);
429 if (G_UNLIKELY (uri == NULL))
430 return NULL;
431
432 /* Conver the uri into a filename, return on fail */
433 filename = g_filename_from_uri (uri, NULL, NULL);
434 g_free (uri);
435 if (G_UNLIKELY (filename == NULL))
436 return NULL;
437
438 /* Load taglib file, return on fail */
439 taglib_file = taglib_file_new (filename);
440 g_free (filename);
441 if (G_UNLIKELY (taglib_file == NULL))
442 return NULL;
443
444 /* Load tag info, return on fail */
445 taglib_tag = taglib_file_tag (taglib_file);
446 if (G_UNLIKELY (taglib_tag == NULL))
447 {
448 taglib_file_free (taglib_file);
449 return NULL;
450 }
451
452 /* Create string with some size */
453 result = g_string_sized_new (512);
454
455 /* walk the string */
456 for (p = format; *p != '\0'; ++p)
457 {
458 if (p[0] == '%' && p[1] != '\0')
459 {
460 switch (*++p)
461 {
462 case 'a':
463 /* Arist */
464 value = taglib_tag_artist (taglib_tag);
465 if (G_UNLIKELY (g_utf8_strlen (value, -1) == 0))
466 value = _("Unknown Artist");
467 result = g_string_append (result, value);
468 break;
469
470 case 't':
471 /* Title */
472 value = taglib_tag_title (taglib_tag);
473 if (G_UNLIKELY (g_utf8_strlen (value, -1) == 0))
474 value = _("Unknown Title");
475 result = g_string_append (result, value);
476 break;
477
478 case 'b':
479 /* Album */
480 value = taglib_tag_album (taglib_tag);
481 if (G_LIKELY (g_utf8_strlen (value, -1) > 0))
482 result = g_string_append (result, value);
483 break;
484
485 case 'g':
486 /* Genre */
487 value = taglib_tag_genre (taglib_tag);
488 if (G_LIKELY (g_utf8_strlen (value, -1) > 0))
489 result = g_string_append (result, value);
490 break;
491
492 case 'n':
493 /* Track Number */
494 integer = taglib_tag_track (taglib_tag);
495 g_string_append_printf (result, "%02d", integer);
496 break;
497
498 case 'y':
499 /* Year */
500 integer = taglib_tag_year (taglib_tag);
501 if (G_LIKELY (integer > 0))
502 g_string_append_printf (result, "%d", integer);
503 break;
504
505 case 'c':
506 /* Comment */
507 value = taglib_tag_comment (taglib_tag);
508 if (G_LIKELY (g_utf8_strlen (value, -1) > 0))
509 result = g_string_append (result, value);
510 break;
511
512 case '%':
513 /* Percentage character */
514 result = g_string_append_c (result, '%');
515 break;
516 }
517 }
518 else
519 {
520 /* Append character */
521 result = g_string_append_c (result, *p);
522 }
523 }
524
525 /* Free tag info strings */
526 taglib_tag_free_strings ();
527
528 /* Cleanup */
529 taglib_file_free (taglib_file);
530
531 /* Get the resulting string */
532 string = g_string_free (result, FALSE);
533
534 /* Replace spaces if requested */
535 if (tag_renamer_get_replace_spaces (tag_renamer))
536 string = g_strdelimit (string, " ", '_');
537
538 /* Convert to lowercase if requested */
539 if (tag_renamer_get_lowercase (tag_renamer))
540 {
541 tmp = g_utf8_strdown (string, -1);
542 g_free (string);
543 string = tmp;
544 }
545
546 /* Replace slashes */
547 string = g_strdelimit (string, G_DIR_SEPARATOR_S, '_');
548
549 /* Return the result */
550 return string;
551 }
552
553
554
555 static gchar*
tag_renamer_process(ThunarxRenamer * renamer,ThunarxFileInfo * file,const gchar * text,guint idx)556 tag_renamer_process (ThunarxRenamer *renamer,
557 ThunarxFileInfo *file,
558 const gchar *text,
559 guint idx)
560 {
561 TagRenamer *tag_renamer = TAG_RENAMER (renamer);
562 const gchar *format;
563
564 switch (tag_renamer_get_format (tag_renamer))
565 {
566 case TAG_RENAMER_FORMAT_TRACK_DOT_TITLE:
567 format = "%n. %t";
568 break;
569
570 case TAG_RENAMER_FORMAT_TRACK_DOT_ARTIST_TITLE:
571 format = "%n. %a - %t";
572 break;
573
574 case TAG_RENAMER_FORMAT_TRACK_TITLE:
575 format = "%n - %t";
576 break;
577
578 case TAG_RENAMER_FORMAT_TRACK_ARTIST_TITLE:
579 format = "%n - %a - %t";
580 break;
581
582 case TAG_RENAMER_FORMAT_TITLE:
583 format = "%t";
584 break;
585
586 case TAG_RENAMER_FORMAT_ARTIST_TITLE:
587 format = "%a - %t";
588 break;
589
590 case TAG_RENAMER_FORMAT_ARTIST_TRACK_TITLE:
591 format = "%a - %n - %t";
592 break;
593
594 default: /* Custom & separator */
595 format = tag_renamer_get_text (tag_renamer);
596 if (format == NULL || *format == '\0')
597 return g_strdup (text);
598 break;
599 }
600
601 return tag_renamer_process_format (tag_renamer, file, format);;
602 }
603
604
605
606 static GList*
tag_renamer_get_menu_items(ThunarxRenamer * renamer,GtkWindow * window,GList * files)607 tag_renamer_get_menu_items (ThunarxRenamer *renamer,
608 GtkWindow *window,
609 GList *files)
610 {
611 ThunarxMenuItem *item;
612 GList *file;
613 GList *items = NULL;
614 ThunarxFileInfo *info;
615
616 if (g_list_length (files) != 1)
617 return NULL;
618
619 file = g_list_first (files);
620
621 if (G_UNLIKELY (file == NULL))
622 return NULL;
623
624 info = THUNARX_FILE_INFO (file->data);
625
626 if (G_LIKELY (media_tags_get_audio_file_supported (info)))
627 {
628 /* Edit tags action */
629 item = thunarx_menu_item_new ("edit-tags", _("Edit _Tags"), _("Edit ID3/OGG tags of this file."), "gtk-edit");
630 g_object_set_data_full (G_OBJECT (item), "window", g_object_ref (G_OBJECT (window)), (GDestroyNotify)g_object_unref);
631 g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (tag_renamer_edit_tags_activated), info);
632 items = g_list_prepend (items, item);
633 }
634
635 return items;
636 }
637
638
639
640 static void
tag_renamer_help_clicked(GtkWidget * button)641 tag_renamer_help_clicked (GtkWidget *button)
642 {
643 GtkWidget *dialog;
644
645 /* Create dialog */
646 dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (button)),
647 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
648 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, _("Tag Help"));
649
650 /* Format help text */
651 gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
652 "<tt>%%a = </tt>%s\n"
653 "<tt>%%t = </tt>%s\n"
654 "<tt>%%b = </tt>%s\n"
655 "<tt>%%g = </tt>%s\n"
656 "<tt>%%n = </tt>%s\n"
657 "<tt>%%y = </tt>%s\n"
658 "<tt>%%c = </tt>%s",
659 _("Artist"), _("Title"),
660 _("Album"), _("Genre"),
661 _("Track number"), _("Year"),
662 _("Comment"));
663
664 /* Run and destroy */
665 gtk_dialog_run (GTK_DIALOG (dialog));
666 gtk_widget_destroy (dialog);
667 }
668
669
670
671 static gboolean
tag_renamer_combo_separator_func(GtkTreeModel * model,GtkTreeIter * iter,gpointer user_data)672 tag_renamer_combo_separator_func (GtkTreeModel *model,
673 GtkTreeIter *iter,
674 gpointer user_data)
675 {
676 gint n;
677
678 /* Get item number from model */
679 gtk_tree_model_get (model, iter, COLUMN_NUMBER, &n, -1);
680
681 /* Return true if this is the separator item */
682 return (n == TAG_RENAMER_FORMAT_SEPARATOR);
683 }
684
685
686
687 static void
tag_renamer_combo_changed(GtkComboBox * combo_box,GtkWidget * entry)688 tag_renamer_combo_changed (GtkComboBox *combo_box,
689 GtkWidget *entry)
690 {
691 GtkTreeModel *model;
692 GtkTreeIter iter;
693 gint n;
694
695 /* Get the combo model and active iter*/
696 model = gtk_combo_box_get_model (combo_box);
697 gtk_combo_box_get_active_iter (combo_box, &iter);
698
699 /* Get item number from model */
700 gtk_tree_model_get (model, &iter, COLUMN_NUMBER, &n, -1);
701
702 /* Whether the entry is sensitive */
703 gtk_widget_set_sensitive (entry, (n == TAG_RENAMER_FORMAT_CUSTOM));
704 }
705
706
707
708 /**
709 * tag_renamer_new:
710 *
711 * Allocates a new #TagRenamer instance.
712 *
713 * Return value: the newly allocated #TagRenamer.
714 **/
715 TagRenamer*
tag_renamer_new(void)716 tag_renamer_new (void)
717 {
718 return g_object_new (TYPE_TAG_RENAMER,
719 "name", _("Audio Tags"),
720 NULL);
721 }
722
723
724
725 /**
726 * tag_renamer_get_format:
727 * @tag_renamer : a #TagRenamer.
728 *
729 * Returns the current #TagRenamerFormat
730 * for the @tag_renamer.
731 *
732 * Return value: the current naming format of @tag_renamer.
733 **/
734 TagRenamerFormat
tag_renamer_get_format(TagRenamer * tag_renamer)735 tag_renamer_get_format (TagRenamer *tag_renamer)
736 {
737 g_return_val_if_fail (IS_TAG_RENAMER (tag_renamer), TAG_RENAMER_FORMAT_TRACK_TITLE);
738 return tag_renamer->format;
739 }
740
741
742
743 /**
744 * tag_renamer_set_format:
745 * @tag_renamer : a #TagRenamer.
746 * @format : the new #TagRenamerFormat.
747 *
748 * Sets the #TagRenamerFormat of the @tag_renamer
749 * to the specified @format.
750 **/
751 void
tag_renamer_set_format(TagRenamer * tag_renamer,TagRenamerFormat format)752 tag_renamer_set_format (TagRenamer *tag_renamer,
753 TagRenamerFormat format)
754 {
755 g_return_if_fail (IS_TAG_RENAMER (tag_renamer));
756
757 /* Check if we already use that format */
758 if (G_UNLIKELY (tag_renamer->format == format))
759 return;
760
761 /* Apply the new format */
762 tag_renamer->format = format;
763
764 /* Notify listeners */
765 g_object_notify (G_OBJECT (tag_renamer), "format");
766
767 /* Emit the "changed" signal */
768 thunarx_renamer_changed (THUNARX_RENAMER (tag_renamer));
769 }
770
771
772
773 const gchar *
tag_renamer_get_text(TagRenamer * tag_renamer)774 tag_renamer_get_text (TagRenamer *tag_renamer)
775 {
776 g_return_val_if_fail (IS_TAG_RENAMER (tag_renamer), NULL);
777 return tag_renamer->text;
778 }
779
780
781
782 void
tag_renamer_set_text(TagRenamer * tag_renamer,const gchar * text)783 tag_renamer_set_text (TagRenamer *tag_renamer,
784 const gchar *text)
785 {
786 g_return_if_fail (IS_TAG_RENAMER (tag_renamer));
787
788 /* check if we have a new text */
789 if (G_LIKELY (!exo_str_is_equal (tag_renamer->text, text)))
790 {
791 /* apply the new text */
792 g_free (tag_renamer->text);
793 tag_renamer->text = g_strdup (text);
794
795 /* update the renamer */
796 thunarx_renamer_changed (THUNARX_RENAMER (tag_renamer));
797
798 /* notify listeners */
799 g_object_notify (G_OBJECT (tag_renamer), "text");
800 }
801 }
802
803
804
805 /**
806 * tag_renamer_get_replace_spaces:
807 * @tag_renamer : a #TagRenamer.
808 *
809 * Returns whether spaces are going to be replaced with underscores or not.
810 *
811 * Return value: whether spaces are going to be replaced or not.
812 **/
813 gboolean
tag_renamer_get_replace_spaces(TagRenamer * tag_renamer)814 tag_renamer_get_replace_spaces (TagRenamer *tag_renamer)
815 {
816 g_return_val_if_fail (IS_TAG_RENAMER (tag_renamer), FALSE);
817 return tag_renamer->replace_spaces;
818 }
819
820
821
822 /**
823 * tag_renamer_set_replace_spaces:
824 * @tag_renamer : a #TagRenamer.
825 * @replace : a boolean flag.
826 *
827 * Sets whether spaces are going to be replaced with underscores or not.
828 **/
829 void
tag_renamer_set_replace_spaces(TagRenamer * tag_renamer,gboolean replace)830 tag_renamer_set_replace_spaces (TagRenamer *tag_renamer,
831 gboolean replace)
832 {
833 g_return_if_fail (IS_TAG_RENAMER (tag_renamer));
834
835 /* Abort if flag is already set */
836 if (G_UNLIKELY (tag_renamer->replace_spaces == replace))
837 return;
838
839 /* Apply the new setting */
840 tag_renamer->replace_spaces = replace;
841
842 /* Notify listeners */
843 g_object_notify (G_OBJECT (tag_renamer), "replace-spaces");
844
845 /* Emit the "changed" signal */
846 thunarx_renamer_changed (THUNARX_RENAMER (tag_renamer));
847 }
848
849
850
851 /**
852 * tag_renamer_get_lowercase:
853 * @tag_renamer : a #TagRenamer.
854 *
855 * Returns whether the resulting filename will be completely lowercase.
856 *
857 * Return value: whether all letters will be lowercase.
858 **/
859 gboolean
tag_renamer_get_lowercase(TagRenamer * tag_renamer)860 tag_renamer_get_lowercase (TagRenamer *tag_renamer)
861 {
862 g_return_val_if_fail (IS_TAG_RENAMER (tag_renamer), FALSE);
863 return tag_renamer->lowercase;
864 }
865
866
867
868 /**
869 * tag_renamer_set_lowercase:
870 * @tag_renamer : a #TagRenamer.
871 * @lowercase : a boolean flag.
872 *
873 * Sets whether all letters are going to be converted to lowercase.
874 **/
875 void
tag_renamer_set_lowercase(TagRenamer * tag_renamer,gboolean lowercase)876 tag_renamer_set_lowercase (TagRenamer *tag_renamer,
877 gboolean lowercase)
878 {
879 g_return_if_fail (IS_TAG_RENAMER (tag_renamer));
880
881 /* Abort if flag is already set */
882 if (G_UNLIKELY (tag_renamer->lowercase == lowercase))
883 return;
884
885 /* Apply the new setting */
886 tag_renamer->lowercase = lowercase;
887
888 /* Notify listeners */
889 g_object_notify (G_OBJECT (tag_renamer), "lowercase");
890
891 /* Emit the "changed" signal */
892 thunarx_renamer_changed (THUNARX_RENAMER (tag_renamer));
893 }
894
895
896
897 static void
tag_renamer_edit_tags_activated(ThunarxMenuItem * item,ThunarxFileInfo * file)898 tag_renamer_edit_tags_activated (ThunarxMenuItem *item,
899 ThunarxFileInfo *file)
900 {
901 GtkWindow *window;
902 GtkWidget *dialog;
903
904 /* Determine the parent window */
905 window = g_object_get_data (G_OBJECT (item), "window");
906 if (G_UNLIKELY (window == NULL))
907 return;
908
909 dialog = audio_tags_page_dialog_new (window, file);
910
911 gtk_dialog_run (GTK_DIALOG (dialog));
912 gtk_widget_destroy (dialog);
913 }
914