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
This commit is contained in:
Not Zed
2000-10-12 13:53:50 +00:00
committed by Michael Zucci
parent 80237e0c26
commit c308f5eeef
10 changed files with 801 additions and 541 deletions

View File

@ -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.

View File

@ -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 (p->terminated)
break;
}
/* 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");
}
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;
}

View File

@ -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 */

View File

@ -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++;

View File

@ -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);
g_free(fr->name);
fr->name = g_strdup(name);
}
xmlNodePtr
filter_rule_xml_encode (FilterRule *fr)
void
filter_rule_set_source(FilterRule * fr, const char *source)
{
return ((FilterRuleClass *)((GtkObject *)fr)->klass)->xml_encode (fr);
g_free(fr->source);
fr->source = g_strdup(source);
}
xmlNodePtr filter_rule_xml_encode(FilterRule * 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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);