diff options
author | Not Zed <NotZed@HelixCode.com> | 2000-10-12 21:53:50 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2000-10-12 21:53:50 +0800 |
commit | c308f5eeef858ef813205af508e8ef94a8208d62 (patch) | |
tree | f2bad01816b88533321c63e809c0d609549b8f74 | |
parent | 80237e0c26dd375b0269dc2099d49fc3cd50a4f2 (diff) | |
download | gsoc2013-evolution-c308f5eeef858ef813205af508e8ef94a8208d62.tar gsoc2013-evolution-c308f5eeef858ef813205af508e8ef94a8208d62.tar.gz gsoc2013-evolution-c308f5eeef858ef813205af508e8ef94a8208d62.tar.bz2 gsoc2013-evolution-c308f5eeef858ef813205af508e8ef94a8208d62.tar.lz gsoc2013-evolution-c308f5eeef858ef813205af508e8ef94a8208d62.tar.xz gsoc2013-evolution-c308f5eeef858ef813205af508e8ef94a8208d62.tar.zst gsoc2013-evolution-c308f5eeef858ef813205af508e8ef94a8208d62.zip |
Report the percentage of file complete for the filter.
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.
svn path=/trunk/; revision=5884
-rw-r--r-- | filter/ChangeLog | 87 | ||||
-rw-r--r-- | filter/filter-driver.c | 379 | ||||
-rw-r--r-- | filter/filter-driver.h | 26 | ||||
-rw-r--r-- | filter/filter-editor.c | 46 | ||||
-rw-r--r-- | filter/filter-rule.c | 586 | ||||
-rw-r--r-- | filter/filter-rule.h | 18 | ||||
-rw-r--r-- | filter/rule-context.c | 167 | ||||
-rw-r--r-- | filter/rule-context.h | 9 | ||||
-rw-r--r-- | filter/score-editor.c | 12 | ||||
-rw-r--r-- | filter/vfolder-editor.c | 12 |
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); |