aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/misc/ChangeLog9
-rw-r--r--widgets/misc/e-filter-bar.c53
-rw-r--r--widgets/misc/e-filter-bar.h3
3 files changed, 60 insertions, 5 deletions
diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog
index 46181a666b..dce3bcbc49 100644
--- a/widgets/misc/ChangeLog
+++ b/widgets/misc/ChangeLog
@@ -1,3 +1,12 @@
+2001-10-30 <NotZed@Ximian.com>
+
+ * e-filter-bar.c (generate_menu): Hook to rule changed events.
+ (destroy): Free change id table/unconnect to signals.
+ (init): Setup change id table.
+ (e_filter_bar_new): Hook onto rule removed signal.
+ (context_rule_removed): If rule removed, disconnect from signal handler.
+ (rule_changed): For changed rules, also rebuild menu. Fixed #12233.
+
2001-10-30 Damon Chaplin <damon@ximian.com>
* e-cell-date-edit.c (e_cell_date_edit_set_popup_values): try to parse
diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c
index b8c33dc093..af026f672e 100644
--- a/widgets/misc/e-filter-bar.c
+++ b/widgets/misc/e-filter-bar.c
@@ -55,6 +55,9 @@ enum {
/* Callbacks. */
+static void rule_changed (FilterRule *rule, gpointer user_data);
+
+
/* rule editor thingy */
static void
rule_editor_destroyed (GtkWidget *w, EFilterBar *efb)
@@ -330,11 +333,18 @@ generate_menu (ESearchBar *esb, ESearchBarItem *items)
{
EFilterBar *efb = (EFilterBar *)esb;
GArray *menu;
-
+ int i;
+
g_ptr_array_set_size (efb->menu_rules, 0);
menu = build_items (esb, items, 0, &efb->menu_base, efb->menu_rules);
((ESearchBarClass *)parent_class)->set_menu (esb, (ESearchBarItem *)menu->data);
g_array_free (menu, TRUE);
+
+ for (i=0;i<efb->menu_rules->len;i++) {
+ if (g_hash_table_lookup(efb->change_ids, efb->menu_rules->pdata[i]) == 0)
+ g_hash_table_insert(efb->change_ids, efb->menu_rules->pdata[i],
+ (void *)gtk_signal_connect(efb->menu_rules->pdata[i], "changed", rule_changed, efb));
+ }
}
static ESearchBarSubitem *
@@ -426,6 +436,29 @@ context_changed (RuleContext *context, gpointer user_data)
generate_menu (esb, efb->default_items);
}
+static void
+context_rule_removed (RuleContext *context, FilterRule *rule, gpointer user_data)
+{
+ EFilterBar *efb = E_FILTER_BAR (user_data);
+ int id;
+
+ id = (int)g_hash_table_lookup(efb->change_ids, rule);
+ if (id != 0) {
+ g_hash_table_remove(efb->change_ids, rule);
+ gtk_signal_disconnect((GtkObject *)rule, id);
+ }
+}
+
+static void
+rule_changed (FilterRule *rule, gpointer user_data)
+{
+ EFilterBar *efb = E_FILTER_BAR (user_data);
+ ESearchBar *esb = E_SEARCH_BAR (user_data);
+
+ /* just generate whole menu again */
+ generate_menu (esb, efb->default_items);
+}
+
/* GtkObject methods. */
@@ -450,6 +483,14 @@ impl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
static void
+remove_change_handler(FilterRule *rule, void *value, EFilterBar *bar)
+{
+ int id = (int)value;
+
+ gtk_signal_disconnect((GtkObject *)rule, id);
+}
+
+static void
destroy (GtkObject *object)
{
EFilterBar *bar;
@@ -463,7 +504,10 @@ destroy (GtkObject *object)
g_ptr_array_free (bar->option_rules, TRUE);
g_free (bar->systemrules);
g_free (bar->userrules);
-
+
+ g_hash_table_foreach(bar->change_ids, (GHFunc)remove_change_handler, bar);
+ g_hash_table_destroy(bar->change_ids);
+
if (bar->default_items)
free_items (bar->default_items);
@@ -520,6 +564,7 @@ init (EFilterBar *efb)
efb->menu_rules = g_ptr_array_new ();
efb->option_rules = g_ptr_array_new ();
+ efb->change_ids = g_hash_table_new(NULL, NULL);
}
@@ -545,8 +590,8 @@ e_filter_bar_new (RuleContext *context, const char *systemrules, const char *use
e_search_bar_construct ((ESearchBar *)bar, &item, &item);
- gtk_signal_connect (GTK_OBJECT (context), "changed",
- context_changed, bar);
+ gtk_signal_connect (GTK_OBJECT (context), "changed", context_changed, bar);
+ gtk_signal_connect (GTK_OBJECT (context), "rule_removed", context_rule_removed, bar);
return bar;
}
diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h
index 8f1dec2b41..3dbcd3dab6 100644
--- a/widgets/misc/e-filter-bar.h
+++ b/widgets/misc/e-filter-bar.h
@@ -57,7 +57,8 @@ struct _EFilterBar {
int menu_base, option_base;
GPtrArray *menu_rules, *option_rules;
-
+ GHashTable *change_ids;
+
ESearchBarItem *default_items;
GtkWidget *save_dialogue; /* current save dialogue (so we dont pop up multiple ones) */