aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schaarschmidt <schaarsc@gmx.de>2014-05-06 20:31:50 +0800
committerMilan Crha <mcrha@redhat.com>2014-05-06 20:31:50 +0800
commitc2de4087369147ed6797f6b7866629ff9da19dfc (patch)
treed9d91c19f4250f5b87bb6a18629d3a8f5465c734
parent5306c9f8b0f3bd173b7864d1ba284ead4e5ffadd (diff)
downloadgsoc2013-evolution-c2de4087369147ed6797f6b7866629ff9da19dfc.tar
gsoc2013-evolution-c2de4087369147ed6797f6b7866629ff9da19dfc.tar.gz
gsoc2013-evolution-c2de4087369147ed6797f6b7866629ff9da19dfc.tar.bz2
gsoc2013-evolution-c2de4087369147ed6797f6b7866629ff9da19dfc.tar.lz
gsoc2013-evolution-c2de4087369147ed6797f6b7866629ff9da19dfc.tar.xz
gsoc2013-evolution-c2de4087369147ed6797f6b7866629ff9da19dfc.tar.zst
gsoc2013-evolution-c2de4087369147ed6797f6b7866629ff9da19dfc.zip
Bug #653892 - Allow to enter more than four email addresses
-rw-r--r--addressbook/gui/contact-editor/contact-editor.ui181
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-dyntable.c30
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.c414
-rw-r--r--addressbook/gui/widgets/eab-contact-merging.c78
-rw-r--r--addressbook/printing/e-contact-print.c285
-rw-r--r--addressbook/tools/evolution-addressbook-export-list-cards.c11
-rw-r--r--e-util/e-name-selector-entry.c98
-rw-r--r--e-util/e-tree-model-generator.c12
-rw-r--r--e-util/e-tree-model-generator.h2
9 files changed, 573 insertions, 538 deletions
diff --git a/addressbook/gui/contact-editor/contact-editor.ui b/addressbook/gui/contact-editor/contact-editor.ui
index 0c6edc838c..d4ae442f49 100644
--- a/addressbook/gui/contact-editor/contact-editor.ui
+++ b/addressbook/gui/contact-editor/contact-editor.ui
@@ -311,157 +311,40 @@
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
- <child>
- <object class="GtkTable" id="email-table">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <property name="n_rows">3</property>
- <property name="n_columns">4</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkEntry" id="entry-email-3">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="name">email-3</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry-email-1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="name">email-1</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry-email-2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="name">email-2</property>
- </object>
- <packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry-email-4">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="name">email-4</property>
- </object>
- <packing>
- <property name="left_attach">3</property>
- <property name="right_attach">4</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="checkbutton-htmlmail">
- <property name="label" translatable="yes">_Wants to receive HTML mail</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">4</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="combobox-email-1">
- <property name="visible">True</property>
- <property name="model">model2</property>
- <child>
- <object class="GtkCellRendererText" id="renderer2"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="combobox-email-3">
- <property name="visible">True</property>
- <property name="model">model3</property>
- <child>
- <object class="GtkCellRendererText" id="renderer3"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="combobox-email-2">
- <property name="visible">True</property>
- <property name="model">model4</property>
- <child>
- <object class="GtkCellRendererText" id="renderer4"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
+
<child>
- <object class="GtkComboBox" id="combobox-email-4">
+ <object class="GtkVBox" id="vboxmail">
<property name="visible">True</property>
- <property name="model">model5</property>
- <child>
- <object class="GtkCellRendererText" id="renderer5"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- </object>
- </child>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <object class="EContactEditorDynTable" type-func="e_contact_editor_dyntable_get_type" id="mail-dyntable">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkCheckButton" id="checkbutton-htmlmail">
+ <property name="label" translatable="yes">_Wants to receive HTML mail</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+
+ </object>
+ </child>
+
<child type="label">
<object class="GtkHBox" id="hbox561">
<property name="visible">True</property>
diff --git a/addressbook/gui/contact-editor/e-contact-editor-dyntable.c b/addressbook/gui/contact-editor/e-contact-editor-dyntable.c
index eb702720bf..68f298cdc9 100644
--- a/addressbook/gui/contact-editor/e-contact-editor-dyntable.c
+++ b/addressbook/gui/contact-editor/e-contact-editor-dyntable.c
@@ -257,6 +257,9 @@ add_empty_entry (EContactEditorDynTable *dyntable)
GtkWidget *box, *entry;
EContactEditorDynTableClass *class;
+ if (dyntable->priv->curr_entries >= dyntable->priv->max_entries)
+ return;
+
grid = GTK_GRID (dyntable);
position_to_grid (dyntable, dyntable->priv->curr_entries, &col, &row);
@@ -331,7 +334,9 @@ remove_empty_entries (EContactEditorDynTable *dyntable, gboolean fillup)
}
- if (fillup && dyntable->priv->curr_entries < dyntable->priv->show_min_entries)
+ if (fillup
+ && (dyntable->priv->curr_entries < dyntable->priv->show_min_entries
+ || (dyntable->priv->justified && col < dyntable->priv->columns-1)))
add_empty_entry (dyntable);
}
@@ -409,21 +414,28 @@ void
e_contact_editor_dyntable_set_max_entries (EContactEditorDynTable *dyntable,
guint max)
{
- GtkTreeIter iter;
GtkTreeModel *store;
- gboolean holds_data;
+ gint n_children;
g_return_if_fail (max > 0);
store = GTK_TREE_MODEL (dyntable->priv->data_store);
- holds_data = gtk_tree_model_get_iter_first (store, &iter);
- g_return_if_fail (!holds_data);
+
+ n_children = gtk_tree_model_iter_n_children (store, NULL);
+ if (n_children > max) {
+ g_warning ("Dyntable holds %i items, setting max to %i, instead of %i",
+ n_children, n_children, max);
+ max = n_children;
+ }
dyntable->priv->max_entries = max;
if (dyntable->priv->show_max_entries>max)
dyntable->priv->show_max_entries = max;
if (dyntable->priv->show_min_entries>max)
dyntable->priv->show_min_entries = max;
+
+ remove_empty_entries (dyntable, TRUE);
+ show_button (dyntable);
}
/* show at least number_of_entries, with or without data */
@@ -492,10 +504,12 @@ e_contact_editor_dyntable_fill_in_data (EContactEditorDynTable *dyntable)
w = gtk_grid_get_child_at (grid, col + 1, row);
class->widget_fill (dyntable, w, str_data);
- if (pos >= dyntable->priv->max_entries)
- break;
-
valid = gtk_tree_model_iter_next (store, &iter);
+
+ if (valid && pos >= dyntable->priv->max_entries) {
+ g_warning ("dyntable is configured with max_entries = %i, ignoring the rest.", dyntable->priv->max_entries);
+ break;
+ }
}
/* fix visibility of added items */
diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c
index ab7557188b..081c9fb8b0 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/addressbook/gui/contact-editor/e-contact-editor.c
@@ -48,7 +48,7 @@
#define SLOTS_PER_LINE 2
#define SLOTS_IN_COLLAPSED_STATE SLOTS_PER_LINE
-#define EMAIL_SLOTS 4
+#define EMAIL_SLOTS 50
#define PHONE_SLOTS 50
#define SIP_SLOTS 4
#define IM_SLOTS 50
@@ -179,7 +179,8 @@ im_service[] =
{ E_CONTACT_IM_ICQ, N_ ("ICQ") },
{ E_CONTACT_IM_GROUPWISE, N_ ("GroupWise") },
{ E_CONTACT_IM_SKYPE, N_ ("Skype") },
- { E_CONTACT_IM_TWITTER, N_ ("Twitter") }
+ { E_CONTACT_IM_TWITTER, N_ ("Twitter") },
+ { E_CONTACT_IM_GOOGLE_TALK, N_ ("Google Talk")}
};
static EContactField
@@ -193,7 +194,8 @@ im_service_fetch_set[] =
E_CONTACT_IM_ICQ,
E_CONTACT_IM_GROUPWISE,
E_CONTACT_IM_SKYPE,
- E_CONTACT_IM_TWITTER
+ E_CONTACT_IM_TWITTER,
+ E_CONTACT_IM_GOOGLE_TALK
};
/* Defaults from the table above */
@@ -899,108 +901,28 @@ set_entry_text (EContactEditor *editor,
}
static void
-set_combo_box_active (EContactEditor *editor,
- GtkComboBox *combo_box,
- gint active)
-{
- g_signal_handlers_block_matched (
- combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
- gtk_combo_box_set_active (combo_box, active);
- g_signal_handlers_unblock_matched (
- combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
-}
-
-static void
-init_email_record_location (EContactEditor *editor,
- gint record)
+init_email_record_location (EContactEditor *editor)
{
- GtkComboBox *location_combo_box;
- GtkWidget *email_entry;
- gchar *widget_name;
- gint i;
- GtkTreeIter iter;
+ GtkWidget *w;
GtkListStore *store;
+ gint i;
+ EContactEditorDynTable *dyntable;
- widget_name = g_strdup_printf ("entry-email-%d", record);
- email_entry = e_builder_get_widget (editor->priv->builder, widget_name);
- g_free (widget_name);
-
- widget_name = g_strdup_printf ("combobox-email-%d", record);
- location_combo_box = GTK_COMBO_BOX (
- e_builder_get_widget (editor->priv->builder, widget_name));
- g_free (widget_name);
-
- store = GTK_LIST_STORE (gtk_combo_box_get_model (location_combo_box));
- gtk_list_store_clear (store);
+ w = e_builder_get_widget (editor->priv->builder, "mail-dyntable");
+ dyntable = E_CONTACT_EDITOR_DYNTABLE (w);
+ store = e_contact_editor_dyntable_get_combo_store (dyntable);
for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ GtkTreeIter iter;
+
gtk_list_store_append (store, &iter);
- gtk_list_store_set (
- store, &iter,
- 0, _(common_location[i].pretty_name),
- -1);
+ gtk_list_store_set (store, &iter,
+ DYNTABLE_COMBO_COLUMN_TEXT, _(common_location[i].pretty_name),
+ DYNTABLE_COMBO_COLUMN_SENSITIVE, TRUE,
+ -1);
}
- g_signal_connect_swapped (
- location_combo_box, "changed",
- G_CALLBACK (gtk_widget_grab_focus), email_entry);
- g_signal_connect (
- location_combo_box, "changed",
- G_CALLBACK (object_changed), editor);
- g_signal_connect (
- email_entry, "changed",
- G_CALLBACK (object_changed), editor);
- g_signal_connect_swapped (
- email_entry, "activate",
- G_CALLBACK (entry_activated), editor);
-}
-
-static void
-fill_in_email_record (EContactEditor *editor,
- gint record,
- const gchar *address,
- gint location)
-{
- GtkWidget *location_combo_box;
- GtkWidget *email_entry;
- gchar *widget_name;
-
- widget_name = g_strdup_printf ("combobox-email-%d", record);
- location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name);
- g_free (widget_name);
-
- widget_name = g_strdup_printf ("entry-email-%d", record);
- email_entry = e_builder_get_widget (editor->priv->builder, widget_name);
- g_free (widget_name);
-
- set_combo_box_active (
- editor, GTK_COMBO_BOX (location_combo_box),
- location >= 0 ? location : email_default[2]);
- set_entry_text (editor, GTK_ENTRY (email_entry), address ? address : "");
-}
-
-static void
-extract_email_record (EContactEditor *editor,
- gint record,
- gchar **address,
- gint *location)
-{
- GtkWidget *location_combo_box;
- GtkWidget *email_entry;
- gchar *widget_name;
- const gchar *text;
-
- widget_name = g_strdup_printf ("combobox-email-%d", record);
- location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name);
- g_free (widget_name);
-
- widget_name = g_strdup_printf ("entry-email-%d", record);
- email_entry = e_builder_get_widget (editor->priv->builder, widget_name);
- g_free (widget_name);
-
- text = gtk_entry_get_text (GTK_ENTRY (email_entry));
- *address = g_strstrip (g_strdup (text));
- *location = gtk_combo_box_get_active (GTK_COMBO_BOX (location_combo_box));
+ e_contact_editor_dyntable_set_combo_defaults (dyntable, email_default, G_N_ELEMENTS (email_default));
}
static const gchar *
@@ -1127,99 +1049,55 @@ set_ui_slot (EVCardAttribute *attr,
g_free (slot_str);
}
-static gint
-alloc_ui_slot (EContactEditor *editor,
- const gchar *widget_base,
- gint preferred_slot,
- gint num_slots)
-{
- gchar *widget_name;
- GtkWidget *widget;
- const gchar *entry_contents;
- gint i;
-
- /* See if we can get the preferred slot */
-
- if (preferred_slot >= 1) {
- widget_name = g_strdup_printf ("%s-%d", widget_base, preferred_slot);
- widget = e_builder_get_widget (editor->priv->builder, widget_name);
- entry_contents = gtk_entry_get_text (GTK_ENTRY (widget));
- g_free (widget_name);
-
- if (STRING_IS_EMPTY (entry_contents))
- return preferred_slot;
- }
-
- /* Find first empty slot */
-
- for (i = 1; i <= num_slots; i++) {
- widget_name = g_strdup_printf ("%s-%d", widget_base, i);
- widget = e_builder_get_widget (editor->priv->builder, widget_name);
- entry_contents = gtk_entry_get_text (GTK_ENTRY (widget));
- g_free (widget_name);
-
- if (STRING_IS_EMPTY (entry_contents))
- return i;
- }
-
- return -1;
-}
-
-static void
-free_attr_list (GList *attr_list)
-{
- GList *l;
-
- for (l = attr_list; l; l = g_list_next (l)) {
- EVCardAttribute *attr = l->data;
- e_vcard_attribute_free (attr);
- }
-
- g_list_free (attr_list);
-}
-
static void
fill_in_email (EContactEditor *editor)
{
GList *email_attr_list;
GList *l;
- gint record_n;
+ GtkWidget *w;
+ EContactEditorDynTable *dyntable;
+ GtkListStore *data_store;
+ GtkTreeIter iter;
+
+ w = e_builder_get_widget (editor->priv->builder, "mail-dyntable");
+ dyntable = E_CONTACT_EDITOR_DYNTABLE (w);
/* Clear */
- for (record_n = 1; record_n <= EMAIL_SLOTS; record_n++) {
- fill_in_email_record (
- editor, record_n, NULL, email_default[record_n - 1]);
- }
+ e_contact_editor_dyntable_clear_data (dyntable);
/* Fill in */
+ data_store = e_contact_editor_dyntable_extract_data (dyntable);
+
email_attr_list = e_contact_get_attributes (
editor->priv->contact, E_CONTACT_EMAIL);
- for (record_n = 1, l = email_attr_list;
- l && record_n <= EMAIL_SLOTS; l = g_list_next (l)) {
+ for (l = email_attr_list; l; l = g_list_next (l)) {
EVCardAttribute *attr = l->data;
gchar *email_address;
+ gint email_location;
gint slot;
email_address = e_vcard_attribute_get_value (attr);
- slot = alloc_ui_slot (
- editor, "entry-email",
- get_ui_slot (attr), EMAIL_SLOTS);
+ email_location = get_email_location (attr);
+ slot = get_ui_slot (attr);
if (slot < 1)
- break;
-
- fill_in_email_record (
- editor, slot, email_address,
- get_email_location (attr));
+ slot = EMAIL_SLOTS + 1; //add at the end
- record_n++;
+ gtk_list_store_append (data_store, &iter);
+ gtk_list_store_set (data_store, &iter,
+ DYNTABLE_STORE_COLUMN_SORTORDER, slot,
+ DYNTABLE_STORE_COLUMN_SELECTED_ITEM, email_location,
+ DYNTABLE_STORE_COLUMN_ENTRY_STRING, email_address,
+ -1);
g_free (email_address);
}
g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
+
+ e_contact_editor_dyntable_fill_in_data (dyntable);
}
static void
@@ -1229,32 +1107,45 @@ extract_email (EContactEditor *editor)
GList *old_attr_list;
GList *ll;
gint i;
+ GtkWidget *w;
+ EContactEditorDynTable *dyntable;
+ GtkListStore *data_store;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ w = e_builder_get_widget (editor->priv->builder, "mail-dyntable");
+ dyntable = E_CONTACT_EDITOR_DYNTABLE (w);
+ data_store = e_contact_editor_dyntable_extract_data (dyntable);
+ tree_model = GTK_TREE_MODEL (data_store);
- for (i = 1; i <= EMAIL_SLOTS; i++) {
+ valid = gtk_tree_model_get_iter_first (tree_model, &iter);
+ while (valid) {
gchar *address;
gint location;
+ EVCardAttribute *attr;
- extract_email_record (editor, i, &address, &location);
+ attr = e_vcard_attribute_new (
+ "", e_contact_vcard_attribute (E_CONTACT_EMAIL));
- if (!STRING_IS_EMPTY (address)) {
- EVCardAttribute *attr;
- attr = e_vcard_attribute_new (
- "", e_contact_vcard_attribute (E_CONTACT_EMAIL));
+ gtk_tree_model_get (tree_model,&iter,
+ DYNTABLE_STORE_COLUMN_SELECTED_ITEM, &location,
+ DYNTABLE_STORE_COLUMN_ENTRY_STRING, &address,
+ -1);
- if (location >= 0)
- e_vcard_attribute_add_param_with_value (
- attr,
- e_vcard_attribute_param_new (EVC_TYPE),
- email_index_to_location (location));
+ if (location >= 0)
+ e_vcard_attribute_add_param_with_value (
+ attr,
+ e_vcard_attribute_param_new (EVC_TYPE),
+ email_index_to_location (location));
- e_vcard_attribute_add_value (attr, address);
- set_ui_slot (attr, i);
+ e_vcard_attribute_add_value (attr, address);
- attr_list = g_list_append (attr_list, attr);
- }
+ attr_list = g_list_prepend (attr_list, attr);
- g_free (address);
+ valid = gtk_tree_model_iter_next (tree_model, &iter);
}
+ attr_list = g_list_reverse (attr_list);
/* Splice in the old attributes, minus the EMAIL_SLOTS first */
@@ -1269,47 +1160,41 @@ extract_email (EContactEditor *editor)
e_contact_set_attributes (editor->priv->contact, E_CONTACT_EMAIL, attr_list);
- free_attr_list (attr_list);
-}
-
-static void
-sensitize_email_record (EContactEditor *editor,
- gint record,
- gboolean enabled)
-{
- GtkWidget *location_combo_box;
- GtkWidget *email_entry;
- gchar *widget_name;
-
- widget_name = g_strdup_printf ("combobox-email-%d", record);
- location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name);
- g_free (widget_name);
-
- widget_name = g_strdup_printf ("entry-email-%d", record);
- email_entry = e_builder_get_widget (editor->priv->builder, widget_name);
- g_free (widget_name);
-
- gtk_widget_set_sensitive (location_combo_box, enabled);
- gtk_editable_set_editable (GTK_EDITABLE (email_entry), enabled);
+ g_list_free_full (attr_list, (GDestroyNotify) e_vcard_attribute_free);
}
static void
sensitize_email (EContactEditor *editor)
{
- gint i;
-
- for (i = 1; i <= EMAIL_SLOTS; i++) {
- gboolean enabled = TRUE;
-
- if (!editor->priv->target_editable)
- enabled = FALSE;
+ gboolean enabled = FALSE;
+ GtkWidget *w;
+ EContactEditorDynTable *dyntable;
+ guint max_entries = SLOTS_IN_COLLAPSED_STATE;
- if (E_CONTACT_FIRST_EMAIL_ID + i - 1 <= E_CONTACT_LAST_EMAIL_ID &&
- !is_field_supported (editor, E_CONTACT_FIRST_EMAIL_ID + i - 1))
- enabled = FALSE;
+ w = e_builder_get_widget (editor->priv->builder, "mail-dyntable");
+ dyntable = E_CONTACT_EDITOR_DYNTABLE (w);
- sensitize_email_record (editor, i, enabled);
+ if (editor->priv->target_editable) {
+ if (is_field_supported (editor, E_CONTACT_EMAIL)) {
+ enabled = TRUE;
+ max_entries = EMAIL_SLOTS;
+ } else if (is_field_supported (editor, E_CONTACT_EMAIL_4)) {
+ enabled = TRUE;
+ max_entries = 4;
+ } else if (is_field_supported (editor, E_CONTACT_EMAIL_3)) {
+ enabled = TRUE;
+ max_entries = 3;
+ } else if (is_field_supported (editor, E_CONTACT_EMAIL_2)) {
+ enabled = TRUE;
+ max_entries = 2;
+ } else if (is_field_supported (editor, E_CONTACT_EMAIL_1)) {
+ enabled = TRUE;
+ max_entries = 1;
+ }
}
+
+ gtk_widget_set_sensitive (w, enabled);
+ e_contact_editor_dyntable_set_max_entries (dyntable, max_entries);
}
static void
@@ -1427,43 +1312,52 @@ static void
expand_mail (EContactEditor *editor,
gboolean expanded)
{
- GtkTable *table;
- GtkWidget *check;
- const gchar *names[] = {
- "entry-email-2", "combobox-email-2",
- "entry-email-3", "combobox-email-3",
- "entry-email-4", "combobox-email-4",
- NULL
- };
+ GtkWidget *w;
+ EContactEditorDynTable *dyntable;
+
set_arrow_image (editor, "arrow-mail-expand", expanded);
- expand_widget_list (editor, names, expanded);
- /* move 'use html mail' into position */
- check = e_builder_get_widget (editor->priv->builder, "checkbutton-htmlmail");
- table = GTK_TABLE (e_builder_get_widget (editor->priv->builder, "email-table"));
- if (check != NULL && table != NULL) {
- GtkWidget *parent;
-
- g_object_ref (check);
- parent = gtk_widget_get_parent (check);
- gtk_container_remove (GTK_CONTAINER (parent), check);
- if (expanded)
- gtk_table_attach_defaults (table, check, 0, 4, 2, 3);
- else
- gtk_table_attach_defaults (table, check, 2, 4, 0, 1);
- g_object_unref (check);
- }
+ w = e_builder_get_widget (editor->priv->builder, "mail-dyntable");
+ dyntable = E_CONTACT_EDITOR_DYNTABLE (w);
+
+ if (expanded)
+ e_contact_editor_dyntable_set_show_max (dyntable, EMAIL_SLOTS);
+ else
+ e_contact_editor_dyntable_set_show_max (dyntable, SLOTS_IN_COLLAPSED_STATE);
+}
+
+static void
+row_added_mail (EContactEditorDynTable *dyntable, EContactEditor *editor)
+{
+ expand_mail (editor, TRUE);
}
static void
init_email (EContactEditor *editor)
{
- gint i;
+ GtkWidget *w;
+ EContactEditorDynTable *dyntable;
+
+ w = e_builder_get_widget (editor->priv->builder, "mail-dyntable");
+ dyntable = E_CONTACT_EDITOR_DYNTABLE (w);
- for (i = 1; i <= EMAIL_SLOTS; i++)
- init_email_record_location (editor, i);
+ e_contact_editor_dyntable_set_max_entries (dyntable, EMAIL_SLOTS);
+ e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE);
+ e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE);
- expand_mail (editor, !editor->priv->compress_ui);
+ g_signal_connect (
+ w, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect_swapped (
+ w, "activate",
+ G_CALLBACK (entry_activated), editor);
+ g_signal_connect (
+ w, "row-added",
+ G_CALLBACK (row_added_mail), editor);
+
+ init_email_record_location (editor);
+
+ expand_mail (editor, TRUE);
}
static void
@@ -1496,6 +1390,9 @@ fill_in_phone (EContactEditor *editor)
gint phone_type;
slot = get_ui_slot (attr);
+ if (slot < 0)
+ slot = PHONE_SLOTS + 1; /* append at the end */
+
phone_type = get_phone_type (attr);
phone = e_vcard_attribute_get_value (attr);
@@ -1510,9 +1407,8 @@ fill_in_phone (EContactEditor *editor)
}
e_contact_editor_dyntable_fill_in_data (dyntable);
- g_list_free_full (tel_attr_list, (GDestroyNotify) e_vcard_attribute_free);
- expand_phone (editor, TRUE);
+ g_list_free_full (tel_attr_list, (GDestroyNotify) e_vcard_attribute_free);
}
static void
@@ -1626,7 +1522,7 @@ init_phone (EContactEditor *editor)
e_contact_editor_dyntable_set_max_entries (dyntable, PHONE_SLOTS);
e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE);
- e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_PER_LINE);
+ e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE);
g_signal_connect (
w, "changed",
@@ -1639,6 +1535,8 @@ init_phone (EContactEditor *editor)
G_CALLBACK (row_added_phone), editor);
init_phone_record_type (editor);
+
+ expand_phone (editor, TRUE);
}
static void
@@ -1676,12 +1574,17 @@ static void
sensitize_phone (EContactEditor *editor)
{
GtkWidget *w;
- gboolean enabled = TRUE;
+ gboolean enabled = FALSE;
+ int i;
w = e_builder_get_widget (editor->priv->builder, "phone-dyntable");
- if (!editor->priv->target_editable)
- enabled = FALSE;
+ if (editor->priv->target_editable) {
+ enabled = is_field_supported (editor, E_CONTACT_TEL);
+ for (i = 0; i < G_N_ELEMENTS (phones) && !enabled; i++) {
+ enabled = is_field_supported (editor, phones[i].field_id);
+ }
+ }
gtk_widget_set_sensitive (w, enabled);
@@ -1734,8 +1637,6 @@ fill_in_sip (EContactEditor *editor)
e_contact_editor_dyntable_fill_in_data (dyntable);
g_list_free_full (sip_attr_list, (GDestroyNotify) e_vcard_attribute_free);
-
- expand_sip (editor, TRUE);
}
static void
@@ -1845,7 +1746,7 @@ init_sip (EContactEditor *editor)
e_contact_editor_dyntable_set_max_entries (dyntable, SIP_SLOTS);
e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE);
- e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_PER_LINE);
+ e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE);
g_signal_connect (
w, "changed",
@@ -1858,6 +1759,8 @@ init_sip (EContactEditor *editor)
G_CALLBACK (row_added_sip), editor);
init_sip_record_type (editor);
+
+ expand_sip (editor, TRUE);
}
static void
@@ -1950,7 +1853,7 @@ init_im (EContactEditor *editor)
e_contact_editor_dyntable_set_max_entries (dyntable, IM_SLOTS);
e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE);
- e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_PER_LINE);
+ e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE);
g_signal_connect (
w, "changed",
@@ -1963,6 +1866,8 @@ init_im (EContactEditor *editor)
G_CALLBACK (row_added_im), editor);
init_im_record_type (editor);
+
+ expand_im (editor, TRUE);
}
static gint
@@ -2034,8 +1939,6 @@ fill_in_im (EContactEditor *editor)
g_list_free_full (im_attr_list, (GDestroyNotify) e_vcard_attribute_free);
e_contact_editor_dyntable_fill_in_data (dyntable);
-
- expand_im (editor, TRUE);
}
static void
@@ -4263,10 +4166,7 @@ expand_im_toggle (EContactEditor *ce)
static void
expand_mail_toggle (EContactEditor *ce)
{
- GtkWidget *mail;
-
- mail = e_builder_get_widget (ce->priv->builder, "entry-email-4");
- expand_mail (ce, !gtk_widget_get_visible (mail));
+ expand_mail (ce, !is_arrow_image_arrow_down (ce, "arrow-mail-expand"));
}
static void
diff --git a/addressbook/gui/widgets/eab-contact-merging.c b/addressbook/gui/widgets/eab-contact-merging.c
index c788d4003a..38431785a5 100644
--- a/addressbook/gui/widgets/eab-contact-merging.c
+++ b/addressbook/gui/widgets/eab-contact-merging.c
@@ -543,40 +543,64 @@ check_if_same (EContact *contact,
EContact *match)
{
EContactField field;
- GList *email_attr_list;
- gint num_of_email;
- gchar *str = NULL, *string = NULL, *string1 = NULL;
+ gchar *string = NULL, *string1 = NULL;
gboolean res = TRUE;
- email_attr_list = e_contact_get_attributes (match, E_CONTACT_EMAIL);
- num_of_email = g_list_length (email_attr_list);
for (field = E_CONTACT_FULL_NAME; res && field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) {
- if ((field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2
- || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) && (num_of_email < 4)) {
- str = (gchar *) e_contact_get_const (contact, field);
- switch (num_of_email)
- {
- case 0:
+ if (field == E_CONTACT_EMAIL_1) {
+ GList *email_attr_list1, *email_attr_list2, *iter1, *iter2;
+ gint num_of_email1, num_of_email2;
+
+ email_attr_list1 = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
+ num_of_email1 = g_list_length (email_attr_list1);
+
+ email_attr_list2 = e_contact_get_attributes (match, E_CONTACT_EMAIL);
+ num_of_email2 = g_list_length (email_attr_list2);
+
+ if (num_of_email1 != num_of_email2) {
res = FALSE;
break;
- case 1:
- if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str)))
- res = FALSE;
- break;
- case 2:
- if ((str && *str) && (g_ascii_strcasecmp (str,e_contact_get_const (match, E_CONTACT_EMAIL_1))) &&
- (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str)))
- res = FALSE;
- break;
- case 3:
- if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str)) &&
- (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str)) &&
- (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_3),str)))
- res = FALSE;
- break;
+ } else { /* Do pairwise-comparisons on all of the e-mail addresses. */
+ iter1 = email_attr_list1;
+ while (iter1) {
+ gboolean match = FALSE;
+ EVCardAttribute *attr;
+ gchar *email_address1;
+
+ attr = iter1->data;
+ email_address1 = e_vcard_attribute_get_value (attr);
+
+ iter2 = email_attr_list2;
+ while ( iter2 && match == FALSE) {
+ gchar *email_address2;
+
+ attr = iter2->data;
+ email_address2 = e_vcard_attribute_get_value (attr);
+
+ if (g_ascii_strcasecmp (email_address1, email_address2) == 0) {
+ match = TRUE;
+ }
+
+ g_free (email_address2);
+ iter2 = g_list_next (iter2);
+ }
+
+ g_free (email_address1);
+ iter1 = g_list_next (iter1);
+
+ if (match == FALSE) {
+ res = FALSE;
+ break;
+ }
+ }
}
+
+ g_list_free_full (email_attr_list1, (GDestroyNotify) e_vcard_attribute_free);
+ g_list_free_full (email_attr_list2, (GDestroyNotify) e_vcard_attribute_free);
+ } else if (field > E_CONTACT_FIRST_EMAIL_ID && field <= E_CONTACT_LAST_EMAIL_ID) {
+ /* nothing to do, all emails are checked above */
}
else {
string = (gchar *) e_contact_get_const (contact, field);
@@ -592,8 +616,6 @@ check_if_same (EContact *contact,
}
}
- g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
-
return res;
}
diff --git a/addressbook/printing/e-contact-print.c b/addressbook/printing/e-contact-print.c
index 3b1b1cd766..bcd27f879e 100644
--- a/addressbook/printing/e-contact-print.c
+++ b/addressbook/printing/e-contact-print.c
@@ -63,6 +63,61 @@ struct _EContactPrintContext
GSList *contact_list;
};
+/* TODO refactor phone_type
+ * to avoid build dependency loop, code related to phone types was copied from e-contact-editor.c
+ * once e-contact offers some kind of "translation service" code should be removed from here.
+ */
+static struct {
+ EContactField field_id;
+ const gchar *type_1;
+ const gchar *type_2;
+} phones[] = {
+ { E_CONTACT_PHONE_ASSISTANT, EVC_X_ASSISTANT, NULL },
+ { E_CONTACT_PHONE_BUSINESS, "WORK", "VOICE" },
+ { E_CONTACT_PHONE_BUSINESS_FAX, "WORK", "FAX" },
+ { E_CONTACT_PHONE_CALLBACK, EVC_X_CALLBACK, NULL },
+ { E_CONTACT_PHONE_CAR, "CAR", NULL },
+ { E_CONTACT_PHONE_COMPANY, "X-EVOLUTION-COMPANY", NULL },
+ { E_CONTACT_PHONE_HOME, "HOME", "VOICE" },
+ { E_CONTACT_PHONE_HOME_FAX, "HOME", "FAX" },
+ { E_CONTACT_PHONE_ISDN, "ISDN", NULL },
+ { E_CONTACT_PHONE_MOBILE, "CELL", NULL },
+ { E_CONTACT_PHONE_OTHER, "VOICE", NULL },
+ { E_CONTACT_PHONE_OTHER_FAX, "FAX", NULL },
+ { E_CONTACT_PHONE_PAGER, "PAGER", NULL },
+ { E_CONTACT_PHONE_PRIMARY, "PREF", NULL },
+ { E_CONTACT_PHONE_RADIO, EVC_X_RADIO, NULL },
+ { E_CONTACT_PHONE_TELEX, EVC_X_TELEX, NULL },
+ { E_CONTACT_PHONE_TTYTDD, EVC_X_TTYTDD, NULL }
+};
+
+static gint
+get_phone_type (EVCardAttribute *attr)
+{
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (phones); i++) {
+ if (e_vcard_attribute_has_type (attr, phones[i].type_1) &&
+ (phones[i].type_2 == NULL || e_vcard_attribute_has_type (attr, phones[i].type_2)))
+ return i;
+ }
+
+ return -1;
+}
+
+static gint
+get_phone_type_field_id (EVCardAttribute *attr)
+{
+ gint type_index;
+
+ type_index = get_phone_type (attr);
+
+ if (type_index >= 0)
+ return phones [type_index].field_id;
+ else
+ return -1;
+}
+
static gdouble
get_font_height (PangoFontDescription *desc)
{
@@ -227,6 +282,30 @@ e_contact_start_new_column (EContactPrintContext *ctxt)
}
}
+/*
+ * returns (transfer-full) a formated email or a copy of value if parsing failed.
+ */
+static gchar*
+format_email (const gchar* value)
+{
+ gchar *email = NULL, *name = NULL;
+
+ if (eab_parse_qp_email (value, &name, &email)) {
+ gchar* res;
+ if (name && *name)
+ res = g_strdup_printf ("%s <%s>", name, email);
+ else
+ res = g_strdup_printf ("%s", email);
+
+ g_free (name);
+ g_free (email);
+
+ return res;
+ }
+
+ return g_strdup (value);
+}
+
static gchar *
get_contact_string_value (EContact *contact,
gint field)
@@ -243,21 +322,8 @@ get_contact_string_value (EContact *contact,
field == E_CONTACT_EMAIL_2 ||
field == E_CONTACT_EMAIL_3 ||
field == E_CONTACT_EMAIL_4) {
- gchar *email = NULL, *name = NULL;
-
- if (eab_parse_qp_email (value, &name, &email)) {
- gchar *res;
-
- if (name && *name)
- res = g_strdup_printf ("%s <%s>", name, email);
- else
- res = g_strdup_printf ("%s", email);
-
- g_free (name);
- g_free (email);
-
- return res;
- }
+ gchar* res = format_email (value);
+ return res;
}
return g_strdup (value);
}
@@ -296,8 +362,34 @@ e_contact_get_contact_height (EContact *contact,
"%s: %s",
e_contact_pretty_name (field), value);
- cntct_height += e_contact_text_height (
- ctxt->context, ctxt->style->body_font, text);
+ if (field == E_CONTACT_FIRST_EMAIL_ID) {
+ GList *emails = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
+ guint n = g_list_length (emails);
+ cntct_height += n * e_contact_text_height (
+ ctxt->context,
+ ctxt->style->body_font,
+ text);
+ g_list_free_full (emails, (GDestroyNotify) e_vcard_attribute_free);
+ } else if (field > E_CONTACT_FIRST_EMAIL_ID &&
+ field <= E_CONTACT_LAST_EMAIL_ID) {
+ /* ignore */
+ } else if (field == E_CONTACT_FIRST_PHONE_ID) {
+ GList *phones = e_contact_get_attributes (contact, E_CONTACT_TEL);
+ guint n = g_list_length (phones);
+ cntct_height += n * e_contact_text_height (
+ ctxt->context,
+ ctxt->style->body_font,
+ text);
+ g_list_free_full (phones, (GDestroyNotify) e_vcard_attribute_free);
+ } else if (field > E_CONTACT_FIRST_PHONE_ID &&
+ field <= E_CONTACT_LAST_PHONE_ID) {
+ /* ignore */
+ } else {
+ cntct_height += e_contact_text_height (
+ ctxt->context,
+ ctxt->style->body_font,
+ text);
+ }
cntct_height += .2 * get_font_height (ctxt->style->body_font);
@@ -309,19 +401,116 @@ e_contact_get_contact_height (EContact *contact,
return cntct_height;
}
+static void
+print_line (EContactPrintContext *ctxt,
+ const gchar *pretty_name,
+ const gchar *value)
+{
+ GtkPageSetup *setup;
+ gdouble page_height;
+ gint wrapped_lines = 0;
+ gchar *text;
+
+ setup = gtk_print_context_get_page_setup (ctxt->context);
+ page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS);
+
+ text = g_strdup_printf (
+ "%s: %s",
+ pretty_name, value);
+
+
+ if (ctxt->y > page_height)
+ e_contact_start_new_column (ctxt);
+
+ if (ctxt->pages == ctxt->page_nr)
+ e_contact_output (
+ ctxt->context, ctxt->style->body_font,
+ ctxt->x, ctxt->y, ctxt->column_width + 4, text);
+
+ if (get_font_width (ctxt->context,
+ ctxt->style->body_font, text) > ctxt->column_width)
+ wrapped_lines =
+ (get_font_width (ctxt->context,
+ ctxt->style->body_font, text) /
+ (ctxt->column_width + 4)) + 1;
+ ctxt->y =
+ ctxt->y + ((wrapped_lines + 1) *
+ e_contact_text_height (
+ ctxt->context,
+ ctxt->style->body_font,
+ text));
+
+ ctxt->y += .2 * get_font_height (ctxt->style->body_font);
+
+ g_free (text);
+}
+
+static void
+print_emails (EContact *contact,
+ EContactPrintContext *ctxt)
+{
+ gint i;
+ GList *emails, *l;
+
+ emails = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
+
+ for (i = 1, l = emails; l; l = g_list_next (l), i++) {
+ EVCardAttribute *attr = l->data;
+ gchar *email_address;
+ gchar *formatted_email;
+ gchar *pretty_name;
+
+ email_address = e_vcard_attribute_get_value (attr);
+ formatted_email = format_email (email_address);
+ pretty_name = g_strdup_printf ("%s %2d", N_ ("Email"), i);
+
+ print_line (ctxt, pretty_name, formatted_email);
+
+ g_free (pretty_name);
+ g_free (email_address);
+ g_free (formatted_email);
+ }
+
+ g_list_free_full (emails, (GDestroyNotify) e_vcard_attribute_free);
+}
+
+static void
+print_phones (EContact *contact,
+ EContactPrintContext * ctxt)
+{
+ GList *phones, *l;
+
+ phones = e_contact_get_attributes (contact, E_CONTACT_TEL);
+
+ for (l = phones; l; l = g_list_next (l)) {
+ EVCardAttribute *attr = l->data;
+ gchar *phone;
+ gint field_id;
+ const gchar *pretty_name;
+
+ phone = e_vcard_attribute_get_value (attr);
+ field_id = get_phone_type_field_id (attr);
+ if (field_id >= 0) {
+ pretty_name = e_contact_pretty_name (field_id);
+ } else {
+ pretty_name = N_ ("unknown phone type");
+ }
+ print_line (ctxt, pretty_name, phone);
+
+ g_free (phone);
+ }
+
+ g_list_free_full (phones, (GDestroyNotify) e_vcard_attribute_free);
+}
static void
e_contact_print_contact (EContact *contact,
EContactPrintContext *ctxt)
{
- GtkPageSetup *setup;
gchar *file_as;
cairo_t *cr;
- gdouble page_height;
gint field;
- setup = gtk_print_context_get_page_setup (ctxt->context);
- page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS);
cr = gtk_print_context_get_cairo_context (ctxt->context);
cairo_save (cr);
@@ -353,45 +542,29 @@ e_contact_print_contact (EContact *contact,
for (field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++)
{
- gchar *value;
- gchar *text;
- gint wrapped_lines = 0;
+ if (field == E_CONTACT_FIRST_EMAIL_ID)
+ print_emails (contact, ctxt);
+ else if (field > E_CONTACT_FIRST_EMAIL_ID &&
+ field <= E_CONTACT_LAST_EMAIL_ID)
+ ; /* ignore, all emails are printed in print_emails() */
+ else if (field == E_CONTACT_FIRST_PHONE_ID)
+ print_phones (contact, ctxt);
+ else if (field > E_CONTACT_FIRST_PHONE_ID &&
+ field <= E_CONTACT_LAST_PHONE_ID)
+ ; /* ignore, all phones are printed in print_phones() */
+ else {
+ gchar *value;
+
+ value = get_contact_string_value (contact, field);
+ if (value == NULL || *value == '\0') {
+ g_free (value);
+ continue;
+ }
- if (ctxt->y > page_height)
- e_contact_start_new_column (ctxt);
+ print_line (ctxt, e_contact_pretty_name (field), value);
- value = get_contact_string_value (contact, field);
- if (value == NULL || *value == '\0') {
g_free (value);
- continue;
}
-
- text = g_strdup_printf (
- "%s: %s",
- e_contact_pretty_name (field), value);
-
- if (ctxt->pages == ctxt->page_nr)
- e_contact_output (
- ctxt->context, ctxt->style->body_font,
- ctxt->x, ctxt->y, ctxt->column_width + 4, text);
-
- if (get_font_width (ctxt->context,
- ctxt->style->body_font, text) > ctxt->column_width)
- wrapped_lines =
- (get_font_width (ctxt->context,
- ctxt->style->body_font, text) /
- (ctxt->column_width + 4)) + 1;
- ctxt->y =
- ctxt->y + ((wrapped_lines + 1) *
- e_contact_text_height (
- ctxt->context,
- ctxt->style->body_font,
- text));
-
- ctxt->y += .2 * get_font_height (ctxt->style->body_font);
-
- g_free (value);
- g_free (text);
}
ctxt->y += get_font_height (ctxt->style->headings_font) * .4 + 8;
diff --git a/addressbook/tools/evolution-addressbook-export-list-cards.c b/addressbook/tools/evolution-addressbook-export-list-cards.c
index 3faf245859..c6261f6c53 100644
--- a/addressbook/tools/evolution-addressbook-export-list-cards.c
+++ b/addressbook/tools/evolution-addressbook-export-list-cards.c
@@ -461,6 +461,17 @@ e_contact_get_csv (EContact *contact,
GSList *csv_all_fields)
{
gchar *aline;
+ GList *emails;
+ guint n_emails;
+ gchar *full_name;
+
+ emails = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
+ n_emails = g_list_length (emails);
+ full_name = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ if (n_emails > 4)
+ g_warning ("%s: only 4 out of %i emails have been exported", full_name, n_emails);
+ g_free (full_name);
+ g_list_free_full (emails, (GDestroyNotify) e_vcard_attribute_free);
aline = e_contact_to_csv (contact, csv_all_fields);
return aline;
diff --git a/e-util/e-name-selector-entry.c b/e-util/e-name-selector-entry.c
index 0f872e718f..a50c886e9c 100644
--- a/e-util/e-name-selector-entry.c
+++ b/e-util/e-name-selector-entry.c
@@ -832,11 +832,13 @@ utf8_casefold_collate_len (const gchar *str1,
static gchar *
build_textrep_for_contact (EContact *contact,
- EContactField cue_field)
+ EContactField cue_field,
+ gint email_num)
{
gchar *name = NULL;
gchar *email = NULL;
gchar *textrep;
+ GList *l;
switch (cue_field) {
case E_CONTACT_FULL_NAME:
@@ -846,12 +848,11 @@ build_textrep_for_contact (EContact *contact,
email = e_contact_get (contact, E_CONTACT_EMAIL_1);
break;
- case E_CONTACT_EMAIL_1:
- case E_CONTACT_EMAIL_2:
- case E_CONTACT_EMAIL_3:
- case E_CONTACT_EMAIL_4:
+ case E_CONTACT_EMAIL:
name = NULL;
- email = e_contact_get (contact, cue_field);
+ l = e_contact_get (contact, cue_field);
+ email = strdup (g_list_nth_data (l, email_num));
+ g_list_free_full (l, g_free);
break;
default:
@@ -877,11 +878,11 @@ contact_match_cue (ENameSelectorEntry *name_selector_entry,
EContact *contact,
const gchar *cue_str,
EContactField *matched_field,
- gint *matched_field_rank)
+ gint *matched_field_rank,
+ gint *matched_email_num)
{
EContactField fields[] = { E_CONTACT_FULL_NAME, E_CONTACT_NICKNAME, E_CONTACT_FILE_AS,
- E_CONTACT_EMAIL_1, E_CONTACT_EMAIL_2, E_CONTACT_EMAIL_3,
- E_CONTACT_EMAIL_4 };
+ E_CONTACT_EMAIL };
gchar *email;
gboolean result = FALSE;
gint cue_len;
@@ -903,36 +904,47 @@ contact_match_cue (ENameSelectorEntry *name_selector_entry,
}
g_free (email);
- for (i = 0; i < G_N_ELEMENTS (fields); i++) {
+ for (i = 0; i < G_N_ELEMENTS (fields) && result == FALSE; i++) {
+ gint email_num;
gchar *value;
gchar *value_sane;
+ GList *emails = NULL, *ll = NULL;
/* Don't match e-mail addresses in contact lists */
if (e_contact_get (contact, E_CONTACT_IS_LIST) &&
- fields[i] >= E_CONTACT_FIRST_EMAIL_ID &&
- fields[i] <= E_CONTACT_LAST_EMAIL_ID)
+ fields[i] == E_CONTACT_EMAIL)
continue;
- value = e_contact_get (contact, fields[i]);
- if (!value)
- continue;
+ if (fields[i] == E_CONTACT_EMAIL) {
+ emails = e_contact_get (contact, fields[i]);
+ } else {
+ value = e_contact_get (contact, fields[i]);
+ if (!value)
+ continue;
+ emails = g_list_append (emails, value);
+ }
- value_sane = sanitize_string (value);
- g_free (value);
+ for (ll = emails, email_num = 0; ll; ll = ll->next, email_num++) {
+ value = ll->data;
+ value_sane = sanitize_string (value);
- ENS_DEBUG (g_print ("Comparing '%s' to '%s'\n", value, cue_str));
+ ENS_DEBUG (g_print ("Comparing '%s' to '%s'\n", value, cue_str));
- if (!utf8_casefold_collate_len (value_sane, cue_str, cue_len)) {
- if (matched_field)
- *matched_field = fields [i];
- if (matched_field_rank)
- *matched_field_rank = i;
+ if (!utf8_casefold_collate_len (value_sane, cue_str, cue_len)) {
+ if (matched_field)
+ *matched_field = fields[i];
+ if (matched_field_rank)
+ *matched_field_rank = i;
+ if (matched_email_num)
+ *matched_email_num = email_num;
- result = TRUE;
+ result = TRUE;
+ g_free (value_sane);
+ break;
+ }
g_free (value_sane);
- break;
}
- g_free (value_sane);
+ g_list_free_full (emails, g_free);
}
return result;
@@ -944,12 +956,14 @@ find_existing_completion (ENameSelectorEntry *name_selector_entry,
EContact **contact,
gchar **text,
EContactField *matched_field,
+ gint *matched_email_num,
EBookClient **book_client)
{
GtkTreeIter iter;
EContact *best_contact = NULL;
gint best_field_rank = G_MAXINT;
EContactField best_field = 0;
+ gint best_email_num = -1;
EBookClient *best_book_client = NULL;
g_assert (cue_str);
@@ -965,6 +979,7 @@ find_existing_completion (ENameSelectorEntry *name_selector_entry,
do {
EContact *current_contact;
gint current_field_rank;
+ gint current_email_num;
EContactField current_field;
gboolean matches;
@@ -972,13 +987,15 @@ find_existing_completion (ENameSelectorEntry *name_selector_entry,
if (!current_contact)
continue;
- matches = contact_match_cue (name_selector_entry, current_contact, cue_str, &current_field, &current_field_rank);
+ matches = contact_match_cue (name_selector_entry, current_contact, cue_str, &current_field, &current_field_rank, &current_email_num);
if (matches && current_field_rank < best_field_rank) {
best_contact = current_contact;
best_field_rank = current_field_rank;
best_field = current_field;
best_book_client = e_contact_store_get_client (name_selector_entry->priv->contact_store, &iter);
+ best_email_num = current_email_num;
}
+
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (name_selector_entry->priv->contact_store), &iter));
if (!best_contact)
@@ -987,12 +1004,13 @@ find_existing_completion (ENameSelectorEntry *name_selector_entry,
if (contact)
*contact = best_contact;
if (text)
- *text = build_textrep_for_contact (best_contact, best_field);
+ *text = build_textrep_for_contact (best_contact, best_field, best_email_num);
if (matched_field)
*matched_field = best_field;
if (book_client)
*book_client = best_book_client;
-
+ if (matched_email_num)
+ *matched_email_num = best_email_num;
return TRUE;
}
@@ -1060,6 +1078,7 @@ type_ahead_complete (ENameSelectorEntry *name_selector_entry)
EBookClient *book_client = NULL;
EContactField matched_field;
EDestination *destination;
+ gint matched_email_num;
gint cursor_pos;
gint range_start = 0;
gint range_end = 0;
@@ -1088,7 +1107,7 @@ type_ahead_complete (ENameSelectorEntry *name_selector_entry)
cue_str = get_entry_substring (name_selector_entry, range_start, range_end);
if (!find_existing_completion (name_selector_entry, cue_str, &contact,
- &textrep, &matched_field, &book_client)) {
+ &textrep, &matched_field, &matched_email_num, &book_client)) {
g_free (cue_str);
return;
}
@@ -1133,9 +1152,8 @@ type_ahead_complete (ENameSelectorEntry *name_selector_entry)
if (contact && destination) {
gint email_n = 0;
- if (matched_field >= E_CONTACT_FIRST_EMAIL_ID && matched_field <= E_CONTACT_LAST_EMAIL_ID)
- email_n = matched_field - E_CONTACT_FIRST_EMAIL_ID;
-
+ if (matched_field == E_CONTACT_EMAIL)
+ email_n = matched_email_num;
e_destination_set_contact (destination, contact, email_n);
if (book_client)
e_destination_set_client (destination, book_client);
@@ -2042,6 +2060,7 @@ contact_layout_pixbuffer (GtkCellLayout *cell_layout,
GtkTreeIter contact_store_iter;
gint email_n;
EContactPhoto *photo;
+ gboolean iter_is_valid;
GdkPixbuf *pixbuf = NULL;
if (!name_selector_entry->priv->contact_store)
@@ -2050,11 +2069,15 @@ contact_layout_pixbuffer (GtkCellLayout *cell_layout,
gtk_tree_model_filter_convert_iter_to_child_iter (
GTK_TREE_MODEL_FILTER (model),
&generator_iter, iter);
- e_tree_model_generator_convert_iter_to_child_iter (
+ iter_is_valid = e_tree_model_generator_convert_iter_to_child_iter (
name_selector_entry->priv->email_generator,
&contact_store_iter, &email_n,
&generator_iter);
+ if (!iter_is_valid) {
+ return;
+ }
+
contact = e_contact_store_get_contact (name_selector_entry->priv->contact_store, &contact_store_iter);
if (!contact) {
g_object_set (cell, "pixbuf", pixbuf, NULL);
@@ -2121,6 +2144,7 @@ contact_layout_formatter (GtkCellLayout *cell_layout,
gchar *file_as_str;
gchar *email_str;
gint email_n;
+ gboolean iter_is_valid;
if (!name_selector_entry->priv->contact_store)
return;
@@ -2128,11 +2152,15 @@ contact_layout_formatter (GtkCellLayout *cell_layout,
gtk_tree_model_filter_convert_iter_to_child_iter (
GTK_TREE_MODEL_FILTER (model),
&generator_iter, iter);
- e_tree_model_generator_convert_iter_to_child_iter (
+ iter_is_valid = e_tree_model_generator_convert_iter_to_child_iter (
name_selector_entry->priv->email_generator,
&contact_store_iter, &email_n,
&generator_iter);
+ if (!iter_is_valid) {
+ return;
+ }
+
contact = e_contact_store_get_contact (name_selector_entry->priv->contact_store, &contact_store_iter);
email_list = e_contact_get (contact, E_CONTACT_EMAIL);
email_str = g_list_nth_data (email_list, email_n);
diff --git a/e-util/e-tree-model-generator.c b/e-util/e-tree-model-generator.c
index f035d120f6..981ca51a0a 100644
--- a/e-util/e-tree-model-generator.c
+++ b/e-util/e-tree-model-generator.c
@@ -969,7 +969,7 @@ e_tree_model_generator_convert_path_to_child_path (ETreeModelGenerator *tree_mod
* The permutation index is the index of the generated row based on this
* child row, with the first generated row based on this child row being 0.
**/
-void
+gboolean
e_tree_model_generator_convert_iter_to_child_iter (ETreeModelGenerator *tree_model_generator,
GtkTreeIter *child_iter,
gint *permutation_n,
@@ -979,9 +979,10 @@ e_tree_model_generator_convert_iter_to_child_iter (ETreeModelGenerator *tree_mod
GArray *group;
gint index;
gint internal_offset = 0;
+ gboolean iter_is_valid = FALSE;
- g_return_if_fail (E_IS_TREE_MODEL_GENERATOR (tree_model_generator));
- g_return_if_fail (ITER_IS_VALID (tree_model_generator, generator_iter));
+ g_return_val_if_fail (E_IS_TREE_MODEL_GENERATOR (tree_model_generator), iter_is_valid);
+ g_return_val_if_fail (ITER_IS_VALID (tree_model_generator, generator_iter), iter_is_valid);
path = gtk_tree_path_new ();
ITER_GET (generator_iter, &group, &index);
@@ -1000,11 +1001,14 @@ e_tree_model_generator_convert_iter_to_child_iter (ETreeModelGenerator *tree_mod
}
if (child_iter)
- gtk_tree_model_get_iter (tree_model_generator->priv->child_model, child_iter, path);
+ iter_is_valid = gtk_tree_model_get_iter (tree_model_generator->priv->child_model, child_iter, path);
+
if (permutation_n)
*permutation_n = internal_offset;
gtk_tree_path_free (path);
+
+ return iter_is_valid;
}
/* ---------------- *
diff --git a/e-util/e-tree-model-generator.h b/e-util/e-tree-model-generator.h
index 59cf0ad90b..739df1fd66 100644
--- a/e-util/e-tree-model-generator.h
+++ b/e-util/e-tree-model-generator.h
@@ -92,7 +92,7 @@ void e_tree_model_generator_convert_child_iter_to_iter
GtkTreePath * e_tree_model_generator_convert_path_to_child_path
(ETreeModelGenerator *tree_model_generator,
GtkTreePath *generator_path);
-void e_tree_model_generator_convert_iter_to_child_iter
+gboolean e_tree_model_generator_convert_iter_to_child_iter
(ETreeModelGenerator *tree_model_generator,
GtkTreeIter *child_iter,
gint *permutation_n,