262
258
gtk_widget_show (error_dialog);
262
totem_playlist_select_subtitle_dialog(TotemPlaylist *playlist, TotemPlaylistSelectDialog mode)
264
char *subtitle, *current, *path;
266
TotemPlaylistStatus playing;
269
if (mode == TOTEM_PLAYLIST_DIALOG_PLAYING) {
270
/* Set subtitle file for the currently playing movie */
271
gtk_tree_model_get_iter (playlist->priv->model, &iter, playlist->priv->current);
272
} else if (mode == TOTEM_PLAYLIST_DIALOG_SELECTED) {
273
/* Set subtitle file in for the first selected playlist item */
276
l = gtk_tree_selection_get_selected_rows (playlist->priv->selection, NULL);
277
gtk_tree_model_get_iter (playlist->priv->model, &iter, l->data);
278
g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL);
281
g_assert_not_reached ();
284
/* Look for the directory of the current movie */
285
gtk_tree_model_get (playlist->priv->model, &iter,
286
FILENAME_COL, ¤t,
293
file = g_file_new_for_commandline_arg (current);
294
dir = g_file_get_parent (file);
295
g_object_unref (file);
297
path = g_file_get_path (dir);
298
g_object_unref (dir);
301
subtitle = totem_add_subtitle (totem_playlist_get_toplevel (playlist), path);
304
if (subtitle == NULL)
307
gtk_tree_model_get (playlist->priv->model, &iter,
308
PLAYING_COL, &playing,
311
gtk_list_store_set (GTK_LIST_STORE(playlist->priv->model), &iter,
312
SUBTITLE_URI_COL, subtitle,
315
if (playing != TOTEM_PLAYLIST_STATUS_NONE) {
316
g_signal_emit (G_OBJECT (playlist),
317
totem_playlist_table_signals[SUBTITLE_CHANGED], 0,
325
totem_playlist_set_current_subtitle (TotemPlaylist *playlist, const char *subtitle_uri)
329
if (playlist->priv->current == NULL)
332
gtk_tree_model_get_iter (playlist->priv->model, &iter, playlist->priv->current);
334
gtk_list_store_set (GTK_LIST_STORE(playlist->priv->model), &iter,
335
SUBTITLE_URI_COL, subtitle_uri,
338
g_signal_emit (G_OBJECT (playlist),
339
totem_playlist_table_signals[SUBTITLE_CHANGED], 0,
265
343
/* This one returns a new string, in UTF8 even if the MRL is encoded
266
344
* in the locale's encoding
462
551
playlist_select_subtitle_action_callback (GtkAction *action, TotemPlaylist *playlist)
464
char *subtitle, *current, *path;
467
TotemPlaylistStatus playing;
470
l = gtk_tree_selection_get_selected_rows (playlist->priv->selection, NULL);
471
gtk_tree_model_get_iter (playlist->priv->model, &iter, l->data);
472
g_list_foreach (l, (GFunc) gtk_tree_path_free, NULL);
475
/* Look for the directory of the current movie */
476
gtk_tree_model_get (playlist->priv->model, &iter,
477
FILENAME_COL, ¤t,
484
file = g_file_new_for_commandline_arg (current);
485
dir = g_file_get_parent (file);
486
g_object_unref (file);
488
path = g_file_get_path (dir);
489
g_object_unref (dir);
492
subtitle = totem_add_subtitle (totem_playlist_get_toplevel (playlist), path);
495
if (subtitle == NULL)
498
gtk_tree_model_get (playlist->priv->model, &iter,
499
PLAYING_COL, &playing,
502
gtk_list_store_set (GTK_LIST_STORE(playlist->priv->model), &iter,
503
SUBTITLE_URI_COL, subtitle,
506
if (playing != TOTEM_PLAYLIST_STATUS_NONE) {
507
g_signal_emit (G_OBJECT (playlist),
508
totem_playlist_table_signals[SUBTITLE_CHANGED], 0,
553
totem_playlist_select_subtitle_dialog (playlist, TOTEM_PLAYLIST_DIALOG_SELECTED);
836
880
playlist_remove_files (TotemPlaylist *playlist)
838
GtkTreeSelection *selection;
839
GtkTreeRowReference *ref;
840
gboolean is_selected = FALSE;
843
selection = gtk_tree_view_get_selection
844
(GTK_TREE_VIEW (playlist->priv->treeview));
845
if (selection == NULL)
848
gtk_tree_selection_selected_foreach (selection,
849
totem_playlist_foreach_selected,
850
(gpointer) playlist);
852
/* If the current item is to change, we need to keep an static
853
* reference to it, TreeIter and TreePath don't allow that */
854
if (playlist->priv->current != NULL)
858
ref = gtk_tree_row_reference_new (playlist->priv->model,
859
playlist->priv->current);
860
is_selected = gtk_tree_selection_path_is_selected (selection,
861
playlist->priv->current);
863
indices = gtk_tree_path_get_indices (playlist->priv->current);
864
next_pos = indices[0];
866
gtk_tree_path_free (playlist->priv->current);
872
/* We destroy the items, one-by-one from the list built above */
873
while (playlist->priv->list != NULL)
878
path = gtk_tree_row_reference_get_path
879
((GtkTreeRowReference *)(playlist->priv->list->data));
880
gtk_tree_model_get_iter (playlist->priv->model, &iter, path);
881
gtk_tree_path_free (path);
883
totem_playlist_emit_item_removed (playlist, &iter);
884
gtk_list_store_remove (GTK_LIST_STORE (playlist->priv->model), &iter);
886
gtk_tree_row_reference_free
887
((GtkTreeRowReference *)(playlist->priv->list->data));
888
playlist->priv->list = g_list_remove (playlist->priv->list,
889
playlist->priv->list->data);
891
g_list_free (playlist->priv->list);
892
playlist->priv->list = NULL;
894
if (is_selected != FALSE)
896
/* The current item was removed from the playlist */
903
str = g_strdup_printf ("%d", next_pos);
904
cur = gtk_tree_path_new_from_string (str);
906
if (gtk_tree_model_get_iter (playlist->priv->model,
907
&iter, cur) == FALSE)
909
playlist->priv->current = NULL;
910
gtk_tree_path_free (cur);
912
playlist->priv->current = cur;
916
playlist->priv->current = NULL;
919
playlist->priv->current_shuffled = -1;
920
ensure_shuffled (playlist, playlist->priv->shuffle);
922
g_signal_emit (G_OBJECT (playlist),
923
totem_playlist_table_signals[CURRENT_REMOVED],
928
/* The path to the current item changed */
929
playlist->priv->current =
930
gtk_tree_row_reference_get_path (ref);
931
gtk_tree_row_reference_free (ref);
934
ensure_shuffled (playlist, playlist->priv->shuffle);
936
g_signal_emit (G_OBJECT (playlist),
937
totem_playlist_table_signals[CHANGED], 0,
940
totem_playlist_update_save_button (playlist);
941
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (playlist->priv->treeview));
882
totem_playlist_clear_with_compare (playlist, NULL, NULL);
957
898
totem_playlist_save_playlist (TotemPlaylist *playlist, char *filename, gint active_format)
959
PlaylistSaveType *cur = NULL;
962
if (active_format > 0)
963
totem_playlist_save_current_playlist_ext (playlist, filename,
964
save_types[active_format - 1].type);
966
for (i = 0; i < G_N_ELEMENTS(save_types); i++) {
967
if (g_str_has_suffix (filename, save_types[i].suffix)) {
968
cur = &save_types[i];
900
if (active_format == 0)
903
totem_playlist_save_current_playlist_ext (playlist, filename,
904
save_types[active_format].type);
908
suffix_match_replace (const char *fname, guint old_format, guint new_format)
912
ext = g_strdup_printf (".%s", save_types[old_format].suffix);
913
if (g_str_has_suffix (fname, ext) != FALSE) {
914
char *no_suffix, *new_fname;
916
no_suffix = g_strndup (fname, strlen (fname) - strlen (ext));
917
new_fname = g_strconcat (no_suffix, ".", save_types[new_format].suffix, NULL);
929
format_selection_changed (EggFileFormatChooser *chooser, TotemPlaylist *playlist)
933
format = egg_file_format_chooser_get_format (chooser, NULL);
935
if (format != playlist->priv->save_format) {
936
char *fname, *new_fname;
939
fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (playlist->priv->file_chooser));
942
/* The new format is "By extension" don't touch anything */
943
} else if (playlist->priv->save_format == 0) {
946
for (i = 1; i < G_N_ELEMENTS (save_types); i++) {
947
new_fname = suffix_match_replace (fname, i, format);
948
if (new_fname != NULL)
973
totem_playlist_error (_("Could not save the playlist"), _("Unknown file extension."), playlist);
975
totem_playlist_save_current_playlist_ext (playlist, filename, cur->type);
952
new_fname = suffix_match_replace (fname, playlist->priv->save_format, format);
954
if (new_fname != NULL) {
957
basename = g_path_get_basename (new_fname);
959
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (playlist->priv->file_chooser), basename);
962
playlist->priv->save_format = format;
979
966
static GtkWidget *
980
totem_playlist_save_add_format_combo_box (GtkFileChooser *fc)
967
totem_playlist_save_add_format_chooser (GtkFileChooser *fc, TotemPlaylist *playlist)
982
GtkWidget *hbox, *label, *combo_box;
969
GtkWidget *format_chooser;
985
hbox = gtk_hbox_new (FALSE, 4);
986
label = gtk_label_new (_("Select playlist format:"));
987
gtk_widget_show (label);
989
combo_box = gtk_combo_box_new_text ();
990
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box),
992
gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
993
for (i = 0; i < G_N_ELEMENTS(save_types); i++) {
994
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box),
972
format_chooser = egg_file_format_chooser_new ();
974
playlist->priv->save_format = 0;
976
for (i = 1; i < G_N_ELEMENTS (save_types) ; i++) {
977
egg_file_format_chooser_add_format (
978
EGG_FILE_FORMAT_CHOOSER (format_chooser), 0, _(save_types[i].name),
979
"gnome-mime-audio", save_types[i].suffix, NULL);
997
gtk_widget_show (combo_box);
999
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
1000
gtk_box_pack_start (GTK_BOX (hbox), combo_box, TRUE, TRUE, 0);
1001
gtk_widget_show (hbox);
1002
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (fc), hbox);
1004
atk_object_add_relationship (gtk_widget_get_accessible (label),
1005
ATK_RELATION_LABEL_FOR,
1006
gtk_widget_get_accessible (combo_box));
1007
atk_object_add_relationship (gtk_widget_get_accessible (combo_box),
1008
ATK_RELATION_LABELLED_BY,
1009
gtk_widget_get_accessible (label));
982
g_signal_connect (format_chooser, "selection-changed",
983
G_CALLBACK (format_selection_changed), playlist);
985
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (fc),
988
return format_chooser;
1015
992
totem_playlist_save_files (GtkWidget *widget, TotemPlaylist *playlist)
1017
GtkWidget *fs, *combo_box;
994
GtkWidget *fs, *format_chooser;
998
g_assert (playlist->priv->file_chooser == NULL);
1021
1000
fs = gtk_file_chooser_dialog_new (_("Save Playlist"),
1022
totem_playlist_get_toplevel (playlist),
1023
GTK_FILE_CHOOSER_ACTION_SAVE,
1024
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1025
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
1001
totem_playlist_get_toplevel (playlist),
1002
GTK_FILE_CHOOSER_ACTION_SAVE,
1003
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1004
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
1027
1006
gtk_dialog_set_default_response (GTK_DIALOG (fs), GTK_RESPONSE_ACCEPT);
1028
1007
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (fs), FALSE);
1029
1008
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fs), TRUE);
1030
1010
/* translators: Playlist is the default saved playlist filename,
1031
1011
* without the suffix */
1032
filename = g_strconcat (_("Playlist"), save_types[0].suffix, NULL);
1012
filename = g_strconcat (_("Playlist"), ".", save_types[1].suffix, NULL);
1033
1013
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fs), filename);
1034
1014
g_free (filename);
1035
combo_box = totem_playlist_save_add_format_combo_box (GTK_FILE_CHOOSER (fs));
1015
format_chooser = totem_playlist_save_add_format_chooser (GTK_FILE_CHOOSER (fs), playlist);
1037
if (playlist->priv->save_path != NULL)
1017
if (playlist->priv->save_path != NULL) {
1039
1018
gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (fs),
1040
1019
playlist->priv->save_path);
1022
playlist->priv->file_chooser = fs;
1043
1024
response = gtk_dialog_run (GTK_DIALOG (fs));
1044
1025
gtk_widget_hide (fs);
1045
1026
while (gtk_events_pending())
1046
1027
gtk_main_iteration();
1048
if (response == GTK_RESPONSE_ACCEPT)
1029
if (response == GTK_RESPONSE_ACCEPT) {
1031
guint active_format;
1053
1033
fname = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fs));
1054
active_format = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
1034
active_format = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (format_chooser),
1037
playlist->priv->file_chooser = NULL;
1056
1038
gtk_widget_destroy (fs);
1058
1040
if (fname == NULL)
1781
1819
ClearComparisonFunc func,
1782
1820
gconstpointer data)
1784
GList *list = NULL, *l;
1786
gboolean has_items, current_removed;
1792
current_removed = FALSE;
1794
for (i = 0; i < num_items; i++)
1799
index = g_strdup_printf ("%d", i);
1800
if (gtk_tree_model_get_iter_from_string
1801
(playlist->priv->model,
1802
&iter, index) == FALSE)
1822
GtkTreeRowReference *ref;
1829
GtkTreeSelection *selection;
1831
selection = gtk_tree_view_get_selection
1832
(GTK_TREE_VIEW (playlist->priv->treeview));
1833
if (selection == NULL)
1836
gtk_tree_selection_selected_foreach (selection,
1837
totem_playlist_foreach_selected,
1838
(gpointer) playlist);
1846
for (i = 0; i < num_items; i++) {
1850
index = g_strdup_printf ("%d", i);
1851
if (gtk_tree_model_get_iter_from_string (playlist->priv->model, &iter, index) == FALSE) {
1804
1855
g_free (index);
1809
if ((* func) (playlist, &iter, data) != FALSE)
1812
GtkTreeRowReference *ref;
1814
path = gtk_tree_path_new_from_indices (i, -1);
1815
ref = gtk_tree_row_reference_new
1816
(playlist->priv->model, path);
1817
list = g_list_prepend (list, ref);
1818
gtk_tree_path_free (path);
1822
has_items = (list != NULL);
1824
for (l = list; l != NULL; l = l->next)
1857
if ((* func) (playlist, &iter, data) != FALSE) {
1859
GtkTreeRowReference *r;
1861
path = gtk_tree_path_new_from_indices (i, -1);
1862
r = gtk_tree_row_reference_new (playlist->priv->model, path);
1863
if (playlist->priv->current != NULL) {
1864
if (gtk_tree_path_compare (path, playlist->priv->current) == 0)
1865
playlist->priv->current_to_be_removed = TRUE;
1867
playlist->priv->list = g_list_prepend (playlist->priv->list, r);
1868
gtk_tree_path_free (path);
1872
if (playlist->priv->list == NULL)
1876
/* If the current item is to change, we need to keep an static
1877
* reference to it, TreeIter and TreePath don't allow that */
1878
if (playlist->priv->current != NULL) {
1881
ref = gtk_tree_row_reference_new (playlist->priv->model,
1882
playlist->priv->current);
1883
indices = gtk_tree_path_get_indices (playlist->priv->current);
1884
next_pos = indices[0];
1888
/* We destroy the items, one-by-one from the list built above */
1889
while (playlist->priv->list != NULL)
1826
1891
GtkTreePath *path;
1827
1892
GtkTreeIter iter;
1829
path = gtk_tree_row_reference_get_path (l->data);
1894
path = gtk_tree_row_reference_get_path
1895
((GtkTreeRowReference *)(playlist->priv->list->data));
1830
1896
gtk_tree_model_get_iter (playlist->priv->model, &iter, path);
1831
if (gtk_tree_path_compare (path, playlist->priv->current) == 0)
1832
current_removed = TRUE;
1897
gtk_tree_path_free (path);
1834
1899
totem_playlist_emit_item_removed (playlist, &iter);
1835
1900
gtk_list_store_remove (GTK_LIST_STORE (playlist->priv->model), &iter);
1836
gtk_tree_path_free (path);
1837
gtk_tree_row_reference_free (l->data);
1902
gtk_tree_row_reference_free
1903
((GtkTreeRowReference *)(playlist->priv->list->data));
1904
playlist->priv->list = g_list_remove (playlist->priv->list,
1905
playlist->priv->list->data);
1841
if (has_items != FALSE && current_removed != FALSE) {
1907
g_list_free (playlist->priv->list);
1908
playlist->priv->list = NULL;
1910
if (playlist->priv->current_to_be_removed != FALSE) {
1911
/* The current item was removed from the playlist */
1912
if (next_pos != -1) {
1917
str = g_strdup_printf ("%d", next_pos);
1918
cur = gtk_tree_path_new_from_string (str);
1920
if (gtk_tree_model_get_iter (playlist->priv->model, &iter, cur) == FALSE) {
1921
playlist->priv->current = NULL;
1922
gtk_tree_path_free (cur);
1924
playlist->priv->current = cur;
1928
playlist->priv->current = NULL;
1842
1931
playlist->priv->current_shuffled = -1;
1932
ensure_shuffled (playlist, playlist->priv->shuffle);
1844
ensure_shuffled (playlist, playlist->priv->shuffle);
1845
gtk_tree_path_free (playlist->priv->current);
1846
playlist->priv->current = NULL;
1847
1934
g_signal_emit (G_OBJECT (playlist),
1848
1935
totem_playlist_table_signals[CURRENT_REMOVED],
1850
} else if (has_items != FALSE) {
1939
/* The path to the current item changed */
1940
playlist->priv->current =
1941
gtk_tree_row_reference_get_path (ref);
1942
gtk_tree_row_reference_free (ref);
1851
1945
ensure_shuffled (playlist, playlist->priv->shuffle);
1852
1947
g_signal_emit (G_OBJECT (playlist),
1853
totem_playlist_table_signals[CHANGED], 0,
1948
totem_playlist_table_signals[CHANGED], 0,
1951
totem_playlist_update_save_button (playlist);
1952
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (playlist->priv->treeview));
1954
playlist->priv->current_to_be_removed = FALSE;
1858
1957
static gboolean