[evolution] I#84 - Filter configuration needs a humanly readable dump
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] I#84 - Filter configuration needs a humanly readable dump
- Date: Thu, 20 Sep 2018 16:56:44 +0000 (UTC)
commit 97995de1571917981366477bc28a9e8d99801b1c
Author: Milan Crha <mcrha redhat com>
Date: Thu Sep 20 18:56:30 2018 +0200
I#84 - Filter configuration needs a humanly readable dump
Closes https://gitlab.gnome.org/GNOME/evolution/issues/84
src/e-util/e-filter-code.c | 15 ++
src/e-util/e-filter-color.c | 24 +++
src/e-util/e-filter-datespec.c | 50 +++--
src/e-util/e-filter-element.c | 28 ++-
src/e-util/e-filter-element.h | 10 +
src/e-util/e-filter-file.c | 12 ++
src/e-util/e-filter-input.c | 27 +++
src/e-util/e-filter-int.c | 13 ++
src/e-util/e-filter-option.c | 11 ++
src/e-util/e-filter-part.c | 19 ++
src/e-util/e-filter-part.h | 2 +
src/libemail-engine/em-filter-folder-element.c | 73 ++++++-
src/libemail-engine/em-filter-folder-element.h | 4 +
src/mail/em-filter-editor-folder-element.c | 12 ++
src/mail/em-filter-editor.c | 259 ++++++++++++++++++++++++-
src/mail/em-filter-source-element.c | 29 +++
16 files changed, 569 insertions(+), 19 deletions(-)
---
diff --git a/src/e-util/e-filter-code.c b/src/e-util/e-filter-code.c
index 5fd6779749..0df165fd6d 100644
--- a/src/e-util/e-filter-code.c
+++ b/src/e-util/e-filter-code.c
@@ -60,6 +60,20 @@ filter_code_format_sexp (EFilterElement *element,
{
}
+static void
+filter_code_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterInput *fi = (EFilterInput *) element;
+ GList *link;
+
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_START);
+ for (link = fi->values; link; link = g_list_next (link)) {
+ g_string_append (out, (const gchar *) link->data);
+ }
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_END);
+}
+
static void
e_filter_code_class_init (EFilterCodeClass *class)
{
@@ -68,6 +82,7 @@ e_filter_code_class_init (EFilterCodeClass *class)
filter_element_class = E_FILTER_ELEMENT_CLASS (class);
filter_element_class->build_code = filter_code_build_code;
filter_element_class->format_sexp = filter_code_format_sexp;
+ filter_element_class->describe = filter_code_describe;
}
static void
diff --git a/src/e-util/e-filter-color.c b/src/e-util/e-filter-color.c
index 24f8e3cf20..5562ae5f5c 100644
--- a/src/e-util/e-filter-color.c
+++ b/src/e-util/e-filter-color.c
@@ -129,6 +129,29 @@ filter_color_format_sexp (EFilterElement *element,
camel_sexp_encode_string (out, spec);
}
+static void
+filter_color_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterColor *fc = E_FILTER_COLOR (element);
+ gchar spec[16];
+
+ #define cnvrt(x) ((255 * (x) / 65535) & 0xFF)
+
+ g_snprintf (
+ spec, sizeof (spec), "#%02x%02x%02x",
+ cnvrt (fc->color.red), cnvrt (fc->color.green), cnvrt (fc->color.blue));
+
+ #undef cnvrt
+
+ g_string_append_c (out, '[');
+ g_string_append (out, spec);
+ g_string_append (out, "] ");
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_COLOR_START);
+ g_string_append (out, spec);
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_COLOR_END);
+}
+
static void
e_filter_color_class_init (EFilterColorClass *class)
{
@@ -140,6 +163,7 @@ e_filter_color_class_init (EFilterColorClass *class)
filter_element_class->xml_decode = filter_color_xml_decode;
filter_element_class->get_widget = filter_color_get_widget;
filter_element_class->format_sexp = filter_color_format_sexp;
+ filter_element_class->describe = filter_color_describe;
}
static void
diff --git a/src/e-util/e-filter-datespec.c b/src/e-util/e-filter-datespec.c
index a975dca1a5..a538c94701 100644
--- a/src/e-util/e-filter-datespec.c
+++ b/src/e-util/e-filter-datespec.c
@@ -115,52 +115,63 @@ get_best_span (time_t val)
return 0;
}
-/* sets button label */
static void
-set_button (EFilterDatespec *fds)
+describe_to_buffer (EFilterDatespec *fds,
+ gchar *buf,
+ gint buf_size,
+ gboolean with_fallback)
{
- gchar buf[128];
- gchar *label = buf;
-
switch (fds->type) {
case FDST_UNKNOWN:
- label = _("<click here to select a date>");
+ if (with_fallback)
+ g_snprintf (buf, buf_size, _("<click here to select a date>"));
+ else
+ g_snprintf (buf, buf_size, "%s", "");
break;
case FDST_NOW:
- label = _("now");
+ g_snprintf (buf, buf_size, _("now"));
break;
case FDST_SPECIFIED: {
struct tm tm;
localtime_r (&fds->value, &tm);
/* strftime for date filter display, only needs to show a day date (i.e. no time) */
- strftime (buf, sizeof (buf), _("%d-%b-%Y"), &tm);
+ strftime (buf, buf_size, _("%d-%b-%Y"), &tm);
break; }
case FDST_X_AGO:
if (fds->value == 0)
- label = _("now");
+ g_snprintf (buf, buf_size, _("now"));
else {
gint span, count;
span = get_best_span (fds->value);
count = fds->value / timespans[span].seconds;
- sprintf (buf, ngettext (timespans[span].past_singular, timespans[span].past_plural,
count), count);
+ g_snprintf (buf, buf_size, ngettext (timespans[span].past_singular,
timespans[span].past_plural, count), count);
}
break;
case FDST_X_FUTURE:
if (fds->value == 0)
- label = _("now");
+ g_snprintf (buf, buf_size, _("now"));
else {
gint span, count;
span = get_best_span (fds->value);
count = fds->value / timespans[span].seconds;
- sprintf (buf, ngettext (timespans[span].future_singular,
timespans[span].future_plural, count), count);
+ g_snprintf (buf, buf_size, ngettext (timespans[span].future_singular,
timespans[span].future_plural, count), count);
}
break;
}
+}
+
+/* sets button label */
+static void
+set_button (EFilterDatespec *fds)
+{
+ gchar buf[128];
+
+ describe_to_buffer (fds, buf, sizeof (buf), TRUE);
- gtk_label_set_text ((GtkLabel *) fds->priv->label_button, label);
+ gtk_label_set_text ((GtkLabel *) fds->priv->label_button, buf);
}
static void
@@ -473,6 +484,18 @@ filter_datespec_format_sexp (EFilterElement *element,
}
}
+static void
+filter_datespec_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterDatespec *fds = E_FILTER_DATESPEC (element);
+ gchar buf[128];
+
+ describe_to_buffer (fds, buf, sizeof (buf), FALSE);
+
+ g_string_append (out, buf);
+}
+
static void
e_filter_datespec_class_init (EFilterDatespecClass *class)
{
@@ -487,6 +510,7 @@ e_filter_datespec_class_init (EFilterDatespecClass *class)
filter_element_class->xml_decode = filter_datespec_xml_decode;
filter_element_class->get_widget = filter_datespec_get_widget;
filter_element_class->format_sexp = filter_datespec_format_sexp;
+ filter_element_class->describe = filter_datespec_describe;
}
static void
diff --git a/src/e-util/e-filter-element.c b/src/e-util/e-filter-element.c
index 05532118d0..416abff8be 100644
--- a/src/e-util/e-filter-element.c
+++ b/src/e-util/e-filter-element.c
@@ -355,13 +355,12 @@ e_filter_element_clone (EFilterElement *element)
}
/**
- * filter_element_get_widget:
+ * e_filter_element_get_widget:
* @fe: filter element
- * @node: xml node
*
* Create a widget to represent this element.
*
- * Return value:
+ * Returns: (transfer full): a new GtkWidget
**/
GtkWidget *
e_filter_element_get_widget (EFilterElement *element)
@@ -453,3 +452,26 @@ e_filter_element_copy_value (EFilterElement *dst_element,
class->copy_value (dst_element, src_element);
}
+
+/**
+ * e_filter_element_describe:
+ * @fe: filter element
+ * @out: a #GString to add the description to
+ *
+ * Describes the @element in a human-readable way.
+ **/
+void
+e_filter_element_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterElementClass *klass;
+
+ g_return_if_fail (E_IS_FILTER_ELEMENT (element));
+ g_return_if_fail (out != NULL);
+
+ klass = E_FILTER_ELEMENT_GET_CLASS (element);
+ g_return_if_fail (klass != NULL);
+ g_return_if_fail (klass->describe != NULL);
+
+ klass->describe (element, out);
+}
diff --git a/src/e-util/e-filter-element.h b/src/e-util/e-filter-element.h
index 881a92c9c9..e3e39d816a 100644
--- a/src/e-util/e-filter-element.h
+++ b/src/e-util/e-filter-element.h
@@ -52,6 +52,12 @@
(G_TYPE_INSTANCE_GET_CLASS \
((obj), E_TYPE_FILTER_ELEMENT, EFilterElementClass))
+/* Keep the values in sync with their escaped values ("" and so on) in em-filter-editor.c */
+#define E_FILTER_ELEMENT_DESCIPTION_VALUE_START '\1'
+#define E_FILTER_ELEMENT_DESCIPTION_VALUE_END '\2'
+#define E_FILTER_ELEMENT_DESCIPTION_COLOR_START '\3'
+#define E_FILTER_ELEMENT_DESCIPTION_COLOR_END '\4'
+
G_BEGIN_DECLS
struct _EFilterPart;
@@ -92,6 +98,8 @@ struct _EFilterElementClass {
struct _EFilterPart *part);
void (*format_sexp) (EFilterElement *element,
GString *out);
+ void (*describe) (EFilterElement *element,
+ GString *out);
};
GType e_filter_element_get_type (void) G_GNUC_CONST;
@@ -116,6 +124,8 @@ void e_filter_element_build_code (EFilterElement *element,
struct _EFilterPart *part);
void e_filter_element_format_sexp (EFilterElement *element,
GString *out);
+void e_filter_element_describe (EFilterElement *element,
+ GString *out);
G_END_DECLS
diff --git a/src/e-util/e-filter-file.c b/src/e-util/e-filter-file.c
index 9cdc2b0ff2..536ddbdcf5 100644
--- a/src/e-util/e-filter-file.c
+++ b/src/e-util/e-filter-file.c
@@ -200,6 +200,17 @@ filter_file_format_sexp (EFilterElement *element,
camel_sexp_encode_string (out, file->path);
}
+static void
+filter_file_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterFile *file = E_FILTER_FILE (element);
+
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_START);
+ g_string_append (out, file->path);
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_END);
+}
+
static void
e_filter_file_class_init (EFilterFileClass *class)
{
@@ -216,6 +227,7 @@ e_filter_file_class_init (EFilterFileClass *class)
filter_element_class->xml_decode = filter_file_xml_decode;
filter_element_class->get_widget = filter_file_get_widget;
filter_element_class->format_sexp = filter_file_format_sexp;
+ filter_element_class->describe = filter_file_describe;
}
static void
diff --git a/src/e-util/e-filter-input.c b/src/e-util/e-filter-input.c
index 9dbc8560f8..33769beff4 100644
--- a/src/e-util/e-filter-input.c
+++ b/src/e-util/e-filter-input.c
@@ -367,6 +367,32 @@ filter_input_build_code (EFilterElement *element,
g_module_close (module);
}
+static void
+filter_input_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterInput *input = E_FILTER_INPUT (element);
+ GList *link;
+ gboolean added = FALSE;
+
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_START);
+
+ for (link = input->values; link; link = g_list_next (link)) {
+ const gchar *value = link->data;
+
+ if (value && *value) {
+ if (added)
+ g_string_append_c (out, ' ');
+ else
+ added = TRUE;
+
+ g_string_append (out, value);
+ }
+ }
+
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_END);
+}
+
static void
e_filter_input_class_init (EFilterInputClass *class)
{
@@ -386,6 +412,7 @@ e_filter_input_class_init (EFilterInputClass *class)
filter_element_class->get_widget = filter_input_get_widget;
filter_element_class->format_sexp = filter_input_format_sexp;
filter_element_class->build_code = filter_input_build_code;
+ filter_element_class->describe = filter_input_describe;
}
static void
diff --git a/src/e-util/e-filter-int.c b/src/e-util/e-filter-int.c
index 9127079a57..df9f3be062 100644
--- a/src/e-util/e-filter-int.c
+++ b/src/e-util/e-filter-int.c
@@ -170,6 +170,18 @@ filter_int_format_sexp (EFilterElement *element,
g_string_append_printf (out, "%d", filter_int->val);
}
+static void
+filter_int_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterInt *filter_int = E_FILTER_INT (element);
+
+ g_string_append_printf (out, "%c%d%c",
+ E_FILTER_ELEMENT_DESCIPTION_VALUE_START,
+ filter_int->val,
+ E_FILTER_ELEMENT_DESCIPTION_VALUE_END);
+}
+
static void
e_filter_int_class_init (EFilterIntClass *class)
{
@@ -186,6 +198,7 @@ e_filter_int_class_init (EFilterIntClass *class)
filter_element_class->xml_decode = filter_int_xml_decode;
filter_element_class->get_widget = filter_int_get_widget;
filter_element_class->format_sexp = filter_int_format_sexp;
+ filter_element_class->describe = filter_int_describe;
}
static void
diff --git a/src/e-util/e-filter-option.c b/src/e-util/e-filter-option.c
index cd4ca4e771..949cab50ec 100644
--- a/src/e-util/e-filter-option.c
+++ b/src/e-util/e-filter-option.c
@@ -465,6 +465,16 @@ filter_option_format_sexp (EFilterElement *element,
camel_sexp_encode_string (out, option->current->value);
}
+static void
+filter_option_describe (EFilterElement *element,
+ GString *out)
+{
+ EFilterOption *option = E_FILTER_OPTION (element);
+
+ if (option->current)
+ g_string_append (out, _(option->current->title));
+}
+
static void
e_filter_option_class_init (EFilterOptionClass *class)
{
@@ -483,6 +493,7 @@ e_filter_option_class_init (EFilterOptionClass *class)
filter_element_class->get_widget = filter_option_get_widget;
filter_element_class->build_code = filter_option_build_code;
filter_element_class->format_sexp = filter_option_format_sexp;
+ filter_element_class->describe = filter_option_describe;
}
static void
diff --git a/src/e-util/e-filter-part.c b/src/e-util/e-filter-part.c
index 4fb2eb90be..4dc5065944 100644
--- a/src/e-util/e-filter-part.c
+++ b/src/e-util/e-filter-part.c
@@ -353,6 +353,25 @@ e_filter_part_get_widget (EFilterPart *part)
return hbox;
}
+void
+e_filter_part_describe (EFilterPart *part,
+ GString *out)
+{
+ GList *link;
+
+ g_return_if_fail (E_IS_FILTER_PART (part));
+ g_return_if_fail (out != NULL);
+
+ g_string_append (out, _(part->title));
+
+ for (link = part->elements; link != NULL; link = g_list_next (link)) {
+ EFilterElement *element = link->data;
+
+ g_string_append_c (out, ' ');
+ e_filter_element_describe (element, out);
+ }
+}
+
/**
* e_filter_part_build_code:
* @part:
diff --git a/src/e-util/e-filter-part.h b/src/e-util/e-filter-part.h
index 4eed142083..071986319e 100644
--- a/src/e-util/e-filter-part.h
+++ b/src/e-util/e-filter-part.h
@@ -93,6 +93,8 @@ void e_filter_part_copy_values (EFilterPart *dst_part,
EFilterElement *e_filter_part_find_element (EFilterPart *part,
const gchar *name);
GtkWidget * e_filter_part_get_widget (EFilterPart *part);
+void e_filter_part_describe (EFilterPart *part,
+ GString *out);
void e_filter_part_build_code (EFilterPart *part,
GString *out);
void e_filter_part_expand_code (EFilterPart *part,
diff --git a/src/libemail-engine/em-filter-folder-element.c b/src/libemail-engine/em-filter-folder-element.c
index fec0e0ba3d..d2e355e84f 100644
--- a/src/libemail-engine/em-filter-folder-element.c
+++ b/src/libemail-engine/em-filter-folder-element.c
@@ -23,13 +23,14 @@
#include "evolution-config.h"
-#include "em-filter-folder-element.h"
-
#include <string.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
+#include "e-mail-folder-utils.h"
+#include "em-filter-folder-element.h"
+
#define EM_FILTER_FOLDER_ELEMENT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), EM_TYPE_FILTER_FOLDER_ELEMENT, EMFilterFolderElementPrivate))
@@ -167,6 +168,21 @@ filter_folder_element_copy_value (EFilterElement *de,
em_filter_folder_element_parent_class)->copy_value (de, se);
}
}
+
+static void
+filter_folder_element_describe (EFilterElement *fe,
+ GString *out)
+{
+ EMFilterFolderElement *ff = (EMFilterFolderElement *) fe;
+
+ if (!ff->priv->uri)
+ return;
+
+ /* This might not be usually used, do some special processing
+ for it and call em_filter_folder_element_describe() instead */
+ g_string_append (out, ff->priv->uri);
+}
+
static void
em_filter_folder_element_class_init (EMFilterFolderElementClass *class)
{
@@ -187,6 +203,7 @@ em_filter_folder_element_class_init (EMFilterFolderElementClass *class)
filter_element_class->build_code = filter_folder_element_build_code;
filter_element_class->format_sexp = filter_folder_element_format_sexp;
filter_element_class->copy_value = filter_folder_element_copy_value;
+ filter_element_class->describe = filter_folder_element_describe;
}
static void
@@ -221,3 +238,55 @@ em_filter_folder_element_set_uri (EMFilterFolderElement *element,
element->priv->uri = g_strdup (uri);
}
+void
+em_filter_folder_element_describe (EMFilterFolderElement *element,
+ CamelSession *session,
+ GString *out)
+{
+ g_return_if_fail (EM_IS_FILTER_FOLDER_ELEMENT (element));
+ g_return_if_fail (CAMEL_IS_SESSION (session));
+ g_return_if_fail (out != NULL);
+
+ if (element->priv->uri) {
+ gchar *full_name = NULL;
+ const gchar *use_name = element->priv->uri;
+ CamelStore *store = NULL;
+ gchar *folder_name = NULL;
+
+ if (e_mail_folder_uri_parse (session, element->priv->uri, &store, &folder_name, NULL)) {
+ CamelFolder *folder;
+
+ folder = camel_store_get_folder_sync (store, folder_name, 0, NULL, NULL);
+ if (folder) {
+ const gchar *service_display_name;
+
+ service_display_name = camel_service_get_display_name (CAMEL_SERVICE (store));
+
+ if (CAMEL_IS_VEE_FOLDER (folder) && (
+ g_strcmp0 (folder_name, CAMEL_VTRASH_NAME) == 0 ||
+ g_strcmp0 (folder_name, CAMEL_VJUNK_NAME) == 0)) {
+ full_name = g_strdup_printf ("%s/%s", service_display_name,
camel_folder_get_display_name (folder));
+ } else {
+ full_name = g_strdup_printf ("%s/%s", service_display_name,
folder_name);
+ }
+
+ g_clear_object (&folder);
+ }
+
+ if (!full_name)
+ full_name = g_strdup_printf ("%s/%s", camel_service_get_display_name
(CAMEL_SERVICE (store)), folder_name);
+
+ if (full_name)
+ use_name = full_name;
+
+ g_clear_object (&store);
+ g_free (folder_name);
+ }
+
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_START);
+ g_string_append (out, use_name);
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_END);
+
+ g_free (full_name);
+ }
+}
diff --git a/src/libemail-engine/em-filter-folder-element.h b/src/libemail-engine/em-filter-folder-element.h
index 9e24242e38..5350f4ee66 100644
--- a/src/libemail-engine/em-filter-folder-element.h
+++ b/src/libemail-engine/em-filter-folder-element.h
@@ -71,6 +71,10 @@ const gchar * em_filter_folder_element_get_uri
void em_filter_folder_element_set_uri
(EMFilterFolderElement *element,
const gchar *uri);
+void em_filter_folder_element_describe
+ (EMFilterFolderElement *element,
+ CamelSession *session,
+ GString *out);
G_END_DECLS
diff --git a/src/mail/em-filter-editor-folder-element.c b/src/mail/em-filter-editor-folder-element.c
index 246210c413..5d7a2f84fc 100644
--- a/src/mail/em-filter-editor-folder-element.c
+++ b/src/mail/em-filter-editor-folder-element.c
@@ -163,6 +163,17 @@ filter_editor_folder_element_get_widget (EFilterElement *fe)
return button;
}
+static void
+filter_editor_folder_element_describe (EFilterElement *fe,
+ GString *out)
+{
+ EMFilterEditorFolderElement *ff = (EMFilterEditorFolderElement *) fe;
+ EMailSession *mail_session;
+
+ mail_session = em_filter_editor_folder_element_get_session (ff);
+ em_filter_folder_element_describe (EM_FILTER_FOLDER_ELEMENT (ff), CAMEL_SESSION (mail_session), out);
+}
+
static void
em_filter_editor_folder_element_class_init (EMFilterEditorFolderElementClass *class)
{
@@ -178,6 +189,7 @@ em_filter_editor_folder_element_class_init (EMFilterEditorFolderElementClass *cl
filter_element_class = E_FILTER_ELEMENT_CLASS (class);
filter_element_class->get_widget = filter_editor_folder_element_get_widget;
+ filter_element_class->describe = filter_editor_folder_element_describe;
g_object_class_install_property (
object_class,
diff --git a/src/mail/em-filter-editor.c b/src/mail/em-filter-editor.c
index e20983b371..8e1653dc7e 100644
--- a/src/mail/em-filter-editor.c
+++ b/src/mail/em-filter-editor.c
@@ -25,6 +25,7 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
+#include "shell/e-shell.h"
#include "e-util/e-util.h"
#include "e-util/e-util-private.h"
@@ -33,6 +34,242 @@
G_DEFINE_TYPE (EMFilterEditor, em_filter_editor, E_TYPE_RULE_EDITOR)
+static void
+emfe_show_html (GtkWindow *parent,
+ const gchar *html)
+{
+ GtkWidget *dialog, *widget, *container;
+
+ dialog = gtk_dialog_new_with_buttons (_("Description of Filters"), parent,
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ _("_Close"), GTK_RESPONSE_CLOSE,
+ NULL);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 480, 410);
+ gtk_window_set_position (GTK_WINDOW (dialog), parent ? GTK_WIN_POS_CENTER_ON_PARENT :
GTK_WIN_POS_CENTER);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_widget_set_vexpand (widget, TRUE);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 12);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_web_view_new ();
+ g_object_set (G_OBJECT (widget),
+ "hexpand", TRUE,
+ "halign", GTK_ALIGN_FILL,
+ "vexpand", TRUE,
+ "valign", GTK_ALIGN_FILL,
+ "visible", TRUE,
+ "editable", FALSE,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+
+ e_web_view_load_string (E_WEB_VIEW (widget), html);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+}
+
+/* Some parts require special processing, which cannot access session from their place */
+static void
+emfe_describe_part (EFilterPart *part,
+ GString *out,
+ CamelSession *session)
+{
+ GList *link;
+
+ g_return_if_fail (E_IS_FILTER_PART (part));
+ g_return_if_fail (out != NULL);
+
+ g_string_append (out, _(part->title));
+
+ for (link = part->elements; link != NULL; link = g_list_next (link)) {
+ EFilterElement *element = link->data;
+
+ g_string_append_c (out, ' ');
+
+ if (EM_IS_FILTER_FOLDER_ELEMENT (element)) {
+ em_filter_folder_element_describe (EM_FILTER_FOLDER_ELEMENT (element), session, out);
+ } else {
+ e_filter_element_describe (element, out);
+ }
+ }
+}
+
+static void
+emfe_describe_filters_cb (GtkWidget *button,
+ gpointer user_data)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ ESourceRegistry *registry;
+ EMFilterEditor *fe = user_data;
+ ERuleContext *context;
+ EFilterRule *rule = NULL;
+ CamelSession *session = NULL;
+ GString *description;
+ gchar *html;
+ const gchar *source;
+
+ g_return_if_fail (EM_IS_FILTER_EDITOR (fe));
+
+ context = E_RULE_EDITOR (fe)->context;
+ source = E_RULE_EDITOR (fe)->source;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+ if (shell_backend)
+ g_object_get (shell_backend, "session", &session, NULL);
+
+ registry = e_shell_get_registry (shell);
+
+ description = g_string_sized_new (2048);
+
+ while (rule = e_rule_context_next_rule (context, rule, source), rule) {
+ GList *link;
+ gchar *account, *rule_name;
+
+ account = g_strdup (em_filter_rule_get_account_uid (EM_FILTER_RULE (rule)));
+ if (account && *account) {
+ ESource *source;
+
+ source = e_source_registry_ref_source (registry, account);
+ if (source) {
+ g_free (account);
+ account = e_source_dup_display_name (source);
+ g_object_unref (source);
+ }
+ } else {
+ g_free (account);
+ account = NULL;
+ }
+
+ if (description->len)
+ g_string_append_c (description, '\n');
+
+ rule_name = g_strdup_printf ("%c%s%c",
+ E_FILTER_ELEMENT_DESCIPTION_VALUE_START,
+ rule->name,
+ E_FILTER_ELEMENT_DESCIPTION_VALUE_END);
+
+ if (account) {
+ /* Translators: The first '%s' is replaced with the rule name;
+ the second '%s' with 'enabled' or 'disabled' word;
+ the third '%s' is replaced with the account name */
+ g_string_append_printf (description, _("%s (%s, for account %s)"), rule_name,
rule->enabled ? _("enabled") : _("disabled"), account);
+ } else {
+ /* Translators: The first '%s' is replaced with the rule name;
+ the second '%s' with 'enabled' or 'disabled' word */
+ g_string_append_printf (description, _("%s (%s, for any account)"), rule_name,
rule->enabled ? _("enabled") : _("disabled"));
+ }
+
+ g_string_append (description, "\n");
+
+ g_free (rule_name);
+ g_free (account);
+
+ g_string_append (description, " ");
+
+ switch (rule->grouping) {
+ case E_FILTER_GROUP_ALL:
+ g_string_append (description, _("If all the following conditions are met"));
+ break;
+ case E_FILTER_GROUP_ANY:
+ g_string_append (description, _("If any of the following conditions are met"));
+ break;
+ }
+ g_string_append_c (description, '\n');
+
+ for (link = rule->parts; link; link = g_list_next (link)) {
+ EFilterPart *part = link->data;
+
+ if (!part)
+ continue;
+
+ g_string_append (description, " ");
+ emfe_describe_part (part, description, session);
+ g_string_append_c (description, '\n');
+ }
+
+ g_string_append (description, " ");
+ g_string_append (description, _("Then"));
+ g_string_append_c (description, '\n');
+
+ for (link = em_filter_rule_get_actions (EM_FILTER_RULE (rule)); link; link = g_list_next
(link)) {
+ EFilterPart *part = link->data;
+
+ if (!part)
+ continue;
+
+ g_string_append (description, " ");
+ emfe_describe_part (part, description, session);
+ g_string_append_c (description, '\n');
+ }
+ }
+
+ html = camel_text_to_html (description->str, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES, 0);
+ g_string_free (description, TRUE);
+
+ description = e_str_replace_string (html, "", "<b>"); /* E_FILTER_ELEMENT_DESCIPTION_VALUE_START
*/
+ g_string_prepend (description, "<div style=\"white-space: nowrap;\">");
+ g_string_append (description, "</div>");
+ g_free (html);
+ html = g_string_free (description, FALSE);
+
+ #define replace_in_html(_find, _replace) \
+ description = e_str_replace_string (html, _find, _replace); \
+ g_free (html); \
+ html = g_string_free (description, FALSE);
+
+ replace_in_html ("", "</b>"); /* E_FILTER_ELEMENT_DESCIPTION_VALUE_END */
+
+ if (strstr (html, "") && strstr (html, "")) {
+ replace_in_html ("", "<span style=\"background-color:"); /*
E_FILTER_ELEMENT_DESCIPTION_COLOR_START */
+ replace_in_html ("",
";\"> </span>"); /*
E_FILTER_ELEMENT_DESCIPTION_COLOR_END */
+ }
+
+ #undef replace_in_html
+
+ emfe_show_html (GTK_WINDOW (fe), html);
+
+ g_clear_object (&session);
+ g_free (html);
+}
+
+static void
+emfe_update_describe_sensitive (GtkTreeModel *model,
+ GtkWidget *button)
+{
+ GtkTreeIter iter;
+
+ gtk_widget_set_sensitive (button, gtk_tree_model_get_iter_first (model, &iter));
+}
+
+static void
+emfe_rules_model_row_inserted_cb (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ emfe_update_describe_sensitive (tree_model, user_data);
+}
+
+static void
+emfe_rules_model_row_deleted_cb (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ gpointer user_data)
+{
+ emfe_update_describe_sensitive (tree_model, user_data);
+}
+
static EFilterRule *
filter_editor_create_rule (ERuleEditor *rule_editor)
{
@@ -131,9 +368,10 @@ em_filter_editor_construct (EMFilterEditor *fe,
GtkBuilder *builder,
const EMFilterSource *source_names)
{
- GtkWidget *combobox;
+ GtkWidget *combobox, *action_area, *button, *tree_view;
gint i;
GtkTreeViewColumn *column;
+ GtkTreeModel *model;
GtkTreeIter iter;
GtkListStore *store;
GSList *sources = NULL;
@@ -165,4 +403,23 @@ em_filter_editor_construct (EMFilterEditor *fe,
/* Show the Enabled column, we support it here */
column = gtk_tree_view_get_column (GTK_TREE_VIEW (E_RULE_EDITOR (fe)->list), 0);
gtk_tree_view_column_set_visible (column, TRUE);
+
+ action_area = gtk_dialog_get_action_area (GTK_DIALOG (fe));
+ button = gtk_button_new_with_mnemonic (_("De_scribe Filters…"));
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (action_area), button, FALSE, TRUE, 0);
+ gtk_box_reorder_child (GTK_BOX (action_area), button, 0);
+
+ if (GTK_IS_BUTTON_BOX (action_area))
+ gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), button, TRUE);
+
+ g_signal_connect (button, "clicked", G_CALLBACK (emfe_describe_filters_cb), fe);
+
+ tree_view = e_builder_get_widget (builder, "rule_tree_view");
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+
+ g_signal_connect_object (model, "row-inserted", G_CALLBACK (emfe_rules_model_row_inserted_cb),
button, 0);
+ g_signal_connect_object (model, "row-deleted", G_CALLBACK (emfe_rules_model_row_deleted_cb), button,
0);
+
+ emfe_update_describe_sensitive (model, button);
}
diff --git a/src/mail/em-filter-source-element.c b/src/mail/em-filter-source-element.c
index dc32d538c5..04ab2f3a98 100644
--- a/src/mail/em-filter-source-element.c
+++ b/src/mail/em-filter-source-element.c
@@ -403,6 +403,34 @@ filter_source_element_format_sexp (EFilterElement *fe,
camel_sexp_encode_string (out, fs->priv->active_id);
}
+static void
+filter_source_element_describe (EFilterElement *fe,
+ GString *out)
+{
+ EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
+ EMailSession *mail_session;
+ ESourceRegistry *registry;
+ ESource *source;
+
+ if (!fs->priv->active_id)
+ return;
+
+ mail_session = em_filter_source_element_get_session (fs);
+ registry = e_mail_session_get_registry (mail_session);
+ source = e_source_registry_ref_source (registry, fs->priv->active_id);
+
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_START);
+
+ if (source) {
+ g_string_append (out, e_source_get_display_name (source));
+ g_object_unref (source);
+ } else {
+ g_string_append (out, fs->priv->active_id);
+ }
+
+ g_string_append_c (out, E_FILTER_ELEMENT_DESCIPTION_VALUE_END);
+}
+
static void
em_filter_source_element_class_init (EMFilterSourceElementClass *class)
{
@@ -425,6 +453,7 @@ em_filter_source_element_class_init (EMFilterSourceElementClass *class)
filter_element_class->get_widget = filter_source_element_get_widget;
filter_element_class->build_code = filter_source_element_build_code;
filter_element_class->format_sexp = filter_source_element_format_sexp;
+ filter_element_class->describe = filter_source_element_describe;
g_object_class_install_property (
object_class,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]