[gnome-contacts] Add inline suggestions



commit f7f1593dbdaa87c537e6d86d12edaa610ab12397
Author: Alexander Larsson <alexl redhat com>
Date:   Mon Jan 23 16:43:20 2012 +0100

    Add inline suggestions
    
    This is only partially done. Also needs undo and support for
    the "no" button.

 data/gnome-contacts.css        |    6 +++
 src/contacts-contact-pane.vala |   74 ++++++++++++++++++++++++++++++++++++++++
 src/contacts-contact.vala      |   37 ++++++++++++++++++++
 3 files changed, 117 insertions(+), 0 deletions(-)
---
diff --git a/data/gnome-contacts.css b/data/gnome-contacts.css
index e68bf35..f899342 100644
--- a/data/gnome-contacts.css
+++ b/data/gnome-contacts.css
@@ -12,6 +12,12 @@
     background-color: #f1f2f1;
 }
 
+.contacts-suggestion {
+    background-color: #434343;
+    color: #ffffff;
+    border-radius: 4;
+}
+
 /* Border on the right in the left menu toolbar */
 .contacts-left-toolbar.toolbar.menubar {
     border-width: 0 1 0 0;
diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala
index 9a8d85d..94535a8 100644
--- a/src/contacts-contact-pane.vala
+++ b/src/contacts-contact-pane.vala
@@ -1722,6 +1722,72 @@ public class Contacts.ContactPane : ScrolledWindow {
       call_button.hide ();
   }
 
+  public void add_suggestion (Contact c) {
+    var row = new FieldRow (row_group);
+    personas_grid.add (row);
+
+    var grid = new Grid ();
+    grid.get_style_context ().add_class ("contacts-suggestion");
+    grid.set_redraw_on_allocate (true);
+    grid.draw.connect ( (cr) => {
+	Allocation allocation;
+	grid.get_allocation (out allocation);
+
+	var context = grid.get_style_context ();
+	Gtk.render_background (context, cr,
+			       0, 0,
+			       allocation.width, allocation.height);
+	return false;
+      });
+    row.pack (grid);
+
+    var image_frame = new ContactFrame (Contact.SMALL_AVATAR_SIZE);
+    c.keep_widget_uptodate (image_frame,  (w) => {
+	(w as ContactFrame).set_image (c.individual, c);
+      });
+    image_frame.set_hexpand (false);
+    grid.attach (image_frame, 0, 0, 1, 2);
+
+    var label = new Label ("");
+    if (contact.is_main)
+      label.set_markup (_("Does %s from %s belong here?").printf (c.display_name, c.format_persona_stores ()));
+    else
+      label.set_markup (_("Do these details belong to %s?").printf (c.display_name));
+    label.set_valign (Align.START);
+    label.set_halign (Align.START);
+    label.set_line_wrap (true);
+    label.set_line_wrap_mode (Pango.WrapMode.WORD_CHAR);
+    label.set_hexpand (false);
+    label.xalign = 0.0f;
+    grid.attach (label, 1, 0, 1, 1);
+
+    var bbox = new ButtonBox (Orientation.HORIZONTAL);
+    var yes = new Button.with_label (_("Yes"));
+    var no = new Button.with_label (_("No"));
+
+    yes.clicked.connect ( () => {
+	link_contacts.begin (contact, c, (obj, result) => {
+	    link_contacts.end (result);
+	  });
+	/* TODO: Add undo */
+	row.destroy ();
+      });
+
+    no.clicked.connect ( () => {
+	/* TODO: Set up anti-linking relationship (and any where we force unlink) */
+	/* TODO: Add undo */
+	row.destroy ();
+      });
+
+    bbox.add (yes);
+    bbox.add (no);
+    bbox.set_spacing (8);
+    bbox.set_halign (Align.END);
+    bbox.set_hexpand (true);
+    bbox.set_border_width (4);
+    grid.attach (bbox, 2, 0, 1, 2);
+  }
+
   public void update_personas () {
     foreach (var w in personas_grid.get_children ()) {
       w.destroy ();
@@ -1737,6 +1803,14 @@ public class Contacts.ContactPane : ScrolledWindow {
       personas_grid.add (sheet);
     }
 
+    var matches = contact.store.aggregator.get_potential_matches (contact.individual, MatchResult.HIGH);
+    foreach (var ind in matches.keys) {
+      var c = Contact.from_individual (ind);
+      if (c != null && contact.suggest_link_to (c)) {
+	add_suggestion (c);
+      }
+    }
+
     personas_grid.show_all ();
   }
 
diff --git a/src/contacts-contact.vala b/src/contacts-contact.vala
index d0b1989..c2e1267 100644
--- a/src/contacts-contact.vala
+++ b/src/contacts-contact.vala
@@ -1113,6 +1113,43 @@ public class Contacts.Contact : GLib.Object  {
     return store.display_name;
   }
 
+  /* These are "regular" address book contacts, i.e. they contain a
+     persona that would be "main" if that persona was the primary store */
+  public bool has_mainable_persona () {
+    foreach (var p in individual.personas) {
+      if (p.store.type_id == "eds" &&
+	  !persona_is_google_other (p))
+	return true;
+    }
+    return false;
+  }
+
+  /* We never want to suggest linking to google contacts that
+     are not My Contacts nor Profiles */
+  private bool non_linkable () {
+    bool all_unlinkable = true;
+
+    foreach (var p in individual.personas) {
+      if (!persona_is_google_other (p) ||
+	  persona_is_google_profile (p))
+	all_unlinkable = false;
+    }
+
+    return all_unlinkable;
+  }
+
+  public bool suggest_link_to (Contact other) {
+    if (this.non_linkable () || other.non_linkable ())
+      return false;
+
+    /* Only connect main contacts with non-mainable contacts, and vice versa. */
+    if ((this.is_main && !other.has_mainable_persona()) ||
+	(!this.has_mainable_persona () && other.is_main)) {
+      return true;
+    }
+    return false;
+  }
+
   private static bool persona_is_google (Persona persona) {
     var store = persona.store;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]