I#1512 - Choose account with which to forward message in filter rule
Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1512
This commit is contained in:
@ -87,6 +87,7 @@
|
||||
<xi:include href="xml/e-filter-file.xml"/>
|
||||
<xi:include href="xml/e-filter-input.xml"/>
|
||||
<xi:include href="xml/e-filter-int.xml"/>
|
||||
<xi:include href="xml/e-filter-label.xml"/>
|
||||
<xi:include href="xml/e-filter-option.xml"/>
|
||||
</chapter>
|
||||
|
||||
@ -323,6 +324,10 @@
|
||||
<title>Index</title>
|
||||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
<index id="api-index-3-42" role="3.42">
|
||||
<title>Index of new symbols in 3.42</title>
|
||||
<xi:include href="xml/api-index-3.42.xml"><xi:fallback /></xi:include>
|
||||
</index>
|
||||
<index id="api-index-3-40" role="3.40">
|
||||
<title>Index of new symbols in 3.40</title>
|
||||
<xi:include href="xml/api-index-3.40.xml"><xi:fallback /></xi:include>
|
||||
|
@ -357,6 +357,7 @@ src/mail/e-mail-ui-session.c
|
||||
src/mail/em-composer-utils.c
|
||||
src/mail/em-filter-editor.c
|
||||
src/mail/em-filter-editor-folder-element.c
|
||||
src/mail/em-filter-mail-identity-element.c
|
||||
src/mail/em-filter-rule.c
|
||||
src/mail/em-folder-properties.c
|
||||
src/mail/em-folder-selection-button.c
|
||||
|
@ -129,6 +129,7 @@ set(SOURCES
|
||||
e-filter-file.c
|
||||
e-filter-input.c
|
||||
e-filter-int.c
|
||||
e-filter-label.c
|
||||
e-filter-option.c
|
||||
e-filter-part.c
|
||||
e-filter-rule.c
|
||||
@ -404,6 +405,7 @@ set(HEADERS
|
||||
e-filter-file.h
|
||||
e-filter-input.h
|
||||
e-filter-int.h
|
||||
e-filter-label.h
|
||||
e-filter-option.h
|
||||
e-filter-part.h
|
||||
e-filter-rule.h
|
||||
|
211
src/e-util/e-filter-label.c
Normal file
211
src/e-util/e-filter-label.c
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Red Hat (www.redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "evolution-config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "e-filter-part.h"
|
||||
|
||||
#include "e-filter-label.h"
|
||||
|
||||
struct _EFilterLabelPrivate {
|
||||
gchar *title;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EFilterLabel, e_filter_label, E_TYPE_FILTER_ELEMENT)
|
||||
|
||||
static void
|
||||
filter_label_finalize (GObject *object)
|
||||
{
|
||||
EFilterLabel *label = E_FILTER_LABEL (object);
|
||||
|
||||
g_free (label->priv->title);
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
G_OBJECT_CLASS (e_filter_label_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint
|
||||
filter_label_eq (EFilterElement *element_a,
|
||||
EFilterElement *element_b)
|
||||
{
|
||||
EFilterLabel *label_a = E_FILTER_LABEL (element_a);
|
||||
EFilterLabel *label_b = E_FILTER_LABEL (element_b);
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
if (!E_FILTER_ELEMENT_CLASS (e_filter_label_parent_class)->eq (element_a, element_b))
|
||||
return FALSE;
|
||||
|
||||
return g_strcmp0 (label_a->priv->title, label_b->priv->title) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_label_xml_create (EFilterElement *element,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
EFilterLabel *label = E_FILTER_LABEL (element);
|
||||
xmlNodePtr n;
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
E_FILTER_ELEMENT_CLASS (e_filter_label_parent_class)->xml_create (element, node);
|
||||
|
||||
n = node->children;
|
||||
while (n) {
|
||||
if (!g_strcmp0 ((gchar *) n->name, "title") ||
|
||||
!g_strcmp0 ((gchar *) n->name, "_title")) {
|
||||
if (!label->priv->title) {
|
||||
xmlChar *tmp;
|
||||
|
||||
tmp = xmlNodeGetContent (n);
|
||||
label->priv->title = tmp ? g_strdup ((gchar *) tmp) : NULL;
|
||||
if (tmp)
|
||||
xmlFree (tmp);
|
||||
}
|
||||
} else if (n->type == XML_ELEMENT_NODE) {
|
||||
g_warning ("Unknown xml node within 'label': %s\n", n->name);
|
||||
}
|
||||
n = n->next;
|
||||
}
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
filter_label_xml_encode (EFilterElement *element)
|
||||
{
|
||||
xmlNodePtr value;
|
||||
|
||||
value = xmlNewNode (NULL, (xmlChar *) "value");
|
||||
xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static gint
|
||||
filter_label_xml_decode (EFilterElement *element,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
xmlFree (element->name);
|
||||
element->name = (gchar *) xmlGetProp (node, (xmlChar *) "name");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EFilterElement *
|
||||
filter_label_clone (EFilterElement *element)
|
||||
{
|
||||
EFilterLabel *label = E_FILTER_LABEL (element);
|
||||
EFilterLabel *clone_label;
|
||||
EFilterElement *clone;
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
clone = E_FILTER_ELEMENT_CLASS (e_filter_label_parent_class)->clone (element);
|
||||
|
||||
clone_label = E_FILTER_LABEL (clone);
|
||||
clone_label->priv->title = g_strdup (label->priv->title);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
filter_label_get_widget (EFilterElement *element)
|
||||
{
|
||||
EFilterLabel *label = E_FILTER_LABEL (element);
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_label_new ((label->priv->title && *label->priv->title) ? _(label->priv->title) : "");
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_label_build_code (EFilterElement *element,
|
||||
GString *out,
|
||||
EFilterPart *part)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
filter_label_format_sexp (EFilterElement *element,
|
||||
GString *out)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
filter_label_describe (EFilterElement *element,
|
||||
GString *out)
|
||||
{
|
||||
EFilterLabel *label = E_FILTER_LABEL (element);
|
||||
|
||||
if (label->priv->title && *label->priv->title)
|
||||
g_string_append (out, _(label->priv->title));
|
||||
}
|
||||
|
||||
static void
|
||||
e_filter_label_class_init (EFilterLabelClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
EFilterElementClass *filter_element_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
object_class->finalize = filter_label_finalize;
|
||||
|
||||
filter_element_class = E_FILTER_ELEMENT_CLASS (class);
|
||||
filter_element_class->eq = filter_label_eq;
|
||||
filter_element_class->xml_create = filter_label_xml_create;
|
||||
filter_element_class->xml_encode = filter_label_xml_encode;
|
||||
filter_element_class->xml_decode = filter_label_xml_decode;
|
||||
filter_element_class->clone = filter_label_clone;
|
||||
filter_element_class->get_widget = filter_label_get_widget;
|
||||
filter_element_class->build_code = filter_label_build_code;
|
||||
filter_element_class->format_sexp = filter_label_format_sexp;
|
||||
filter_element_class->describe = filter_label_describe;
|
||||
}
|
||||
|
||||
static void
|
||||
e_filter_label_init (EFilterLabel *label)
|
||||
{
|
||||
label->priv = e_filter_label_get_instance_private (label);
|
||||
}
|
||||
|
||||
EFilterElement *
|
||||
e_filter_label_new (void)
|
||||
{
|
||||
return g_object_new (E_TYPE_FILTER_LABEL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
e_filter_label_set_title (EFilterLabel *label,
|
||||
const gchar *title)
|
||||
{
|
||||
g_return_if_fail (E_IS_FILTER_LABEL (label));
|
||||
|
||||
if (label->priv->title != title) {
|
||||
g_free (label->priv->title);
|
||||
label->priv->title = g_strdup (title);
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
e_filter_label_get_title (EFilterLabel *label)
|
||||
{
|
||||
g_return_val_if_fail (E_IS_FILTER_LABEL (label), NULL);
|
||||
|
||||
return label->priv->title;
|
||||
}
|
69
src/e-util/e-filter-label.h
Normal file
69
src/e-util/e-filter-label.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Red Hat (www.redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION)
|
||||
#error "Only <e-util/e-util.h> should be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef E_FILTER_LABEL_H
|
||||
#define E_FILTER_LABEL_H
|
||||
|
||||
#include <e-util/e-filter-element.h>
|
||||
|
||||
/* Standard GObject macros */
|
||||
#define E_TYPE_FILTER_LABEL \
|
||||
(e_filter_label_get_type ())
|
||||
#define E_FILTER_LABEL(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST \
|
||||
((obj), E_TYPE_FILTER_LABEL, EFilterLabel))
|
||||
#define E_FILTER_LABEL_CLASS(cls) \
|
||||
(G_TYPE_CHECK_CLASS_CAST \
|
||||
((cls), E_TYPE_FILTER_LABEL, EFilterLabelClass))
|
||||
#define E_IS_FILTER_LABEL(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE \
|
||||
((obj), E_TYPE_FILTER_LABEL))
|
||||
#define E_IS_FILTER_LABEL_CLASS(cls) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE \
|
||||
((cls), E_TYPE_FILTER_LABEL))
|
||||
#define E_FILTER_LABEL_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS \
|
||||
((obj), E_TYPE_FILTER_LABEL, EFilterLabelClass))
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _EFilterLabel EFilterLabel;
|
||||
typedef struct _EFilterLabelClass EFilterLabelClass;
|
||||
typedef struct _EFilterLabelPrivate EFilterLabelPrivate;
|
||||
|
||||
struct _EFilterLabel {
|
||||
EFilterElement parent;
|
||||
EFilterLabelPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EFilterLabelClass {
|
||||
EFilterElementClass parent_class;
|
||||
};
|
||||
|
||||
GType e_filter_label_get_type (void) G_GNUC_CONST;
|
||||
EFilterElement *e_filter_label_new (void);
|
||||
void e_filter_label_set_title (EFilterLabel *option,
|
||||
const gchar *title);
|
||||
const gchar * e_filter_label_get_title (EFilterLabel *option);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* E_FILTER_LABEL_H */
|
@ -45,6 +45,8 @@ struct _EMailIdentityComboBoxPrivate {
|
||||
gulong source_changed_handler_id;
|
||||
gulong source_removed_handler_id;
|
||||
|
||||
gchar *none_title;
|
||||
|
||||
gboolean allow_none;
|
||||
gboolean allow_aliases;
|
||||
|
||||
@ -256,6 +258,7 @@ mail_identity_combo_box_dispose (GObject *object)
|
||||
priv->refresh_idle_id = 0;
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->none_title, g_free);
|
||||
g_clear_object (&priv->registry);
|
||||
|
||||
/* Chain up to parent's dispose() method. */
|
||||
@ -691,7 +694,7 @@ e_mail_identity_combo_box_refresh (EMailIdentityComboBox *combo_box)
|
||||
|
||||
gtk_list_store_set (
|
||||
GTK_LIST_STORE (tree_model), &iter,
|
||||
E_MAIL_IDENTITY_COMBO_BOX_COLUMN_DISPLAY_NAME, _("None"),
|
||||
E_MAIL_IDENTITY_COMBO_BOX_COLUMN_DISPLAY_NAME, e_mail_identity_combo_box_get_none_title (combo_box),
|
||||
E_MAIL_IDENTITY_COMBO_BOX_COLUMN_UID, "",
|
||||
E_MAIL_IDENTITY_COMBO_BOX_COLUMN_COMBO_ID, "",
|
||||
-1);
|
||||
@ -776,6 +779,47 @@ e_mail_identity_combo_box_set_allow_none (EMailIdentityComboBox *combo_box,
|
||||
e_mail_identity_combo_box_refresh (combo_box);
|
||||
}
|
||||
|
||||
/**
|
||||
* e_mail_identity_combo_box_get_none_title:
|
||||
* @combo_box: an #EMailIdentityComboBox
|
||||
*
|
||||
* Returns: what title the none item should have
|
||||
*
|
||||
* Since: 3.42
|
||||
**/
|
||||
const gchar *
|
||||
e_mail_identity_combo_box_get_none_title (EMailIdentityComboBox *combo_box)
|
||||
{
|
||||
g_return_val_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box), NULL);
|
||||
|
||||
if (combo_box->priv->none_title)
|
||||
return combo_box->priv->none_title;
|
||||
|
||||
return _("None");
|
||||
}
|
||||
|
||||
/**
|
||||
* e_mail_identity_combo_box_set_none_title:
|
||||
* @combo_box: an #EMailIdentityComboBox
|
||||
* @none_title: (nullable): a title to use, or %NULL
|
||||
*
|
||||
* Set what title the none item should have. This is a user visible string, thus
|
||||
* it should be localized. Use %NULL to reset to the default "None" title.
|
||||
*
|
||||
* Since: 3.42
|
||||
**/
|
||||
void
|
||||
e_mail_identity_combo_box_set_none_title (EMailIdentityComboBox *combo_box,
|
||||
const gchar *none_title)
|
||||
{
|
||||
g_return_if_fail (E_IS_MAIL_IDENTITY_COMBO_BOX (combo_box));
|
||||
|
||||
if (combo_box->priv->none_title != none_title) {
|
||||
g_free (combo_box->priv->none_title);
|
||||
combo_box->priv->none_title = g_strdup (none_title);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e_mail_identity_combo_box_get_allow_aliases:
|
||||
* @combo_box: an #EMailIdentityComboBox
|
||||
|
@ -87,6 +87,11 @@ gboolean e_mail_identity_combo_box_get_allow_none
|
||||
void e_mail_identity_combo_box_set_allow_none
|
||||
(EMailIdentityComboBox *combo_box,
|
||||
gboolean allow_none);
|
||||
const gchar * e_mail_identity_combo_box_get_none_title
|
||||
(EMailIdentityComboBox *combo_box);
|
||||
void e_mail_identity_combo_box_set_none_title
|
||||
(EMailIdentityComboBox *combo_box,
|
||||
const gchar *none_title);
|
||||
gboolean e_mail_identity_combo_box_get_allow_aliases
|
||||
(EMailIdentityComboBox *combo_box);
|
||||
void e_mail_identity_combo_box_set_allow_aliases
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "e-filter-file.h"
|
||||
#include "e-filter-input.h"
|
||||
#include "e-filter-int.h"
|
||||
#include "e-filter-label.h"
|
||||
#include "e-filter-option.h"
|
||||
#include "e-filter-rule.h"
|
||||
#include "e-rule-context.h"
|
||||
@ -460,7 +461,9 @@ static EFilterElement *
|
||||
rule_context_new_element (ERuleContext *context,
|
||||
const gchar *type)
|
||||
{
|
||||
if (!strcmp (type, "string")) {
|
||||
if (!strcmp (type, "label")) {
|
||||
return (EFilterElement *) e_filter_label_new ();
|
||||
} else if (!strcmp (type, "string")) {
|
||||
return (EFilterElement *) e_filter_input_new ();
|
||||
} else if (!strcmp (type, "address")) {
|
||||
/* FIXME: temporary ... need real address type */
|
||||
|
@ -114,6 +114,7 @@
|
||||
#include <e-util/e-filter-file.h>
|
||||
#include <e-util/e-filter-input.h>
|
||||
#include <e-util/e-filter-int.h>
|
||||
#include <e-util/e-filter-label.h>
|
||||
#include <e-util/e-filter-option.h>
|
||||
#include <e-util/e-filter-part.h>
|
||||
#include <e-util/e-filter-rule.h>
|
||||
|
@ -1523,6 +1523,67 @@ mail_session_forget_password (CamelSession *session,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Expects 'forward_with' encoded as: "identity_uid|alias_name|alias_address" with '\\' and '|' being backslash-escaped */
|
||||
static ESource *
|
||||
mail_session_decode_forward_with (ESourceRegistry *registry,
|
||||
const gchar *forward_with,
|
||||
gchar **out_alias_name,
|
||||
gchar **out_alias_address)
|
||||
{
|
||||
ESource *source = NULL;
|
||||
GString *str;
|
||||
gint step;
|
||||
const gchar *ptr;
|
||||
|
||||
if (!forward_with || !*forward_with)
|
||||
return NULL;
|
||||
|
||||
str = g_string_sized_new (strlen (forward_with));
|
||||
|
||||
for (step = 0, ptr = forward_with; *ptr; ptr++) {
|
||||
if (*ptr == '\\' && ptr[1]) {
|
||||
g_string_append_c (str, ptr[1]);
|
||||
ptr++;
|
||||
g_string_append_c (str, *ptr);
|
||||
} else if (*ptr == '|') {
|
||||
if (step == 0) { /* identity_uid */
|
||||
source = e_source_registry_ref_source (registry, str->str);
|
||||
if (!source)
|
||||
break;
|
||||
} else if (step == 1) { /* alias_name */
|
||||
if (str->len)
|
||||
*out_alias_name = g_strdup (str->str);
|
||||
} else if (step == 2) { /* alias_address */
|
||||
if (str->len)
|
||||
*out_alias_address = g_strdup (str->str);
|
||||
}
|
||||
|
||||
g_string_truncate (str, 0);
|
||||
step++;
|
||||
|
||||
if (step == 3)
|
||||
break;
|
||||
} else {
|
||||
g_string_append_c (str, *ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* When the string doesn't end with the '|' */
|
||||
if (step < 3 && str->len) {
|
||||
if (step == 0) { /* identity_uid */
|
||||
source = e_source_registry_ref_source (registry, str->str);
|
||||
} else if (step == 1) { /* alias_name */
|
||||
*out_alias_name = g_strdup (str->str);
|
||||
} else if (step == 2) { /* alias_address */
|
||||
*out_alias_address = g_strdup (str->str);
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mail_session_forward_to_sync (CamelSession *session,
|
||||
CamelFolder *folder,
|
||||
@ -1569,9 +1630,16 @@ mail_session_forward_to_sync (CamelSession *session,
|
||||
|
||||
registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
|
||||
|
||||
/* This returns a new ESource reference. */
|
||||
source = em_utils_guess_mail_identity_with_recipients (
|
||||
registry, message, folder, NULL, &alias_name, &alias_address);
|
||||
source = mail_session_decode_forward_with (registry,
|
||||
camel_medium_get_header (CAMEL_MEDIUM (message), "X-Evolution-Forward-With"),
|
||||
&alias_name, &alias_address);
|
||||
|
||||
if (!source) {
|
||||
/* This returns a new ESource reference. */
|
||||
source = em_utils_guess_mail_identity_with_recipients (
|
||||
registry, message, folder, NULL, &alias_name, &alias_address);
|
||||
}
|
||||
|
||||
if (source == NULL) {
|
||||
g_set_error (
|
||||
error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
|
||||
|
@ -100,6 +100,7 @@ set(SOURCES
|
||||
em-filter-context.c
|
||||
em-filter-editor.c
|
||||
em-filter-editor-folder-element.c
|
||||
em-filter-mail-identity-element.c
|
||||
em-filter-rule.c
|
||||
em-filter-source-element.c
|
||||
em-folder-properties.c
|
||||
@ -191,6 +192,7 @@ set(HEADERS
|
||||
em-filter-context.h
|
||||
em-filter-editor.h
|
||||
em-filter-editor-folder-element.h
|
||||
em-filter-mail-identity-element.h
|
||||
em-filter-rule.h
|
||||
em-filter-source-element.h
|
||||
em-folder-properties.h
|
||||
|
@ -26,10 +26,9 @@
|
||||
|
||||
#include "em-filter-context.h"
|
||||
#include "em-filter-rule.h"
|
||||
#include "em-filter-source-element.h"
|
||||
|
||||
/* For poking into filter-folder guts */
|
||||
#include "em-filter-editor-folder-element.h"
|
||||
#include "em-filter-mail-identity-element.h"
|
||||
#include "em-filter-source-element.h"
|
||||
|
||||
#define EM_FILTER_CONTEXT_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE \
|
||||
@ -238,6 +237,9 @@ filter_context_new_element (ERuleContext *context,
|
||||
if (strcmp (type, "source") == 0)
|
||||
return em_filter_source_element_new (priv->session);
|
||||
|
||||
if (strcmp (type, "mail-identity") == 0)
|
||||
return em_filter_mail_identity_element_new (e_mail_session_get_registry (priv->session));
|
||||
|
||||
return E_RULE_CONTEXT_CLASS (em_filter_context_parent_class)->
|
||||
new_element (context, type);
|
||||
}
|
||||
|
350
src/mail/em-filter-mail-identity-element.c
Normal file
350
src/mail/em-filter-mail-identity-element.c
Normal file
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Red Hat (www.redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "evolution-config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "e-util/e-util.h"
|
||||
#include "em-filter-mail-identity-element.h"
|
||||
|
||||
struct _EMFilterMailIdentityElementPrivate {
|
||||
ESourceRegistry *registry;
|
||||
gchar *display_name;
|
||||
gchar *identity_uid;
|
||||
gchar *alias_name;
|
||||
gchar *alias_address;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EMFilterMailIdentityElement, em_filter_mail_identity_element, E_TYPE_FILTER_ELEMENT)
|
||||
|
||||
static void
|
||||
filter_mail_identity_take_value (EMFilterMailIdentityElement *mail_identity,
|
||||
gchar *display_name,
|
||||
gchar *identity_uid,
|
||||
gchar *alias_name,
|
||||
gchar *alias_address)
|
||||
{
|
||||
if (mail_identity->priv->display_name != display_name) {
|
||||
g_free (mail_identity->priv->display_name);
|
||||
mail_identity->priv->display_name = display_name;
|
||||
} else {
|
||||
g_free (display_name);
|
||||
}
|
||||
|
||||
if (mail_identity->priv->identity_uid != identity_uid) {
|
||||
g_free (mail_identity->priv->identity_uid);
|
||||
mail_identity->priv->identity_uid = identity_uid;
|
||||
} else {
|
||||
g_free (identity_uid);
|
||||
}
|
||||
|
||||
if (mail_identity->priv->alias_name != alias_name) {
|
||||
g_free (mail_identity->priv->alias_name);
|
||||
mail_identity->priv->alias_name = alias_name;
|
||||
} else {
|
||||
g_free (alias_name);
|
||||
}
|
||||
|
||||
if (mail_identity->priv->alias_address != alias_address) {
|
||||
g_free (mail_identity->priv->alias_address);
|
||||
mail_identity->priv->alias_address = alias_address;
|
||||
} else {
|
||||
g_free (alias_address);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
filter_mail_identity_element_finalize (GObject *object)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (object);
|
||||
|
||||
g_clear_object (&mail_identity->priv->registry);
|
||||
g_free (mail_identity->priv->display_name);
|
||||
g_free (mail_identity->priv->identity_uid);
|
||||
g_free (mail_identity->priv->alias_name);
|
||||
g_free (mail_identity->priv->alias_address);
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
G_OBJECT_CLASS (em_filter_mail_identity_element_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint
|
||||
filter_mail_identity_element_eq (EFilterElement *element_a,
|
||||
EFilterElement *element_b)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity_a = EM_FILTER_MAIL_IDENTITY_ELEMENT (element_a);
|
||||
EMFilterMailIdentityElement *mail_identity_b = EM_FILTER_MAIL_IDENTITY_ELEMENT (element_b);
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
if (!E_FILTER_ELEMENT_CLASS (em_filter_mail_identity_element_parent_class)->eq (element_a, element_b))
|
||||
return FALSE;
|
||||
|
||||
return g_strcmp0 (mail_identity_a->priv->display_name, mail_identity_b->priv->display_name) == 0 &&
|
||||
g_strcmp0 (mail_identity_a->priv->identity_uid, mail_identity_b->priv->identity_uid) == 0 &&
|
||||
g_strcmp0 (mail_identity_a->priv->alias_name, mail_identity_b->priv->alias_name) == 0 &&
|
||||
g_strcmp0 (mail_identity_a->priv->alias_address, mail_identity_b->priv->alias_address) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_mail_identity_element_xml_create (EFilterElement *element,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
xmlNodePtr n;
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
E_FILTER_ELEMENT_CLASS (em_filter_mail_identity_element_parent_class)->xml_create (element, node);
|
||||
|
||||
n = node->children;
|
||||
while (n) {
|
||||
if (n->type == XML_ELEMENT_NODE) {
|
||||
g_warning ("Unknown xml node within 'label': %s\n", n->name);
|
||||
}
|
||||
n = n->next;
|
||||
}
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
filter_mail_identity_element_xml_encode (EFilterElement *element)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (element);
|
||||
xmlNodePtr value;
|
||||
|
||||
value = xmlNewNode (NULL, (xmlChar *) "value");
|
||||
xmlSetProp (value, (xmlChar *) "name", (xmlChar *) element->name);
|
||||
|
||||
if (mail_identity->priv->display_name)
|
||||
xmlSetProp (value, (xmlChar *) "display-name", (xmlChar *) mail_identity->priv->display_name);
|
||||
|
||||
if (mail_identity->priv->identity_uid)
|
||||
xmlSetProp (value, (xmlChar *) "identity-uid", (xmlChar *) mail_identity->priv->identity_uid);
|
||||
|
||||
if (mail_identity->priv->alias_name)
|
||||
xmlSetProp (value, (xmlChar *) "alias-name", (xmlChar *) mail_identity->priv->alias_name);
|
||||
|
||||
if (mail_identity->priv->alias_address)
|
||||
xmlSetProp (value, (xmlChar *) "alias-address", (xmlChar *) mail_identity->priv->alias_address);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static gint
|
||||
filter_mail_identity_element_xml_decode (EFilterElement *element,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (element);
|
||||
xmlChar *x_display_name, *x_identity_uid, *x_alias_name, *x_alias_address;
|
||||
|
||||
xmlFree (element->name);
|
||||
element->name = (gchar *) xmlGetProp (node, (xmlChar *) "name");
|
||||
|
||||
x_display_name = xmlGetProp (node, (xmlChar *) "display-name");
|
||||
x_identity_uid = xmlGetProp (node, (xmlChar *) "identity-uid");
|
||||
x_alias_name = xmlGetProp (node, (xmlChar *) "alias-name");
|
||||
x_alias_address = xmlGetProp (node, (xmlChar *) "alias-address");
|
||||
|
||||
filter_mail_identity_take_value (mail_identity,
|
||||
g_strdup ((gchar *) x_display_name),
|
||||
g_strdup ((gchar *) x_identity_uid),
|
||||
g_strdup ((gchar *) x_alias_name),
|
||||
g_strdup ((gchar *) x_alias_address));
|
||||
|
||||
g_clear_pointer (&x_display_name, xmlFree);
|
||||
g_clear_pointer (&x_identity_uid, xmlFree);
|
||||
g_clear_pointer (&x_alias_name, xmlFree);
|
||||
g_clear_pointer (&x_alias_address, xmlFree);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EFilterElement *
|
||||
filter_mail_identity_element_clone (EFilterElement *element)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (element);
|
||||
EMFilterMailIdentityElement *clone_mail_identity;
|
||||
EFilterElement *clone;
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
clone = E_FILTER_ELEMENT_CLASS (em_filter_mail_identity_element_parent_class)->clone (element);
|
||||
|
||||
clone_mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (clone);
|
||||
clone_mail_identity->priv->display_name = g_strdup (mail_identity->priv->display_name);
|
||||
clone_mail_identity->priv->identity_uid = g_strdup (mail_identity->priv->identity_uid);
|
||||
clone_mail_identity->priv->alias_name = g_strdup (mail_identity->priv->alias_name);
|
||||
clone_mail_identity->priv->alias_address = g_strdup (mail_identity->priv->alias_address);
|
||||
|
||||
if (mail_identity->priv->registry)
|
||||
clone_mail_identity->priv->registry = g_object_ref (mail_identity->priv->registry);
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_mail_identity_element_changed_cb (GtkComboBox *combo_box,
|
||||
gpointer user_data)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = user_data;
|
||||
GtkTreeIter iter;
|
||||
gchar *display_name = NULL, *identity_uid = NULL, *alias_name = NULL, *alias_address = NULL;
|
||||
|
||||
g_return_if_fail (EM_IS_FILTER_MAIL_IDENTITY_ELEMENT (mail_identity));
|
||||
|
||||
if (!e_mail_identity_combo_box_get_active_uid (E_MAIL_IDENTITY_COMBO_BOX (combo_box), &identity_uid, &alias_name, &alias_address)) {
|
||||
identity_uid = NULL;
|
||||
alias_name = NULL;
|
||||
alias_address = NULL;
|
||||
}
|
||||
|
||||
if (gtk_combo_box_get_active_iter (combo_box, &iter)) {
|
||||
GtkTreeModel *model;
|
||||
|
||||
model = gtk_combo_box_get_model (combo_box);
|
||||
gtk_tree_model_get (model, &iter,
|
||||
E_MAIL_IDENTITY_COMBO_BOX_COLUMN_DISPLAY_NAME, &display_name,
|
||||
-1);
|
||||
}
|
||||
|
||||
filter_mail_identity_take_value (mail_identity, display_name, identity_uid, alias_name, alias_address);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
filter_mail_identity_element_get_widget (EFilterElement *element)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (element);
|
||||
EMailIdentityComboBox *combo_box;
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = e_mail_identity_combo_box_new (mail_identity->priv->registry);
|
||||
combo_box = E_MAIL_IDENTITY_COMBO_BOX (widget);
|
||||
e_mail_identity_combo_box_set_none_title (combo_box, _("Default Account"));
|
||||
e_mail_identity_combo_box_set_allow_none (combo_box, TRUE);
|
||||
e_mail_identity_combo_box_set_allow_aliases (combo_box, TRUE);
|
||||
|
||||
g_signal_connect_object (combo_box, "changed",
|
||||
G_CALLBACK (filter_mail_identity_element_changed_cb), mail_identity, 0);
|
||||
|
||||
if (mail_identity->priv->identity_uid) {
|
||||
e_mail_identity_combo_box_set_active_uid (combo_box,
|
||||
mail_identity->priv->identity_uid,
|
||||
mail_identity->priv->alias_name,
|
||||
mail_identity->priv->alias_address);
|
||||
} else {
|
||||
e_mail_identity_combo_box_set_active_uid (combo_box, "", NULL, NULL);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
filter_mail_identity_element_add_value (GString *str,
|
||||
const gchar *value)
|
||||
{
|
||||
const gchar *pp;
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
for (pp = value; *pp; pp++) {
|
||||
if (*pp == '\\' || *pp == '|')
|
||||
g_string_append_c (str, '\\');
|
||||
g_string_append_c (str, *pp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
filter_mail_identity_element_format_sexp (EFilterElement *element,
|
||||
GString *out)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (element);
|
||||
GString *value = NULL;
|
||||
|
||||
if (mail_identity->priv->identity_uid && *mail_identity->priv->identity_uid) {
|
||||
/* Encode the value as: "identity_uid|alias_name|alias_value" */
|
||||
value = g_string_sized_new (strlen (mail_identity->priv->identity_uid) * 2);
|
||||
|
||||
filter_mail_identity_element_add_value (value, mail_identity->priv->identity_uid);
|
||||
g_string_append_c (value, '|');
|
||||
filter_mail_identity_element_add_value (value, mail_identity->priv->alias_name);
|
||||
g_string_append_c (value, '|');
|
||||
filter_mail_identity_element_add_value (value, mail_identity->priv->alias_address);
|
||||
}
|
||||
|
||||
camel_sexp_encode_string (out, value ? value->str : NULL);
|
||||
|
||||
if (value)
|
||||
g_string_free (value, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
filter_mail_identity_element_describe (EFilterElement *element,
|
||||
GString *out)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity = EM_FILTER_MAIL_IDENTITY_ELEMENT (element);
|
||||
|
||||
if (mail_identity->priv->display_name && *mail_identity->priv->display_name)
|
||||
g_string_append (out, mail_identity->priv->display_name);
|
||||
}
|
||||
|
||||
static void
|
||||
em_filter_mail_identity_element_class_init (EMFilterMailIdentityElementClass *class)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
EFilterElementClass *filter_element_class;
|
||||
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
object_class->finalize = filter_mail_identity_element_finalize;
|
||||
|
||||
filter_element_class = E_FILTER_ELEMENT_CLASS (class);
|
||||
filter_element_class->eq = filter_mail_identity_element_eq;
|
||||
filter_element_class->xml_create = filter_mail_identity_element_xml_create;
|
||||
filter_element_class->xml_encode = filter_mail_identity_element_xml_encode;
|
||||
filter_element_class->xml_decode = filter_mail_identity_element_xml_decode;
|
||||
filter_element_class->clone = filter_mail_identity_element_clone;
|
||||
filter_element_class->get_widget = filter_mail_identity_element_get_widget;
|
||||
filter_element_class->format_sexp = filter_mail_identity_element_format_sexp;
|
||||
filter_element_class->describe = filter_mail_identity_element_describe;
|
||||
}
|
||||
|
||||
static void
|
||||
em_filter_mail_identity_element_init (EMFilterMailIdentityElement *mail_identity)
|
||||
{
|
||||
mail_identity->priv = em_filter_mail_identity_element_get_instance_private (mail_identity);
|
||||
}
|
||||
|
||||
EFilterElement *
|
||||
em_filter_mail_identity_element_new (ESourceRegistry *registry)
|
||||
{
|
||||
EMFilterMailIdentityElement *mail_identity;
|
||||
|
||||
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
|
||||
|
||||
mail_identity = g_object_new (EM_TYPE_FILTER_MAIL_IDENTITY_ELEMENT, NULL);
|
||||
mail_identity->priv->registry = g_object_ref (registry);
|
||||
|
||||
return E_FILTER_ELEMENT (mail_identity);
|
||||
}
|
||||
|
||||
ESourceRegistry *
|
||||
em_filter_mail_identity_element_get_registry (EMFilterMailIdentityElement *mail_identity)
|
||||
{
|
||||
g_return_val_if_fail (EM_IS_FILTER_MAIL_IDENTITY_ELEMENT (mail_identity), NULL);
|
||||
|
||||
return mail_identity->priv->registry;
|
||||
}
|
65
src/mail/em-filter-mail-identity-element.h
Normal file
65
src/mail/em-filter-mail-identity-element.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Red Hat (www.redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EM_FILTER_MAIL_IDENTITY_ELEMENT_H
|
||||
#define EM_FILTER_MAIL_IDENTITY_ELEMENT_H
|
||||
|
||||
#include <libedataserver/libedataserver.h>
|
||||
#include <e-util/e-util.h>
|
||||
|
||||
/* Standard GObject macros */
|
||||
#define EM_TYPE_FILTER_MAIL_IDENTITY_ELEMENT \
|
||||
(em_filter_mail_identity_element_get_type ())
|
||||
#define EM_FILTER_MAIL_IDENTITY_ELEMENT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST \
|
||||
((obj), EM_TYPE_FILTER_MAIL_IDENTITY_ELEMENT, EMFilterMailIdentityElement))
|
||||
#define EM_FILTER_MAIL_IDENTITY_ELEMENT_CLASS(cls) \
|
||||
(G_TYPE_CHECK_CLASS_CAST \
|
||||
((cls), EM_TYPE_FILTER_MAIL_IDENTITY_ELEMENT, EMFilterMailIdentityElementClass))
|
||||
#define EM_IS_FILTER_MAIL_IDENTITY_ELEMENT(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE \
|
||||
((obj), EM_TYPE_FILTER_MAIL_IDENTITY_ELEMENT))
|
||||
#define EM_IS_FILTER_MAIL_IDENTITY_ELEMENT_CLASS(cls) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE \
|
||||
((cls), EM_TYPE_FILTER_MAIL_IDENTITY_ELEMENT))
|
||||
#define EM_FILTER_MAIL_IDENTITY_ELEMENT_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS \
|
||||
((obj), EM_TYPE_FILTER_MAIL_IDENTITY_ELEMENT, EMFilterMailIdentityElementClass))
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _EMFilterMailIdentityElement EMFilterMailIdentityElement;
|
||||
typedef struct _EMFilterMailIdentityElementClass EMFilterMailIdentityElementClass;
|
||||
typedef struct _EMFilterMailIdentityElementPrivate EMFilterMailIdentityElementPrivate;
|
||||
|
||||
struct _EMFilterMailIdentityElement {
|
||||
EFilterElement parent;
|
||||
EMFilterMailIdentityElementPrivate *priv;
|
||||
};
|
||||
|
||||
struct _EMFilterMailIdentityElementClass {
|
||||
EFilterElementClass parent_class;
|
||||
};
|
||||
|
||||
GType em_filter_mail_identity_element_get_type (void) G_GNUC_CONST;
|
||||
EFilterElement *em_filter_mail_identity_element_new (ESourceRegistry *registry);
|
||||
ESourceRegistry *
|
||||
em_filter_mail_identity_element_get_registry (EMFilterMailIdentityElement *mail_identity);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* EM_FILTER_MAIL_IDENTITY_ELEMENT_H */
|
@ -806,8 +806,12 @@
|
||||
|
||||
<part name="forward">
|
||||
<_title>Forward to</_title>
|
||||
<code>(forward-to ${address})</code>
|
||||
<code>(forward-to ${address} ${from})</code>
|
||||
<input type="address" name="address" allow-empty="false"/>
|
||||
<input type="label" name="with">
|
||||
<_title>with</_title>
|
||||
</input>
|
||||
<input type="mail-identity" name="from"/>
|
||||
</part>
|
||||
</actionset>
|
||||
</filterdescription>
|
||||
|
Reference in New Issue
Block a user