1 /* vim: set sw=2 ts=2 sts=2 et: */
2 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 /*
4  * autoar-gtk-chooser.c
5  * GTK+ widgets to choose archive format and filter
6  *
7  * Copyright (C) 2013, 2014  Ting-Wei Lan
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this program; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA  02110-1301, USA.
23  *
24  */
25 
26 #include "config.h"
27 
28 #include "autoar-gtk-chooser.h"
29 
30 #include <glib.h>
31 #include <glib/gi18n.h>
32 #include <gtk/gtk.h>
33 
34 
35 /**
36  * SECTION:autoar-gtk-chooser
37  * @Short_description: GTK+ widgets to choose archive format and filter
38  * @Title: autoar-gtk-chooser
39  * @Include: gnome-autoar/autoar-gtk.h
40  *
41  * autoar-gtk-chooser contains two widgets for users to choose preferred
42  * archive format and filter.
43  **/
44 
45 /* autoar_gtk_chooser_simple */
46 
47 enum
48 {
49   SIMPLE_COL_FORMAT,
50   SIMPLE_COL_FILTER,
51   SIMPLE_COL_DESCRIPTION,
52   N_SIMPLE_COLS
53 };
54 
55 static char*
format_filter_full_description(AutoarFormat format,AutoarFilter filter)56 format_filter_full_description (AutoarFormat format,
57                                 AutoarFilter filter)
58 {
59   char *description, *extension, *full_description;
60 
61   description = autoar_format_filter_get_description (format, filter);
62   extension = autoar_format_filter_get_extension (format, filter);
63   full_description = g_strdup_printf ("%s (*%s)", description, extension);
64 
65   g_free (description);
66   g_free (extension);
67 
68   return full_description;
69 }
70 
71 static gboolean
simple_row_separator_cb(GtkTreeModel * model,GtkTreeIter * iter,void * data)72 simple_row_separator_cb (GtkTreeModel *model,
73                          GtkTreeIter *iter,
74                          void *data)
75 {
76   char *description, first_char;
77 
78   gtk_tree_model_get (model, iter, SIMPLE_COL_DESCRIPTION, &description, -1);
79   first_char = description != NULL ? *description : '\0';
80   g_free (description);
81 
82   if (first_char == '\0')
83     return TRUE;
84   else
85     return FALSE;
86 }
87 
88 static void
simple_get_variable_row(GtkTreeModel * model,GtkTreeIter * base_iter,GtkTreeIter * dest_iter)89 simple_get_variable_row (GtkTreeModel *model,
90                          GtkTreeIter *base_iter,
91                          GtkTreeIter *dest_iter)
92 {
93   GtkTreeIter iter;
94 
95   iter = *base_iter;
96   if (!gtk_tree_model_iter_previous (model, &iter) ||
97       !gtk_tree_model_iter_previous (model, &iter) ||
98       !simple_row_separator_cb (model, &iter, NULL)) {
99     /* Create two new rows if it does not exist */
100     GtkListStore *store;
101 
102     store = GTK_LIST_STORE (model);
103     gtk_list_store_insert_before (store, dest_iter, base_iter);
104     gtk_list_store_insert_before (store, &iter, dest_iter);
105     gtk_list_store_set (store, &iter,
106                         SIMPLE_COL_FORMAT, 0,
107                         SIMPLE_COL_FILTER, 0,
108                         SIMPLE_COL_DESCRIPTION, "", -1);
109   } else {
110     /* Use the existing row */
111 
112     iter = *base_iter;
113     gtk_tree_model_iter_previous (model, &iter);
114     *dest_iter = iter;
115   }
116 }
117 
118 static void
simple_set_active(GtkComboBox * simple,GtkTreeModel * model,AutoarFormat format,AutoarFilter filter)119 simple_set_active (GtkComboBox *simple,
120                    GtkTreeModel *model,
121                    AutoarFormat format,
122                    AutoarFilter filter)
123 {
124   GtkTreeIter iter, prev;
125   AutoarFormat this_format;
126   AutoarFilter this_filter;
127   int get_format, get_filter;
128   int *previous;
129 
130   previous = g_object_get_data ((GObject*)simple, "previous");
131   if (autoar_format_is_valid (format) && autoar_filter_is_valid (filter)) {
132     gtk_tree_model_get_iter_first (model, &iter);
133     do {
134       gtk_tree_model_get (model, &iter,
135                           SIMPLE_COL_FORMAT, &this_format,
136                           SIMPLE_COL_FILTER, &this_filter, -1);
137       if (this_format == format && this_filter == filter) {
138         gtk_combo_box_set_active_iter (simple, &iter);
139         previous[0] = format;
140         previous[1] = filter;
141         return;
142       }
143       prev = iter;
144     } while (gtk_tree_model_iter_next (model, &iter));
145 
146     if (gtk_tree_model_iter_previous (model, &prev)) {
147       GtkTreeIter active;
148       char *description_string;
149 
150       simple_get_variable_row (model, &prev, &active);
151       description_string = format_filter_full_description (format, filter);
152       gtk_list_store_set (GTK_LIST_STORE (model), &active,
153                           SIMPLE_COL_FORMAT, format,
154                           SIMPLE_COL_FILTER, filter,
155                           SIMPLE_COL_DESCRIPTION, description_string, -1);
156       g_free (description_string);
157 
158       gtk_combo_box_set_active_iter (simple, &active);
159       previous[0] = format;
160       previous[1] = filter;
161       return;
162     }
163   }
164 
165   gtk_tree_model_get_iter_first (model, &iter);
166   gtk_combo_box_set_active_iter (simple, &iter);
167   gtk_tree_model_get (model, &iter,
168                       SIMPLE_COL_FORMAT, &get_format,
169                       SIMPLE_COL_FILTER, &get_filter, -1);
170   previous[0] = format;
171   previous[1] = filter;
172 }
173 
174 static void
simple_changed_cb(GtkComboBox * simple,void * data)175 simple_changed_cb (GtkComboBox *simple,
176                    void *data) {
177   GtkTreeIter iter;
178   GtkTreeModel* model;
179   int format, filter;
180   int *previous;
181 
182   if (!gtk_combo_box_get_active_iter (simple, &iter))
183     return;
184 
185   model = gtk_combo_box_get_model (simple);
186   gtk_tree_model_get (model, &iter,
187                       SIMPLE_COL_FORMAT, &format,
188                       SIMPLE_COL_FILTER, &filter, -1);
189 
190   previous = g_object_get_data ((GObject*)simple, "previous");
191 
192   if (!format) {
193     GtkWidget *dialog_widget;
194     GtkDialog *dialog;
195     GtkWidget *dialog_content;
196 
197     GtkWidget *simple_widget;
198     GtkWidget *advanced_widget;
199     int response;
200 
201     simple_widget = GTK_WIDGET (simple);
202     dialog_widget =
203       gtk_dialog_new_with_buttons (
204         _("Choose an archive format"),
205         GTK_WINDOW (gtk_widget_get_ancestor (simple_widget, GTK_TYPE_WINDOW)),
206         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
207         _("Cancel"), GTK_RESPONSE_CANCEL,
208         _("OK"), GTK_RESPONSE_ACCEPT, NULL);
209     dialog = GTK_DIALOG (dialog_widget);
210     gtk_dialog_set_default_response (dialog, GTK_RESPONSE_ACCEPT);
211 
212     dialog_content = gtk_dialog_get_content_area (dialog);
213     advanced_widget = autoar_gtk_chooser_advanced_new (previous[0],
214                                                              previous[1]);
215     gtk_container_add (GTK_CONTAINER (dialog_content), advanced_widget);
216     gtk_widget_show_all (dialog_widget);
217 
218     response = gtk_dialog_run (dialog);
219     if (response == GTK_RESPONSE_ACCEPT &&
220         gtk_tree_model_iter_previous (model, &iter) &&
221         autoar_gtk_chooser_advanced_get (advanced_widget, &format, &filter))
222       simple_set_active (simple, model, format, filter);
223     else
224       simple_set_active (simple, model, previous[0], previous[1]);
225 
226     gtk_widget_destroy (dialog_widget);
227   } else {
228     previous[0] = format;
229     previous[1] = filter;
230   }
231 }
232 
233 /**
234  * autoar_gtk_chooser_simple_new:
235  * @default_format: an #AutoarFormat
236  * @default_filter: an #AutoarFilter
237  *
238  * Create a #GtkComboBox with a list of common archive format. There is also
239  * an option called "Other format…", which will use
240  * autoar_gtk_chooser_advanced_new() and
241  * autoar_gtk_chooser_advanced_get() to select less common archive
242  * format. Arguments @default_format and @default_filter are the default archive
243  * format selected on the returned widget. You may want to get the preferred
244  * format of users using autoar_pref_get_default_format() and
245  * autoar_pref_get_default_filter(), or just set them to 1 to select
246  * the default archive format.
247  *
248  * Returns: (transfer full): a new #GtkComboBox widget
249  **/
250 GtkWidget*
autoar_gtk_chooser_simple_new(AutoarFormat default_format,AutoarFilter default_filter)251 autoar_gtk_chooser_simple_new (AutoarFormat default_format,
252                                AutoarFilter default_filter)
253 {
254   GtkWidget *simple_widget;
255   GtkComboBox *simple_combo;
256   GtkCellLayout *simple;
257   GtkCellRenderer *cell_renderer;
258 
259   GtkTreeModel *model;
260   GtkListStore *store;
261   GtkTreeIter iter;
262   int i;
263 
264   int *previous;
265 
266   struct format_filter
267   {
268     AutoarFormat format;
269     AutoarFilter filter;
270   };
271 
272   struct format_filter defaults [] = {
273     { AUTOAR_FORMAT_ZIP,   AUTOAR_FILTER_NONE  },
274     { AUTOAR_FORMAT_TAR,   AUTOAR_FILTER_NONE  },
275     { AUTOAR_FORMAT_TAR,   AUTOAR_FILTER_GZIP  },
276     { AUTOAR_FORMAT_TAR,   AUTOAR_FILTER_BZIP2 },
277     { AUTOAR_FORMAT_TAR,   AUTOAR_FILTER_XZ    },
278     { AUTOAR_FORMAT_CPIO,  AUTOAR_FILTER_NONE  },
279     { AUTOAR_FORMAT_7ZIP,  AUTOAR_FILTER_NONE  },
280   };
281 
282   store = gtk_list_store_new (N_SIMPLE_COLS, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING);
283   model = GTK_TREE_MODEL (store);
284   for (i = 0; i < sizeof (defaults) / sizeof (struct format_filter); i++) {
285     char *description;
286 
287     gtk_list_store_append (store, &iter);
288 
289     description = format_filter_full_description (defaults[i].format,
290                                                   defaults[i].filter);
291     gtk_list_store_set (store, &iter,
292                         SIMPLE_COL_FORMAT, defaults[i].format,
293                         SIMPLE_COL_FILTER, defaults[i].filter,
294                         SIMPLE_COL_DESCRIPTION, description, -1);
295     g_free (description);
296   }
297 
298   gtk_list_store_append (store, &iter);
299   gtk_list_store_set (store, &iter,
300                       SIMPLE_COL_FORMAT, 0,
301                       SIMPLE_COL_FILTER, 0,
302                       SIMPLE_COL_DESCRIPTION, "", -1);
303 
304   gtk_list_store_append (store, &iter);
305   gtk_list_store_set (store, &iter,
306                       SIMPLE_COL_FORMAT, 0,
307                       SIMPLE_COL_FILTER, 0,
308                       SIMPLE_COL_DESCRIPTION, _("Other format…"), -1);
309 
310   simple_widget = gtk_combo_box_new_with_model (model);
311   simple = GTK_CELL_LAYOUT (simple_widget);
312   simple_combo = GTK_COMBO_BOX (simple_widget);
313   cell_renderer = gtk_cell_renderer_text_new ();
314 
315   gtk_cell_layout_pack_start (simple, cell_renderer, FALSE);
316   gtk_cell_layout_add_attribute (simple, cell_renderer, "text", SIMPLE_COL_DESCRIPTION);
317 
318   previous = g_new (int, 2);
319   g_object_set_data_full ((GObject*)simple, "previous", previous, g_free);
320   simple_set_active (simple_combo, model, default_format, default_filter);
321 
322   gtk_combo_box_set_row_separator_func (simple_combo, simple_row_separator_cb, NULL, NULL);
323   g_signal_connect (simple, "changed", G_CALLBACK (simple_changed_cb), NULL);
324 
325   g_object_unref (store);
326 
327   return simple_widget;
328 }
329 
330 /**
331  * autoar_gtk_chooser_simple_get:
332  * @simple: a #GtkComboBox returned by autoar_gtk_chooser_simple_new()
333  * @format: the place to store the #AutoarFormat selected by the user
334  * @filter: the place to store the #AutoarFilter selected by the user
335  *
336  * Gets the selected archive format of the widget created by
337  * autoar_gtk_chooser_simple_new().
338  *
339  * Returns: %TRUE if @format and @filter are set. %FALSE if there is no
340  * selected item on @simple, so @format and @filter are not modified.
341  **/
342 gboolean
autoar_gtk_chooser_simple_get(GtkWidget * simple,int * format,int * filter)343 autoar_gtk_chooser_simple_get (GtkWidget *simple,
344                                int *format,
345                                int *filter)
346 {
347   GtkComboBox *combo;
348   GtkTreeModel *model;
349   GtkTreeIter iter;
350 
351   if (!gtk_combo_box_get_active_iter (combo = GTK_COMBO_BOX (simple), &iter))
352     return FALSE;
353 
354   model = gtk_combo_box_get_model (combo);
355   gtk_tree_model_get (model, &iter,
356                       SIMPLE_COL_FORMAT, format,
357                       SIMPLE_COL_FILTER, filter, -1);
358   return TRUE;
359 }
360 
361 
362 /* autoar_gtk_chooser_advanced */
363 
364 enum
365 {
366   ADVANCED_FORMAT_COL_FORMAT,
367   ADVANCED_FORMAT_COL_DESCRIPTION,
368   N_ADVANCED_FORMAT_COLS
369 };
370 
371 enum
372 {
373   ADVANCED_FILTER_COL_FILTER,
374   ADVANCED_FILTER_COL_DESCRIPTION,
375   N_ADVANCED_FILTER_COLS
376 };
377 
378 static void
advanced_update_description_cb(GtkTreeView * unused_variable,GtkWidget * advanced)379 advanced_update_description_cb (GtkTreeView *unused_variable,
380                                 GtkWidget *advanced)
381 {
382   int format;
383   int filter;
384   GtkLabel *description;
385   char *description_string;
386 
387   if (!autoar_gtk_chooser_advanced_get (advanced, &format, &filter))
388     return;
389 
390   description = GTK_LABEL (gtk_grid_get_child_at (GTK_GRID (advanced), 0, 1));
391   description_string = format_filter_full_description (format, filter);
392   gtk_label_set_text (description, description_string);
393   g_free (description_string);
394 }
395 
396 static GtkTreeModel*
advanced_format_store(void)397 advanced_format_store (void)
398 {
399   GtkListStore *store;
400   int i, last;
401 
402   store = gtk_list_store_new (N_ADVANCED_FORMAT_COLS, G_TYPE_INT, G_TYPE_STRING);
403   last = autoar_format_last ();
404   for (i = 1; i < last; i++) {
405     GtkTreeIter iter;
406     const char *description;
407 
408     gtk_list_store_append (store, &iter);
409     description = autoar_format_get_description (i);
410     gtk_list_store_set (store, &iter,
411                         ADVANCED_FORMAT_COL_FORMAT, i,
412                         ADVANCED_FORMAT_COL_DESCRIPTION, description, -1);
413   }
414 
415   return GTK_TREE_MODEL (store);
416 }
417 
418 static GtkTreeModel*
advanced_filter_store(void)419 advanced_filter_store (void)
420 {
421   GtkListStore *store;
422   int i, last;
423 
424   store = gtk_list_store_new (N_ADVANCED_FILTER_COLS, G_TYPE_INT, G_TYPE_STRING);
425   last = autoar_filter_last ();
426   for (i = 1; i < last; i++) {
427     GtkTreeIter iter;
428     const char *description;
429 
430     gtk_list_store_append (store, &iter);
431     description = autoar_filter_get_description (i);
432     gtk_list_store_set (store, &iter,
433                         ADVANCED_FILTER_COL_FILTER, i,
434                         ADVANCED_FILTER_COL_DESCRIPTION, description, -1);
435   }
436 
437   return GTK_TREE_MODEL (store);
438 }
439 
440 /**
441  * autoar_gtk_chooser_advanced_new:
442  * @default_format: an #AutoarFormat
443  * @default_filter: an #AutoarFilter
444  *
445  * Create a #GtkGrid with two lists. One list shows all available formats,
446  * and the other list shows all available filters.
447  *
448  * Returns: (transfer full): a new #GtkGrid widget
449  **/
450 GtkWidget*
autoar_gtk_chooser_advanced_new(AutoarFormat default_format,AutoarFilter default_filter)451 autoar_gtk_chooser_advanced_new (AutoarFormat default_format,
452                                  AutoarFilter default_filter)
453 {
454   GtkWidget *advanced_widget;
455   GtkGrid *advanced;
456 
457   GtkTreeModel *format_model;
458   GtkWidget *format_widget;
459   GtkTreeView *format;
460   GtkTreeSelection *format_selection;
461   GtkCellRenderer *format_renderer;
462   GtkTreePath *format_path;
463 
464   GtkTreeModel *filter_model;
465   GtkWidget *filter_widget;
466   GtkTreeView *filter;
467   GtkTreeSelection *filter_selection;
468   GtkCellRenderer *filter_renderer;
469   GtkTreePath *filter_path;
470 
471   GtkWidget *description_widget;
472   GtkLabel *description;
473 
474   advanced_widget = gtk_grid_new ();
475   advanced = GTK_GRID (advanced_widget);
476   gtk_grid_set_row_spacing (advanced, 5);
477   gtk_grid_set_column_spacing (advanced, 5);
478   gtk_grid_set_column_homogeneous (advanced, TRUE);
479 
480   format_model = advanced_format_store ();
481   format_widget = gtk_tree_view_new_with_model (format_model);
482   format = GTK_TREE_VIEW (format_widget);
483   format_selection = gtk_tree_view_get_selection (format);
484   format_renderer = gtk_cell_renderer_text_new ();
485   gtk_tree_selection_set_mode (format_selection, GTK_SELECTION_SINGLE);
486   gtk_tree_view_insert_column_with_attributes (format, -1, _("Format"),
487                                                format_renderer, "text",
488                                                ADVANCED_FORMAT_COL_DESCRIPTION,
489                                                NULL);
490   if (autoar_format_is_valid (default_format)) {
491     GtkTreeIter iter;
492     gboolean valid;
493     format_path = NULL;
494     for (valid = gtk_tree_model_get_iter_first (format_model, &iter);
495          valid;
496          valid = gtk_tree_model_iter_next (format_model, &iter)) {
497       int get_format;
498       gtk_tree_model_get (format_model, &iter,
499                           ADVANCED_FORMAT_COL_FORMAT, &get_format, -1);
500       if (default_format == get_format) {
501         format_path = gtk_tree_model_get_path (format_model, &iter);
502         break;
503       }
504     }
505     if (format_path == NULL)
506       format_path = gtk_tree_path_new_first ();
507   } else {
508     format_path = gtk_tree_path_new_first ();
509   }
510   gtk_tree_view_set_cursor (format, format_path, NULL, FALSE);
511   gtk_tree_path_free (format_path);
512   gtk_grid_attach (advanced, format_widget, 0, 0, 1, 1);
513   g_object_unref (format_model);
514 
515   filter_model = advanced_filter_store ();
516   filter_widget = gtk_tree_view_new_with_model (filter_model);
517   filter = GTK_TREE_VIEW (filter_widget);
518   filter_selection = gtk_tree_view_get_selection (filter);
519   filter_renderer = gtk_cell_renderer_text_new ();
520   gtk_tree_selection_set_mode (filter_selection, GTK_SELECTION_SINGLE);
521   gtk_tree_view_insert_column_with_attributes (filter, -1, _("Filter"),
522                                                filter_renderer, "text",
523                                                ADVANCED_FILTER_COL_DESCRIPTION,
524                                                NULL);
525   if (autoar_filter_is_valid (default_filter)) {
526     GtkTreeIter iter;
527     gboolean valid;
528     filter_path = NULL;
529     for (valid = gtk_tree_model_get_iter_first (filter_model, &iter);
530          valid;
531          valid = gtk_tree_model_iter_next (filter_model, &iter)) {
532       int get_filter;
533       gtk_tree_model_get (filter_model, &iter,
534                           ADVANCED_FILTER_COL_FILTER, &get_filter, -1);
535       if (default_filter == get_filter) {
536         filter_path = gtk_tree_model_get_path (filter_model, &iter);
537         break;
538       }
539     }
540     if (filter_path == NULL)
541       filter_path = gtk_tree_path_new_first ();
542   } else {
543     filter_path = gtk_tree_path_new_first ();
544   }
545   gtk_tree_view_set_cursor (filter, filter_path, NULL, FALSE);
546   gtk_tree_path_free (filter_path);
547   gtk_grid_attach (advanced, filter_widget, 1, 0, 1, 1);
548   g_object_unref (filter_model);
549 
550   description_widget = gtk_label_new (NULL);
551   description = GTK_LABEL (description_widget);
552   gtk_label_set_justify (description, GTK_JUSTIFY_CENTER);
553   gtk_grid_attach (advanced, description_widget, 0, 1, 2, 1);
554 
555   g_signal_connect (format_widget, "cursor-changed",
556                     G_CALLBACK (advanced_update_description_cb), advanced);
557   g_signal_connect (filter_widget, "cursor-changed",
558                     G_CALLBACK (advanced_update_description_cb), advanced);
559 
560   /* Run the callback now to set the initial text on the label */
561   advanced_update_description_cb (NULL, advanced_widget);
562 
563   return advanced_widget;
564 }
565 
566 /**
567  * autoar_gtk_chooser_advanced_get:
568  * @advanced: a #GtkGrid returned by autoar_gtk_chooser_advanced_new()
569  * @format: the place to store the #AutoarFormat selected by the user
570  * @filter: the place to store the #AutoarFilter selected by the user
571  *
572  * Gets the selected archive format of the widget created by
573  * autoar_gtk_chooser_advanced_new().
574  *
575  * Returns: %TRUE if @format and @filter are set. %FALSE if there is no
576  * selected item on @advanced, so @format and @filter are not modified.
577  **/
578 gboolean
autoar_gtk_chooser_advanced_get(GtkWidget * advanced,int * format,int * filter)579 autoar_gtk_chooser_advanced_get (GtkWidget *advanced,
580                                  int *format,
581                                  int *filter)
582 {
583   GtkGrid *grid;
584   GtkTreeIter format_iter, filter_iter;
585   GtkTreeView *format_view, *filter_view;
586   GtkTreePath *format_path, *filter_path;
587   GtkTreeModel *format_model, *filter_model;
588 
589   grid = GTK_GRID (advanced);
590   format_view = GTK_TREE_VIEW (gtk_grid_get_child_at (grid, 0, 0));
591   filter_view = GTK_TREE_VIEW (gtk_grid_get_child_at (grid, 1, 0));
592 
593   gtk_tree_view_get_cursor (format_view, &format_path, NULL);
594   gtk_tree_view_get_cursor (filter_view, &filter_path, NULL);
595   if (format_path == NULL || filter_path == NULL) {
596     gtk_tree_path_free (format_path);
597     gtk_tree_path_free (filter_path);
598     return FALSE;
599   }
600 
601   format_model = gtk_tree_view_get_model (format_view);
602   filter_model = gtk_tree_view_get_model (filter_view);
603   if (!gtk_tree_model_get_iter (format_model, &format_iter, format_path) ||
604       !gtk_tree_model_get_iter (filter_model, &filter_iter, filter_path)) {
605     gtk_tree_path_free (format_path);
606     gtk_tree_path_free (filter_path);
607     return FALSE;
608   }
609   gtk_tree_path_free (format_path);
610   gtk_tree_path_free (filter_path);
611 
612   gtk_tree_model_get (format_model, &format_iter,
613                       ADVANCED_FORMAT_COL_FORMAT, format, -1);
614   gtk_tree_model_get (filter_model, &filter_iter,
615                       ADVANCED_FILTER_COL_FILTER, filter, -1);
616 
617   return TRUE;
618 }
619