715 lines
21 KiB
C
715 lines
21 KiB
C
/*
|
|
* mooedit/mooeditfilemgr.c
|
|
*
|
|
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* See COPYING file that comes with this distribution.
|
|
*/
|
|
|
|
#include "mooedit/mooeditfilemgr.h"
|
|
#include "mooedit/mooeditprefs.h"
|
|
#include "mooutils/moodialogs.h"
|
|
#include <string.h>
|
|
|
|
#define PREFS_FILTERS "filters"
|
|
#define PREFS_LAST_FILTER PREFS_FILTERS "/last"
|
|
#define PREFS_USER "user"
|
|
#define NUM_USER_FILTERS 3
|
|
|
|
|
|
typedef struct {
|
|
MooEditFileInfo *info;
|
|
} RecentEntry;
|
|
|
|
static RecentEntry *recent_entry_new (const char *filename);
|
|
static RecentEntry *recent_entry_copy (RecentEntry *entry);
|
|
static void recent_entry_free (RecentEntry *entry);
|
|
|
|
|
|
typedef struct {
|
|
GtkFileFilter *filter;
|
|
GtkFileFilter *aux;
|
|
char *description;
|
|
char *glob;
|
|
} Filter;
|
|
|
|
static Filter *filter_new (const char *description,
|
|
const char *glob);
|
|
static void filter_free (Filter *filter);
|
|
|
|
static GtkFileFilter *filter_get_gtk_filter (Filter *filter);
|
|
static const char *filter_get_glob (Filter *filter);
|
|
static const char *filter_get_description (Filter *filter);
|
|
|
|
|
|
struct _MooEditFileMgrPrivate {
|
|
GSList *recent_files; /* RecentEntry* */
|
|
GtkListStore *filters;
|
|
Filter *last_filter;
|
|
Filter *null_filter;
|
|
guint num_user_filters;
|
|
};
|
|
|
|
enum {
|
|
COLUMN_DESCRIPTION,
|
|
COLUMN_FILTER,
|
|
NUM_COLUMNS
|
|
};
|
|
|
|
|
|
static void moo_edit_file_mgr_class_init (MooEditFileMgrClass *klass);
|
|
static void moo_edit_file_mgr_init (MooEditFileMgr *mgr);
|
|
static void moo_edit_file_mgr_finalize (GObject *object);
|
|
|
|
static void mgr_load_filter_prefs (MooEditFileMgr *mgr);
|
|
static void mgr_save_filter_prefs (MooEditFileMgr *mgr);
|
|
static Filter *mgr_new_user_filter (MooEditFileMgr *mgr,
|
|
const char *glob);
|
|
static void mgr_set_last_filter (MooEditFileMgr *mgr,
|
|
Filter *filter);
|
|
static Filter *mgr_get_last_filter (MooEditFileMgr *mgr);
|
|
static Filter *mgr_get_null_filter (MooEditFileMgr *mgr);
|
|
static void mgr_set_filter (MooEditFileMgr *mgr,
|
|
GtkFileChooser *dialog,
|
|
Filter *filter);
|
|
static void list_store_init (MooEditFileMgr *mgr);
|
|
static void list_store_destroy (MooEditFileMgr *mgr);
|
|
static void list_store_append_filter (MooEditFileMgr *mgr,
|
|
Filter *filter);
|
|
static Filter *list_store_find_filter (MooEditFileMgr *mgr,
|
|
const char *text);
|
|
static void list_store_add_user (MooEditFileMgr *mgr,
|
|
Filter *filter);
|
|
|
|
|
|
/* MOO_TYPE_EDIT_FILE_MGR */
|
|
G_DEFINE_TYPE (MooEditFileMgr, moo_edit_file_mgr, G_TYPE_OBJECT)
|
|
|
|
|
|
static void moo_edit_file_mgr_class_init (MooEditFileMgrClass *klass)
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
gobject_class->finalize = moo_edit_file_mgr_finalize;
|
|
}
|
|
|
|
|
|
static void moo_edit_file_mgr_init (MooEditFileMgr *mgr)
|
|
{
|
|
mgr->priv = g_new0 (MooEditFileMgrPrivate, 1);
|
|
list_store_init (mgr);
|
|
}
|
|
|
|
|
|
static void moo_edit_file_mgr_finalize (GObject *object)
|
|
{
|
|
MooEditFileMgr *mgr = MOO_EDIT_FILE_MGR (object);
|
|
list_store_destroy (mgr);
|
|
G_OBJECT_CLASS (moo_edit_file_mgr_parent_class)->finalize (object);
|
|
}
|
|
|
|
|
|
MooEditFileMgr *moo_edit_file_mgr_new (void)
|
|
{
|
|
return MOO_EDIT_FILE_MGR (g_object_new (MOO_TYPE_EDIT_FILE_MGR, NULL));
|
|
}
|
|
|
|
|
|
static gboolean row_is_separator (GtkTreeModel *model,
|
|
GtkTreeIter *iter,
|
|
G_GNUC_UNUSED gpointer data)
|
|
{
|
|
Filter *filter;
|
|
gtk_tree_model_get (model, iter, COLUMN_FILTER, &filter, -1);
|
|
return filter == NULL;
|
|
}
|
|
|
|
|
|
static void filter_entry_activated (GtkEntry *entry,
|
|
GtkFileChooser *dialog);
|
|
static void combo_changed (GtkComboBox *combo,
|
|
GtkFileChooser *dialog);
|
|
|
|
static void setup_open_dialog (MooEditFileMgr *mgr,
|
|
GtkWidget *dialog)
|
|
{
|
|
GtkWidget *alignment;
|
|
GtkWidget *hbox;
|
|
GtkWidget *label;
|
|
GtkWidget *combo;
|
|
GtkWidget *entry;
|
|
Filter *filter;
|
|
|
|
alignment = gtk_alignment_new (1, 0.5, 0, 1);
|
|
gtk_widget_show (alignment);
|
|
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), alignment);
|
|
|
|
hbox = gtk_hbox_new (FALSE, 0);
|
|
gtk_widget_show (hbox);
|
|
gtk_container_add (GTK_CONTAINER (alignment), hbox);
|
|
|
|
label = gtk_label_new ("Filter:");
|
|
gtk_widget_show (label);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
|
|
combo = gtk_combo_box_entry_new_with_model (GTK_TREE_MODEL (mgr->priv->filters),
|
|
COLUMN_DESCRIPTION);
|
|
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
|
|
row_is_separator,
|
|
NULL, NULL);
|
|
gtk_widget_show (combo);
|
|
gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
|
|
|
|
entry = GTK_WIDGET (GTK_BIN(combo)->child);
|
|
|
|
g_signal_connect (entry, "activate",
|
|
G_CALLBACK (filter_entry_activated),
|
|
dialog);
|
|
g_signal_connect (combo, "changed",
|
|
G_CALLBACK (combo_changed),
|
|
dialog);
|
|
|
|
g_object_set_data (G_OBJECT (dialog), "filter-combo", combo);
|
|
g_object_set_data (G_OBJECT (dialog), "filter-entry", entry);
|
|
g_object_set_data (G_OBJECT (dialog), "file-mgr", mgr);
|
|
|
|
filter = mgr_get_last_filter (mgr);
|
|
|
|
if (filter)
|
|
mgr_set_filter (mgr, GTK_FILE_CHOOSER (dialog), filter);
|
|
}
|
|
|
|
|
|
MooEditFileInfo *moo_edit_file_mgr_open_dialog (MooEditFileMgr *mgr,
|
|
GtkWidget *parent)
|
|
{
|
|
const char *filename;
|
|
const char *title = "Open File";
|
|
const char *start = NULL;
|
|
MooEditFileInfo *file = NULL;
|
|
GtkWidget *dialog;
|
|
|
|
g_return_val_if_fail (MOO_IS_EDIT_FILE_MGR (mgr), NULL);
|
|
|
|
start = moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_DIALOGS_OPEN));
|
|
|
|
dialog = moo_file_dialog_create (parent, MOO_DIALOG_FILE_OPEN_EXISTING,
|
|
title, start);
|
|
|
|
setup_open_dialog (mgr, dialog);
|
|
moo_file_dialog_run (dialog);
|
|
|
|
filename = moo_file_dialog_get_filename (dialog);
|
|
|
|
if (filename)
|
|
{
|
|
char *new_start = g_path_get_dirname (filename);
|
|
moo_prefs_set_string (moo_edit_setting (MOO_EDIT_PREFS_DIALOGS_OPEN), new_start);
|
|
g_free (new_start);
|
|
file = moo_edit_file_info_new (filename, NULL);
|
|
}
|
|
|
|
gtk_widget_destroy (dialog);
|
|
return file;
|
|
}
|
|
|
|
|
|
MooEditFileInfo *moo_edit_file_mgr_save_as_dialog (G_GNUC_UNUSED MooEditFileMgr *mgr,
|
|
MooEdit *edit)
|
|
{
|
|
const char *title = "Save File";
|
|
const char *start = NULL;
|
|
const char *filename = NULL;
|
|
MooEditFileInfo *file = NULL;
|
|
GtkWidget *dialog;
|
|
|
|
start = moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_DIALOGS_SAVE));
|
|
if (!start)
|
|
start = moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_DIALOGS_OPEN));
|
|
|
|
dialog = moo_file_dialog_create (GTK_WIDGET (edit), MOO_DIALOG_FILE_SAVE,
|
|
title, start);
|
|
|
|
moo_file_dialog_run (dialog);
|
|
|
|
filename = moo_file_dialog_get_filename (dialog);
|
|
|
|
if (filename)
|
|
{
|
|
char *new_start = g_path_get_dirname (filename);
|
|
moo_prefs_set_string (moo_edit_setting (MOO_EDIT_PREFS_DIALOGS_SAVE), new_start);
|
|
g_free (new_start);
|
|
file = moo_edit_file_info_new (filename, NULL);
|
|
}
|
|
|
|
gtk_widget_destroy (dialog);
|
|
return file;
|
|
}
|
|
|
|
|
|
static Filter *mgr_get_null_filter (MooEditFileMgr *mgr)
|
|
{
|
|
if (!mgr->priv->null_filter)
|
|
{
|
|
Filter *filter = filter_new ("All Files", "*");
|
|
list_store_append_filter (mgr, filter);
|
|
mgr->priv->null_filter = filter;
|
|
}
|
|
return mgr->priv->null_filter;
|
|
}
|
|
|
|
static Filter *mgr_get_last_filter (MooEditFileMgr *mgr)
|
|
{
|
|
mgr_load_filter_prefs (mgr);
|
|
if (!mgr->priv->last_filter)
|
|
mgr->priv->last_filter = mgr_get_null_filter (mgr);
|
|
return mgr->priv->last_filter;
|
|
}
|
|
|
|
|
|
static void list_store_init (MooEditFileMgr *mgr)
|
|
{
|
|
mgr->priv->filters = gtk_list_store_new (NUM_COLUMNS,
|
|
G_TYPE_STRING,
|
|
G_TYPE_POINTER);
|
|
mgr_get_null_filter (mgr);
|
|
}
|
|
|
|
|
|
static gboolean filter_free_func (GtkTreeModel *model,
|
|
G_GNUC_UNUSED GtkTreePath *path,
|
|
GtkTreeIter *iter,
|
|
G_GNUC_UNUSED gpointer data)
|
|
{
|
|
Filter *filter;
|
|
gtk_tree_model_get (model, iter, COLUMN_FILTER, &filter, -1);
|
|
if (filter)
|
|
filter_free (filter);
|
|
return FALSE;
|
|
}
|
|
|
|
static void list_store_destroy (MooEditFileMgr *mgr)
|
|
{
|
|
gtk_tree_model_foreach (GTK_TREE_MODEL (mgr->priv->filters),
|
|
filter_free_func, NULL);
|
|
g_object_unref (mgr->priv->filters);
|
|
mgr->priv->filters = NULL;
|
|
mgr->priv->last_filter = NULL;
|
|
mgr->priv->null_filter = NULL;
|
|
}
|
|
|
|
|
|
static void list_store_append_filter (MooEditFileMgr *mgr,
|
|
Filter *filter)
|
|
{
|
|
GtkTreeIter iter;
|
|
gtk_list_store_append (mgr->priv->filters, &iter);
|
|
if (filter)
|
|
gtk_list_store_set (mgr->priv->filters, &iter,
|
|
COLUMN_DESCRIPTION, filter_get_description (filter),
|
|
COLUMN_FILTER, filter, -1);
|
|
}
|
|
|
|
|
|
#define NEGATE_CHAR '!'
|
|
#define GLOB_SEPARATOR ";"
|
|
|
|
static gboolean neg_filter_func (const GtkFileFilterInfo *filter_info,
|
|
Filter *filter)
|
|
{
|
|
return !gtk_file_filter_filter (filter->aux, filter_info);
|
|
}
|
|
|
|
|
|
static Filter *filter_new (const char *description,
|
|
const char *glob)
|
|
{
|
|
Filter *filter;
|
|
char **globs, **p;
|
|
gboolean negative;
|
|
|
|
g_return_val_if_fail (description != NULL, NULL);
|
|
g_return_val_if_fail (glob != NULL && glob[0] != 0, NULL);
|
|
g_return_val_if_fail (glob[0] != NEGATE_CHAR || glob[1] != 0, NULL);
|
|
|
|
if (glob[0] == NEGATE_CHAR)
|
|
{
|
|
negative = TRUE;
|
|
globs = g_strsplit (glob + 1, GLOB_SEPARATOR, 0);
|
|
}
|
|
else
|
|
{
|
|
negative = FALSE;
|
|
globs = g_strsplit (glob, GLOB_SEPARATOR, 0);
|
|
}
|
|
|
|
g_return_val_if_fail (globs != NULL, NULL);
|
|
|
|
filter = g_new0 (Filter, 1);
|
|
|
|
filter->description = g_strdup (description);
|
|
filter->glob = g_strdup (glob);
|
|
|
|
filter->filter = gtk_file_filter_new ();
|
|
gtk_object_sink (gtk_object_ref (GTK_OBJECT (filter->filter)));
|
|
gtk_file_filter_set_name (filter->filter, description);
|
|
|
|
if (negative)
|
|
{
|
|
filter->aux = gtk_file_filter_new ();
|
|
gtk_object_sink (gtk_object_ref (GTK_OBJECT (filter->aux)));
|
|
|
|
for (p = globs; *p != NULL; p++)
|
|
gtk_file_filter_add_pattern (filter->aux, *p);
|
|
|
|
gtk_file_filter_add_custom (filter->filter,
|
|
gtk_file_filter_get_needed (filter->aux),
|
|
(GtkFileFilterFunc) neg_filter_func,
|
|
filter, NULL);
|
|
}
|
|
else
|
|
{
|
|
for (p = globs; *p != NULL; p++)
|
|
gtk_file_filter_add_pattern (filter->filter, *p);
|
|
}
|
|
|
|
g_strfreev (globs);
|
|
return filter;
|
|
}
|
|
|
|
|
|
static void filter_free (Filter *filter)
|
|
{
|
|
if (filter)
|
|
{
|
|
if (filter->filter)
|
|
g_object_unref (filter->filter);
|
|
filter->filter = NULL;
|
|
if (filter->aux)
|
|
g_object_unref (filter->aux);
|
|
filter->aux = NULL;
|
|
g_free (filter->description);
|
|
filter->description = NULL;
|
|
g_free (filter->glob);
|
|
filter->glob = NULL;
|
|
g_free (filter);
|
|
}
|
|
}
|
|
|
|
|
|
static GtkFileFilter *filter_get_gtk_filter (Filter *filter)
|
|
{
|
|
return filter->filter;
|
|
}
|
|
|
|
static const char *filter_get_glob (Filter *filter)
|
|
{
|
|
return filter->glob;
|
|
}
|
|
|
|
static const char *filter_get_description (Filter *filter)
|
|
{
|
|
return filter->description;
|
|
}
|
|
|
|
|
|
static void filter_entry_activated (GtkEntry *entry,
|
|
GtkFileChooser *dialog)
|
|
{
|
|
const char *text;
|
|
Filter *filter;
|
|
MooEditFileMgr *mgr;
|
|
|
|
mgr = g_object_get_data (G_OBJECT (dialog), "file-mgr");
|
|
g_return_if_fail (mgr != NULL);
|
|
|
|
text = gtk_entry_get_text (entry);
|
|
|
|
if (text && text[0])
|
|
filter = mgr_new_user_filter (mgr, text);
|
|
|
|
if (!filter)
|
|
filter = mgr_get_null_filter (mgr);
|
|
|
|
mgr_set_filter (mgr, dialog, filter);
|
|
}
|
|
|
|
|
|
static void combo_changed (GtkComboBox *combo,
|
|
GtkFileChooser *dialog)
|
|
{
|
|
GtkTreeIter iter;
|
|
Filter *filter;
|
|
MooEditFileMgr *mgr;
|
|
|
|
if (!gtk_combo_box_get_active_iter (combo, &iter))
|
|
return;
|
|
|
|
mgr = g_object_get_data (G_OBJECT (dialog), "file-mgr");
|
|
g_return_if_fail (mgr != NULL);
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (mgr->priv->filters), &iter,
|
|
COLUMN_FILTER, &filter, -1);
|
|
g_return_if_fail (filter != NULL);
|
|
|
|
mgr_set_filter (mgr, dialog, filter);
|
|
}
|
|
|
|
|
|
static void mgr_set_filter (MooEditFileMgr *mgr,
|
|
GtkFileChooser *dialog,
|
|
Filter *filter)
|
|
{
|
|
GtkEntry *entry = g_object_get_data (G_OBJECT (dialog),
|
|
"filter-entry");
|
|
gtk_entry_set_text (entry, filter_get_description (filter));
|
|
gtk_file_chooser_set_filter (dialog, filter_get_gtk_filter (filter));
|
|
mgr_set_last_filter (mgr, filter);
|
|
}
|
|
|
|
|
|
static void mgr_set_last_filter (MooEditFileMgr *mgr,
|
|
Filter *filter)
|
|
{
|
|
mgr->priv->last_filter = filter;
|
|
|
|
if (filter == mgr->priv->null_filter)
|
|
moo_prefs_set_string (moo_edit_setting (PREFS_LAST_FILTER),
|
|
NULL);
|
|
else
|
|
moo_prefs_set_string (moo_edit_setting (PREFS_LAST_FILTER),
|
|
filter_get_glob (filter));
|
|
}
|
|
|
|
|
|
typedef gboolean (*ListFoundFunc) (GtkTreeModel *model,
|
|
GtkTreeIter *iter,
|
|
gpointer data);
|
|
|
|
typedef struct {
|
|
GtkTreeIter *iter;
|
|
ListFoundFunc func;
|
|
gpointer user_data;
|
|
gboolean found;
|
|
} ListStoreFindData;
|
|
|
|
static gboolean list_store_find_check_func (GtkTreeModel *model,
|
|
G_GNUC_UNUSED GtkTreePath *path,
|
|
GtkTreeIter *iter,
|
|
ListStoreFindData *data)
|
|
{
|
|
if (data->func (model, iter, data->user_data))
|
|
{
|
|
data->found = TRUE;
|
|
if (data->iter)
|
|
*data->iter = *iter;
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static gboolean list_store_find (GtkListStore *store,
|
|
GtkTreeIter *iter,
|
|
ListFoundFunc func,
|
|
gpointer user_data)
|
|
{
|
|
ListStoreFindData data = {iter, func, user_data, FALSE};
|
|
gtk_tree_model_foreach (GTK_TREE_MODEL (store),
|
|
(GtkTreeModelForeachFunc) list_store_find_check_func,
|
|
&data);
|
|
return data.found;
|
|
}
|
|
|
|
|
|
static gboolean check_filter_match (GtkTreeModel *model,
|
|
GtkTreeIter *iter,
|
|
const char *text)
|
|
{
|
|
Filter *filter = NULL;
|
|
|
|
gtk_tree_model_get (model, iter, COLUMN_FILTER, &filter, -1);
|
|
|
|
if (!filter)
|
|
return FALSE;
|
|
|
|
if (!strcmp (text, filter_get_description (filter)) ||
|
|
!strcmp (text, filter_get_glob (filter)))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Filter *list_store_find_filter (MooEditFileMgr *mgr,
|
|
const char *text)
|
|
{
|
|
GtkTreeIter iter;
|
|
|
|
g_return_val_if_fail (text != NULL, NULL);
|
|
|
|
if (list_store_find (mgr->priv->filters, &iter,
|
|
(ListFoundFunc)check_filter_match,
|
|
(gpointer)text))
|
|
{
|
|
Filter *filter;
|
|
gtk_tree_model_get (GTK_TREE_MODEL (mgr->priv->filters),
|
|
&iter, COLUMN_FILTER, &filter, -1);
|
|
return filter;
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
static void mgr_load_filter_prefs (MooEditFileMgr *mgr)
|
|
{
|
|
guint i;
|
|
char *key;
|
|
char *glob;
|
|
Filter *filter;
|
|
|
|
for (i = 0; i < NUM_USER_FILTERS; ++i)
|
|
{
|
|
key = g_strdup_printf (MOO_EDIT_PREFS_PREFIX "/"
|
|
PREFS_FILTERS "/" PREFS_USER "%d", i);
|
|
|
|
glob = g_strdup (moo_prefs_get_string (key));
|
|
|
|
if (glob && glob[0])
|
|
mgr_new_user_filter (mgr, glob);
|
|
|
|
g_free (key);
|
|
g_free (glob);
|
|
}
|
|
|
|
glob = g_strdup (moo_prefs_get_string (moo_edit_setting (PREFS_LAST_FILTER)));
|
|
|
|
if (glob && glob[0])
|
|
{
|
|
filter = mgr_new_user_filter (mgr, glob);
|
|
|
|
if (filter)
|
|
mgr_set_last_filter (mgr, filter);
|
|
}
|
|
|
|
g_free (glob);
|
|
}
|
|
|
|
|
|
static void set_user_filter_prefs (guint num,
|
|
const char *val)
|
|
{
|
|
char *key = g_strdup_printf (MOO_EDIT_PREFS_PREFIX "/"
|
|
PREFS_FILTERS "/" PREFS_USER "%d", num);
|
|
moo_prefs_set_string (key, val);
|
|
g_free (key);
|
|
}
|
|
|
|
|
|
static void mgr_save_filter_prefs (MooEditFileMgr *mgr)
|
|
{
|
|
GtkTreeIter iter;
|
|
gboolean user_present;
|
|
guint i = 0;
|
|
|
|
user_present = list_store_find (mgr->priv->filters, &iter,
|
|
row_is_separator, NULL);
|
|
|
|
if (user_present)
|
|
{
|
|
while (i < NUM_USER_FILTERS &&
|
|
gtk_tree_model_iter_next (GTK_TREE_MODEL (mgr->priv->filters), &iter))
|
|
{
|
|
Filter *filter = NULL;
|
|
gtk_tree_model_get (GTK_TREE_MODEL (mgr->priv->filters), &iter,
|
|
COLUMN_FILTER, &filter, -1);
|
|
g_assert (filter != NULL);
|
|
set_user_filter_prefs (i, filter_get_glob (filter));
|
|
i++;
|
|
}
|
|
}
|
|
|
|
for ( ; i < NUM_USER_FILTERS; ++i)
|
|
set_user_filter_prefs (i, NULL);
|
|
}
|
|
|
|
|
|
static Filter *mgr_new_user_filter (MooEditFileMgr *mgr,
|
|
const char *glob)
|
|
{
|
|
Filter *filter;
|
|
|
|
g_return_val_if_fail (glob && glob[0], NULL);
|
|
|
|
filter = list_store_find_filter (mgr, glob);
|
|
|
|
if (filter)
|
|
{
|
|
GtkTreeIter iter;
|
|
gboolean user_present;
|
|
|
|
user_present = list_store_find (mgr->priv->filters, &iter,
|
|
row_is_separator, NULL);
|
|
|
|
g_return_val_if_fail (user_present, filter);
|
|
g_return_val_if_fail (gtk_tree_model_iter_next
|
|
(GTK_TREE_MODEL (mgr->priv->filters), &iter), filter);
|
|
gtk_list_store_move_before (mgr->priv->filters, &iter, NULL);
|
|
}
|
|
else
|
|
{
|
|
filter = filter_new (glob, glob);
|
|
|
|
if (filter)
|
|
{
|
|
GtkTreeIter iter;
|
|
gboolean user_present;
|
|
|
|
user_present = list_store_find (mgr->priv->filters, &iter,
|
|
row_is_separator, NULL);
|
|
|
|
if (!user_present)
|
|
gtk_list_store_append (mgr->priv->filters, &iter);
|
|
|
|
if (mgr->priv->num_user_filters == NUM_USER_FILTERS)
|
|
{
|
|
Filter *old = NULL;
|
|
|
|
--mgr->priv->num_user_filters;
|
|
|
|
if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (mgr->priv->filters),
|
|
&iter))
|
|
{
|
|
filter_free (filter);
|
|
g_return_val_if_reached (NULL);
|
|
}
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (mgr->priv->filters),
|
|
&iter, COLUMN_FILTER, &old, -1);
|
|
g_assert (old != NULL && old != mgr->priv->last_filter);
|
|
gtk_list_store_remove (mgr->priv->filters, &iter);
|
|
filter_free (old);
|
|
}
|
|
|
|
gtk_list_store_append (mgr->priv->filters, &iter);
|
|
gtk_list_store_set (mgr->priv->filters, &iter,
|
|
COLUMN_FILTER, filter,
|
|
COLUMN_DESCRIPTION, filter_get_description (filter),
|
|
-1);
|
|
++mgr->priv->num_user_filters;
|
|
}
|
|
}
|
|
|
|
mgr_save_filter_prefs (mgr);
|
|
|
|
return filter;
|
|
}
|