~mniess/ubuntu/trusty/totem/fix-lp1292262

« back to all changes in this revision

Viewing changes to src/totem-menu.c

  • Committer: Bazaar Package Importer
  • Author(s): Raphaël Hertzog
  • Date: 2011-04-10 18:12:25 UTC
  • mfrom: (1.1.14 upstream)
  • mto: (1.5.7 upstream)
  • mto: This revision was merged to the branch mainline in revision 19.
  • Revision ID: james.westby@ubuntu.com-20110410181225-u3x8yhsscjoe8ony
Tags: upstream-3.0.0
Import upstream version 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 
25
25
#include <gtk/gtk.h>
26
26
#include <glib/gi18n.h>
 
27
#include <gst/tag/tag.h>
27
28
#include <string.h>
 
29
#include <libpeas-gtk/peas-gtk-plugin-manager.h>
28
30
 
29
31
#include "totem-menu.h"
30
32
#include "totem.h"
32
34
#include "totem-private.h"
33
35
#include "totem-sidebar.h"
34
36
#include "totem-statusbar.h"
35
 
#include "totem-plugin-manager.h"
36
37
#include "bacon-video-widget.h"
37
38
#include "totem-uri.h"
38
39
 
72
73
G_MODULE_EXPORT void plugins_action_callback (GtkAction *action, Totem *totem);
73
74
G_MODULE_EXPORT void repeat_mode_action_callback (GtkToggleAction *action, Totem *totem);
74
75
G_MODULE_EXPORT void shuffle_mode_action_callback (GtkToggleAction *action, Totem *totem);
75
 
G_MODULE_EXPORT void deinterlace_action_callback (GtkToggleAction *action, Totem *totem);
76
76
G_MODULE_EXPORT void show_controls_action_callback (GtkToggleAction *action, Totem *totem);
77
77
G_MODULE_EXPORT void show_sidebar_action_callback (GtkToggleAction *action, Totem *totem);
78
78
G_MODULE_EXPORT void aspect_ratio_changed_callback (GtkRadioAction *action, GtkRadioAction *current, Totem *totem);
93
93
        return new;
94
94
}
95
95
 
96
 
/* ISO-639 helpers */
97
 
static GHashTable *lang_table;
98
 
 
99
 
static void
100
 
totem_lang_table_free (void)
101
 
{
102
 
        g_hash_table_destroy (lang_table);
103
 
        lang_table = NULL;
104
 
}
105
 
 
106
 
static void
107
 
totem_lang_table_parse_start_tag (GMarkupParseContext *ctx,
108
 
                const gchar         *element_name,
109
 
                const gchar        **attr_names,
110
 
                const gchar        **attr_values,
111
 
                gpointer             data,
112
 
                GError             **error)
113
 
{
114
 
        const char *ccode_longB, *ccode_longT, *ccode, *lang_name;
115
 
 
116
 
        if (!g_str_equal (element_name, "iso_639_entry")
117
 
                        || attr_names == NULL
118
 
                        || attr_values == NULL)
119
 
                return;
120
 
 
121
 
        ccode = NULL;
122
 
        ccode_longB = NULL;
123
 
        ccode_longT = NULL;
124
 
        lang_name = NULL;
125
 
 
126
 
        while (*attr_names && *attr_values)
127
 
        {
128
 
                if (g_str_equal (*attr_names, "iso_639_1_code"))
129
 
                {
130
 
                        /* skip if empty */
131
 
                        if (**attr_values)
132
 
                        {
133
 
                                g_return_if_fail (strlen (*attr_values) == 2);
134
 
                                ccode = *attr_values;
135
 
                        }
136
 
                } else if (g_str_equal (*attr_names, "iso_639_2B_code")) {
137
 
                        /* skip if empty */
138
 
                        if (**attr_values)
139
 
                        {
140
 
                                g_return_if_fail (strlen (*attr_values) == 3 || strcmp (*attr_values, "qaa-qtz") == 0);
141
 
                                ccode_longB = *attr_values;
142
 
                        }
143
 
                } else if (g_str_equal (*attr_names, "iso_639_2T_code")) {
144
 
                        /* skip if empty */
145
 
                        if (**attr_values)
146
 
                        {
147
 
                                g_return_if_fail (strlen (*attr_values) == 3 || strcmp (*attr_values, "qaa-qtz") == 0);
148
 
                                ccode_longT = *attr_values;
149
 
                        }
150
 
                } else if (g_str_equal (*attr_names, "name")) {
151
 
                        lang_name = *attr_values;
152
 
                }
153
 
 
154
 
                ++attr_names;
155
 
                ++attr_values;
156
 
        }
157
 
 
158
 
        if (lang_name == NULL)
159
 
                return;
160
 
 
161
 
        if (ccode != NULL)
162
 
        {
163
 
                g_hash_table_insert (lang_table,
164
 
                                g_strdup (ccode),
165
 
                                g_strdup (lang_name));
166
 
        }
167
 
        if (ccode_longB != NULL)
168
 
        {
169
 
                g_hash_table_insert (lang_table,
170
 
                                g_strdup (ccode_longB),
171
 
                                g_strdup (lang_name));
172
 
        }
173
 
        if (ccode_longT != NULL)
174
 
        {
175
 
                g_hash_table_insert (lang_table,
176
 
                                g_strdup (ccode_longT),
177
 
                                g_strdup (lang_name));
178
 
        }
179
 
}
180
 
 
181
 
