21
22
#include "ui/rule_editor.h"
23
#include "ui/ui_common.h"
25
static void rule_editor_class_init (RuleEditorClass *klass);
26
static void rule_editor_init (RuleEditor *ld);
28
A 'rule editor' is a dialog allowing editing arbitrary filtering
29
'rules'. The rules edited are loaded from an 'item set' which
30
can belong to a 'search folder' or an 'item list' filter.
32
The rule editing is independant of any search folder handling.
28
35
#define RULE_EDITOR_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), RULE_EDITOR_TYPE, RuleEditorPrivate))
30
37
struct RuleEditorPrivate {
31
38
GtkWidget *root; /**< root widget */
32
vfolderPtr vfolder; /**< the search folder being edited (FIXME: why do we need this?) */
33
39
GSList *newRules; /**< new list of rules currently in editing */
43
49
static GObjectClass *parent_class = NULL;
46
rule_editor_get_type (void)
48
static GType type = 0;
50
if (G_UNLIKELY (type == 0))
52
static const GTypeInfo our_info =
54
sizeof (RuleEditorClass),
56
NULL, /* base_finalize */
57
(GClassInitFunc) rule_editor_class_init,
59
NULL, /* class_data */
62
(GInstanceInitFunc) rule_editor_init
65
type = g_type_register_static (G_TYPE_OBJECT,
51
G_DEFINE_TYPE (RuleEditor, rule_editor, G_TYPE_OBJECT);
74
54
rule_editor_finalize (GObject *object)
124
104
/* callback for rule additive option menu */
126
on_rule_set_additive (GtkOptionMenu *optionmenu, gpointer user_data)
128
rulePtr rule = (rulePtr)user_data;
130
rule->additive = TRUE;
133
/* callback for rule additive option menu */
135
on_rule_unset_additive (GtkOptionMenu *optionmenu, gpointer user_data)
137
rulePtr rule = (rulePtr)user_data;
139
rule->additive = FALSE;
107
on_rule_changed_additive (GtkComboBox *optionmenu, gpointer user_data)
109
rulePtr rule = (rulePtr)user_data;
110
gint active = gtk_combo_box_get_active (optionmenu);
112
rule->additive = ((active==0) ? TRUE : FALSE);
142
116
/* sets up the widgets for a single rule */
144
118
rule_editor_setup_widgets (struct changeRequest *changeRequest, rulePtr rule)
146
GtkWidget *widget, *menu;
147
121
ruleInfoPtr ruleInfo;
149
ruleInfo = ruleFunctions + changeRequest->rule;
123
ruleInfo = g_slist_nth_data (rule_get_available_rules (), changeRequest->rule);
150
124
g_object_set_data (G_OBJECT (changeRequest->paramHBox), "rule", rule);
152
126
/* remove of old widgets */
153
127
gtk_container_foreach (GTK_CONTAINER (changeRequest->paramHBox), rule_editor_destroy_param_widget, NULL);
155
129
/* add popup menu for selection of positive or negative logic */
156
menu = gtk_menu_new ();
158
widget = gtk_menu_item_new_with_label (ruleInfo->positive);
159
gtk_container_add (GTK_CONTAINER (menu), widget);
160
g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (on_rule_set_additive), rule);
162
widget = gtk_menu_item_new_with_label (ruleInfo->negative);
163
gtk_container_add (GTK_CONTAINER (menu), widget);
164
g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (on_rule_unset_additive), rule);
166
gtk_menu_set_active (GTK_MENU (menu), (rule->additive)?0:1);
168
widget = gtk_option_menu_new ();
169
gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
131
widget = gtk_combo_box_new_text ();
132
gtk_combo_box_append_text ((GtkComboBox*)widget, ruleInfo->positive);
133
gtk_combo_box_append_text ((GtkComboBox*)widget, ruleInfo->negative);
134
gtk_combo_box_set_active ((GtkComboBox*)widget, (rule->additive)?0:1);
135
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (on_rule_changed_additive), rule);
170
136
gtk_widget_show_all (widget);
171
137
gtk_box_pack_start (GTK_BOX (changeRequest->paramHBox), widget, FALSE, FALSE, 0);
185
/* callback for rule type option menu */
187
on_ruletype_changed (GtkOptionMenu *optionmenu, gpointer user_data)
153
do_ruletype_changed (struct changeRequest *changeRequest)
189
struct changeRequest *changeRequest = (struct changeRequest *)user_data;
190
155
ruleInfoPtr ruleInfo;
196
158
rule = g_object_get_data (G_OBJECT (changeRequest->paramHBox), "rule");
198
160
changeRequest->editor->priv->newRules = g_slist_remove (changeRequest->editor->priv->newRules, rule);
199
161
rule_free (rule);
201
ruleInfo = ruleFunctions + changeRequest->rule;
202
rule = rule_new (changeRequest->editor->priv->vfolder, ruleInfo->ruleId, "", TRUE);
163
ruleInfo = g_slist_nth_data (rule_get_available_rules (), changeRequest->rule);
164
rule = rule_new (ruleInfo->ruleId, "", TRUE);
203
165
changeRequest->editor->priv->newRules = g_slist_append (changeRequest->editor->priv->newRules, rule);
205
167
rule_editor_setup_widgets (changeRequest, rule);
170
/* callback for rule type option menu */
172
on_ruletype_changed (GtkComboBox *optionmenu, gpointer user_data)
174
struct changeRequest *changeRequest = NULL;
177
if (gtk_combo_box_get_active_iter (optionmenu, &iter)) {
178
gtk_tree_model_get (gtk_combo_box_get_model (optionmenu), &iter, 1, &changeRequest, -1);
180
do_ruletype_changed (changeRequest);
208
184
/* callback for each rules remove button */
210
186
on_ruleremove_clicked (GtkButton *button, gpointer user_data)
225
201
rule_editor_add_rule (RuleEditor *re, rulePtr rule)
227
GtkWidget *hbox, *hbox2, *menu, *widget;
204
GtkWidget *hbox, *hbox2, *widget;
228
206
struct changeRequest *changeRequest, *selected = NULL;
229
ruleInfoPtr ruleInfo;
207
gint i = 0, active = 0;
232
209
hbox = gtk_hbox_new (FALSE, 2); /* hbox to contain all rule widgets */
233
210
hbox2 = gtk_hbox_new (FALSE, 2); /* another hbox where the rule specific widgets are added */
235
if (nrOfRuleFunctions == 0)
238
212
/* set up the rule type selection popup */
239
menu = gtk_menu_new ();
240
for (i = 0, ruleInfo = ruleFunctions; i < nrOfRuleFunctions; i++, ruleInfo++) {
213
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
214
ruleIter = rule_get_available_rules ();
216
ruleInfoPtr ruleInfo = (ruleInfoPtr)ruleIter->data;
242
219
/* we add a change request to each popup option */
243
220
changeRequest = g_new0 (struct changeRequest, 1);
244
221
changeRequest->paramHBox = hbox2;
249
226
selected = changeRequest;
251
228
/* build the menu option */
252
widget = gtk_menu_item_new_with_label (ruleInfo->title);
253
gtk_container_add (GTK_CONTAINER (menu), widget);
254
g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (on_ruletype_changed), changeRequest);
229
gtk_list_store_append (store, &iter);
230
gtk_list_store_set (store, &iter, 0, ruleInfo->title, 1, changeRequest, -1);
257
233
if (ruleInfo == rule->ruleInfo) {
258
234
selected = changeRequest;
259
gtk_menu_set_active (GTK_MENU (menu), i);
239
ruleIter = g_slist_next (ruleIter);
263
widget = gtk_option_menu_new ();
264
gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
242
widget = gtk_combo_box_new ();
243
ui_common_setup_combo_text (GTK_COMBO_BOX (widget), 0);
245
gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
246
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active);
247
g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (on_ruletype_changed), NULL);
265
250
gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
266
251
gtk_box_pack_start (GTK_BOX (hbox), hbox2, FALSE, FALSE, 0);
269
254
/* fake a rule type change to initialize parameter widgets */
270
on_ruletype_changed (GTK_OPTION_MENU (widget), selected);
255
do_ruletype_changed (selected);
272
rulePtr newRule = rule_new (rule->vp, rule->ruleInfo->ruleId, rule->value, rule->additive);
257
rulePtr newRule = rule_new (rule->ruleInfo->ruleId, rule->value, rule->additive);
274
259
/* set up widgets with existing rule type and value */
275
260
rule_editor_setup_widgets (selected, newRule);
303
288
/* Set up rule list vbox */
304
289
re->priv->root = gtk_vbox_new (FALSE, 0);
305
re->priv->vfolder = vfolder; /* FIXME: why do we need this? */
307
291
/* load rules into dialog */
308
iter = vfolder->rules;
292
iter = itemset->rules;
310
294
rule_editor_add_rule (re, (rulePtr)(iter->data));
311
295
iter = g_slist_next (iter);
320
rule_editor_save (RuleEditor *re, vfolderPtr vfolder)
304
rule_editor_save (RuleEditor *re, itemSetPtr itemset)
324
308
/* delete all old rules */
325
iter = vfolder->rules;
309
iter = itemset->rules;
327
311
rule_free ((rulePtr)iter->data);
328
312
iter = g_slist_next (iter);
330
g_slist_free (vfolder->rules);
331
vfolder->rules = NULL;
314
g_slist_free (itemset->rules);
315
itemset->rules = NULL;
333
317
/* and add all rules from editor */
334
318
iter = re->priv->newRules;
336
320
rulePtr rule = (rulePtr)iter->data;
337
vfolder_add_rule (vfolder, rule->ruleInfo->ruleId, rule->value, rule->additive);
321
itemset_add_rule (itemset, rule->ruleInfo->ruleId, rule->value, rule->additive);
338
322
iter = g_slist_next (iter);
341
/* FIXME: move the following code from search_folder_dialog.c and search_dialog.c here:
342
vfolder->anyMatch = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (re->priv->anyRuleRadioBtn)); */