[gnome-contacts] Moved ContactSheet widget to a separate source.



commit f5fb4d0eeac36c37280520e523d9844c7a53183f
Author: Erick PÃrez Castellanos <erick red gmail com>
Date:   Sun Dec 16 14:38:48 2012 -0500

    Moved ContactSheet widget to a separate source.
    
    Contact.set_individual_property was moved to Contact
    class and made static so I can use it everywhere.

 src/Makefile.am                 |    1 +
 src/contacts-contact-pane.vala  |  143 ++++-------------------------
 src/contacts-contact-sheet.vala |  194 +++++++++++++++++++++++++++++++++++++++
 src/contacts-contact.vala       |   25 +++++
 4 files changed, 238 insertions(+), 125 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 26bdd8d..fc170b8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,6 +26,7 @@ bin_PROGRAMS = gnome-contacts
 vala_sources = \
 	contacts-app.vala \
 	contacts-contact.vala \
+	contacts-contact-sheet.vala \
 	contacts-contact-pane.vala \
 	contacts-types.vala \
 	contacts-list-pane.vala \
diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala
index 8209931..1e3657a 100644
--- a/src/contacts-contact-pane.vala
+++ b/src/contacts-contact-pane.vala
@@ -20,132 +20,26 @@ using Gtk;
 using Folks;
 using Gee;
 