#define ISO_CODES_DATADIR ISO_CODES_PREFIX"/share/xml/iso-codes"
182
 
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX"/share/locale"
183
 
 
184
 
static void
185
 
totem_lang_table_init (void)
186
 
{
187
 
        GError *err = NULL;
188
 
        char *buf;
189
 
        gsize buf_len;
190
 
 
191
 
        lang_table = g_hash_table_new_full
192
 
                (g_str_hash, g_str_equal, g_free, g_free);
193
 
 
194
 
        g_atexit (totem_lang_table_free);
195
 
 
196
 
        bindtextdomain ("iso_639", ISO_CODES_LOCALESDIR);
197
 
        bind_textdomain_codeset ("iso_639", "UTF-8");
198
 
 
199
 
        if (g_file_get_contents (ISO_CODES_DATADIR "/iso_639.xml",
200
 
                                &buf, &buf_len, &err))
201
 
        {
202
 
                GMarkupParseContext *ctx;
203
 
                GMarkupParser parser =
204
 
                { totem_lang_table_parse_start_tag, NULL, NULL, NULL, NULL };
205
 
 
206
 
                ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
207
 
 
208
 
                if (!g_markup_parse_context_parse (ctx, buf, buf_len, &err))
209
 
                {
210
 
                        g_warning ("Failed to parse '%s': %s\n",
211
 
                                        ISO_CODES_DATADIR"/iso_639.xml",
212
 
                                        err->message);
213
 
                        g_error_free (err);
214
 
                }
215
 
 
216
 
                g_markup_parse_context_free (ctx);
217
 
                g_free (buf);
218
 
        } else {
219
 
                g_warning ("Failed to load '%s': %s\n",
220
 
                                ISO_CODES_DATADIR"/iso_639.xml", err->message);
221
 
                g_error_free (err);
222
 
        }
223
 
}
224
 
 
225
 
static const char *
226
 
totem_lang_get_full (const char *lang)
227
 
{
228
 
        const char *lang_name;
229
 
        int len;
230
 
 
231
 
        g_return_val_if_fail (lang != NULL, NULL);
232
 
 
233
 
        len = strlen (lang);
234
 
        if (len != 2 && len != 3)
235
 
                return NULL;
236
 
        if (lang_table == NULL)
237
 
                totem_lang_table_init ();
238
 
 
239
 
        lang_name = (const gchar*) g_hash_table_lookup (lang_table, lang);
240
 
 
241
 
        if (lang_name)
242
 
                return dgettext ("iso_639", lang_name);
243
 
 
244
 
        return NULL;
245
 
}
246
 
 
247
96
/* Subtitle and language menus */
248
97
static void
249
98
totem_g_list_deep_free (GList *list)
289
138
        GtkAction *action;
290
139
        guint i;
291
140
 
292
 
        full_lang = totem_lang_get_full (lang);
 
141
        full_lang = gst_tag_get_language_name (lang);
293
142
 
