aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filter/ChangeLog87
-rw-r--r--filter/filter-driver.c379
-rw-r--r--filter/filter-driver.h26
-rw-r--r--filter/filter-editor.c46
-rw-r--r--filter/filter-rule.c586
-rw-r--r--filter/filter-rule.h18
-rw-r--r--filter/rule-context.c167
-rw-r--r--filter/rule-context.h9
-rw-r--r--filter/score-editor.c12
-rw-r--r--filter/vfolder-editor.c12
10 files changed, 801 insertions, 541 deletions
diff --git a/filter/ChangeLog b/filter/ChangeLog
index ca73c950ff..67c957f1c6 100644
--- a/filter/ChangeLog
+++ b/filter/ChangeLog
@@ -1,3 +1,90 @@
+2000-10-11 Not Zed <NotZed@HelixCode.com>
+
+ * filter-driver.c (filter_driver_filter_mbox): Report the
+ percentage of file complete for the filter.
+
+2000-10-10 Not Zed <NotZed@HelixCode.com>
+
+ * filter-driver.c (filter_driver_run): Why on earth does this code
+ ref all these objects for? This is not right at all.
+ (filter_driver_run): Changed source type to a string.
+ (filter_driver_run): REmove the very weird exception copying
+ stuff - just ref it instead.
+ (do_score):
+ (do_colour):
+ (do_stop):
+ (do_copy):
+ (mark_forward):
+ (do_delete): Removed bogus 'terminated' testing. This is NOT
+ NEEDED HERE. It is tested after every rule/action, and
+ termination only makes sense at that point.
+ (filter_driver_filter_message): new funciton (renamed), filter
+ only a message.
+ (filter_driver_filter_mbox): Filter a whole mbox.
+ (filter_driver_run): If we aren't given an info, create a simple
+ one based on the message headers.
+ (filter_driver_filter_message): Renamed from filter_driver_run().
+ (filter_driver_set_status_func): Set the status callback function.
+ (filter_driver_set_default_folder): Set the default folder for
+ filtering.
+ (report_status): Internal function to report the status of a given
+ event.
+ (do_copy): Removed a pointless cache lookup - duh, we do it in
+ open_folder anyway (infact, we do it in camel too!!).
+ (filter_driver_filter_message): Removed pointless re-refing of
+ arguments. Why would anyone think this could be any use at all?
+ (filter_driver_filter_folder): New function to filter a whole
+ folder.
+
+ * filter-editor.c (rule_add): api fixes.
+ (rule_edit):
+ (rule_up):
+ (rule_down):
+ (set_sensitive): This didn't take into account the source, now it
+ does.
+ (select_source): Fix for api changes. Changed the rather generic
+ 'number' argument to be 'source', and a string.
+ (filter_editor_construct): Changed the 'number' to 'source', and
+ set the string appropriately. Added a warning for one case where
+ the glade file is out of sync.
+
+ * score-editor.c (score_editor_construct):
+ (rule_edit):
+ (rule_delete):
+ (rule_up):
+ (rule_down):
+ (set_sensitive): api fixes.
+
+ * vfolder-editor.c (set_sensitive): Api fixes.
+ (vfolder_editor_construct):
+ (rule_edit):
+ (vfolder_editor_construct):
+
+ * rule-context.h (RCNextRuleFunc): Added a source argument.
+
+ * rule-context.c (rule_context_next_rule): Added source argument.
+ (rule_context_find_rule): Added source argument.
+ (rule_context_get_rank_rule): Added source argument.
+ (rule_context_get_rank_rule_with_source): Removed.
+ (save): Fixed for changes to RCNextRuleFunc prototype.
+
+ * filter-rule.h: Changed the source to be a string, removed the
+ filter_source_t type.
+
+ * filter-rule.c (filter_rule_set_source): New function to set the
+ source of a rule. What idiot ran this code through indent?
+ (filter_rule_find_list): Added a source argument.
+ (filter_rule_next_list): Added a source argument.
+ (get_widget): Fixed the wording. You dont remove search parts,
+ you can only remove the last one. Why you even need to mention
+ they are search 'criteria' is beyond me. Whoever added the
+ scrolled window needs to be shot, its the single most awful GUI
+ feature ever invented (ranks with the close button next to
+ maximise).
+ (xml_encode): Save source as a string (if present).
+ (xml_decode): Likewise for loading & fixed a small memleak.
+ (filter_rule_finalise): Free source.
+
2000-10-06 Not Zed <NotZed@HelixCode.com>
* rule-context.c (load): Remove the stupid on-demand cb shit.
diff --git a/filter/filter-driver.c b/filter/filter-driver.c
index a7737d7be3..2e6c797ab6 100644
--- a/filter/filter-driver.c
+++ b/filter/filter-driver.c
@@ -44,7 +44,11 @@
struct _FilterDriverPrivate {
GHashTable *globals; /* global variables */
-
+
+ CamelFolder *defaultfolder; /* defualt folder */
+ FDStatusFunc *statusfunc; /* status callback */
+ void *statusdata; /* status callback data */
+
FilterContext *context;
/* for callback */
@@ -61,7 +65,7 @@ struct _FilterDriverPrivate {
CamelMimeMessage *message; /* input message */
CamelMessageInfo *info; /* message summary info */
-
+
FILE *logfile; /* log file */
CamelException *ex;
@@ -164,9 +168,6 @@ filter_driver_init (FilterDriver *obj)
p->globals = g_hash_table_new (g_str_hash, g_str_equal);
p->folders = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Will get set in filter_driver_run */
- p->ex = NULL;
}
static void
@@ -190,6 +191,9 @@ filter_driver_finalise (GtkObject *obj)
g_hash_table_destroy (p->globals);
gtk_object_unref (GTK_OBJECT (p->eval));
+
+ if (p->defaultfolder)
+ camel_object_unref((CamelObject *)p->defaultfolder);
g_free (p);
@@ -224,6 +228,43 @@ filter_driver_new (FilterContext *context, FilterGetFolderFunc get_folder, void
}
+void
+filter_driver_set_status_func(FilterDriver *d, FDStatusFunc *func, void *data)
+{
+ struct _FilterDriverPrivate *p = _PRIVATE (d);
+
+ p->statusfunc = func;
+ p->statusdata = data;
+}
+
+void
+filter_driver_set_default_folder(FilterDriver *d, CamelFolder *def)
+{
+ struct _FilterDriverPrivate *p = _PRIVATE (d);
+
+ if (p->defaultfolder)
+ camel_object_unref((CamelObject *)p->defaultfolder);
+ p->defaultfolder = def;
+ if (p->defaultfolder)
+ camel_object_ref((CamelObject *)p->defaultfolder);
+}
+
+static void
+report_status(FilterDriver *driver, enum filter_status_t status, const char *desc, ...)
+{
+ struct _FilterDriverPrivate *p = _PRIVATE (driver);
+ va_list ap;
+ char *str;
+
+ if (p->statusfunc) {
+ va_start(ap, desc);
+ str = g_strdup_vprintf(desc, ap);
+ p->statusfunc(driver, status, str, p->message, p->statusdata);
+ g_free(str);
+ }
+}
+
+
#if 0
void
filter_driver_set_global (FilterDriver *d, const char *name, const char *value)
@@ -245,27 +286,21 @@ do_delete (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver
{
struct _FilterDriverPrivate *p = _PRIVATE (driver);
- if (!p->terminated) {
- d(fprintf (stderr, "doing delete\n"));
- p->deleted = TRUE;
- if (p->logfile)
- fprintf (p->logfile, "Action = Deleted\n");
- }
-
+ d(fprintf (stderr, "doing delete\n"));
+ p->deleted = TRUE;
+ report_status(driver, FILTER_STATUS_ACTION, "Delete");
+
return NULL;
}
static ESExpResult *
mark_forward (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *driver)
{
- struct _FilterDriverPrivate *p = _PRIVATE (driver);
+ /*struct _FilterDriverPrivate *p = _PRIVATE (driver);*/
- if (!p->terminated) {
- d(fprintf (stderr, "marking message for forwarding\n"));
- /* FIXME: do stuff here */
- if (p->logfile)
- fprintf (p->logfile, "Action = Forwarded\n");
- }
+ d(fprintf (stderr, "marking message for forwarding\n"));
+ /* FIXME: do stuff here */
+ report_status(driver, FILTER_STATUS_ACTION, "Forward");
return NULL;
}
@@ -276,28 +311,22 @@ do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d
struct _FilterDriverPrivate *p = _PRIVATE (driver);
int i;
- if (!p->terminated) {
- d(fprintf (stderr, "copying message...\n"));
- p->copied = TRUE;
- for (i = 0; i < argc; i++) {
- if (argv[i]->type == ESEXP_RES_STRING) {
+ d(fprintf (stderr, "copying message...\n"));
+ p->copied = TRUE;
+ for (i = 0; i < argc; i++) {
+ if (argv[i]->type == ESEXP_RES_STRING) {
/* open folders we intent to copy to */
- char *folder = argv[i]->value.string;
- CamelFolder *outbox;
-
- outbox = g_hash_table_lookup (p->folders, folder);
- if (!outbox) {
- outbox = open_folder (driver, folder);
- if (!outbox)
- continue;
- }
-
- mail_tool_camel_lock_up ();
- camel_folder_append_message (outbox, p->message, p->info, p->ex);
- if (p->logfile)
- fprintf (p->logfile, "Action = Copied to folder %s\n", outbox->full_name);
- mail_tool_camel_lock_down ();
- }
+ char *folder = argv[i]->value.string;
+ CamelFolder *outbox;
+
+ outbox = open_folder (driver, folder);
+ if (!outbox)
+ continue;
+
+ mail_tool_camel_lock_up ();
+ camel_folder_append_message (outbox, p->message, p->info, p->ex);
+ report_status(driver, FILTER_STATUS_ACTION, "Copy to folder %s", outbox->full_name);
+ mail_tool_camel_lock_down ();
}
}
@@ -309,10 +338,9 @@ do_stop (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *d
{
struct _FilterDriverPrivate *p = _PRIVATE (driver);
- if (!p->terminated) {
- d(fprintf (stderr, "terminating message processing\n"));
- p->terminated = TRUE;
- }
+ report_status(driver, FILTER_STATUS_ACTION, "Stopped processing");
+ d(fprintf (stderr, "terminating message processing\n"));
+ p->terminated = TRUE;
return NULL;
}
@@ -322,13 +350,10 @@ do_colour (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver
{
struct _FilterDriverPrivate *p = _PRIVATE (driver);
- if (!p->terminated) {
- d(fprintf (stderr, "setting colour tag\n"));
- if (argc > 0 && argv[0]->type == ESEXP_RES_STRING) {
- camel_tag_set (&p->info->user_tags, "colour", argv[0]->value.string);
- if (p->logfile)
- fprintf (p->logfile, "Action = Set color to %s\n", argv[0]->value.string);
- }
+ d(fprintf (stderr, "setting colour tag\n"));
+ if (argc > 0 && argv[0]->type == ESEXP_RES_STRING) {
+ camel_tag_set (&p->info->user_tags, "colour", argv[0]->value.string);
+ report_status(driver, FILTER_STATUS_ACTION, "Set colour to %s", argv[0]->value.string);
}
return NULL;
@@ -339,17 +364,14 @@ do_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterDriver *
{
struct _FilterDriverPrivate *p = _PRIVATE (driver);
- if (!p->terminated) {
- d(fprintf (stderr, "setting score tag\n"));
- if (argc > 0 && argv[0]->type == ESEXP_RES_INT) {
- char *value;
-
- value = g_strdup_printf ("%d", argv[0]->value.number);
- camel_tag_set (&p->info->user_tags, "score", value);
- if (p->logfile)
- fprintf (p->logfile, "Action = Set score to %d\n", argv[0]->value.number);
- g_free (value);
- }
+ d(fprintf (stderr, "setting score tag\n"));
+ if (argc > 0 && argv[0]->type == ESEXP_RES_INT) {
+ char *value;
+
+ value = g_strdup_printf ("%d", argv[0]->value.number);
+ camel_tag_set (&p->info->user_tags, "score", value);
+ report_status(driver, FILTER_STATUS_ACTION, "Set score to %d", argv[0]->value.number);
+ g_free (value);
}
return NULL;
@@ -415,43 +437,177 @@ free_key (gpointer key, gpointer value, gpointer user_data)
}
#endif
+
+void
+filter_driver_status_log(FilterDriver *driver, enum filter_status_t status, const char *desc, CamelMimeMessage *msg, void *data)
+{
+ FILE *out = data;
+
+ switch(status) {
+ case FILTER_STATUS_END: {
+ /* write log header */
+ time_t t;
+ char date[50];
+
+ time(&t);
+ strftime(date, 49, "%a, %d %b %Y %H:%M:%S", localtime(&t));
+ fprintf(out, " - Applied filter \"%s\" to message from %s - \"%s\" at %s\n",
+ desc, msg?camel_mime_message_get_from(msg):"unknown",
+ msg?camel_mime_message_get_subject(msg):"", date);
+ break;
+ }
+ case FILTER_STATUS_START:
+ fprintf(out, "\n");
+ break;
+ case FILTER_STATUS_ACTION:
+ fprintf(out, "Action: %s\n", desc);
+ break;
+ default:
+ /* nothing else is loggable */
+ break;
+ }
+}
+
+
+/* will filter only an mbox - is more efficient as it doesn't need to open the folder through camel directly */
+void
+filter_driver_filter_mbox(FilterDriver *driver, const char *mbox, const char *source, CamelException *ex)
+{
+ CamelMimeParser *mp =NULL;
+ int fd = -1;
+ int i = 0;
+ struct stat st;
+
+ fd = open(mbox, O_RDONLY);
+ if (fd == -1) {
+ camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, "Unable to open spool folder");
+ goto fail;
+ }
+ /* to get the filesize */
+ fstat(fd, &st);
+
+ mp = camel_mime_parser_new();
+ camel_mime_parser_scan_from(mp, TRUE);
+ if (camel_mime_parser_init_with_fd(mp, fd) == -1) {
+ camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, "Unable to process spool folder");
+ goto fail;
+ }
+ fd = -1;
+ while (camel_mime_parser_step(mp, 0, 0) == HSCAN_FROM) {
+ CamelMimeMessage *msg;
+ int pc;
+
+ pc = camel_mime_parser_tell(mp) * 100 / st.st_size;
+ report_status(driver, FILTER_STATUS_START, "Getting message %d (%d%% of file)", i, pc);
+
+ msg = camel_mime_message_new();
+ if (camel_mime_part_construct_from_parser((CamelMimePart *)msg, mp) == -1) {
+ report_status(driver, FILTER_STATUS_END, "Failed message %d", i);
+ camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, "Cannot open message");
+ camel_object_unref((CamelObject *)msg);
+ goto fail;
+ }
+
+ filter_driver_filter_message(driver, msg, NULL, source, ex);
+ camel_object_unref((CamelObject *)msg);
+ if (camel_exception_is_set(ex)) {
+ report_status(driver, FILTER_STATUS_END, "Failed message %d", i);
+ goto fail;
+ }
+
+ report_status(driver, FILTER_STATUS_END, "Finished message %d", i);
+ i++;
+
+ /* skip over the FROM_END state */
+ camel_mime_parser_step(mp, 0, 0);
+ }
+fail:
+ if (fd != -1)
+ close(fd);
+ if (mp)
+ camel_object_unref((CamelObject *)mp);
+}
+
+/* will filter a folder */
+void
+filter_driver_filter_folder(FilterDriver *driver, CamelFolder *folder, const char *source, GPtrArray *uids, gboolean remove, CamelException *ex)
+{
+ int i;
+ int freeuids = FALSE;
+ CamelMimeMessage *message;
+ const CamelMessageInfo *info;
+
+ if (uids == NULL) {
+ uids = camel_folder_get_uids(folder);
+ freeuids = TRUE;
+ }
+
+ for (i=0;i<uids->len;i++) {
+
+ report_status(driver, FILTER_STATUS_START, "Getting message %d of %d", i, uids->len);
+
+ message = camel_folder_get_message (folder, uids->pdata[i], ex);
+ if (camel_exception_is_set (ex)) {
+ report_status(driver, FILTER_STATUS_END, "Failed at message %d of %d", i, uids->len);
+ break;
+ }
+
+ if (camel_folder_has_summary_capability (folder))
+ info = camel_folder_get_message_info (folder, uids->pdata[i]);
+ else
+ info = NULL;
+
+ filter_driver_filter_message(driver, message, (CamelMessageInfo *)info, source, ex);
+ if (camel_exception_is_set (ex)) {
+ report_status(driver, FILTER_STATUS_END, "Failed at message %d of %d", i, uids->len);
+ break;
+ }
+
+ if (remove)
+ camel_folder_set_message_flags (folder, uids->pdata[i], CAMEL_MESSAGE_DELETED,CAMEL_MESSAGE_DELETED);
+
+ camel_object_unref (CAMEL_OBJECT (message));
+ }
+
+ if (freeuids)
+ camel_folder_free_uids(folder, uids);
+}
+
gboolean
-filter_driver_run (FilterDriver *driver, CamelMimeMessage *message, CamelMessageInfo *info,
- CamelFolder *inbox, enum _filter_source_t sourcetype,
- FILE *logfile, CamelException *ex)
+filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, CamelMessageInfo *info,
+ const char *source, CamelException *ex)
{
struct _FilterDriverPrivate *p = _PRIVATE (driver);
ESExpResult *r;
GString *fsearch, *faction;
FilterFilter *rule;
-
- gtk_object_ref (GTK_OBJECT (driver));
- camel_object_ref (CAMEL_OBJECT (message));
-
- if (inbox)
- camel_object_ref (CAMEL_OBJECT (inbox));
-
- p->ex = camel_exception_new ();
+ int freeinfo = FALSE;
+
+ if (info == NULL) {
+ struct _header_raw *h = CAMEL_MIME_PART(message)->headers;
+
+ info = g_malloc0(sizeof(*info));
+ freeinfo = TRUE;
+ info->subject = camel_folder_summary_format_string(h, "subject");
+ info->from = camel_folder_summary_format_address(h, "from");
+ info->to = camel_folder_summary_format_address(h, "to");
+ info->cc = camel_folder_summary_format_address(h, "cc");
+ }
+
+ p->ex = ex;
p->terminated = FALSE;
p->deleted = FALSE;
p->copied = FALSE;
p->message = message;
p->info = info;
- p->logfile = logfile;
fsearch = g_string_new ("");
faction = g_string_new ("");
rule = NULL;
- while ((rule = (FilterFilter *)rule_context_next_rule ((RuleContext *)p->context, (FilterRule *)rule))) {
+ while ((rule = (FilterFilter *)rule_context_next_rule ((RuleContext *)p->context, (FilterRule *)rule, source))) {
gboolean matched;
- if (((FilterRule *)rule)->source != sourcetype) {
- d(fprintf (stderr, "skipping rule %s - wrong source type (%d %d)\n", ((FilterRule *)rule)->name,
- ((FilterRule *)rule)->source, sourcetype));
- continue;
- }
-
g_string_truncate (fsearch, 0);
g_string_truncate (faction, 0);
@@ -464,59 +620,40 @@ filter_driver_run (FilterDriver *driver, CamelMimeMessage *message, CamelMessage
matched = filter_message_search (p->message, p->info, fsearch->str, p->ex);
mail_tool_camel_lock_down ();
- if (!matched)
- continue;
-
+ if (matched) {
#ifndef NO_WARNINGS
#warning "Must check expression parsed and executed properly?"
#endif
- if (logfile) {
- /* write log header */
- time_t t;
- char date[50];
-
- time (&t);
- strftime (date, 49, "%a, %d %b %Y %H:%M:%S", localtime (&t));
- fprintf (logfile, "Applied filter \"%s\" to message from %s - \"%s\" at %s\n",
- fsearch->str, camel_mime_message_get_from (message),
- camel_mime_message_get_subject (message), date);
- }
-
- /* perform necessary filtering actions */
- e_sexp_input_text (p->eval, faction->str, strlen (faction->str));
- e_sexp_parse (p->eval);
- r = e_sexp_eval (p->eval);
- e_sexp_result_free (r);
-
- if (logfile) {
- /* spacer between filters */
- fprintf (logfile, "\n");
+ /* perform necessary filtering actions */
+ e_sexp_input_text (p->eval, faction->str, strlen (faction->str));
+ e_sexp_parse (p->eval);
+ r = e_sexp_eval (p->eval);
+ e_sexp_result_free (r);
+ if (p->terminated)
+ break;
}
-
- if (p->terminated)
- break;
}
g_string_free (fsearch, TRUE);
g_string_free (faction, TRUE);
- if (!p->deleted && !p->copied && inbox) {
+ if (!p->deleted && !p->copied && p->defaultfolder) {
/* copy it to the default inbox */
+ report_status(driver, FILTER_STATUS_ACTION, "Copy to default folder");
mail_tool_camel_lock_up ();
- camel_folder_append_message (inbox, p->message, p->info, p->ex);
+ camel_folder_append_message (p->defaultfolder, p->message, p->info, p->ex);
mail_tool_camel_lock_down ();
}
-
- /* transfer the exception over to the parents exception */
- if (camel_exception_is_set (p->ex))
- camel_exception_xfer (ex, p->ex);
- camel_exception_free (p->ex);
-
- camel_object_unref (CAMEL_OBJECT (message));
- if (inbox)
- camel_object_unref (CAMEL_OBJECT (inbox));
-
- gtk_object_unref (GTK_OBJECT (driver));
+
+ if (freeinfo) {
+ camel_flag_list_free(&info->user_flags);
+ camel_tag_list_free(&info->user_tags);
+ g_free(info->subject);
+ g_free(info->from);
+ g_free(info->to);
+ g_free(info->cc);
+ g_free(info);
+ }
return p->copied;
}
diff --git a/filter/filter-driver.h b/filter/filter-driver.h
index 36a5561ed1..90a6db6a7b 100644
--- a/filter/filter-driver.h
+++ b/filter/filter-driver.h
@@ -46,17 +46,37 @@ struct _FilterDriverClass {
GtkObjectClass parent_class;
};
+/* type of status for a status report */
+enum filter_status_t {
+ FILTER_STATUS_NONE,
+ FILTER_STATUS_START, /* start of new message processed */
+ FILTER_STATUS_ACTION, /* an action performed */
+ FILTER_STATUS_PROGRESS, /* (an) extra update(s), if its taking longer to process */
+ FILTER_STATUS_END, /* end of message */
+};
+
typedef CamelFolder * (*FilterGetFolderFunc) (FilterDriver *, const char *uri, void *data);
+/* report status */
+typedef void (FDStatusFunc)(FilterDriver *driver, enum filter_status_t status, const char *desc, CamelMimeMessage *msg, void *data);
guint filter_driver_get_type (void);
FilterDriver *filter_driver_new (FilterContext *ctx, FilterGetFolderFunc fetcher, void *data);
+/* modifiers */
+void filter_driver_set_status_func(FilterDriver *d, FDStatusFunc *func, void *data);
+void filter_driver_set_default_folder(FilterDriver *d, CamelFolder *def);
+
/*void filter_driver_set_global(FilterDriver *, const char *name, const char *value);*/
/* filter a message - returns TRUE if the message was filtered into some location other than inbox */
-gboolean filter_driver_run (FilterDriver *driver, CamelMimeMessage *message, CamelMessageInfo *info,
- CamelFolder *inbox, enum _filter_source_t sourcetype,
- FILE *logfile, CamelException *ex);
+gboolean filter_driver_filter_message (FilterDriver *driver, CamelMimeMessage *message, CamelMessageInfo *info,
+ const char *source, CamelException *ex);
+void filter_driver_filter_mbox (FilterDriver *driver, const char *mbox, const char *source, CamelException *ex);
+void filter_driver_filter_folder (FilterDriver *driver, CamelFolder *folder, const char *source,
+ GPtrArray *uids, gboolean remove, CamelException *ex);
+
+/* convenience function to log the status, data should be the FILE * of the logfile */
+void filter_driver_status_log(FilterDriver *driver, enum filter_status_t status, const char *desc, CamelMimeMessage *msg, void *data);
#if 0
/* generate the search query/action string for a filter option */
diff --git a/filter/filter-editor.c b/filter/filter-editor.c
index cb3e879f04..bed8a0f032 100644
--- a/filter/filter-editor.c
+++ b/filter/filter-editor.c
@@ -130,7 +130,7 @@ struct _editor_data {
FilterRule *current;
GtkList *list;
GtkButton *buttons[BUTTON_LAST];
- enum _filter_source_t current_source;
+ char *current_source;
};
static void set_sensitive (struct _editor_data *data);
@@ -147,7 +147,7 @@ rule_add (GtkWidget *widget, struct _editor_data *data)
d(printf ("add rule\n"));
/* create a new rule with 1 match and 1 action */
rule = filter_filter_new ();
- ((FilterRule *)rule)->source = data->current_source;
+ filter_rule_set_source((FilterRule *)rule, data->current_source);
part = rule_context_next_part (data->f, NULL);
filter_rule_add_part ((FilterRule *)rule, filter_part_clone (part));
@@ -196,15 +196,13 @@ rule_edit (GtkWidget *widget, struct _editor_data *data)
d(printf ("edit rule\n"));
rule = data->current;
w = filter_rule_get_widget (rule, data->f);
- gd = gnome_dialog_new (_("Edit Rule"),
- GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL,
- NULL);
+ gd = gnome_dialog_new(_("Edit Rule"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (gd)->vbox), w, FALSE, TRUE, 0);
gtk_widget_show (gd);
result = gnome_dialog_run_and_close (GNOME_DIALOG (gd));
if (result == 0) {
- pos = rule_context_get_rank_rule_with_source (data->f, data->current, data->current_source);
+ pos = rule_context_get_rank_rule(data->f, data->current, data->current_source);
if (pos != -1) {
GtkListItem *item = g_list_nth_data (data->list->children, pos);
gchar *s = e_utf8_to_gtk_string ((GtkWidget *) item, data->current->name);
@@ -222,7 +220,7 @@ rule_delete (GtkWidget *widget, struct _editor_data *data)
GtkListItem *item;
d(printf("ddelete rule\n"));
- pos = rule_context_get_rank_rule_with_source (data->f, data->current, data->current_source);
+ pos = rule_context_get_rank_rule(data->f, data->current, data->current_source);
if (pos != -1) {
rule_context_remove_rule (data->f, data->current);
@@ -260,7 +258,7 @@ rule_up (GtkWidget *widget, struct _editor_data *data)
int pos;
d(printf("up rule\n"));
- pos = rule_context_get_rank_rule_with_source (data->f, data->current, data->current_source);
+ pos = rule_context_get_rank_rule(data->f, data->current, data->current_source);
if (pos > 0) {
rule_move (data, pos, pos-1);
}
@@ -272,7 +270,7 @@ rule_down (GtkWidget *widget, struct _editor_data *data)
int pos;
d(printf ("down rule\n"));
- pos = rule_context_get_rank_rule_with_source (data->f, data->current, data->current_source);
+ pos = rule_context_get_rank_rule(data->f, data->current, data->current_source);
rule_move (data, pos, pos+1);
}
@@ -293,7 +291,7 @@ set_sensitive (struct _editor_data *data)
FilterRule *rule = NULL;
int index = -1, count = 0;
- while ((rule = rule_context_next_rule (data->f, rule))) {
+ while ((rule = rule_context_next_rule (data->f, rule, data->current_source))) {
if (rule == data->current)
index=count;
count++;
@@ -335,22 +333,16 @@ select_source (GtkMenuItem *mi, struct _editor_data *data)
{
FilterRule *rule = NULL;
GList *newitems = NULL;
- enum _filter_source_t source;
+ char *source;
- source = (enum _filter_source_t) GPOINTER_TO_INT (
- gtk_object_get_data (GTK_OBJECT (mi), "number"));
+ source = gtk_object_get_data (GTK_OBJECT (mi), "source");
gtk_list_clear_items (GTK_LIST (data->list), 0, -1);
d(printf ("Checking for rules that are of type %d\n", source));
- while ((rule = rule_context_next_rule (data->f, rule)) != NULL) {
+ while ((rule = rule_context_next_rule (data->f, rule, source)) != NULL) {
GtkWidget *item;
- gchar *s;
-
- if (rule->source != source) {
- d(printf (" skipping %s: %d != %d\n", rule->name, rule->source, source));
- continue;
- }
+ char *s;
d(printf (" hit %s (%d)\n", rule->name, source));
s = e_utf8_to_gtk_string (GTK_WIDGET (data->list), rule->name);
@@ -367,6 +359,12 @@ select_source (GtkMenuItem *mi, struct _editor_data *data)
set_sensitive (data);
}
+static char *source_names[] = {
+ "incoming",
+ "demand",
+ "outgoing"
+};
+
GtkWidget *
filter_editor_construct (struct _FilterContext *f)
{
@@ -400,8 +398,12 @@ filter_editor_construct (struct _FilterContext *f)
if (i == 0)
firstitem = b;
- /* make sure that the glade is in sync with enum _filter_source_t! */
- gtk_object_set_data (GTK_OBJECT (b), "number", GINT_TO_POINTER (i));
+ /* make sure that the glade is in sync with the source list! */
+ if (i < sizeof(source_names)/sizeof(source_names[0])) {
+ gtk_object_set_data (GTK_OBJECT (b), "source", source_names[i]);
+ } else {
+ g_warning("Glade file " FILTER_GLADEDIR "/filter.glade out of sync with editor code");
+ }
gtk_signal_connect (GTK_OBJECT (b), "activate", select_source, data);
i++;
diff --git a/filter/filter-rule.c b/filter/filter-rule.c
index 33dc290c80..11c5e1adde 100644
--- a/filter/filter-rule.c
+++ b/filter/filter-rule.c
@@ -30,14 +30,14 @@
#define d(x)
-static xmlNodePtr xml_encode (FilterRule *);
-static int xml_decode (FilterRule *, xmlNodePtr, RuleContext *);
-static void build_code (FilterRule *, GString *out);
-static GtkWidget *get_widget (FilterRule *fr, struct _RuleContext *f);
+static xmlNodePtr xml_encode(FilterRule *);
+static int xml_decode(FilterRule *, xmlNodePtr, RuleContext *);
+static void build_code(FilterRule *, GString * out);
+static GtkWidget *get_widget(FilterRule * fr, struct _RuleContext *f);
-static void filter_rule_class_init (FilterRuleClass *class);
-static void filter_rule_init (FilterRule *gspaper);
-static void filter_rule_finalise (GtkObject *obj);
+static void filter_rule_class_init(FilterRuleClass * class);
+static void filter_rule_init(FilterRule * gspaper);
+static void filter_rule_finalise(GtkObject * obj);
#define _PRIVATE(x) (((FilterRule *)(x))->priv)
@@ -53,73 +53,73 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-guint
-filter_rule_get_type (void)
+guint filter_rule_get_type(void)
{
static guint type = 0;
-
+
if (!type) {
GtkTypeInfo type_info = {
"FilterRule",
sizeof(FilterRule),
sizeof(FilterRuleClass),
- (GtkClassInitFunc)filter_rule_class_init,
- (GtkObjectInitFunc)filter_rule_init,
- (GtkArgSetFunc)NULL,
- (GtkArgGetFunc)NULL
+ (GtkClassInitFunc) filter_rule_class_init,
+ (GtkObjectInitFunc) filter_rule_init,
+ (GtkArgSetFunc) NULL,
+ (GtkArgGetFunc) NULL
};
-
- type = gtk_type_unique (gtk_object_get_type (), &type_info);
+
+ type = gtk_type_unique(gtk_object_get_type(), &type_info);
}
-
+
return type;
}
static void
-filter_rule_class_init (FilterRuleClass *class)
+filter_rule_class_init(FilterRuleClass * class)
{
GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *)class;
- parent_class = gtk_type_class (gtk_object_get_type ());
-
+
+ object_class = (GtkObjectClass *) class;
+ parent_class = gtk_type_class(gtk_object_get_type());
+
object_class->finalize = filter_rule_finalise;
-
+
/* override methods */
class->xml_encode = xml_encode;
class->xml_decode = xml_decode;
class->build_code = build_code;
class->get_widget = get_widget;
-
+
/* signals */
-
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+
+ gtk_object_class_add_signals(object_class, signals, LAST_SIGNAL);
}
static void
-filter_rule_init (FilterRule *o)
+filter_rule_init(FilterRule * o)
{
- o->priv = g_malloc0 (sizeof (*o->priv));
+ o->priv = g_malloc0(sizeof(*o->priv));
}
static void
-unref_list (GList *l)
+unref_list(GList * l)
{
while (l) {
- gtk_object_unref (GTK_OBJECT (l->data));
- l = g_list_next (l);
+ gtk_object_unref(GTK_OBJECT(l->data));
+ l = g_list_next(l);
}
}
static void
-filter_rule_finalise (GtkObject *obj)
+filter_rule_finalise(GtkObject * obj)
{
- FilterRule *o = (FilterRule *)obj;
-
- g_free (o->name);
- unref_list (o->parts);
-
- ((GtkObjectClass *)(parent_class))->finalize (obj);
+ FilterRule *o = (FilterRule *) obj;
+
+ g_free(o->name);
+ g_free(o->source);
+ unref_list(o->parts);
+
+ ((GtkObjectClass *) (parent_class))->finalize(obj);
}
/**
@@ -130,206 +130,196 @@ filter_rule_finalise (GtkObject *obj)
* Return value: A new #FilterRule object.
**/
FilterRule *
-filter_rule_new (void)
+filter_rule_new(void)
{
- FilterRule *o = (FilterRule *)gtk_type_new (filter_rule_get_type ());
+ FilterRule *o = (FilterRule *) gtk_type_new(filter_rule_get_type());
+
return o;
}
void
-filter_rule_set_name (FilterRule *fr, const char *name)
+filter_rule_set_name(FilterRule * fr, const char *name)
+{
+ g_free(fr->name);
+ fr->name = g_strdup(name);
+}
+
+void
+filter_rule_set_source(FilterRule * fr, const char *source)
{
- g_free (fr->name);
- fr->name = g_strdup (name);
+ g_free(fr->source);
+ fr->source = g_strdup(source);
}
-xmlNodePtr
-filter_rule_xml_encode (FilterRule *fr)
+xmlNodePtr filter_rule_xml_encode(FilterRule * fr)
{
- return ((FilterRuleClass *)((GtkObject *)fr)->klass)->xml_encode (fr);
+ return ((FilterRuleClass *) ((GtkObject *) fr)->klass)->xml_encode(fr);
}
static xmlNodePtr
-xml_encode (FilterRule *fr)
+xml_encode(FilterRule * fr)
{
xmlNodePtr node, set, work;
GList *l;
-
- node = xmlNewNode (NULL, "rule");
+
+ node = xmlNewNode(NULL, "rule");
switch (fr->grouping) {
case FILTER_GROUP_ALL:
- xmlSetProp (node, "grouping", "all");
+ xmlSetProp(node, "grouping", "all");
break;
case FILTER_GROUP_ANY:
- xmlSetProp (node, "grouping", "any");
+ xmlSetProp(node, "grouping", "any");
break;
}
-
- switch (fr->source) {
- case FILTER_SOURCE_INCOMING:
- xmlSetProp (node, "source", "incoming");
- break;
- case FILTER_SOURCE_DEMAND:
- xmlSetProp (node, "source", "ondemand");
- break;
- case FILTER_SOURCE_OUTGOING:
- xmlSetProp (node, "source", "outgoing");
- break;
+
+ if (fr->source) {
+ xmlSetProp(node, "source", "incoming");
}
-
+
if (fr->name) {
- work = xmlNewNode (NULL, "title");
- xmlNodeSetContent (work, fr->name);
- xmlAddChild (node, work);
+ work = xmlNewNode(NULL, "title");
+ xmlNodeSetContent(work, fr->name);
+ xmlAddChild(node, work);
}
- set = xmlNewNode (NULL, "partset");
- xmlAddChild (node, set);
+ set = xmlNewNode(NULL, "partset");
+ xmlAddChild(node, set);
l = fr->parts;
while (l) {
- work = filter_part_xml_encode ((FilterPart *)l->data);
- xmlAddChild (set, work);
- l = g_list_next (l);
+ work = filter_part_xml_encode((FilterPart *) l->data);
+ xmlAddChild(set, work);
+ l = g_list_next(l);
}
return node;
}
static void
-load_set (xmlNodePtr node, FilterRule *fr, RuleContext *f)
+load_set(xmlNodePtr node, FilterRule * fr, RuleContext * f)
{
xmlNodePtr work;
char *rulename;
FilterPart *part;
-
+
work = node->childs;
while (work) {
- if (!strcmp (work->name, "part")) {
- rulename = xmlGetProp (work, "name");
- part = rule_context_find_part (f, rulename);
+ if (!strcmp(work->name, "part")) {
+ rulename = xmlGetProp(work, "name");
+ part = rule_context_find_part(f, rulename);
if (part) {
- part = filter_part_clone (part);
- filter_part_xml_decode (part, work);
- filter_rule_add_part (fr, part);
+ part = filter_part_clone(part);
+ filter_part_xml_decode(part, work);
+ filter_rule_add_part(fr, part);
} else {
- g_warning ("cannot find rule part '%s'\n", rulename);
+ g_warning("cannot find rule part '%s'\n", rulename);
}
- xmlFree (rulename);
+ xmlFree(rulename);
} else {
- g_warning ("Unknwon xml node in part: %s", work->name);
+ g_warning("Unknwon xml node in part: %s", work->name);
}
work = work->next;
}
}
int
-filter_rule_xml_decode (FilterRule *fr, xmlNodePtr node, RuleContext *f)
+filter_rule_xml_decode(FilterRule * fr, xmlNodePtr node, RuleContext * f)
{
- return ((FilterRuleClass *)((GtkObject *)fr)->klass)->xml_decode (fr, node, f);
+ return ((FilterRuleClass *) ((GtkObject *) fr)->klass)->xml_decode(fr, node, f);
}
static int
-xml_decode (FilterRule *fr, xmlNodePtr node, RuleContext *f)
+xml_decode(FilterRule * fr, xmlNodePtr node, RuleContext * f)
{
xmlNodePtr work;
char *grouping;
char *source;
-
+
if (fr->name) {
- g_free (fr->name);
+ g_free(fr->name);
fr->name = NULL;
}
-
- grouping = xmlGetProp (node, "grouping");
- if (!strcmp (grouping, "any"))
+
+ grouping = xmlGetProp(node, "grouping");
+ if (!strcmp(grouping, "any"))
fr->grouping = FILTER_GROUP_ANY;
else
fr->grouping = FILTER_GROUP_ALL;
-
- /* FIXME: free source and grouping? */
- source = xmlGetProp (node, "source");
- if (!source) /*default to incoming*/
- fr->source = FILTER_SOURCE_INCOMING;
- else if (!strcmp (source, "outgoing"))
- fr->source = FILTER_SOURCE_OUTGOING;
- else if (!strcmp (source, "ondemand"))
- fr->source = FILTER_SOURCE_DEMAND;
- else if (!strcmp (source, "incoming"))
- fr->source = FILTER_SOURCE_INCOMING;
- else {
- g_warning ("Unknown filter source type \"%s\"", source);
- fr->source = FILTER_SOURCE_INCOMING;
+ xmlFree(grouping);
+
+ source = xmlGetProp(node, "source");
+ if (source) {
+ fr->source = source;
}
-
+
work = node->childs;
while (work) {
- if (!strcmp (work->name, "partset")) {
- load_set (work, fr, f);
- } else if (!strcmp (work->name, "title")) {
+ if (!strcmp(work->name, "partset")) {
+ load_set(work, fr, f);
+ } else if (!strcmp(work->name, "title")) {
if (!fr->name)
- fr->name = xmlNodeGetContent (work);
+ fr->name = xmlNodeGetContent(work);
}
work = work->next;
}
-
+
return 0;
}
void
-filter_rule_add_part (FilterRule *fr, FilterPart *fp)
+filter_rule_add_part(FilterRule * fr, FilterPart * fp)
{
- fr->parts = g_list_append (fr->parts, fp);
+ fr->parts = g_list_append(fr->parts, fp);
}
void
-filter_rule_remove_part (FilterRule *fr, FilterPart *fp)
+filter_rule_remove_part(FilterRule * fr, FilterPart * fp)
{
- fr->parts = g_list_remove (fr->parts, fp);
+ fr->parts = g_list_remove(fr->parts, fp);
}
void
-filter_rule_replace_part (FilterRule *fr, FilterPart *fp, FilterPart *new)
+filter_rule_replace_part(FilterRule * fr, FilterPart * fp, FilterPart * new)
{
GList *l;
-
- l = g_list_find (fr->parts, fp);
+
+ l = g_list_find(fr->parts, fp);
if (l) {
l->data = new;
} else {
- fr->parts = g_list_append (fr->parts, new);
+ fr->parts = g_list_append(fr->parts, new);
}
}
void
-filter_rule_build_code (FilterRule *fr, GString *out)
+filter_rule_build_code(FilterRule * fr, GString * out)
{
- return ((FilterRuleClass *)((GtkObject *)fr)->klass)->build_code (fr, out);
+ return ((FilterRuleClass *) ((GtkObject *) fr)->klass)->build_code(fr, out);
}
static void
-build_code (FilterRule *fr, GString *out)
+build_code(FilterRule * fr, GString * out)
{
switch (fr->grouping) {
case FILTER_GROUP_ALL:
- g_string_append (out, " (and\n ");
+ g_string_append(out, " (and\n ");
break;
case FILTER_GROUP_ANY:
- g_string_append (out, " (or\n ");
+ g_string_append(out, " (or\n ");
break;
default:
- g_warning ("Invalid grouping");
+ g_warning("Invalid grouping");
}
-
- filter_part_build_code_list (fr->parts, out);
- g_string_append (out, ")\n");
+
+ filter_part_build_code_list(fr->parts, out);
+ g_string_append(out, ")\n");
}
static void
-match_all (GtkWidget *widget, FilterRule *fr)
+match_all(GtkWidget * widget, FilterRule * fr)
{
fr->grouping = FILTER_GROUP_ALL;
}
static void
-match_any (GtkWidget *widget, FilterRule *fr)
+match_any(GtkWidget * widget, FilterRule * fr)
{
fr->grouping = FILTER_GROUP_ANY;
}
@@ -342,30 +332,30 @@ struct _part_data {
};
static void
-option_activate (GtkMenuItem *item, struct _part_data *data)
+option_activate(GtkMenuItem * item, struct _part_data *data)
{
- FilterPart *part = gtk_object_get_data (GTK_OBJECT (item), "part");
+ FilterPart *part = gtk_object_get_data(GTK_OBJECT(item), "part");
FilterPart *newpart;
-
+
/* dont update if we haven't changed */
- if (!strcmp (part->title, data->part->title))
+ if (!strcmp(part->title, data->part->title))
return;
-
+
/* here we do a widget shuffle, throw away the old widget/rulepart,
and create another */
if (data->partwidget)
- gtk_container_remove (GTK_CONTAINER (data->container), data->partwidget);
- newpart = filter_part_clone (part);
- filter_rule_replace_part (data->fr, data->part, newpart);
- gtk_object_unref (GTK_OBJECT (data->part));
+ gtk_container_remove(GTK_CONTAINER(data->container), data->partwidget);
+ newpart = filter_part_clone(part);
+ filter_rule_replace_part(data->fr, data->part, newpart);
+ gtk_object_unref(GTK_OBJECT(data->part));
data->part = newpart;
- data->partwidget = filter_part_get_widget (newpart);
+ data->partwidget = filter_part_get_widget(newpart);
if (data->partwidget)
- gtk_box_pack_start (GTK_BOX (data->container), data->partwidget, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(data->container), data->partwidget, FALSE, FALSE, 0);
}
static GtkWidget *
-get_rule_part_widget (RuleContext *f, FilterPart *newpart, FilterRule *fr)
+get_rule_part_widget(RuleContext * f, FilterPart * newpart, FilterRule * fr)
{
FilterPart *part = NULL;
GtkWidget *menu;
@@ -376,48 +366,48 @@ get_rule_part_widget (RuleContext *f, FilterPart *newpart, FilterRule *fr)
int index = 0, current = 0;
struct _part_data *data;
gchar *s;
-
- data = g_malloc0 (sizeof (*data));
+
+ data = g_malloc0(sizeof(*data));
data->fr = fr;
data->f = f;
data->part = newpart;
-
- hbox = gtk_hbox_new (FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 0);
/* only set to automatically clean up the memory */
- gtk_object_set_data_full (GTK_OBJECT (hbox), "data", data, g_free);
-
- p = filter_part_get_widget (newpart);
-
+ gtk_object_set_data_full(GTK_OBJECT(hbox), "data", data, g_free);
+
+ p = filter_part_get_widget(newpart);
+
data->partwidget = p;
data->container = hbox;
-
- menu = gtk_menu_new ();
+
+ menu = gtk_menu_new();
/* sigh, this is a little ugly */
- while ((part = rule_context_next_part (f, part))) {
- s = e_utf8_to_gtk_string (menu, part->title);
- item = gtk_menu_item_new_with_label (s);
- g_free (s);
- gtk_object_set_data (GTK_OBJECT (item), "part", part);
- gtk_signal_connect (GTK_OBJECT (item), "activate", option_activate, data);
- gtk_menu_append (GTK_MENU (menu), item);
- gtk_widget_show (item);
- if (!strcmp (newpart->title, part->title)) {
+ while ((part = rule_context_next_part(f, part))) {
+ s = e_utf8_to_gtk_string(menu, part->title);
+ item = gtk_menu_item_new_with_label(s);
+ g_free(s);
+ gtk_object_set_data(GTK_OBJECT(item), "part", part);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", option_activate, data);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+ if (!strcmp(newpart->title, part->title)) {
current = index;
}
index++;
}
-
- omenu = gtk_option_menu_new ();
- gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
- gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), current);
- gtk_widget_show (omenu);
-
- gtk_box_pack_start (GTK_BOX (hbox), omenu, FALSE, FALSE, 0);
+
+ omenu = gtk_option_menu_new();
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), menu);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(omenu), current);
+ gtk_widget_show(omenu);
+
+ gtk_box_pack_start(GTK_BOX(hbox), omenu, FALSE, FALSE, 0);
if (p) {
- gtk_box_pack_start (GTK_BOX (hbox), p, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), p, FALSE, FALSE, 0);
}
- gtk_widget_show_all (hbox);
-
+ gtk_widget_show_all(hbox);
+
return hbox;
}
@@ -428,59 +418,59 @@ struct _rule_data {
};
static void
-less_parts (GtkWidget *button, struct _rule_data *data)
+less_parts(GtkWidget * button, struct _rule_data *data)
{
GList *l;
FilterPart *part;
GtkWidget *w;
-
+
l = data->fr->parts;
- if (g_list_length (l) < 2)
+ if (g_list_length(l) < 2)
return;
-
+
/* remove the last one from the list */
- l = g_list_last (l);
+ l = g_list_last(l);
part = l->data;
- filter_rule_remove_part (data->fr, part);
- gtk_object_unref ((GtkObject *)part);
-
+ filter_rule_remove_part(data->fr, part);
+ gtk_object_unref((GtkObject *) part);
+
/* and from the display */
- l = g_list_last (GTK_BOX(data->parts)->children);
- w = ((GtkBoxChild *)l->data)->widget;
- gtk_container_remove (GTK_CONTAINER (data->parts), w);
+ l = g_list_last(GTK_BOX(data->parts)->children);
+ w = ((GtkBoxChild *) l->data)->widget;
+ gtk_container_remove(GTK_CONTAINER(data->parts), w);
}
static void
-more_parts (GtkWidget *button, struct _rule_data *data)
+more_parts(GtkWidget * button, struct _rule_data *data)
{
FilterPart *new;
GtkWidget *w;
-
+
/* create a new rule entry, use the first type of rule */
- new = rule_context_next_part (data->f, NULL);
+ new = rule_context_next_part(data->f, NULL);
if (new) {
- new = filter_part_clone (new);
- filter_rule_add_part (data->fr, new);
- w = get_rule_part_widget (data->f, new, data->fr);
- gtk_box_pack_start (GTK_BOX (data->parts), w, FALSE, FALSE, 0);
+ new = filter_part_clone(new);
+ filter_rule_add_part(data->fr, new);
+ w = get_rule_part_widget(data->f, new, data->fr);
+ gtk_box_pack_start(GTK_BOX(data->parts), w, FALSE, FALSE, 0);
}
}
static void
-name_changed (GtkEntry *entry, FilterRule *fr)
+name_changed(GtkEntry * entry, FilterRule * fr)
{
- g_free (fr->name);
- fr->name = e_utf8_gtk_entry_get_text (entry);
+ g_free(fr->name);
+ fr->name = e_utf8_gtk_entry_get_text(entry);
}
GtkWidget *
-filter_rule_get_widget (FilterRule *fr, struct _RuleContext *f)
+filter_rule_get_widget(FilterRule * fr, struct _RuleContext *f)
{
- return ((FilterRuleClass *)((GtkObject *)fr)->klass)->get_widget (fr, f);
+ return ((FilterRuleClass *) ((GtkObject *) fr)->klass)->get_widget(fr, f);
}
static GtkWidget *
-get_widget (FilterRule *fr, struct _RuleContext *f)
+get_widget(FilterRule * fr, struct _RuleContext *f)
{
GtkWidget *vbox, *parts, *inframe;
GtkWidget *hbox;
@@ -496,139 +486,149 @@ get_widget (FilterRule *fr, struct _RuleContext *f)
FilterPart *part;
char *string;
struct _rule_data *data;
-
+
/* this stuff should probably be a table, but the
rule parts need to be a vbox */
- vbox = gtk_vbox_new (FALSE, 3);
-
- label = gtk_label_new (_("Rule name: "));
- name = gtk_entry_new ();
-
+ vbox = gtk_vbox_new(FALSE, 3);
+
+ label = gtk_label_new(_("Rule name: "));
+ name = gtk_entry_new();
+
if (!fr->name)
- fr->name = g_strdup (_("untitled"));
-
+ fr->name = g_strdup(_("untitled"));
+
if (fr->name)
- e_utf8_gtk_entry_set_text (GTK_ENTRY (name), fr->name);
-
- hbox = gtk_hbox_new (FALSE, 3);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), name, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3);
- gtk_signal_connect (GTK_OBJECT (name), "changed", name_changed, fr);
-
- frame = gtk_frame_new (_("If"));
- inframe = gtk_vbox_new (FALSE, 3);
- gtk_container_add (GTK_CONTAINER (frame), inframe);
-
+ e_utf8_gtk_entry_set_text(GTK_ENTRY(name), fr->name);
+
+ hbox = gtk_hbox_new(FALSE, 3);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), name, TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
+ gtk_signal_connect(GTK_OBJECT(name), "changed", name_changed, fr);
+
+ frame = gtk_frame_new(_("If"));
+ inframe = gtk_vbox_new(FALSE, 3);
+ gtk_container_add(GTK_CONTAINER(frame), inframe);
+
/* this is the parts list, it should probably be inside a scrolling list */
- parts = gtk_vbox_new (FALSE, 3);
-
+ parts = gtk_vbox_new(FALSE, 3);
+
/* data for the parts part of the display */
- data = g_malloc0 (sizeof (*data));
+ data = g_malloc0(sizeof(*data));
data->f = f;
data->fr = fr;
data->parts = parts;
-
+
/* only set to automatically clean up the memory */
- gtk_object_set_data_full (GTK_OBJECT (vbox), "data", data, g_free);
-
- hbox = gtk_hbox_new (FALSE, 3);
- label = gtk_label_new (_("Execute actions"));
-
- menu = gtk_menu_new ();
-
- string = e_utf8_to_gtk_string (menu, _("if all criteria are met"));
- item = gtk_menu_item_new_with_label (string);
- g_free (string);
- gtk_signal_connect (GTK_OBJECT (item), "activate", match_all, fr);
- gtk_menu_append (GTK_MENU (menu), item);
- gtk_widget_show (item);
-
- string = e_utf8_to_gtk_string (menu, _("if any criteria are met"));
- item = gtk_menu_item_new_with_label (string);
- g_free (string);
- gtk_signal_connect (GTK_OBJECT (item), "activate", match_any, fr);
- gtk_menu_append (GTK_MENU (menu), item);
- gtk_widget_show (item);
-
- omenu = gtk_option_menu_new ();
- gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
- gtk_option_menu_set_history (GTK_OPTION_MENU (omenu),
- fr->grouping == FILTER_GROUP_ALL ? 0 : 1);
- gtk_widget_show (omenu);
-
- pixmap = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_ADD);
- button = gnome_pixmap_button (pixmap, _("Add criterion"));
- gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
- gtk_signal_connect (GTK_OBJECT (button), "clicked", more_parts, data);
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 3);
-
- pixmap = gnome_stock_new_with_icon (GNOME_STOCK_PIXMAP_REMOVE);
- button = gnome_pixmap_button (pixmap, _("Remove criterion"));
- gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
- gtk_signal_connect (GTK_OBJECT (button), "clicked", less_parts, data);
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 3);
-
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), omenu, FALSE, FALSE, 0);
-
- gtk_box_pack_start (GTK_BOX (inframe), hbox, FALSE, FALSE, 3);
-
+ gtk_object_set_data_full(GTK_OBJECT(vbox), "data", data, g_free);
+
+ hbox = gtk_hbox_new(FALSE, 3);
+ label = gtk_label_new(_("Execute actions"));
+
+ menu = gtk_menu_new();
+
+ string = e_utf8_to_gtk_string(menu, _("if all criteria are met"));
+ item = gtk_menu_item_new_with_label(string);
+ g_free(string);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", match_all, fr);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ string = e_utf8_to_gtk_string(menu, _("if any criteria are met"));
+ item = gtk_menu_item_new_with_label(string);
+ g_free(string);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", match_any, fr);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ omenu = gtk_option_menu_new();
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(omenu), menu);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(omenu), fr->grouping == FILTER_GROUP_ALL ? 0 : 1);
+ gtk_widget_show(omenu);
+
+ pixmap = gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_ADD);
+ button = gnome_pixmap_button(pixmap, _("More criterion"));
+ gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", more_parts, data);
+ gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 3);
+
+ pixmap = gnome_stock_new_with_icon(GNOME_STOCK_PIXMAP_REMOVE);
+ button = gnome_pixmap_button(pixmap, _("Fewer criterion"));
+ gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", less_parts, data);
+ gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 3);
+
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), omenu, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(inframe), hbox, FALSE, FALSE, 3);
+
l = fr->parts;
while (l) {
part = l->data;
- w = get_rule_part_widget (f, part, fr);
- gtk_box_pack_start (GTK_BOX (parts), w, FALSE, FALSE, 3);
- l = g_list_next (l);
+ w = get_rule_part_widget(f, part, fr);
+ gtk_box_pack_start(GTK_BOX(parts), w, FALSE, FALSE, 3);
+ l = g_list_next(l);
}
-
- hadj = gtk_adjustment_new (0.0, 0.0, 1.0, 1.0 ,1.0, 1.0);
- vadj = gtk_adjustment_new (0.0, 0.0, 1.0, 1.0 ,1.0, 1.0);
- scrolledwindow = gtk_scrolled_window_new (GTK_ADJUSTMENT (hadj), GTK_ADJUSTMENT (vadj));
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledwindow), parts);
-
- gtk_box_pack_start (GTK_BOX (inframe), scrolledwindow, FALSE, FALSE, 3);
-
- /*gtk_box_pack_start (GTK_BOX (inframe), parts, FALSE, FALSE, 3);*/
-
- gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 3);
-
- gtk_widget_show_all (vbox);
-
+
+ hadj = gtk_adjustment_new(0.0, 0.0, 1.0, 1.0, 1.0, 1.0);
+ vadj = gtk_adjustment_new(0.0, 0.0, 1.0, 1.0, 1.0, 1.0);
+ scrolledwindow = gtk_scrolled_window_new(GTK_ADJUSTMENT(hadj), GTK_ADJUSTMENT(vadj));
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwindow), parts);
+
+ gtk_box_pack_start(GTK_BOX(inframe), scrolledwindow, FALSE, FALSE, 3);
+
+ /*gtk_box_pack_start (GTK_BOX (inframe), parts, FALSE, FALSE, 3); */
+
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 3);
+
+ gtk_widget_show_all(vbox);
+
return vbox;
}
FilterRule *
-filter_rule_next_list (GList *l, FilterRule *last)
+filter_rule_next_list(GList * l, FilterRule * last, const char *source)
{
GList *node = l;
-
+
if (last != NULL) {
- node = g_list_find (node, last);
+ node = g_list_find(node, last);
if (node == NULL)
node = l;
else
- node = g_list_next (node);
+ node = g_list_next(node);
+ }
+
+ if (source) {
+ while (node) {
+ FilterRule *rule = node->data;
+
+ if (rule->source && strcmp(rule->source, source) == 0)
+ break;
+ node = g_list_next(node);
+ }
}
-
+
if (node)
return node->data;
-
+
return NULL;
}
FilterRule *
-filter_rule_find_list (GList *l, const char *name)
+filter_rule_find_list(GList * l, const char *name, const char *source)
{
while (l) {
FilterRule *rule = l->data;
- if (!strcmp (rule->name, name))
- return rule;
- l = g_list_next (l);
+
+ if (strcmp(rule->name, name) == 0)
+ if (source == NULL || (rule->source != NULL && strcmp(rule->source, source) == 0))
+ return rule;
+ l = g_list_next(l);
}
-
+
return NULL;
}
diff --git a/filter/filter-rule.h b/filter/filter-rule.h
index e1d5655050..8c6f9cf42b 100644
--- a/filter/filter-rule.h
+++ b/filter/filter-rule.h
@@ -39,21 +39,20 @@ enum _filter_grouping_t {
FILTER_GROUP_ANY /* any rule must match */
};
-enum _filter_source_t {
- FILTER_SOURCE_INCOMING, /* performed on incoming email */
- FILTER_SOURCE_DEMAND, /* performed on the selected folder
- * when the user asks for it */
- FILTER_SOURCE_OUTGOING /* performed on outgoing mail */
-};
+
+#define FILTER_SOURCE_INCOMING "incoming" /* performed on incoming email */
+#define FILTER_SOURCE_DEMAND "demand" /* performed on the selected folder
+ * when the user asks for it */
+#define FILTER_SOURCE_OUTGOING "outgoing"/* performed on outgoing mail */
struct _FilterRule {
GtkObject parent;
struct _FilterRulePrivate *priv;
char *name;
+ char *source;
enum _filter_grouping_t grouping;
- enum _filter_source_t source;
GList *parts;
};
@@ -76,6 +75,7 @@ FilterRule *filter_rule_new (void);
/* methods */
void filter_rule_set_name (FilterRule *fr, const char *name);
+void filter_rule_set_source (FilterRule *fr, const char *source);
xmlNodePtr filter_rule_xml_encode (FilterRule *fr);
int filter_rule_xml_decode (FilterRule *fr, xmlNodePtr node, struct _RuleContext *f);
@@ -92,8 +92,8 @@ void filter_rule_build_action(FilterRule *fr, GString *out);
*/
/* static functions */
-FilterRule *filter_rule_next_list (GList *l, FilterRule *last);
-FilterRule *filter_rule_find_list (GList *l, const char *name);
+FilterRule *filter_rule_next_list (GList *l, FilterRule *last, const char *source);
+FilterRule *filter_rule_find_list (GList *l, const char *name, const char *source);
#endif /* ! _FILTER_RULE_H */
diff --git a/filter/rule-context.c b/filter/rule-context.c
index be3c2e5540..399d5787ef 100644
--- a/filter/rule-context.c
+++ b/filter/rule-context.c
@@ -26,12 +26,12 @@
#define d(x)
-static int load(RuleContext *f, const char *system, const char *user);
-static int save(RuleContext *f, const char *user);
+static int load(RuleContext * f, const char *system, const char *user);
+static int save(RuleContext * f, const char *user);
-static void rule_context_class_init (RuleContextClass *class);
-static void rule_context_init (RuleContext *gspaper);
-static void rule_context_finalise (GtkObject *obj);
+static void rule_context_class_init(RuleContextClass * class);
+static void rule_context_init(RuleContext * gspaper);
+static void rule_context_finalise(GtkObject * obj);
#define _PRIVATE(x) (((RuleContext *)(x))->priv)
@@ -47,34 +47,34 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
guint
-rule_context_get_type (void)
+rule_context_get_type(void)
{
static guint type = 0;
-
+
if (!type) {
GtkTypeInfo type_info = {
"RuleContext",
sizeof(RuleContext),
sizeof(RuleContextClass),
- (GtkClassInitFunc)rule_context_class_init,
- (GtkObjectInitFunc)rule_context_init,
- (GtkArgSetFunc)NULL,
- (GtkArgGetFunc)NULL
+ (GtkClassInitFunc) rule_context_class_init,
+ (GtkObjectInitFunc) rule_context_init,
+ (GtkArgSetFunc) NULL,
+ (GtkArgGetFunc) NULL
};
-
- type = gtk_type_unique(gtk_object_get_type (), &type_info);
+
+ type = gtk_type_unique(gtk_object_get_type(), &type_info);
}
-
+
return type;
}
static void
-rule_context_class_init (RuleContextClass *class)
+rule_context_class_init(RuleContextClass * class)
{
GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *)class;
- parent_class = gtk_type_class(gtk_object_get_type ());
+
+ object_class = (GtkObjectClass *) class;
+ parent_class = gtk_type_class(gtk_object_get_type());
object_class->finalize = rule_context_finalise;
@@ -88,7 +88,7 @@ rule_context_class_init (RuleContextClass *class)
}
static void
-rule_context_init (RuleContext *o)
+rule_context_init(RuleContext * o)
{
o->priv = g_malloc0(sizeof(*o->priv));
@@ -97,13 +97,13 @@ rule_context_init (RuleContext *o)
}
static void
-rule_context_finalise(GtkObject *obj)
+rule_context_finalise(GtkObject * obj)
{
- RuleContext *o = (RuleContext *)obj;
+ RuleContext *o = (RuleContext *) obj;
o = o;
- ((GtkObjectClass *)(parent_class))->finalize(obj);
+ ((GtkObjectClass *) (parent_class))->finalize(obj);
}
/**
@@ -116,11 +116,13 @@ rule_context_finalise(GtkObject *obj)
RuleContext *
rule_context_new(void)
{
- RuleContext *o = (RuleContext *)gtk_type_new(rule_context_get_type ());
+ RuleContext *o = (RuleContext *) gtk_type_new(rule_context_get_type());
+
return o;
}
-void rule_context_add_part_set(RuleContext *f, const char *setname, int part_type, RCPartFunc append, RCNextPartFunc next)
+void
+rule_context_add_part_set(RuleContext * f, const char *setname, int part_type, RCPartFunc append, RCNextPartFunc next)
{
struct _part_set_map *map;
@@ -134,7 +136,8 @@ void rule_context_add_part_set(RuleContext *f, const char *setname, int part_ty
d(printf("adding part set '%s'\n", setname));
}
-void rule_context_add_rule_set(RuleContext *f, const char *setname, int rule_type, RCRuleFunc append, RCNextRuleFunc next)
+void
+rule_context_add_rule_set(RuleContext * f, const char *setname, int rule_type, RCRuleFunc append, RCNextRuleFunc next)
{
struct _rule_set_map *map;
@@ -156,7 +159,7 @@ void rule_context_add_rule_set(RuleContext *f, const char *setname, int rule_ty
* Set the text error for the context, or NULL to clear it.
**/
static void
-rule_context_set_error(RuleContext *f, char *error)
+rule_context_set_error(RuleContext * f, char *error)
{
g_free(f->error);
f->error = error;
@@ -172,14 +175,16 @@ rule_context_set_error(RuleContext *f, char *error)
*
* Return value:
**/
-int rule_context_load(RuleContext *f, const char *system, const char *user)
+int
+rule_context_load(RuleContext * f, const char *system, const char *user)
{
d(printf("rule_context: loading %s %s\n", system, user));
- return ((RuleContextClass *)((GtkObject *)f)->klass)->load(f, system, user);
+ return ((RuleContextClass *) ((GtkObject *) f)->klass)->load(f, system, user);
}
-static int load(RuleContext *f, const char *system, const char *user)
+static int
+load(RuleContext * f, const char *system, const char *user)
{
xmlNodePtr set, rule;
struct _part_set_map *part_map;
@@ -216,10 +221,11 @@ static int load(RuleContext *f, const char *system, const char *user)
while (rule) {
if (!strcmp(rule->name, "part")) {
FilterPart *part = FILTER_PART(gtk_type_new(part_map->type));
+
if (filter_part_xml_create(part, rule) == 0) {
part_map->append(f, part);
} else {
- gtk_object_unref((GtkObject *)part);
+ gtk_object_unref((GtkObject *) part);
g_warning("Cannot load filter part");
}
}
@@ -242,10 +248,11 @@ static int load(RuleContext *f, const char *system, const char *user)
d(printf("checking node: %s\n", rule->name));
if (!strcmp(rule->name, "rule")) {
FilterRule *part = FILTER_RULE(gtk_type_new(rule_map->type));
+
if (filter_rule_xml_decode(part, rule, f) == 0) {
rule_map->append(f, part);
} else {
- gtk_object_unref((GtkObject *)part);
+ gtk_object_unref((GtkObject *) part);
g_warning("Cannot load filter part");
}
}
@@ -267,12 +274,14 @@ static int load(RuleContext *f, const char *system, const char *user)
*
* Return value:
**/
-int rule_context_save(RuleContext *f, const char *user)
+int
+rule_context_save(RuleContext * f, const char *user)
{
- return ((RuleContextClass *)((GtkObject *)f)->klass)->save(f, user);
+ return ((RuleContextClass *) ((GtkObject *) f)->klass)->save(f, user);
}
-static int save(RuleContext *f, const char *user)
+static int
+save(RuleContext * f, const char *user)
{
xmlDocPtr doc;
xmlNodePtr root, rules, work;
@@ -289,7 +298,7 @@ static int save(RuleContext *f, const char *user)
rules = xmlNewDocNode(doc, NULL, map->name, NULL);
xmlAddChild(root, rules);
rule = NULL;
- while ( (rule = map->next(f, rule)) ) {
+ while ((rule = map->next(f, rule, NULL))) {
d(printf("processing rule %s\n", rule->name));
work = filter_rule_xml_encode(rule);
xmlAddChild(rules, work);
@@ -301,13 +310,15 @@ static int save(RuleContext *f, const char *user)
return 0;
}
-FilterPart *rule_context_find_part(RuleContext *f, const char *name)
+FilterPart *
+rule_context_find_part(RuleContext * f, const char *name)
{
d(printf("find part : "));
return filter_part_find_list(f->parts, name);
}
-FilterPart *rule_context_create_part(RuleContext *f, const char *name)
+FilterPart *
+rule_context_create_part(RuleContext * f, const char *name)
{
FilterPart *part;
@@ -317,100 +328,104 @@ FilterPart *rule_context_create_part(RuleContext *f, const char *name)
return part;
}
-FilterPart *rule_context_next_part(RuleContext *f, FilterPart *last)
+FilterPart *
+rule_context_next_part(RuleContext * f, FilterPart * last)
{
return filter_part_next_list(f->parts, last);
}
-FilterRule *rule_context_next_rule(RuleContext *f, FilterRule *last)
+FilterRule *
+rule_context_next_rule(RuleContext * f, FilterRule * last, const char *source)
{
- return filter_rule_next_list(f->rules, last);
+ return filter_rule_next_list(f->rules, last, source);
}
-FilterRule *rule_context_find_rule(RuleContext *f, const char *name)
+FilterRule *
+rule_context_find_rule(RuleContext * f, const char *name, const char *source)
{
- return filter_rule_find_list(f->rules, name);
+ return filter_rule_find_list(f->rules, name, source);
}
-void rule_context_add_part(RuleContext *f, FilterPart *part)
+void
+rule_context_add_part(RuleContext * f, FilterPart * part)
{
f->parts = g_list_append(f->parts, part);
}
-void rule_context_add_rule(RuleContext *f, FilterRule *new)
+void
+rule_context_add_rule(RuleContext * f, FilterRule * new)
{
f->rules = g_list_append(f->rules, new);
}
static void
-new_rule_clicked(GtkWidget *w, int button, RuleContext *context)
+new_rule_clicked(GtkWidget * w, int button, RuleContext * context)
{
#ifndef NO_WARNINGS
#warning "Need a changed signal for this to work best"
#endif
if (button == 0) {
- FilterRule *rule = gtk_object_get_data((GtkObject *)w, "rule");
- char *user = gtk_object_get_data((GtkObject *)w, "path");
+ FilterRule *rule = gtk_object_get_data((GtkObject *) w, "rule");
+ char *user = gtk_object_get_data((GtkObject *) w, "path");
- gtk_object_ref((GtkObject *)rule);
+ gtk_object_ref((GtkObject *) rule);
rule_context_add_rule(context, rule);
if (user) {
- rule_context_save((RuleContext *)context, user);
+ rule_context_save((RuleContext *) context, user);
}
}
if (button != -1) {
- gnome_dialog_close((GnomeDialog *)w);
+ gnome_dialog_close((GnomeDialog *) w);
}
}
/* add a rule, with a gui, asking for confirmation first ... optionally save to path */
-void rule_context_add_rule_gui(RuleContext *f, FilterRule *rule, const char *title, const char *path)
+void
+rule_context_add_rule_gui(RuleContext * f, FilterRule * rule, const char *title, const char *path)
{
GtkWidget *w;
GnomeDialog *gd;
w = filter_rule_get_widget(rule, f);
- gd = (GnomeDialog *)gnome_dialog_new(title, GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
- gtk_box_pack_start((GtkBox *)gd->vbox, w, FALSE, TRUE, 0);
- gtk_widget_show((GtkWidget *)gd);
- gtk_object_set_data_full((GtkObject *)gd, "rule", rule, (GtkDestroyNotify)gtk_object_unref);
+ gd = (GnomeDialog *) gnome_dialog_new(title, GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
+ gtk_box_pack_start((GtkBox *) gd->vbox, w, FALSE, TRUE, 0);
+ gtk_widget_show((GtkWidget *) gd);
+ gtk_object_set_data_full((GtkObject *) gd, "rule", rule, (GtkDestroyNotify) gtk_object_unref);
if (path)
- gtk_object_set_data_full((GtkObject *)gd, "path", g_strdup(path), (GtkDestroyNotify)g_free);
- gtk_signal_connect((GtkObject *)gd, "clicked", new_rule_clicked, f);
- gtk_object_ref((GtkObject *)f);
- gtk_object_set_data_full((GtkObject *)gd, "context", f, (GtkDestroyNotify)gtk_object_unref);
- gtk_widget_show((GtkWidget *)gd);
+ gtk_object_set_data_full((GtkObject *) gd, "path", g_strdup(path), (GtkDestroyNotify) g_free);
+ gtk_signal_connect((GtkObject *) gd, "clicked", new_rule_clicked, f);
+ gtk_object_ref((GtkObject *) f);
+ gtk_object_set_data_full((GtkObject *) gd, "context", f, (GtkDestroyNotify) gtk_object_unref);
+ gtk_widget_show((GtkWidget *) gd);
}
-void rule_context_remove_rule(RuleContext *f, FilterRule *rule)
+void
+rule_context_remove_rule(RuleContext * f, FilterRule * rule)
{
f->rules = g_list_remove(f->rules, rule);
}
-void rule_context_rank_rule(RuleContext *f, FilterRule *rule, int rank)
+void
+rule_context_rank_rule(RuleContext * f, FilterRule * rule, int rank)
{
f->rules = g_list_remove(f->rules, rule);
f->rules = g_list_insert(f->rules, rule, rank);
}
-int rule_context_get_rank_rule(RuleContext *f, FilterRule *rule)
+int
+rule_context_get_rank_rule(RuleContext * f, FilterRule * rule, const char *source)
{
- return g_list_index(f->rules, rule);
-}
+ GList *n = f->rules;
+ int i = 0;
-int
-rule_context_get_rank_rule_with_source(RuleContext *f, FilterRule *rule, enum _filter_source_t source)
-{
- int i;
- GList *iter;
+ while (n) {
+ FilterRule *r = n->data;
- i = 0;
- for (iter = f->rules; iter; iter = iter->next) {
- if (iter->data == rule)
+ if (r == rule)
return i;
- if (((FilterRule *)iter->data)->source == source)
+ if (source == NULL || (r->source && strcmp(r->source, source) == 0))
i++;
+ n = g_list_next(n);
}
-
- return -1;
+ return i;
}
diff --git a/filter/rule-context.h b/filter/rule-context.h
index dfdca62f28..e2338d5cb5 100644
--- a/filter/rule-context.h
+++ b/filter/rule-context.h
@@ -67,7 +67,7 @@ struct _RuleContextClass {
typedef void (*RCPartFunc)(RuleContext *f, FilterPart *part);
typedef void (*RCRuleFunc)(RuleContext *f, FilterRule *part);
typedef FilterPart * (*RCNextPartFunc)(RuleContext *f, FilterPart *part);
-typedef FilterRule * (*RCNextRuleFunc)(RuleContext *f, FilterRule *rule);
+typedef FilterRule * (*RCNextRuleFunc)(RuleContext *f, FilterRule *rule, const char *source);
struct _part_set_map {
char *name;
@@ -95,16 +95,15 @@ FilterPart *rule_context_find_part(RuleContext *f, const char *name);
FilterPart *rule_context_create_part(RuleContext *f, const char *name);
FilterPart *rule_context_next_part(RuleContext *f, FilterPart *last);
-FilterRule *rule_context_next_rule(RuleContext *f, FilterRule *last);
-FilterRule *rule_context_find_rule(RuleContext *f, const char *name);
+FilterRule *rule_context_next_rule(RuleContext *f, FilterRule *last, const char *source);
+FilterRule *rule_context_find_rule(RuleContext *f, const char *name, const char *source);
void rule_context_add_rule(RuleContext *f, FilterRule *new);
void rule_context_add_rule_gui(RuleContext *f, FilterRule *rule, const char *title, const char *path);
void rule_context_remove_rule(RuleContext *f, FilterRule *rule);
/* get/set the rank (position) of a rule */
void rule_context_rank_rule(RuleContext *f, FilterRule *rule, int rank);
-int rule_context_get_rank_rule(RuleContext *f, FilterRule *rule);
-int rule_context_get_rank_rule_with_source(RuleContext *f, FilterRule *rule, enum _filter_source_t source);
+int rule_context_get_rank_rule(RuleContext *f, FilterRule *rule, const char *source);
void rule_context_delete_rule(RuleContext *f, FilterRule *rule);
diff --git a/filter/score-editor.c b/filter/score-editor.c
index c0d20eea65..aa575120a8 100644
--- a/filter/score-editor.c
+++ b/filter/score-editor.c
@@ -168,7 +168,7 @@ static void rule_edit(GtkWidget *widget, struct _editor_data *data)
result = gnome_dialog_run_and_close(gd);
if (result == 0) {
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
if (pos != -1) {
GtkListItem *item = g_list_nth_data(data->list->children, pos);
gchar *s = e_utf8_to_gtk_string ((GtkWidget *) data->list, data->current->name);
@@ -185,7 +185,7 @@ static void rule_delete(GtkWidget *widget, struct _editor_data *data)
GtkListItem *item;
d(printf("ddelete rule\n"));
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
if (pos != -1) {
rule_context_remove_rule(data->f, data->current);
@@ -221,7 +221,7 @@ static void rule_up(GtkWidget *widget, struct _editor_data *data)
int pos;
d(printf("up rule\n"));
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
if (pos>0) {
rule_move(data, pos, pos-1);
}
@@ -232,7 +232,7 @@ static void rule_down(GtkWidget *widget, struct _editor_data *data)
int pos;
d(printf("down rule\n"));
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
rule_move(data, pos, pos+1);
}
@@ -253,7 +253,7 @@ set_sensitive(struct _editor_data *data)
FilterRule *rule = NULL;
int index=-1, count=0;
- while ((rule = rule_context_next_rule(data->f, rule))) {
+ while ((rule = rule_context_next_rule(data->f, rule, NULL))) {
if (rule == data->current)
index=count;
count++;
@@ -304,7 +304,7 @@ GtkWidget *score_editor_construct (struct _ScoreContext *f)
w = glade_xml_get_widget (gui, "rule_list");
data->list = (GtkList *)w;
l = NULL;
- while ((rule = rule_context_next_rule((RuleContext *)f, rule))) {
+ while ((rule = rule_context_next_rule((RuleContext *)f, rule, NULL))) {
GtkListItem *item;
gchar *s;
diff --git a/filter/vfolder-editor.c b/filter/vfolder-editor.c
index 5b296a6762..327dc36e96 100644
--- a/filter/vfolder-editor.c
+++ b/filter/vfolder-editor.c
@@ -195,7 +195,7 @@ static void rule_edit(GtkWidget *widget, struct _editor_data *data)
result = gnome_dialog_run_and_close(gd);
if (result == 0) {
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
if (pos != -1) {
GtkListItem *item = g_list_nth_data(data->list->children, pos);
gchar *s = e_utf8_to_gtk_string ((GtkWidget *) item, data->current->name);
@@ -212,7 +212,7 @@ static void rule_delete(GtkWidget *widget, struct _editor_data *data)
GtkListItem *item;
d(printf("ddelete rule\n"));
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
if (pos != -1) {
rule_context_remove_rule(data->f, data->current);
@@ -248,7 +248,7 @@ static void rule_up(GtkWidget *widget, struct _editor_data *data)
int pos;
d(printf("up rule\n"));
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
if (pos>0) {
rule_move(data, pos, pos-1);
}
@@ -259,7 +259,7 @@ static void rule_down(GtkWidget *widget, struct _editor_data *data)
int pos;
d(printf("down rule\n"));
- pos = rule_context_get_rank_rule(data->f, data->current);
+ pos = rule_context_get_rank_rule(data->f, data->current, NULL);
rule_move(data, pos, pos+1);
}
@@ -280,7 +280,7 @@ set_sensitive(struct _editor_data *data)
FilterRule *rule = NULL;
int index=-1, count=0;
- while ((rule = rule_context_next_rule(data->f, rule))) {
+ while ((rule = rule_context_next_rule(data->f, rule, NULL))) {
if (rule == data->current)
index=count;
count++;
@@ -331,7 +331,7 @@ GtkWidget *vfolder_editor_construct (struct _VfolderContext *f)
w = glade_xml_get_widget (gui, "rule_list");
data->list = (GtkList *)w;
l = NULL;
- while ((rule = rule_context_next_rule((RuleContext *)f, rule))) {
+ while ((rule = rule_context_next_rule((RuleContext *)f, rule, NULL))) {
GtkListItem *item;
gchar *s = e_utf8_to_gtk_string ((GtkWidget *) data->list, rule->name);
item = (GtkListItem *)gtk_list_item_new_with_label(s);