-public class Contacts.ContactSheet : Grid {
+const int PROFILE_SIZE = 128;
 
-  const int PROFILE_SIZE = 128;
-
-  public ContactSheet () {
-    set_row_spacing (12);
-    set_column_spacing (16);
-  }
-
-  public void update (Contact c) {
-    var image_frame = new ContactFrame (PROFILE_SIZE, true);
-    image_frame.set_vexpand (false);
-    image_frame.set_valign (Align.START);
-    c.keep_widget_uptodate (image_frame,  (w) => {
-	(w as ContactFrame).set_image (c.individual, c);
-      });
-    attach (image_frame,  0, 0, 1, 3);
-
-    var name_label = new Label (null);
-    name_label.set_hexpand (true);
-    name_label.set_halign (Align.START);
-    name_label.set_valign (Align.START);
-    name_label.set_margin_top (4);
-    name_label.set_ellipsize (Pango.EllipsizeMode.END);
-    name_label.xalign = 0.0f;
-
-    c.keep_widget_uptodate (name_label, (w) => {
-	(w as Label).set_markup (Markup.printf_escaped ("<span font='16'>%s</span>", c.display_name));
+namespace Contacts {
+  public static void change_avatar (Contact contact, ContactFrame image_frame) {
+    var dialog = new AvatarDialog (contact);
+    dialog.show ();
+    dialog.set_avatar.connect ( (icon) =>  {
+	Value v = Value (icon.get_type ());
+	v.set_object (icon);
+	Contact.set_individual_property.begin (contact,
+					       "avatar", v,
+					       (obj, result) => {
+						 try {
+						   Contact.set_individual_property.end (result);
+						 } catch (GLib.Error e) {
+						   App.app.show_message (e.message);
+						   image_frame.set_image (contact.individual, contact);
+					       }
+					       });
       });
-    attach (name_label,  1, 0, 1, 1);
-
-    var merged_presence = c.create_merged_presence_widget ();
-    merged_presence.set_halign (Align.START);
-    merged_presence.set_valign (Align.START);
-    attach (merged_presence,  1, 1, 1, 1);
-
-    int i = 3;
-    int last_store_position = 0;
-    PersonaStore last_store = null;
-
-    var personas = c.get_personas_for_display ();
-    /* Cause personas are sorted properly I can do this */
-    foreach (var p in personas) {
-      if (! Contact.persona_is_main (p) && p.store != last_store) {
-	var store_name = new Label("");
-	store_name.set_markup (Markup.printf_escaped ("<span font='16px bold'>%s</span>",
-						      Contact.format_persona_store_name_for_contact (p)));
-	store_name.set_halign (Align.START);
-	store_name.xalign = 0.0f;
-	store_name.margin_left = 6;
-	attach (store_name, 0, i, 1, 1);
-	last_store = p.store;
-	last_store_position = ++i;
-      }
-
-      /* emails first */
-      var details = p as EmailDetails;
-      if (details != null) {
-	var emails = Contact.sort_fields<EmailFieldDetails>(details.email_addresses);
-	foreach (var email in emails) {
-	  var type_label = new Label (TypeSet.general.format_type (email));
-	  type_label.xalign = 1.0f;
-	  type_label.set_halign (Align.END);
-	  type_label.get_style_context ().add_class ("dim-label");
-	  attach (type_label, 0, i, 1, 1);
-
-	  var value_label = new Button.with_label (email.value);
-	  value_label.focus_on_click = false;
-	  value_label.relief = ReliefStyle.NONE;
-	  value_label.xalign = 0.0f;
-	  value_label.set_hexpand (true);
-	  attach (value_label, 1, i, 1, 1);
-	  i++;
-
-	  value_label.clicked.connect (() => {
-	      Utils.compose_mail ("%s <%s>".printf(c.display_name, email.value));
-	    });
-	}
-      }
-
-      /* phones then */
-      var phone_details = p as PhoneDetails;
-      if (phone_details != null) {
-	var phones = Contact.sort_fields<PhoneFieldDetails>(phone_details.phone_numbers);
-	foreach (var phone in phones) {
-	  var type_label = new Label (TypeSet.general.format_type (phone));
-	  type_label.xalign = 1.0f;
-	  type_label.set_halign (Align.END);
-	  type_label.get_style_context ().add_class ("dim-label");
-	  attach (type_label, 0, i, 1, 1);
-
-	  Widget value_label;
-	  if (App.app.contacts_store.can_call) {
-	    value_label = new Button.with_label (phone.value);
-	    value_label.set_hexpand (true);
-	    (value_label as Button).focus_on_click = false;
-	    (value_label as Button).relief = ReliefStyle.NONE;
-
-	    (value_label as Button).clicked.connect (() => {
-		Utils.start_call (phone.value, App.app.contacts_store.calling_accounts);
-	      });
-	  } else {
-	    value_label = new Label (phone.value);
-	    value_label.set_halign (Align.START);
-	    /* FXIME: hardcode gap to match the button-label starting */
-	    value_label.margin_left = 6;
-	  }
-
-	  attach (value_label, 1, i, 1, 1);
-	  i++;
-
-	}
-      }
-
-      if (i == last_store_position) {
-	get_child_at (0, i - 1).destroy ();
-      }
-    }
-
-    show_all ();
-  }
-
-  public void clear () {
-    foreach (var w in get_children ()) {
-      w.destroy ();
-    }
   }
 }
 
@@ -421,7 +315,6 @@ public class Contacts.ContactPane : ScrolledWindow {
     this.get_child().get_style_context ().add_class ("view");
 
     sheet = new ContactSheet ();
-    sheet.set_orientation (Orientation.VERTICAL);
     top_grid.add (sheet);
 
     top_grid.show_all ();
diff --git a/src/contacts-contact-sheet.vala b/src/contacts-contact-sheet.vala
new file mode 100644
index 0000000..a866a76
--- /dev/null
+++ b/src/contacts-contact-sheet.vala
@@ -0,0 +1,194 @@
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2011 Alexander Larsson <alexl redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Gtk;
+using Folks;
+using Gee;
+
+public class Contacts.ContactSheet : Grid {
+
+  Button add_row_with_button (ref int row, string label_value, string value) {
+    var type_label = new Label (label_value);
+    type_label.xalign = 1.0f;
+    type_label.set_halign (Align.END);
+    type_label.get_style_context ().add_class ("dim-label");
+    attach (type_label, 0, row, 1, 1);
+
+    var value_button = new Button.with_label (value);
+    value_button.focus_on_click = false;
+    value_button.relief = ReliefStyle.NONE;
+    value_button.xalign = 0.0f;
+    value_button.set_hexpand (true);
+    attach (value_button, 1, row, 1, 1);
+    row++;
+
+    return value_button;
+  }
+
+  void add_row_with_label (ref int row, string label_value, string value) {
+    var type_label = new Label (label_value);
+    type_label.xalign = 1.0f;
+    type_label.set_halign (Align.END);
+    type_label.set_valign (Align.START);
+    type_label.get_style_context ().add_class ("dim-label");
+    attach (type_label, 0, row, 1, 1);
+
+    var value_label = new Label (value);
+    value_label.set_line_wrap (true);
+    value_label.xalign = 0.0f;
+    value_label.set_halign (Align.START);
+
+    /* FIXME: hardcode gap to match the button size */
+    type_label.margin_top = 3;
+    value_label.margin_left = 6;
+    value_label.margin_top = 3;
+    value_label.margin_bottom = 3;
+
+    attach (value_label, 1, row, 1, 1);
+    row++;
+  }
+
+  public ContactSheet () {
+    set_row_spacing (12);
+    set_column_spacing (16);
+    set_orientation (Orientation.VERTICAL);
+  }
+
+  public void update (Contact c) {
+    var image_frame = new ContactFrame (PROFILE_SIZE, true);
+    image_frame.set_vexpand (false);
+    image_frame.set_valign (Align.START);
+    image_frame.clicked.connect ( () => {
+	change_avatar (c, image_frame);
+      });
+    c.keep_widget_uptodate (image_frame,  (w) => {
+	(w as ContactFrame).set_image (c.individual, c);
+      });
+    attach (image_frame,  0, 0, 1, 3);
+
+    var name_label = new Label (null);
+    name_label.set_hexpand (true);
+    name_label.set_halign (Align.START);
+    name_label.set_valign (Align.START);
+    name_label.set_margin_top (4);
+    name_label.set_ellipsize (Pango.EllipsizeMode.END);
+    name_label.xalign = 0.0f;
+
+    c.keep_widget_uptodate (name_label, (w) => {
+	(w as Label).set_markup (Markup.printf_escaped ("<span font='16'>%s</span>", c.display_name));
+      });
+    attach (name_label,  1, 0, 1, 1);
+
+    var merged_presence = c.create_merged_presence_widget ();
+    merged_presence.set_halign (Align.START);
+    merged_presence.set_valign (Align.START);
+    attach (merged_presence,  1, 1, 1, 1);
+
+    int i = 3;
+    int last_store_position = 0;
+    bool is_first_persona = true;
+
+    var personas = c.get_personas_for_display ();
+    /* Cause personas are sorted properly I can do this */
+    foreach (var p in personas) {
+      if (!is_first_persona) {
+	var store_name = new Label("");
+	store_name.set_markup (Markup.printf_escaped ("<span font='16px bold'>%s</span>",
+						      Contact.format_persona_store_name_for_contact (p)));
+	store_name.set_halign (Align.START);
+	store_name.xalign = 0.0f;
+	store_name.margin_left = 6;
+	attach (store_name, 0, i, 1, 1);
+	last_store_position = ++i;
+      }
+
+      /* FIXME: add all of these: postal-addresses */
+      var details = p as EmailDetails;
+      if (details != null) {
+	var emails = Contact.sort_fields<EmailFieldDetails>(details.email_addresses);
+	foreach (var email in emails) {
+	  var button = add_row_with_button (ref i, TypeSet.general.format_type (email), email.value);
+	  button.clicked.connect (() => {
+	      Utils.compose_mail ("%s <%s>".printf(c.display_name, email.value));
+	    });
+	}
+      }
+
+      var phone_details = p as PhoneDetails;
+      if (phone_details != null) {
+	var phones = Contact.sort_fields<PhoneFieldDetails>(phone_details.phone_numbers);
+	foreach (var phone in phones) {
+	  if (App.app.contacts_store.can_call) {
+	    var button = add_row_with_button (ref i, TypeSet.phone.format_type (phone), phone.value);
+	    button.clicked.connect (() => {
+		Utils.start_call (phone.value, App.app.contacts_store.calling_accounts);
+	      });
+	  } else {
+	    add_row_with_label (ref i, TypeSet.phone.format_type (phone), phone.value);
+	  }
+	}
+      }
+
+      var url_details = p as UrlDetails;
+      if (url_details != null) {
+	foreach (var url in url_details.urls) {
+	  var button = add_row_with_button (ref i, _("Website"), Contact.format_uri_link_text (url));
+	  button.clicked.connect (() => {
+	      Gtk.show_uri (null, url.value, 0);
+	    });
+	}
+      }
+
+      var name_details = p as NameDetails;
+      if (name_details != null) {
+	if (is_set (name_details.nickname)) {
+	  add_row_with_label (ref i, _("Nickname"), name_details.nickname);
+	}
+      }
+
+      var birthday_details = p as BirthdayDetails;
+      if (birthday_details != null) {
+	if (birthday_details.birthday != null) {
+	  add_row_with_label (ref i, _("Birthday"), birthday_details.birthday.to_local ().format ("%d %B"));
+	}
+      }
+
+      var note_details = p as NoteDetails;
+      if (note_details != null) {
+	foreach (var note in note_details.notes) {
+	  add_row_with_label (ref i, _("Note"), note.value);
+	}
+      }
+
+      if (i != 3)
+	is_first_persona = false;
+
+      if (i == last_store_position) {
+	get_child_at (0, i - 1).destroy ();
+      }
+    }
+
+    show_all ();
+  }
+
+  public void clear () {
+    foreach (var w in get_children ()) {
+      w.destroy ();
+    }
+  }
+}
diff --git a/src/contacts-contact.vala b/src/contacts-contact.vala
index 3c47028..3f873fe 100644
--- a/src/contacts-contact.vala
+++ b/src/contacts-contact.vala
@@ -1286,6 +1286,31 @@ public class Contacts.Contact : GLib.Object  {
     return sorted_props.to_array ();
 
   }
+
+  /* Tries to set the property on all persons that have it writeable, and
+   * if none, creates a new persona and writes to it, returning the new
+   * persona.
+   */
+  public static async Persona? set_individual_property (Contact contact,
+							string property_name,
+							Value value) throws GLib.Error, PropertyError {
+    bool did_set = false;
+    // Need to make a copy here as it could change during the yields
+    var personas_copy = contact.individual.personas.to_array ();
+    foreach (var p in personas_copy) {
+      if (property_name in p.writeable_properties) {
+	did_set = true;
+	yield Contact.set_persona_property (p, property_name, value);
+      }
+    }
+
+    if (!did_set) {
+      var fake = new FakePersona (contact);
+      return yield fake.make_real_and_set (property_name, value);
+    }
+    return null;
+  }
+
   public Account? is_callable (string proto, string id) {
     Tpf.Persona? t_persona = this.find_im_persona (proto, id);
     if (t_persona != null && t_persona.contact != null) {



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