294
143
        if (lang_index > 1) {
295
144
                char *num_lang;
339
188
 
340
189
        if (is_lang == FALSE) {
341
190
                add_lang_action (totem, action_group, ui_id, paths, prefix,
 
191
                                /* Translators: an entry in the "Languages" menu, used to choose the audio language of a DVD */
342
192
                                _("None"), -2, 0, &group);
343
193
        }
344
194
 
345
195
        action = add_lang_action (totem, action_group, ui_id, paths, prefix,
346
 
                        _("Auto"), -1, 0, &group);
 
196
                                  /* Translators: an entry in the "Languages" menu, used to choose the audio language of a DVD */
 
197
                                  C_("Language", "Auto"), -1, 0, &group);
347
198
 
348
199
        i = 0;
349
200
        lookup = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
516
367
                  gpointer data)
517
368
{
518
369
        GtkLabel *label;
519
 
        GtkRecentInfo *recent_info;
520
 
        GdkPixbuf *icon;
521
 
        GtkWidget *image = NULL;
522
 
        gint w, h;
523
370
 
524
371
        if (!GTK_IS_MENU_ITEM (proxy))
525
372
                return;
528
375
 
529
376
        gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_MIDDLE);
530
377
        gtk_label_set_max_width_chars (label,TOTEM_MAX_RECENT_ITEM_LEN);
531
 
 
532
 
        if (!GTK_IS_IMAGE_MENU_ITEM (proxy))
533
 
                return;
534
 
 
535
 
        recent_info = g_object_get_data (G_OBJECT (action), "recent-info");
536
 
        g_assert (recent_info != NULL);
537
 
 
538
 
        gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
539
 
 
540
 
        icon = gtk_recent_info_get_icon (recent_info, w);
541
 
        if (icon != NULL) {
542
 
                image = gtk_image_new_from_pixbuf (icon);
543
 
                g_object_unref (icon);
544
 
        }
545
 
 
546
 
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), image);
547
 
        gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (proxy), TRUE);
548
378
}
549
379
 
550
380
static void
552
382
                               Totem *totem)
553
383
{
554
384
        GtkRecentInfo *recent_info;
555
 
        const gchar *uri;
 
385
        const gchar *uri, *display_name;
556
386
 
557
387
        recent_info = g_object_get_data (G_OBJECT (action), "recent-info");
558
388
        uri = gtk_recent_info_get_uri (recent_info);
 
389
        display_name = gtk_recent_info_get_display_name (recent_info);
559
390
 
560
 
        totem_add_to_playlist_and_play (totem, uri, NULL, FALSE);
 
391
        totem_add_to_playlist_and_play (totem, uri, display_name, FALSE);
561
392
}
562
393
 
563
394
static gint
634
465
                const char    *display_name;
635
466
                char          *label;
636
467
                char          *escaped_label;
 
468
                const gchar   *mime_type;
 
469
                gchar         *content_type;
 
470
                GIcon         *icon = NULL;
637
471
 
638
472
                info = (GtkRecentInfo *) l->data;
639
473
 
656
490
                                  G_CALLBACK (on_recent_file_item_activated),
657
491
                                  totem);
658
492
 
 
493
                mime_type = gtk_recent_info_get_mime_type (info);
 
494
                content_type = g_content_type_from_mime_type (mime_type);
 
495
                if (content_type != NULL) {
 
496
                        icon = g_content_type_get_icon (content_type);
 
497
                        g_free (content_type);
 
498
                }
 
499
                if (icon != NULL) {
 
500
                        gtk_action_set_gicon (action, icon);
 
501
                        gtk_action_set_always_show_image (action, TRUE);
 
502
                        g_object_unref (icon);
 
503
                }
 
504
 
659
505
                gtk_action_group_add_action (totem->recent_action_group,
660
506
                                            action);
661
507
                g_object_unref (action);
734
580
}
735
581
 
736
582
void
737
 
totem_action_add_recent (Totem *totem, const char *uri, const char *display_name)
 
583
totem_action_add_recent (Totem      *totem,
 
584
                         const char *uri,
 
585
                         const char *display_name,
 
586
                         const char *content_type)
