[evolution/wip/gsettings] Bug #224687 - Various fixes in contact list editor
- From: Rodrigo Moya <rodrigo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/wip/gsettings] Bug #224687 - Various fixes in contact list editor
- Date: Wed, 29 Jun 2011 17:57:22 +0000 (UTC)
commit b9ee422f50e9c634baa674347a139807b8085a5e
Author: Dan VrÃtil <dvratil redhat com>
Date: Wed Jun 29 15:30:38 2011 +0200
Bug #224687 - Various fixes in contact list editor
- fixed order of buttons in duplicate adding confirmation dialog
- in the editor, don't display email addresses in sublist nodes
- automatically remove sublists with no children
addressbook/addressbook.error.xml | 10 ++-
.../contact-list-editor/e-contact-list-editor.c | 47 ++++++--
.../gui/contact-list-editor/e-contact-list-model.c | 122 ++++++++++++++++----
.../gui/contact-list-editor/e-contact-list-model.h | 3 +-
4 files changed, 147 insertions(+), 35 deletions(-)
---
diff --git a/addressbook/addressbook.error.xml b/addressbook/addressbook.error.xml
index 6a7dc4b..88010ed 100644
--- a/addressbook/addressbook.error.xml
+++ b/addressbook/addressbook.error.xml
@@ -98,8 +98,16 @@
<button stock="gtk-ok" _label="_Add" response="GTK_RESPONSE_YES"/>
</error>
+ <error id="ask-list-add-some-mails-exist" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Some addresses already exist in this contact list.</_primary>
+ <_secondary>You are trying to add addresses that are part of this list already. Would you like to add them anyway?</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="Skip duplicates" response="GTK_RESPONSE_NO"/>
+ <button _label="Add with duplicates" response="GTK_RESPONSE_YES"/>
+ </error>
+
<error id="ask-list-add-list-exists" type="question" default="GTK_RESPONSE_NO">
- <_primary>'{0}' is already in this contact list.</_primary>
+ <_primary>List '{0}' is already in this contact list.</_primary>
<_secondary>A contact list named '{0}' is already in this contact list. Would you like to add it anyway?</_secondary>
<button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
<button stock="gtk-ok" _label="_Add" response="GTK_RESPONSE_YES"/>
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.c b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
index c87d2e4..a0de8a5 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
@@ -194,15 +194,40 @@ contact_list_editor_add_destination (GtkWidget *widget,
EDestinationStore *dest_store;
GtkTreeView *treeview = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
GtkTreePath *path;
+ gboolean ignore_conflicts = TRUE;
if (e_destination_is_evolution_list (dest)) {
const gchar *id = e_destination_get_contact_uid (dest);
const gchar *name = e_destination_get_name (dest);
- const gchar *tag = "addressbook:ask-list-add-list-exists";
- if (e_contact_list_model_has_uid (model, id) &&
- (e_alert_run_dialog_for_args (GTK_WINDOW (WIDGET (DIALOG)), tag, name, NULL) != GTK_RESPONSE_YES))
- return FALSE;
+ if (e_contact_list_model_has_uid (model, id)) {
+ if (e_alert_run_dialog_for_args (GTK_WINDOW (WIDGET (DIALOG)),
+ "addressbook:ask-list-add-list-exists", name, NULL) != GTK_RESPONSE_YES)
+ return FALSE;
+ } else {
+ const GList *l_dests, *l_dest;
+ gint reply;
+
+ /* Check the new list mail-by-mail for conflicts and eventually ask user what to do
+ with all conflicts */
+ l_dests = e_destination_list_get_dests (dest);
+ for (l_dest = l_dests; l_dest; l_dest = l_dest->next) {
+ if (e_contact_list_model_has_email (model, e_destination_get_email (l_dest->data))) {
+ reply = e_alert_run_dialog_for_args (GTK_WINDOW (WIDGET (DIALOG)),
+ "addressbook:ask-list-add-some-mails-exist", NULL);
+ if (reply == GTK_RESPONSE_YES) {
+ ignore_conflicts = TRUE;
+ break;
+ } else if (reply == GTK_RESPONSE_NO) {
+ ignore_conflicts = FALSE;
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+ }
+
} else {
const gchar *email = e_destination_get_email (dest);
const gchar *tag = "addressbook:ask-list-add-exists";
@@ -213,7 +238,7 @@ contact_list_editor_add_destination (GtkWidget *widget,
}
/* always add to the root level */
- path = e_contact_list_model_add_destination (model, dest, NULL);
+ path = e_contact_list_model_add_destination (model, dest, NULL, ignore_conflicts);
if (path) {
contact_list_editor_scroll_to_end (editor);
gtk_tree_view_expand_to_path (treeview, path);
@@ -363,9 +388,13 @@ contact_list_editor_render_destination (GtkTreeViewColumn *column,
textrep = e_destination_get_textrep (destination, TRUE);
if (eab_parse_qp_email (textrep, &name, &email)) {
- out = g_strdup_printf ("%s <%s>", name, email);
- g_object_set (renderer, "text", out, NULL);
- g_free (out);
+ if (e_destination_is_evolution_list (destination)) {
+ g_object_set (renderer, "text", name, NULL);
+ } else {
+ out = g_strdup_printf ("%s <%s>", name, email);
+ g_object_set (renderer, "text", out, NULL);
+ g_free (out);
+ }
g_free (email);
g_free (name);
} else {
@@ -1771,7 +1800,7 @@ e_contact_list_editor_set_contact (EContactListEditor *editor,
dests = e_destination_list_get_root_dests (list_dest);
for (dest = dests; dest; dest = dest->next) {
GtkTreePath *path;
- path = e_contact_list_model_add_destination (E_CONTACT_LIST_MODEL (priv->model), dest->data, NULL);
+ path = e_contact_list_model_add_destination (E_CONTACT_LIST_MODEL (priv->model), dest->data, NULL, TRUE);
gtk_tree_path_free (path);
}
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.c b/addressbook/gui/contact-list-editor/e-contact-list-model.c
index 63e0f59..b94e8e7 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.c
@@ -82,12 +82,12 @@ contact_list_model_dispose (GObject *object)
EContactListModelPrivate *priv = E_CONTACT_LIST_MODEL (object)->priv;
if (priv->uids_table) {
- g_hash_table_unref (priv->uids_table);
+ g_hash_table_destroy (priv->uids_table);
priv->uids_table = NULL;
}
if (priv->emails_table) {
- g_hash_table_unref (priv->emails_table);
+ g_hash_table_destroy (priv->emails_table);
priv->emails_table = NULL;
}
@@ -140,7 +140,8 @@ e_contact_list_model_has_uid (EContactListModel *model,
GtkTreePath*
e_contact_list_model_add_destination (EContactListModel *model,
EDestination *destination,
- GtkTreeIter *parent)
+ GtkTreeIter *parent,
+ gboolean ignore_conflicts)
{
GtkTreeIter iter;
GtkTreePath *path;
@@ -148,25 +149,46 @@ e_contact_list_model_add_destination (EContactListModel *model,
g_return_val_if_fail (E_IS_CONTACT_LIST_MODEL (model), NULL);
g_return_val_if_fail (E_IS_DESTINATION (destination), NULL);
- gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
- gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 0, destination, -1);
-
if (e_destination_is_evolution_list (destination)) {
const GList *dest, *dests = e_destination_list_get_root_dests (destination);
+ /* Get number of instances of this list in the model */
+ gint list_refs = GPOINTER_TO_INT (g_hash_table_lookup (model->priv->uids_table,
+ e_destination_get_contact_uid (destination)));
- g_hash_table_insert (model->priv->uids_table,
- g_strdup (e_destination_get_contact_uid (destination)),
- destination);
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 0, destination, -1);
for (dest = dests; dest; dest = dest->next) {
- path = e_contact_list_model_add_destination (model, dest->data, &iter);
- if (dest->next)
+ path = e_contact_list_model_add_destination (model, dest->data, &iter, ignore_conflicts);
+ if (dest->next && path)
gtk_tree_path_free (path);
}
+
+ /* When the list has no children the remove it. We don't want empty sublists displayed. */
+ if (!gtk_tree_model_iter_has_child (GTK_TREE_MODEL (model), &iter)) {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+ } else {
+ g_hash_table_insert (model->priv->uids_table,
+ g_strdup (e_destination_get_contact_uid (destination)),
+ GINT_TO_POINTER (list_refs + 1));
+ }
} else {
+ gint dest_refs;
+
+ if (e_contact_list_model_has_email (model, e_destination_get_email (destination)) &&
+ ignore_conflicts == FALSE) {
+ return NULL;
+ }
+
+ dest_refs = GPOINTER_TO_INT (g_hash_table_lookup (model->priv->emails_table,
+ e_destination_get_email (destination)));
+
g_hash_table_insert (model->priv->emails_table,
g_strdup (e_destination_get_email (destination)),
- destination);
+ GINT_TO_POINTER (dest_refs + 1));
+
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 0, destination, -1);
path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
}
@@ -186,30 +208,82 @@ e_contact_list_model_add_contact (EContactListModel *model,
destination = e_destination_new ();
e_destination_set_contact (destination, contact, email_num);
- e_contact_list_model_add_destination (model, destination, NULL);
+ e_contact_list_model_add_destination (model, destination, NULL, TRUE);
+}
+
+static void
+contact_list_model_unref_row_dest (EContactListModel *model,
+ GtkTreeIter *iter)
+{
+ EDestination *dest;
+ GtkTreeModel *tree_model;
+
+ tree_model = GTK_TREE_MODEL (model);
+ gtk_tree_model_get (tree_model, iter, 0, &dest, -1);
+
+ if (gtk_tree_model_iter_has_child (tree_model, iter)) {
+ GtkTreeIter child_iter;
+ gint list_refs = GPOINTER_TO_INT (g_hash_table_lookup (model->priv->uids_table,
+ e_destination_get_contact_uid (dest)));
+
+ /* If the list is only once in the model, then remove it from the hash table,
+ otherwise decrease the counter by one */
+ if (list_refs <= 1) {
+ g_hash_table_remove (model->priv->uids_table,
+ e_destination_get_contact_uid (dest));
+ } else {
+ g_hash_table_insert (model->priv->uids_table,
+ g_strdup (e_destination_get_contact_uid (dest)),
+ GINT_TO_POINTER (list_refs - 1));
+ }
+
+ if (gtk_tree_model_iter_children (tree_model, &child_iter, iter)) {
+ do {
+ contact_list_model_unref_row_dest (model, &child_iter);
+ } while (gtk_tree_model_iter_next (tree_model, &child_iter));
+ }
+
+ } else {
+ gint dest_refs = GPOINTER_TO_INT (g_hash_table_lookup (model->priv->emails_table,
+ e_destination_get_email (dest)));
+
+ if (dest_refs <= 1) {
+ g_hash_table_remove (model->priv->emails_table,
+ e_destination_get_email (dest));
+ } else {
+ g_hash_table_insert (model->priv->emails_table,
+ g_strdup (e_destination_get_email (dest)),
+ GINT_TO_POINTER (dest_refs - 1));
+ }
+ }
+
+ g_object_unref (dest);
}
void
e_contact_list_model_remove_row (EContactListModel *model,
GtkTreeIter *iter)
{
- EDestination *dest;
+ GtkTreeIter parent_iter;
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
g_return_if_fail (iter);
- gtk_tree_model_get (GTK_TREE_MODEL (model), iter, 0, &dest, -1);
-
- if (e_destination_is_evolution_list (dest)) {
- const gchar *uid = e_destination_get_contact_uid (dest);
- g_hash_table_remove (model->priv->uids_table, uid);
+ /* Use helper function to update our reference counters in
+ hash tables but don't remove any row. */
+ contact_list_model_unref_row_dest (model, iter);
+
+ /* Get iter of parent of the row to be removed. After the row is removed, check if there are
+ any more children left for the parent_iter, an eventually remove the parent_iter as well */
+ if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (model), &parent_iter, iter)) {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+ if (!gtk_tree_model_iter_has_child (GTK_TREE_MODEL (model), &parent_iter)) {
+ contact_list_model_unref_row_dest (model, &parent_iter);
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &parent_iter);
+ }
} else {
- const gchar *email = e_destination_get_email (dest);
- g_hash_table_remove (model->priv->emails_table, email);
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
}
-
- g_object_unref (dest);
- gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
}
void
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.h b/addressbook/gui/contact-list-editor/e-contact-list-model.h
index b902658..91e8a82 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.h
@@ -69,7 +69,8 @@ gboolean e_contact_list_model_has_uid (EContactListModel *model,
GtkTreePath * e_contact_list_model_add_destination
(EContactListModel *model,
EDestination *dest,
- GtkTreeIter *parent);
+ GtkTreeIter *parent,
+ gboolean ignore_conflicts);
void e_contact_list_model_add_contact (EContactListModel *model,
EContact *contact,
gint email_num);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]