1 /* EggFileFormatChooser
2 * Copyright (C) 2007 Mathias Hasselmann
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
19 #include "eggfileformatchooser.h"
20 #include "egg-macros.h"
22 #include <glib/gi18n.h>
27 typedef struct _EggFileFormatFilterInfo EggFileFormatFilterInfo;
28 typedef struct _EggFileFormatSearch EggFileFormatSearch;
35 MODEL_COLUMN_EXTENSIONS,
43 SIGNAL_SELECTION_CHANGED,
47 struct _EggFileFormatChooserPrivate
50 GtkTreeSelection *selection;
54 GtkFileChooser *chooser;
55 GtkFileFilter *all_files;
56 GtkFileFilter *supported_files;
59 struct _EggFileFormatFilterInfo
61 GHashTable *extension_set;
62 GSList *extension_list;
63 gboolean show_extensions;
67 struct _EggFileFormatSearch
73 const gchar *extension;
76 static guint signals[SIGNAL_LAST];
78 G_DEFINE_TYPE (EggFileFormatChooser,
79 egg_file_format_chooser,
81 EGG_DEFINE_QUARK (EggFileFormatFilterInfo,
82 egg_file_format_filter_info);
84 static EggFileFormatFilterInfo*
85 egg_file_format_filter_info_new (const gchar *name,
86 gboolean show_extensions)
88 EggFileFormatFilterInfo *self;
90 self = g_new0 (EggFileFormatFilterInfo, 1);
91 self->extension_set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
92 self->show_extensions = show_extensions;
93 self->name = g_strdup (name);
99 egg_file_format_filter_info_free (gpointer boxed)
101 EggFileFormatFilterInfo *self;
107 g_hash_table_unref (self->extension_set);
108 g_slist_foreach (self->extension_list, (GFunc) g_free, NULL);
109 g_slist_free (self->extension_list);
116 egg_file_format_filter_find (gpointer key,
117 gpointer value G_GNUC_UNUSED,
120 const GtkFileFilterInfo *info = data;
121 const gchar *pattern = key;
123 return g_str_has_suffix (info->filename, pattern + 1);
127 egg_file_format_filter_filter (const GtkFileFilterInfo *info,
130 EggFileFormatFilterInfo *self = data;
132 return NULL != g_hash_table_find (self->extension_set,
133 egg_file_format_filter_find,
137 static GtkFileFilter*
138 egg_file_format_filter_new (const gchar *name,
139 gboolean show_extensions)
141 GtkFileFilter *filter;
142 EggFileFormatFilterInfo *info;
144 filter = gtk_file_filter_new ();
145 gtk_file_filter_set_name (filter, name);
147 info = egg_file_format_filter_info_new (name, show_extensions);
149 gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME,
150 egg_file_format_filter_filter,
152 g_object_set_qdata_full (G_OBJECT (filter),
153 egg_file_format_filter_info_quark (),
154 info, egg_file_format_filter_info_free);
160 egg_file_format_filter_add_extensions (GtkFileFilter *filter,
161 const gchar *extensions)
163 EggFileFormatFilterInfo *info;
164 GString *filter_name;
169 g_assert (NULL != extensions);
171 info = g_object_get_qdata (G_OBJECT (filter),
172 egg_file_format_filter_info_quark ());
174 info->extension_list = g_slist_prepend (info->extension_list,
175 g_strdup (extensions));
177 if (info->show_extensions)
179 filter_name = g_string_new (info->name);
180 g_string_append (filter_name, " (");
188 length = strcspn (extptr, ",");
189 pattern = g_new (gchar, length + 3);
191 memcpy (pattern, "*.", 2);
192 memcpy (pattern + 2, extptr, length);
193 pattern[length + 2] = '\0';
197 if (extptr != extensions)
198 g_string_append (filter_name, ", ");
200 g_string_append (filter_name, pattern);
208 g_hash_table_replace (info->extension_set, pattern, pattern);
213 g_string_append (filter_name, ")");
214 gtk_file_filter_set_name (filter, filter_name->str);
215 g_string_free (filter_name, TRUE);
220 selection_changed_cb (GtkTreeSelection *selection,
221 EggFileFormatChooser *self)
226 GtkFileFilter *filter;
231 if (gtk_tree_selection_get_selected (selection, &model, &iter))
233 gtk_tree_model_get (model, &iter, MODEL_COLUMN_NAME, &name, -1);
235 label = g_strdup_printf (_("File _Format: %s"), name);
236 gtk_expander_set_use_underline (GTK_EXPANDER (self), TRUE);
237 gtk_expander_set_label (GTK_EXPANDER (self), label);
242 if (self->priv->chooser)
244 while (gtk_tree_model_iter_parent (model, &parent, &iter))
247 gtk_tree_model_get (model, &iter, MODEL_COLUMN_FILTER, &filter, -1);
248 gtk_file_chooser_set_filter (self->priv->chooser, filter);
249 g_object_unref (filter);
252 g_signal_emit (self, signals[SIGNAL_SELECTION_CHANGED], 0);
256 /* XXX This hack is needed, as gtk_expander_set_label seems
257 * not to work from egg_file_format_chooser_init */
259 select_default_file_format (gpointer data)
261 EggFileFormatChooser *self = EGG_FILE_FORMAT_CHOOSER (data);
262 egg_file_format_chooser_set_format (self, 0);
263 self->priv->idle_hack = 0;
268 find_by_format (GtkTreeModel *model,
269 GtkTreePath *path G_GNUC_UNUSED,
273 EggFileFormatSearch *search = data;
276 gtk_tree_model_get (model, iter, MODEL_COLUMN_ID, &id, -1);
278 if (id == search->format)
280 search->success = TRUE;
281 search->iter = *iter;
284 return search->success;
288 find_in_list (gchar *list,
294 for (token = strtok_r (list, ",", &saveptr); NULL != token;
295 token = strtok_r (NULL, ",", &saveptr))
297 token = g_strstrip (token);
299 if (g_str_equal (needle, token))
307 accept_filename (gchar *extensions,
308 const gchar *filename)
315 length = strlen (filename);
317 for (token = strtok_r (extensions, ",", &saveptr); NULL != token;
318 token = strtok_r (NULL, ",", &saveptr))
320 token = g_strstrip (token);
321 extptr = filename + length - strlen (token) - 1;
323 if (extptr > filename && '.' == *extptr &&
324 !strcmp (extptr + 1, token))
332 find_by_extension (GtkTreeModel *model,
333 GtkTreePath *path G_GNUC_UNUSED,
337 EggFileFormatSearch *search = data;
339 gchar *extensions = NULL;
342 gtk_tree_model_get (model, iter,
343 MODEL_COLUMN_EXTENSIONS, &extensions,
344 MODEL_COLUMN_ID, &format,
347 if (extensions && find_in_list (extensions, search->extension))
349 search->format = format;
350 search->success = TRUE;
351 search->iter = *iter;
355 return search->success;
359 egg_file_format_chooser_init (EggFileFormatChooser *self)
364 GtkTreeViewColumn *column;
365 GtkCellRenderer *cell;
368 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EGG_TYPE_FILE_FORMAT_CHOOSER,
369 EggFileFormatChooserPrivate);
373 self->priv->all_files = g_object_ref_sink (gtk_file_filter_new ());
374 gtk_file_filter_set_name (self->priv->all_files, _("All Files"));
375 self->priv->supported_files = egg_file_format_filter_new (_("All Supported Files"), FALSE);
379 self->priv->model = gtk_tree_store_new (7, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
380 GTK_TYPE_FILE_FILTER, G_TYPE_POINTER, G_TYPE_POINTER);
382 gtk_tree_store_append (self->priv->model, &iter, NULL);
383 gtk_tree_store_set (self->priv->model, &iter,
384 MODEL_COLUMN_NAME, _("By Extension"),
385 MODEL_COLUMN_FILTER, self->priv->supported_files,
391 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->priv->model));
392 self->priv->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
393 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
395 /* file format column */
397 column = gtk_tree_view_column_new ();
398 gtk_tree_view_column_set_expand (column, TRUE);
399 gtk_tree_view_column_set_title (column, _("File Format"));
400 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
402 cell = gtk_cell_renderer_pixbuf_new ();
403 gtk_tree_view_column_pack_start (column, cell, FALSE);
404 gtk_tree_view_column_set_attributes (column, cell,
405 "icon-name", MODEL_COLUMN_ICON,
408 cell = gtk_cell_renderer_text_new ();
409 gtk_tree_view_column_pack_start (column, cell, TRUE);
410 gtk_tree_view_column_set_attributes (column, cell,
411 "text", MODEL_COLUMN_NAME,
414 /* extensions column */
416 column = gtk_tree_view_column_new_with_attributes (
417 _("Extension(s)"), gtk_cell_renderer_text_new (),
418 "text", MODEL_COLUMN_EXTENSIONS, NULL);
419 gtk_tree_view_column_set_expand (column, FALSE);
420 gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
424 gtk_tree_selection_set_mode (self->priv->selection, GTK_SELECTION_BROWSE);
425 g_signal_connect (self->priv->selection, "changed",
426 G_CALLBACK (selection_changed_cb), self);
427 self->priv->idle_hack = g_idle_add (select_default_file_format, self);
431 scroller = gtk_scrolled_window_new (NULL, NULL);
432 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
433 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
434 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroller),
436 gtk_widget_set_size_request (scroller, -1, 150);
437 gtk_container_add (GTK_CONTAINER (scroller), view);
438 gtk_widget_show_all (scroller);
440 gtk_container_add (GTK_CONTAINER (self), scroller);
444 reset_model (EggFileFormatChooser *self)
446 GtkTreeModel *model = GTK_TREE_MODEL (self->priv->model);
449 if (gtk_tree_model_get_iter_first (model, &iter))
453 GDestroyNotify destroy = NULL;
454 gpointer data = NULL;
456 gtk_tree_model_get (model, &iter,
457 MODEL_COLUMN_DESTROY, &destroy,
458 MODEL_COLUMN_DATA, &data,
464 while (gtk_tree_model_iter_next (model, &iter));
467 gtk_tree_store_clear (self->priv->model);
471 egg_file_format_chooser_dispose (GObject *obj)
473 EggFileFormatChooser *self = EGG_FILE_FORMAT_CHOOSER (obj);
477 if (self->priv->idle_hack)
479 g_source_remove (self->priv->idle_hack);
480 self->priv->idle_hack = 0;
484 G_OBJECT_CLASS (egg_file_format_chooser_parent_class)->dispose (obj);
488 egg_file_format_chooser_finalize (GObject *obj)
490 EggFileFormatChooser *self = EGG_FILE_FORMAT_CHOOSER (obj);
494 if (self->priv->model)
498 g_object_unref (self->priv->model);
499 self->priv->model = NULL;
501 g_object_unref (self->priv->all_files);
502 self->priv->all_files = NULL;
506 G_OBJECT_CLASS (egg_file_format_chooser_parent_class)->finalize (obj);
510 filter_changed_cb (GObject *object,
514 EggFileFormatChooser *self;
516 GtkFileFilter *current_filter;
517 GtkFileFilter *format_filter;
523 self = EGG_FILE_FORMAT_CHOOSER (data);
525 format_filter = NULL;
526 current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (object));
527 model = GTK_TREE_MODEL (self->priv->model);
529 if (gtk_tree_selection_get_selected (self->priv->selection, &model, &iter))
531 while (gtk_tree_model_iter_parent (model, &parent, &iter))
534 gtk_tree_model_get (model, &iter,
537 g_object_unref (format_filter);
540 if (current_filter && current_filter != format_filter &&
541 gtk_tree_model_get_iter_first (model, &iter))
543 if (current_filter == self->priv->all_files)
544 format_filter = current_filter;
547 format_filter = NULL;
551 gtk_tree_model_get (model, &iter,
554 g_object_unref (format_filter);
556 if (format_filter == current_filter)
559 while (gtk_tree_model_iter_next (model, &iter));
563 gtk_tree_selection_select_iter (self->priv->selection, &iter);
567 /* Shows an error dialog set as transient for the specified window */
569 error_message_with_parent (GtkWindow *parent,
573 gboolean first_call = TRUE;
578 g_warning ("%s: Merge with the code in Gtk{File,Recent}ChooserDefault.", G_STRLOC);
582 dialog = gtk_message_dialog_new (parent,
583 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
588 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
592 gtk_window_group_add_window (parent->group, GTK_WINDOW (dialog));
594 gtk_dialog_run (GTK_DIALOG (dialog));
595 gtk_widget_destroy (dialog);
598 /* Returns a toplevel GtkWindow, or NULL if none */
600 get_toplevel (GtkWidget *widget)
604 toplevel = gtk_widget_get_toplevel (widget);
605 if (!GTK_WIDGET_TOPLEVEL (toplevel))
608 return GTK_WINDOW (toplevel);
611 /* Shows an error dialog for the file chooser */
613 error_message (EggFileFormatChooser *impl,
617 error_message_with_parent (get_toplevel (GTK_WIDGET (impl)), msg, detail);
621 chooser_response_cb (GtkDialog *dialog,
625 EggFileFormatChooser *self;
626 gchar *filename, *basename;
630 self = EGG_FILE_FORMAT_CHOOSER (data);
632 if (EGG_IS_POSITIVE_RESPONSE (response_id))
634 filename = gtk_file_chooser_get_filename (self->priv->chooser);
635 basename = g_filename_display_basename (filename);
638 format = egg_file_format_chooser_get_format (self, basename);
639 g_print ("%s: %s - %d\n", G_STRFUNC, basename, format);
644 message = g_strdup_printf (
645 _("The program was not able to find out the file format "
646 "you want to use for `%s'. Please make sure to use a "
647 "known extension for that file or manually choose a "
648 "file format from the list below."),
652 _("File format not recognized"),
657 g_signal_stop_emission_by_name (dialog, "response");
661 filename = egg_file_format_chooser_append_extension (self, basename, format);
663 if (strcmp (filename, basename))
665 gtk_file_chooser_set_current_name (self->priv->chooser, filename);
666 g_signal_stop_emission_by_name (dialog, "response");
678 egg_file_format_chooser_realize (GtkWidget *widget)
680 EggFileFormatChooser *self;
683 GtkFileFilter *filter;
687 GTK_WIDGET_CLASS (egg_file_format_chooser_parent_class)->realize (widget);
689 self = EGG_FILE_FORMAT_CHOOSER (widget);
691 g_return_if_fail (NULL == self->priv->chooser);
693 parent = gtk_widget_get_toplevel (widget);
695 if (!GTK_IS_FILE_CHOOSER (parent))
696 parent = gtk_widget_get_parent (widget);
698 while (parent && !GTK_IS_FILE_CHOOSER (parent))
699 parent = gtk_widget_get_parent (parent);
701 self->priv->chooser = GTK_FILE_CHOOSER (parent);
703 g_return_if_fail (GTK_IS_FILE_CHOOSER (self->priv->chooser));
704 g_return_if_fail (gtk_file_chooser_get_action (self->priv->chooser) ==
705 GTK_FILE_CHOOSER_ACTION_SAVE);
707 g_object_ref (self->priv->chooser);
709 g_signal_connect (self->priv->chooser, "notify::filter",
710 G_CALLBACK (filter_changed_cb), self);
711 gtk_file_chooser_add_filter (self->priv->chooser, self->priv->all_files);
713 model = GTK_TREE_MODEL (self->priv->model);
715 if (gtk_tree_model_get_iter_first (model, &iter))
719 gtk_tree_model_get (model, &iter, MODEL_COLUMN_FILTER, &filter, -1);
720 gtk_file_chooser_add_filter (self->priv->chooser, filter);
721 g_object_unref (filter);
723 while (gtk_tree_model_iter_next (model, &iter));
726 gtk_file_chooser_set_filter (self->priv->chooser,
727 self->priv->supported_files);
729 if (GTK_IS_DIALOG (self->priv->chooser))
730 g_signal_connect (self->priv->chooser, "response",
731 G_CALLBACK (chooser_response_cb), self);
735 egg_file_format_chooser_unrealize (GtkWidget *widget)
737 EggFileFormatChooser *self;
739 GtkFileFilter *filter;
743 GTK_WIDGET_CLASS (egg_file_format_chooser_parent_class)->unrealize (widget);
745 self = EGG_FILE_FORMAT_CHOOSER (widget);
746 model = GTK_TREE_MODEL (self->priv->model);
748 g_signal_handlers_disconnect_by_func (self->priv->chooser,
749 filter_changed_cb, self);
750 g_signal_handlers_disconnect_by_func (self->priv->chooser,
751 chooser_response_cb, self);
753 if (gtk_tree_model_get_iter_first (model, &iter))
757 gtk_tree_model_get (model, &iter, MODEL_COLUMN_FILTER, &filter, -1);
758 gtk_file_chooser_remove_filter (self->priv->chooser, filter);
759 g_object_unref (filter);
761 while (gtk_tree_model_iter_next (model, &iter));
764 gtk_file_chooser_remove_filter (self->priv->chooser, self->priv->all_files);
765 g_object_unref (self->priv->chooser);
769 egg_file_format_chooser_class_init (EggFileFormatChooserClass *cls)
771 GObjectClass *object_class = G_OBJECT_CLASS (cls);
772 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (cls);
774 g_type_class_add_private (cls, sizeof (EggFileFormatChooserPrivate));
776 object_class->dispose = egg_file_format_chooser_dispose;
777 object_class->finalize = egg_file_format_chooser_finalize;
779 widget_class->realize = egg_file_format_chooser_realize;
780 widget_class->unrealize = egg_file_format_chooser_unrealize;
782 signals[SIGNAL_SELECTION_CHANGED] = g_signal_new (
783 "selection-changed", EGG_TYPE_FILE_FORMAT_CHOOSER, G_SIGNAL_RUN_FIRST,
784 G_STRUCT_OFFSET (EggFileFormatChooserClass, selection_changed),
785 NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
789 egg_file_format_chooser_new (void)
791 return g_object_new (EGG_TYPE_FILE_FORMAT_CHOOSER, NULL);
795 egg_file_format_chooser_add_format_impl (EggFileFormatChooser *self,
799 const gchar *extensions)
801 EggFileFormatSearch search;
802 GtkFileFilter *filter;
805 search.success = FALSE;
806 search.format = parent;
811 gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->model),
812 find_by_format, &search);
813 g_return_val_if_fail (search.success, -1);
816 filter = egg_file_format_filter_new (name, TRUE);
818 gtk_tree_store_append (self->priv->model, &iter,
819 parent > 0 ? &search.iter : NULL);
821 gtk_tree_store_set (self->priv->model, &iter,
822 MODEL_COLUMN_ID, ++self->priv->last_id,
823 MODEL_COLUMN_EXTENSIONS, extensions,
824 MODEL_COLUMN_FILTER, filter,
825 MODEL_COLUMN_NAME, name,
826 MODEL_COLUMN_ICON, icon,
832 gtk_tree_model_get (GTK_TREE_MODEL (self->priv->model), &search.iter,
833 MODEL_COLUMN_FILTER, &filter, -1);
835 egg_file_format_filter_add_extensions (self->priv->supported_files, extensions);
836 egg_file_format_filter_add_extensions (filter, extensions);
839 g_object_unref (filter);
842 return self->priv->last_id;
846 egg_file_format_chooser_add_format (EggFileFormatChooser *self,
852 GString *buffer = NULL;
857 g_return_val_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self), 0);
858 g_return_val_if_fail (NULL != name, 0);
860 va_start (extensions, icon);
862 while (NULL != (extptr = va_arg (extensions, const gchar*)))
865 buffer = g_string_new (NULL);
867 g_string_append (buffer, ", ");
869 g_string_append (buffer, extptr);
874 id = egg_file_format_chooser_add_format_impl (self, parent, name, icon,
875 buffer ? buffer->str : NULL);
878 g_string_free (buffer, TRUE);
884 get_icon_name (const gchar *mime_type)
886 static gboolean first_call = TRUE;
892 g_warning ("%s: Replace by g_content_type_get_icon "
893 "when GVFS is merged into GLib.", G_STRLOC);
899 name = g_strconcat ("gnome-mime-", mime_type, NULL);
901 for(s = name; *s; ++s)
903 if (!isalpha (*s) || !isascii (*s))
909 !gtk_icon_theme_has_icon (gtk_icon_theme_get_default (), name))
912 name = g_strdup ("gnome-mime-image");
919 egg_file_format_chooser_add_pixbuf_formats (EggFileFormatChooser *self,
920 guint parent G_GNUC_UNUSED,
923 GSList *pixbuf_formats = NULL;
927 g_return_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self));
929 pixbuf_formats = gdk_pixbuf_get_formats ();
932 *formats = g_new0 (guint, g_slist_length (pixbuf_formats) + 1);
934 for(iter = pixbuf_formats, i = 0; iter; iter = iter->next, ++i)
936 GdkPixbufFormat *format = iter->data;
938 gchar *description, *name, *extensions, *icon;
939 gchar **mime_types, **extension_list;
942 if (gdk_pixbuf_format_is_disabled (format) ||
943 !gdk_pixbuf_format_is_writable (format))
946 mime_types = gdk_pixbuf_format_get_mime_types (format);
947 icon = get_icon_name (mime_types[0]);
948 g_strfreev (mime_types);
950 extension_list = gdk_pixbuf_format_get_extensions (format);
951 extensions = g_strjoinv (", ", extension_list);
952 g_strfreev (extension_list);
954 description = gdk_pixbuf_format_get_description (format);
955 name = gdk_pixbuf_format_get_name (format);
957 id = egg_file_format_chooser_add_format_impl (self, parent, description,
960 g_free (description);
964 egg_file_format_chooser_set_format_data (self, id, name, g_free);
970 g_slist_free (pixbuf_formats);
974 egg_file_format_chooser_remove_format (EggFileFormatChooser *self,
977 GDestroyNotify destroy = NULL;
978 gpointer data = NULL;
980 EggFileFormatSearch search;
981 GtkFileFilter *filter;
984 g_return_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self));
986 search.success = FALSE;
987 search.format = format;
989 model = GTK_TREE_MODEL (self->priv->model);
990 gtk_tree_model_foreach (model, find_by_format, &search);
992 g_return_if_fail (search.success);
994 gtk_tree_model_get (model, &search.iter,
995 MODEL_COLUMN_FILTER, &filter,
996 MODEL_COLUMN_DESTROY, &destroy,
997 MODEL_COLUMN_DATA, &data,
1005 if (self->priv->chooser)
1006 gtk_file_chooser_remove_filter (self->priv->chooser, filter);
1008 g_object_unref (filter);
1011 g_warning ("TODO: Remove extensions from parent filter");
1013 gtk_tree_store_remove (self->priv->model, &search.iter);
1017 egg_file_format_chooser_set_format (EggFileFormatChooser *self,
1020 EggFileFormatSearch search;
1022 GtkTreeModel *model;
1026 g_return_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self));
1028 search.success = FALSE;
1029 search.format = format;
1031 model = GTK_TREE_MODEL (self->priv->model);
1032 gtk_tree_model_foreach (model, find_by_format, &search);
1034 g_return_if_fail (search.success);
1036 path = gtk_tree_model_get_path (model, &search.iter);
1037 view = gtk_tree_selection_get_tree_view (self->priv->selection);
1039 gtk_tree_view_expand_to_path (view, path);
1040 gtk_tree_selection_unselect_all (self->priv->selection);
1041 gtk_tree_selection_select_path (self->priv->selection, path);
1043 gtk_tree_path_free (path);
1045 if (self->priv->idle_hack > 0)
1047 g_source_remove (self->priv->idle_hack);
1048 self->priv->idle_hack = 0;
1053 egg_file_format_chooser_get_format (EggFileFormatChooser *self,
1054 const gchar *filename)
1056 GtkTreeModel *model;
1060 g_return_val_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self), -1);
1062 if (gtk_tree_selection_get_selected (self->priv->selection, &model, &iter))
1063 gtk_tree_model_get (model, &iter, MODEL_COLUMN_ID, &format, -1);
1065 if (0 == format && NULL != filename)
1067 EggFileFormatSearch search;
1069 search.extension = strrchr(filename, '.');
1070 search.success = FALSE;
1072 if (search.extension++)
1073 gtk_tree_model_foreach (model, find_by_extension, &search);
1075 format = search.format;
1082 egg_file_format_chooser_set_format_data (EggFileFormatChooser *self,
1085 GDestroyNotify destroy)
1087 EggFileFormatSearch search;
1089 g_return_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self));
1091 search.success = FALSE;
1092 search.format = format;
1094 gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->model),
1095 find_by_format, &search);
1097 g_return_if_fail (search.success);
1099 gtk_tree_store_set (self->priv->model, &search.iter,
1100 MODEL_COLUMN_DESTROY, destroy,
1101 MODEL_COLUMN_DATA, data,
1106 egg_file_format_chooser_get_format_data (EggFileFormatChooser *self,
1109 EggFileFormatSearch search;
1110 gpointer data = NULL;
1111 GtkTreeModel *model;
1113 g_return_val_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self), NULL);
1115 search.success = FALSE;
1116 search.format = format;
1118 model = GTK_TREE_MODEL (self->priv->model);
1119 gtk_tree_model_foreach (model, find_by_format, &search);
1121 g_return_val_if_fail (search.success, NULL);
1123 gtk_tree_model_get (model, &search.iter,
1124 MODEL_COLUMN_DATA, &data,
1130 egg_file_format_chooser_append_extension (EggFileFormatChooser *self,
1131 const gchar *filename,
1134 EggFileFormatSearch search;
1135 GtkTreeModel *model;
1141 g_return_val_if_fail (EGG_IS_FILE_FORMAT_CHOOSER (self), NULL);
1142 g_return_val_if_fail (NULL != filename, NULL);
1145 format = egg_file_format_chooser_get_format (self, NULL);
1149 g_warning ("%s: No file format selected. Cannot append extension.", __FUNCTION__);
1153 search.success = FALSE;
1154 search.format = format;
1156 model = GTK_TREE_MODEL (self->priv->model);
1157 gtk_tree_model_foreach (model, find_by_format, &search);
1159 g_return_val_if_fail (search.success, NULL);
1161 gtk_tree_model_get (model, &search.iter,
1162 MODEL_COLUMN_EXTENSIONS, &extensions,
1165 if (NULL == extensions &&
1166 gtk_tree_model_iter_nth_child (model, &child, &search.iter, 0))
1168 gtk_tree_model_get (model, &child,
1169 MODEL_COLUMN_EXTENSIONS, &extensions,
1173 if (NULL == extensions)
1175 g_warning ("%s: File format %d doesn't provide file extensions. "
1176 "Cannot append extension.", __FUNCTION__, format);
1180 if (accept_filename (extensions, filename))
1181 result = g_strdup (filename);
1183 result = g_strconcat (filename, ".", extensions, NULL);
1185 g_assert (NULL == strchr(extensions, ','));
1186 g_free (extensions);
1190 /* vim: set sw=2 sta et: */