738
587
{
739
588
        GFile *file;
740
589
 
741
590
        if (totem_is_special_mrl (uri) != FALSE)
742
591
                return;
743
592
 
 
593
        /* If we already have a content-type, the display_name is
 
594
         * probably decent as well */
 
595
        if (content_type != NULL) {
 
596
                GtkRecentData data;
 
597
                char *groups[] = { NULL, NULL };
 
598
 
 
599
                memset (&data, 0, sizeof (data));
 
600
 
 
601
                data.mime_type = (char *) content_type;
 
602
                data.display_name = (char *) display_name;
 
603
                groups[0] = (char*) "Totem";
 
604
                data.app_name = (char *) g_get_application_name ();
 
605
                data.app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL);
 
606
                data.groups = groups;
 
607
 
 
608
                if (gtk_recent_manager_add_full (totem->recent_manager,
 
609
                                                 uri, &data) == FALSE) {
 
610
                        g_warning ("Couldn't add recent file for '%s'", uri);
 
611
                }
 
612
                g_free (data.app_exec);
 
613
 
 
614
                return;
 
615
        }
 
616
 
744
617
        file = g_file_new_for_uri (uri);
745
618
        g_object_set_data_full (G_OBJECT (file), "uri", g_strdup (uri), g_free);
746
619
        g_object_set_data_full (G_OBJECT (file), "display_name", g_strdup (display_name), g_free);
936
809
        char *menu_item_path;
937
810
 
938
811
        disabled = FALSE;
 
812
        device_path = NULL;
939
813
 
940
814
        /* Add devices with blank CDs and audio CDs in them, but disable them */
941
815
        if (drive != NULL) {
1276
1150
void
1277
1151
skip_forward_action_callback (GtkAction *action, Totem *totem)
1278
1152
{
1279
 
        totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000);
 
1153
        totem_action_seek_relative (totem, SEEK_FORWARD_OFFSET * 1000, FALSE);
1280
1154
}
1281
1155
 
1282
1156
void
1283
1157
skip_backwards_action_callback (GtkAction *action, Totem *totem)
1284
1158
{
1285
 
        totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000);
 
1159
        totem_action_seek_relative (totem, SEEK_BACKWARD_OFFSET * 1000, FALSE);
1286
1160
}
1287
1161
 
1288
1162
void
1361
1235
                              int response_id,
1362
1236
                              gpointer data)
1363
1237
{
1364
 
        if (response_id == GTK_RESPONSE_CLOSE)
1365
 
                gtk_widget_hide (GTK_WIDGET (dialog));
 
1238
        gtk_widget_hide (GTK_WIDGET (dialog));
1366
1239
}
1367
1240
 
1368
1241
 
1380
1253
                                                              NULL);
1381
1254
                gtk_container_set_border_width (GTK_CONTAINER (totem->plugins), 5);
1382
1255
                gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (totem->plugins))), 2);
1383
 
                gtk_dialog_set_has_separator (GTK_DIALOG (totem->plugins), FALSE);
1384
1256
 
1385
1257
                g_signal_connect_object (G_OBJECT (totem->plugins),
1386
1258
                                         "delete_event",
1391
1263
                                         G_CALLBACK (totem_plugins_response_cb),
1392
1264
                                         NULL, 0);
1393
1265
 
1394
 
                manager = totem_plugin_manager_new ();
 
1266
                manager = peas_gtk_plugin_manager_new (NULL);
1395
1267
                gtk_widget_show_all (GTK_WIDGET (manager));
1396
 
                gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (totem->plugins))),
1397
 
                                   manager);
 
1268
                gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (totem->plugins))),
 
1269
                                    manager, TRUE, TRUE, 0);
 
1270
                gtk_window_set_default_size (GTK_WINDOW (totem->plugins), 600, 400);
1398
1271
        }
1399
1272
 
1400
1273
        gtk_window_present (GTK_WINDOW (totem->plugins));
1415
1288
}
1416
1289
 
1417
1290
void
1418
 
deinterlace_action_callback (GtkToggleAction *action, Totem *totem)
1419
 
{
1420
 
        gboolean value;
1421
 
 
1422
 
        value = gtk_toggle_action_get_active (action);
1423
 
        bacon_video_widget_set_deinterlacing (totem->bvw, value);
1424
 
        gconf_client_set_bool (totem->gc, GCONF_PREFIX"/deinterlace",
1425
 
                        value, NULL);
1426
 
}
1427
 
 
1428
 
void
1429
1291
show_controls_action_callback (GtkToggleAction *action, Totem *totem)
1430
1292
{
1431
1293
        gboolean show;