Re: [evolution-patches] Bug 127513: Gaim/addressbook identity integration



On Wed, Dec 03, 2003 at 11:42:20PM -0800, Christian Hammond wrote:
> Here is the latest incarnation of the Gaim/Evolution addressbook
> synchronization patch. Once again, this comes in a patch for e-d-s,
> one for evolution, and a tarball for evolution as well.

Helps if I attach the patches.

Christian
 
-- 
Christian Hammond         <>  The GNUpdate Project
chipx86 gnupdate org      <>  http://www.gnupdate.org/
   There are 3 kinds of people: those who can count and those who can't.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/ChangeLog,v
retrieving revision 1.51
diff -u -r1.51 ChangeLog
--- ChangeLog	1 Dec 2003 18:04:00 -0000	1.51
+++ ChangeLog	4 Dec 2003 07:17:51 -0000
@@ -1,3 +1,10 @@
+2003-12-03  Christian Hammond <chipx86 gnupdate org>
+
+	* addressbook/libebook/e-contact.[ch]: Changed the IM account field
+	types from LIST_FIELD to MULTI_LIST_FIELD, as discussed with Chris
+	Toshok. Added convenience fields for WORK and HOME entries for each
+	IM account list. Add support for setting LIST_FIELD types.
+
 2003-12-01  Rodrigo Moya <rodrigo ximian com>
 
 	* libedataserver/e-cache.[ch]: new class for a cache implementation,
Index: addressbook/libebook/e-contact.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-contact.c,v
retrieving revision 1.4
diff -u -r1.4 e-contact.c
--- addressbook/libebook/e-contact.c	26 Nov 2003 00:35:29 -0000	1.4
+++ addressbook/libebook/e-contact.c	4 Dec 2003 07:17:52 -0000
@@ -142,11 +142,42 @@
 	BOOLEAN_FIELD        (E_CONTACT_WANTS_HTML, EVC_X_WANTS_HTML, "wants_html", N_("Wants HTML Mail"), FALSE),
 
 	/* Instant messaging fields */
-	LIST_FIELD (E_CONTACT_IM_AIM,    EVC_X_AIM,    "im_aim",    N_("AIM Screen Name List"),    FALSE),
-	LIST_FIELD (E_CONTACT_IM_JABBER, EVC_X_JABBER, "im_jabber", N_("Jabber Id List"),          FALSE),
-	LIST_FIELD (E_CONTACT_IM_YAHOO,  EVC_X_YAHOO,  "im_yahoo",  N_("Yahoo! Screen Name List"), FALSE),
-	LIST_FIELD (E_CONTACT_IM_MSN,    EVC_X_MSN,    "im_msn",    N_("MSN Screen Name List"),    FALSE),
-	LIST_FIELD (E_CONTACT_IM_ICQ,    EVC_X_ICQ,    "im_icq",    N_("ICQ Id List"),             FALSE),
+	MULTI_LIST_FIELD (E_CONTACT_IM_AIM,    EVC_X_AIM,    "im_aim",    N_("AIM Screen Name List"),    FALSE),
+	MULTI_LIST_FIELD (E_CONTACT_IM_JABBER, EVC_X_JABBER, "im_jabber", N_("Jabber Id List"),          FALSE),
+	MULTI_LIST_FIELD (E_CONTACT_IM_YAHOO,  EVC_X_YAHOO,  "im_yahoo",  N_("Yahoo! Screen Name List"), FALSE),
+	MULTI_LIST_FIELD (E_CONTACT_IM_MSN,    EVC_X_MSN,    "im_msn",    N_("MSN Screen Name List"),    FALSE),
+	MULTI_LIST_FIELD (E_CONTACT_IM_ICQ,    EVC_X_ICQ,    "im_icq",    N_("ICQ Id List"),             FALSE),
+
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_AIM_HOME_1,    EVC_X_AIM,    "im_aim_home_1",    N_("AIM Home Screen Name 1"),    FALSE, "HOME", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_AIM_HOME_2,    EVC_X_AIM,    "im_aim_home_2",    N_("AIM Home Screen Name 2"),    FALSE, "HOME", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_AIM_HOME_3,    EVC_X_AIM,    "im_aim_home_3",    N_("AIM Home Screen Name 3"),    FALSE, "HOME", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_AIM_WORK_1,    EVC_X_AIM,    "im_aim_work_1",    N_("AIM Work Screen Name 1"),    FALSE, "WORK", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_AIM_WORK_2,    EVC_X_AIM,    "im_aim_work_2",    N_("AIM Work Screen Name 2"),    FALSE, "WORK", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_AIM_WORK_3,    EVC_X_AIM,    "im_aim_work_3",    N_("AIM Work Screen Name 3"),    FALSE, "WORK", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_JABBER_HOME_1, EVC_X_JABBER, "im_jabber_home_1", N_("Jabber Home Id 1"),          FALSE, "HOME", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_JABBER_HOME_2, EVC_X_JABBER, "im_jabber_home_2", N_("Jabber Home Id 2"),          FALSE, "HOME", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_JABBER_HOME_3, EVC_X_JABBER, "im_jabber_home_3", N_("Jabber Home Id 3"),          FALSE, "HOME", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_JABBER_WORK_1, EVC_X_JABBER, "im_jabber_work_1", N_("Jabber Work Id 1"),          FALSE, "WORK", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_JABBER_WORK_2, EVC_X_JABBER, "im_jabber_work_3", N_("Jabber Work Id 2"),          FALSE, "WORK", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_JABBER_WORK_3, EVC_X_JABBER, "im_jabber_work_2", N_("Jabber Work Id 3"),          FALSE, "WORK", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_YAHOO_HOME_1,  EVC_X_YAHOO,  "im_yahoo_home_1",  N_("Yahoo! Home Screen Name 1"), FALSE, "HOME", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_YAHOO_HOME_2,  EVC_X_YAHOO,  "im_yahoo_home_2",  N_("Yahoo! Home Screen Name 2"), FALSE, "HOME", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_YAHOO_HOME_3,  EVC_X_YAHOO,  "im_yahoo_home_3",  N_("Yahoo! Home Screen Name 3"), FALSE, "HOME", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_YAHOO_WORK_1,  EVC_X_YAHOO,  "im_yahoo_work_1",  N_("Yahoo! Work Screen Name 1"), FALSE, "WORK", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_YAHOO_WORK_2,  EVC_X_YAHOO,  "im_yahoo_work_2",  N_("Yahoo! Work Screen Name 2"), FALSE, "WORK", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_YAHOO_WORK_3,  EVC_X_YAHOO,  "im_yahoo_work_3",  N_("Yahoo! Work Screen Name 3"), FALSE, "WORK", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_MSN_HOME_1,    EVC_X_MSN,    "im_msn_home_1",    N_("MSN Home Screen Name 1"),    FALSE, "HOME", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_MSN_HOME_2,    EVC_X_MSN,    "im_msn_home_2",    N_("MSN Home Screen Name 2"),    FALSE, "HOME", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_MSN_HOME_3,    EVC_X_MSN,    "im_msn_home_3",    N_("MSN Home Screen Name 3"),    FALSE, "HOME", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_MSN_WORK_1,    EVC_X_MSN,    "im_msn_work_1",    N_("MSN Work Screen Name 1"),    FALSE, "WORK", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_MSN_WORK_2,    EVC_X_MSN,    "im_msn_work_2",    N_("MSN Work Screen Name 2"),    FALSE, "WORK", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_MSN_WORK_3,    EVC_X_MSN,    "im_msn_work_3",    N_("MSN Work Screen Name 3"),    FALSE, "WORK", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_ICQ_HOME_1,    EVC_X_ICQ,    "im_icq_home_1",    N_("ICQ Home Id 1"),             FALSE, "HOME", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_ICQ_HOME_2,    EVC_X_ICQ,    "im_icq_home_2",    N_("ICQ Home Id 2"),             FALSE, "HOME", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_ICQ_HOME_3,    EVC_X_ICQ,    "im_icq_home_3",    N_("ICQ Home Id 3"),             FALSE, "HOME", 2),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_ICQ_WORK_1,    EVC_X_ICQ,    "im_icq_work_1",    N_("ICQ Work Id 1"),             FALSE, "WORK", 0),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_ICQ_WORK_2,    EVC_X_ICQ,    "im_icq_work_2",    N_("ICQ Work Id 2"),             FALSE, "WORK", 1),
+	ATTR_TYPE_STR_FIELD (E_CONTACT_IM_ICQ_WORK_3,    EVC_X_ICQ,    "im_icq_work_3",    N_("ICQ Work Id 3"),             FALSE, "WORK", 2),
 
 	/* Organizational fields */
 	LIST_ELEM_STR_FIELD (E_CONTACT_ORG,      EVC_ORG, "org",      N_("Organization"),        FALSE, 0),
@@ -777,6 +808,28 @@
 
 		info->struct_setter (contact, attr, data);
 	}
+	else if (info->t & E_CONTACT_FIELD_TYPE_LIST) {
+		EVCardAttribute *attr;
+		GList *values, *l;
+
+		values = g_value_get_pointer (value);
+
+		attr = e_contact_get_first_attr (contact, info->vcard_field_name);
+
+		if (attr) {
+			e_vcard_attribute_remove_values (attr);
+
+			if (!values)
+				e_vcard_remove_attribute (E_VCARD (contact), attr);
+		}
+		else if (values) {
+			attr = e_vcard_attribute_new (NULL, info->vcard_field_name);
+			e_vcard_add_attribute (E_VCARD (contact), attr);
+		}
+
+		for (l = values; l != NULL; l = l->next)
+			e_vcard_attribute_add_value (attr, l->data);
+	}
 	else {
 		g_warning ("unhandled attribute `%s'", info->vcard_field_name);
 	}
Index: addressbook/libebook/e-contact.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/addressbook/libebook/e-contact.h,v
retrieving revision 1.3
diff -u -r1.3 e-contact.h
--- addressbook/libebook/e-contact.h	26 Nov 2003 00:35:30 -0000	1.3
+++ addressbook/libebook/e-contact.h	4 Dec 2003 07:17:53 -0000
@@ -107,6 +107,37 @@
 	E_CONTACT_IM_MSN,     	 /* Multi-valued */
 	E_CONTACT_IM_ICQ,     	 /* Multi-valued */
 
+	E_CONTACT_IM_AIM_HOME_1,     /* Synthetic string field */
+	E_CONTACT_IM_AIM_HOME_2,     /* Synthetic string field */
+	E_CONTACT_IM_AIM_HOME_3,     /* Synthetic string field */
+	E_CONTACT_IM_AIM_WORK_1,     /* Synthetic string field */
+	E_CONTACT_IM_AIM_WORK_2,     /* Synthetic string field */
+	E_CONTACT_IM_AIM_WORK_3,     /* Synthetic string field */
+	E_CONTACT_IM_JABBER_HOME_1,  /* Synthetic string field */
+	E_CONTACT_IM_JABBER_HOME_2,  /* Synthetic string field */
+	E_CONTACT_IM_JABBER_HOME_3,  /* Synthetic string field */
+	E_CONTACT_IM_JABBER_WORK_1,  /* Synthetic string field */
+	E_CONTACT_IM_JABBER_WORK_2,  /* Synthetic string field */
+	E_CONTACT_IM_JABBER_WORK_3,  /* Synthetic string field */
+	E_CONTACT_IM_YAHOO_HOME_1,   /* Synthetic string field */
+	E_CONTACT_IM_YAHOO_HOME_2,   /* Synthetic string field */
+	E_CONTACT_IM_YAHOO_HOME_3,   /* Synthetic string field */
+	E_CONTACT_IM_YAHOO_WORK_1,   /* Synthetic string field */
+	E_CONTACT_IM_YAHOO_WORK_2,   /* Synthetic string field */
+	E_CONTACT_IM_YAHOO_WORK_3,   /* Synthetic string field */
+	E_CONTACT_IM_MSN_HOME_1,     /* Synthetic string field */
+	E_CONTACT_IM_MSN_HOME_2,     /* Synthetic string field */
+	E_CONTACT_IM_MSN_HOME_3,     /* Synthetic string field */
+	E_CONTACT_IM_MSN_WORK_1,     /* Synthetic string field */
+	E_CONTACT_IM_MSN_WORK_2,     /* Synthetic string field */
+	E_CONTACT_IM_MSN_WORK_3,     /* Synthetic string field */
+	E_CONTACT_IM_ICQ_HOME_1,     /* Synthetic string field */
+	E_CONTACT_IM_ICQ_HOME_2,     /* Synthetic string field */
+	E_CONTACT_IM_ICQ_HOME_3,     /* Synthetic string field */
+	E_CONTACT_IM_ICQ_WORK_1,     /* Synthetic string field */
+	E_CONTACT_IM_ICQ_WORK_2,     /* Synthetic string field */
+	E_CONTACT_IM_ICQ_WORK_3,     /* Synthetic string field */
+
 	/* Address fields */
 	E_CONTACT_ADDRESS,       /* Multi-valued structured (EContactAddress) */
 	E_CONTACT_ADDRESS_HOME,  /* synthetic structured field (EContactAddress) */
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/ChangeLog,v
retrieving revision 1.1270
diff -u -r1.1270 ChangeLog
--- ChangeLog	2 Dec 2003 16:23:47 -0000	1.1270
+++ ChangeLog	4 Dec 2003 07:32:29 -0000
@@ -1,3 +1,17 @@
+2003-12-03  Christian Hammond  <chipx86 gnupdate org>
+
+	* addressbook/gui/contact-editor/e-contact-editor-im.[ch],
+	  addressbook/gui/contact-editor/im.glade: Added a dialog for
+	  adding a new IM account.
+	* addressbook/gui/contact-editor/Makefile.am: Added the previously
+	  mentioned files, and depend on camel for necessary MIME parsing.
+
+	* addressbook/gui/contact-editor/contact-editor.[ch],
+	  addressbook/gui/contact-editor/contact-editor.glade: Add and implement
+	  the Instant Messaging tab.
+
+	* art/im-*.png, art/Makefile.am: Added IM png files from Gaim.
+
 2003-12-02  Jeffrey Stedfast  <fejj ximian com>
 
 	* configure.in (EVOLUTION_DIR): Remove the Junk folder
Index: addressbook/gui/contact-editor/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/contact-editor/Makefile.am,v
retrieving revision 1.54
diff -u -r1.54 Makefile.am
--- addressbook/gui/contact-editor/Makefile.am	26 Nov 2003 15:29:19 -0000	1.54
+++ addressbook/gui/contact-editor/Makefile.am	4 Dec 2003 07:32:29 -0000
@@ -6,6 +6,8 @@
 	-I$(top_srcdir)/addressbook/gui/merging		\
 	-I$(top_srcdir)/widgets/e-table			\
 	-I$(top_builddir)/shell				\
+	-I$(top_srcdir)/camel				\
+	-I$(top_builddir)/camel				\
 	-DEVOLUTION_GLADEDIR=\""$(gladedir)"\"		\
 	-DEVOLUTION_DATADIR=\""$(datadir)"\"		\
 	-DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\"	\
@@ -22,6 +24,8 @@
 
 libecontacteditor_la_SOURCES = 			\
 	$(MARSHAL_GENERATED)			\
+	e-contact-editor-im.c		\
+	e-contact-editor-im.h		\
 	e-contact-editor-address.c		\
 	e-contact-editor-address.h		\
 	e-contact-editor-fullname.c		\
@@ -35,6 +39,7 @@
 @EVO_MARSHAL_RULE@
 
 glade_DATA = 				\
+	im.glade				\
 	contact-editor.glade		\
 	fulladdr.glade			\
 	fullname.glade
Index: addressbook/gui/contact-editor/contact-editor.glade
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/contact-editor/contact-editor.glade,v
retrieving revision 1.41
diff -u -r1.41 contact-editor.glade
--- addressbook/gui/contact-editor/contact-editor.glade	21 Oct 2003 18:48:44 -0000	1.41
+++ addressbook/gui/contact-editor/contact-editor.glade	4 Dec 2003 07:32:30 -0000
@@ -1153,46 +1153,6 @@
 	      </child>
 
 	      <child>
-		<widget class="Custom" id="custom1">
-		  <property name="visible">True</property>
-		  <property name="creation_function">e_create_image_widget</property>
-		  <property name="string1">malehead.png</property>
-		  <property name="string2"></property>
-		  <property name="int1">0</property>
-		  <property name="int2">0</property>
-		  <property name="last_modification_time">Thu, 18 May 2000 12:19:47 GMT</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">4</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options">fill</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="Custom" id="custom2">
-		  <property name="visible">True</property>
-		  <property name="creation_function">e_create_image_widget</property>
-		  <property name="string1">cellphone.png</property>
-		  <property name="string2"></property>
-		  <property name="int1">0</property>
-		  <property name="int2">0</property>
-		  <property name="last_modification_time">Thu, 18 May 2000 12:20:02 GMT</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">4</property>
-		  <property name="right_attach">5</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">4</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options">fill</property>
-		</packing>
-	      </child>
-
-	      <child>
 		<widget class="Custom" id="custom3">
 		  <property name="visible">True</property>
 		  <property name="creation_function">e_create_image_widget</property>
@@ -1515,8 +1475,48 @@
 		<packing>
 		  <property name="left_attach">3</property>
 		  <property name="right_attach">4</property>
-		  <property name="top_attach">9</property>
-		  <property name="bottom_attach">10</property>
+		  <property name="top_attach">8</property>
+		  <property name="bottom_attach">9</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="Custom" id="custom2">
+		  <property name="visible">True</property>
+		  <property name="creation_function">e_create_image_widget</property>
+		  <property name="string1">cellphone.png</property>
+		  <property name="string2"></property>
+		  <property name="int1">0</property>
+		  <property name="int2">0</property>
+		  <property name="last_modification_time">Thu, 18 May 2000 12:20:02 GMT</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">4</property>
+		  <property name="right_attach">5</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="Custom" id="custom1">
+		  <property name="visible">True</property>
+		  <property name="creation_function">e_create_image_widget</property>
+		  <property name="string1">malehead.png</property>
+		  <property name="string2"></property>
+		  <property name="int1">0</property>
+		  <property name="int2">0</property>
+		  <property name="last_modification_time">Thu, 18 May 2000 12:19:47 GMT</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">4</property>
 		  <property name="x_options">fill</property>
 		  <property name="y_options">fill</property>
 		</packing>
@@ -2138,6 +2138,233 @@
 	  </child>
 
 	  <child>
+	    <widget class="GtkVBox" id="vbox4">
+	      <property name="border_width">6</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox2">
+		  <property name="border_width">7</property>
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">4</property>
+
+		  <child>
+		    <widget class="Custom" id="custom13">
+		      <property name="visible">True</property>
+		      <property name="creation_function">e_create_image_widget</property>
+		      <property name="string1">im.png</property>
+		      <property name="string2"></property>
+		      <property name="int1">0</property>
+		      <property name="int2">0</property>
+		      <property name="last_modification_time">Thu, 18 May 2000 12:19:47 GMT</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label26">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Enter the person's instant messenger accounts here.</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHBox" id="hbox4">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkScrolledWindow" id="scrolledwindow4">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		      <property name="shadow_type">GTK_SHADOW_IN</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<widget class="GtkTreeView" id="treeview-im">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="headers_visible">True</property>
+			  <property name="rules_hint">True</property>
+			  <property name="reorderable">False</property>
+			  <property name="enable_search">True</property>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkVButtonBox" id="vbuttonbox1">
+		      <property name="border_width">6</property>
+		      <property name="visible">True</property>
+		      <property name="layout_style">GTK_BUTTONBOX_START</property>
+		      <property name="spacing">6</property>
+
+		      <child>
+			<widget class="GtkButton" id="button-im-add">
+			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-add</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="button-im-edit">
+			  <property name="visible">True</property>
+			  <property name="sensitive">False</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+
+			  <child>
+			    <widget class="GtkAlignment" id="alignment22">
+			      <property name="visible">True</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xscale">0</property>
+			      <property name="yscale">0</property>
+
+			      <child>
+				<widget class="GtkHBox" id="hbox5">
+				  <property name="visible">True</property>
+				  <property name="homogeneous">False</property>
+				  <property name="spacing">2</property>
+
+				  <child>
+				    <widget class="GtkImage" id="image2">
+				      <property name="visible">True</property>
+				      <property name="stock">gtk-properties</property>
+				      <property name="icon_size">4</property>
+				      <property name="xalign">0.5</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				    </widget>
+				    <packing>
+				      <property name="padding">0</property>
+				      <property name="expand">False</property>
+				      <property name="fill">False</property>
+				    </packing>
+				  </child>
+
+				  <child>
+				    <widget class="GtkLabel" id="label34">
+				      <property name="visible">True</property>
+				      <property name="label" translatable="yes">_Edit</property>
+				      <property name="use_underline">True</property>
+				      <property name="use_markup">False</property>
+				      <property name="justify">GTK_JUSTIFY_LEFT</property>
+				      <property name="wrap">False</property>
+				      <property name="selectable">False</property>
+				      <property name="xalign">0.5</property>
+				      <property name="yalign">0.5</property>
+				      <property name="xpad">0</property>
+				      <property name="ypad">0</property>
+				    </widget>
+				    <packing>
+				      <property name="padding">0</property>
+				      <property name="expand">False</property>
+				      <property name="fill">False</property>
+				    </packing>
+				  </child>
+				</widget>
+			      </child>
+			    </widget>
+			  </child>
+			</widget>
+		      </child>
+
+		      <child>
+			<widget class="GtkButton" id="button-im-remove">
+			  <property name="visible">True</property>
+			  <property name="sensitive">False</property>
+			  <property name="can_default">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label">gtk-remove</property>
+			  <property name="use_stock">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			</widget>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label25">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Instant Messaging</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+
+	  <child>
 	    <widget class="GtkVBox" id="vbox3">
 	      <property name="border_width">6</property>
 	      <property name="visible">True</property>
Index: addressbook/gui/contact-editor/e-contact-editor.c
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/contact-editor/e-contact-editor.c,v
retrieving revision 1.153
diff -u -r1.153 e-contact-editor.c
--- addressbook/gui/contact-editor/e-contact-editor.c	21 Oct 2003 18:48:45 -0000	1.153
+++ addressbook/gui/contact-editor/e-contact-editor.c	4 Dec 2003 07:32:31 -0000
@@ -35,6 +35,7 @@
 #include <gtk/gtklabel.h>
 #include <libgnomeui/gnome-popup-menu.h>
 #include <libgnomeui/gnome-window-icon.h>
+#include <libgnome/gnome-util.h>
 #include <libgnome/gnome-i18n.h>
 
 #include <bonobo/bonobo-ui-container.h>
@@ -47,6 +48,8 @@
 
 #include <e-util/e-categories-master-list-wombat.h>
 
+#include <camel/camel.h>
+
 #include "addressbook/printing/e-contact-print.h"
 #include "addressbook/printing/e-contact-print-envelope.h"
 #include "addressbook/gui/widgets/eab-gui-util.h"
@@ -58,6 +61,7 @@
 #include "eab-contact-merging.h"
 
 #include "e-contact-editor-address.h"
+#include "e-contact-editor-im.h"
 #include "e-contact-editor-fullname.h"
 #include "e-contact-editor-marshal.h"
 
@@ -70,6 +74,17 @@
 	LAST_SIGNAL
 };
 
+/* IM columns */
+enum {
+	COLUMN_IM_ICON,
+	COLUMN_IM_SERVICE,
+	COLUMN_IM_SCREENNAME,
+	COLUMN_IM_LOCATION,
+	COLUMN_IM_SERVICE_FIELD,
+	NUM_IM_COLUMNS
+};
+
+
 static void e_contact_editor_init		(EContactEditor		 *editor);
 static void e_contact_editor_class_init	(EContactEditorClass	 *klass);
 static void e_contact_editor_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
@@ -79,6 +94,7 @@
 static void _email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
 static void _phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
 static void _address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
+static void set_im_fields(EContactEditor *editor);
 static void find_address_mailing (EContactEditor *editor);
 static void enable_writable_fields(EContactEditor *editor);
 static void set_editable(EContactEditor *editor);
@@ -283,6 +299,444 @@
 }
 
 static void
+add_im_clicked(GtkWidget *widget, EContactEditor *editor)
+{
+	GtkDialog *dialog;
+	int result;
+
+	dialog = GTK_DIALOG(e_contact_editor_im_new(E_CONTACT_IM_AIM, "HOME", NULL));
+
+	gtk_widget_show(GTK_WIDGET(dialog));
+	result = gtk_dialog_run(dialog);
+	gtk_widget_hide(GTK_WIDGET(dialog));
+
+	if (result == GTK_RESPONSE_OK) {
+		GList *old_list, *new_list = NULL, *l;
+		EContactField service;
+		const char *screenname;
+
+		g_object_get(dialog,
+					 "service", &service,
+					 "username", &screenname,
+					 NULL);
+
+		old_list = e_contact_get(editor->contact, service);
+
+		for (l = old_list; l != NULL; l = l->next)
+			new_list = g_list_append(new_list, g_strdup(l->data));
+
+		new_list = g_list_append(new_list, g_strdup(screenname));
+
+		e_contact_set(editor->contact, service, new_list);
+
+		g_list_foreach(new_list, (GFunc)g_free, NULL);
+		g_list_free(new_list);
+
+		set_im_fields(editor);
+
+		editor->changed = TRUE;
+	}
+
+	gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+static void
+edit_im_clicked(GtkWidget *widget, EContactEditor *editor)
+{
+	GtkWidget *treeview;
+	GtkTreeSelection *selection;
+	GtkDialog *dialog;
+	GtkTreeIter iter;
+	EContactField old_service, service;
+	const char *old_location, *location;
+	const char *old_screenname, *screenname;
+	int result;
+
+	treeview = glade_xml_get_widget(editor->gui, "treeview-im");
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+
+	gtk_tree_selection_get_selected(selection, NULL, &iter);
+
+	gtk_tree_model_get(GTK_TREE_MODEL(editor->im_model), &iter,
+					   COLUMN_IM_SERVICE_FIELD, &old_service,
+					   COLUMN_IM_LOCATION, &old_location,
+					   COLUMN_IM_SCREENNAME, &old_screenname,
+					   -1);
+
+	dialog = GTK_DIALOG(e_contact_editor_im_new(old_service, old_location, old_screenname));
+
+	gtk_widget_show(GTK_WIDGET(dialog));
+	result = gtk_dialog_run(dialog);
+	gtk_widget_hide(GTK_WIDGET(dialog));
+
+	if (result == GTK_RESPONSE_OK) {
+		GList *old_list, *new_list = NULL, *l;
+
+		g_object_get(dialog,
+					 "service", &service,
+					 "location", &location,
+					 "username", &screenname,
+					 NULL);
+
+		if (service == old_service &&
+			(location == old_location ||
+			 (location != NULL && old_location == NULL) ||
+			 (location == NULL && old_location != NULL) ||
+			 !strcmp(old_location, location)) &&
+			!strcmp(screenname, old_screenname)) {
+
+			gtk_widget_destroy(GTK_WIDGET(dialog));
+			return;
+		}
+
+		/* Remove the old. */
+		old_list = e_contact_get(editor->contact, old_service);
+
+		for (l = old_list; l != NULL; l = l->next) {
+			const char *temp_screenname = (const char *)l->data;
+
+			if (strcmp(temp_screenname, old_screenname))
+				new_list = g_list_append(new_list, g_strdup(temp_screenname));
+		}
+
+		if (service == old_service)
+			new_list = g_list_append(new_list, g_strdup(screenname));
+
+		e_contact_set(editor->contact, old_service, new_list);
+
+		for (l = new_list; l != NULL; l = l->next)
+			g_free(l->data);
+
+		g_list_free(new_list);
+
+		if (old_service != service)
+		{
+			/* We have to add this elsewhere. */
+			new_list = NULL;
+
+			old_list = e_contact_get(editor->contact, service);
+
+			for (l = old_list; l != NULL; l = l->next) {
+				new_list = g_list_append(new_list, g_strdup(l->data));
+			}
+
+			new_list = g_list_append(new_list, g_strdup(screenname));
+
+			e_contact_set(editor->contact, service, new_list);
+
+			for (l = new_list; l != NULL; l = l->next)
+				g_free(l->data);
+
+			g_list_free(new_list);
+		}
+
+		set_im_fields(editor);
+
+		editor->changed = TRUE;
+	}
+
+	gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+static void
+remove_im_clicked(GtkWidget *widget, EContactEditor *editor)
+{
+	GtkWidget *treeview;
+	GtkTreeSelection *selection;
+	GtkTreeIter iter;
+	EContactField old_service;
+	const char *old_screenname;
+	GList *old_list, *new_list = NULL, *l;
+
+	treeview = glade_xml_get_widget(editor->gui, "treeview-im");
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+
+	gtk_tree_selection_get_selected(selection, NULL, &iter);
+
+	gtk_tree_model_get(GTK_TREE_MODEL(editor->im_model), &iter,
+					   COLUMN_IM_SERVICE_FIELD, &old_service,
+					   COLUMN_IM_SCREENNAME, &old_screenname,
+					   -1);
+
+	old_list = e_contact_get(editor->contact, old_service);
+
+	for (l = old_list; l != NULL; l = l->next) {
+		const char *temp_screenname = (const char *)l->data;
+
+		if (strcmp(temp_screenname, old_screenname))
+			new_list = g_list_append(new_list, g_strdup(temp_screenname));
+	}
+
+	e_contact_set(editor->contact, old_service, new_list);
+
+	for (l = new_list; l != NULL; l = l->next)
+		g_free(l->data);
+
+	if (new_list != NULL)
+		g_list_free(new_list);
+
+	gtk_list_store_remove(editor->im_model, &iter);
+
+	editor->changed = TRUE;
+}
+
+
+static gboolean
+im_button_press_cb(GtkWidget *treeview, GdkEventButton *event,
+				   EContactEditor *editor)
+{
+	if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
+		edit_im_clicked(NULL, editor);
+
+	return FALSE;
+}
+
+static void
+im_selected_cb(GtkTreeSelection *selection, EContactEditor *editor)
+{
+	gboolean sensitive = gtk_tree_selection_get_selected(selection, NULL, NULL);
+
+	gtk_widget_set_sensitive(glade_xml_get_widget(editor->gui, "button-im-remove"), sensitive);
+	gtk_widget_set_sensitive(glade_xml_get_widget(editor->gui, "button-im-edit"),   sensitive);
+}
+
+
+static void
+im_treeview_drag_data_get_cb(GtkWidget *widget, GdkDragContext *dc,
+							 GtkSelectionData *data, guint info,
+							 guint time, EContactEditor *editor)
+{
+	if (data->target == gdk_atom_intern("application/x-im-contact", FALSE)) {
+		GtkTreeRowReference *ref;
+		GtkTreePath *sourcerow;
+		GtkTreeIter iter;
+		const char *protocol;
+		const char *screenname;
+		const char *alias;
+		GString *str;
+		char *mime_str;
+		EContactField service_field;
+		static char *protocols[] = { "aim", "jabber", "yahoo", "msn", "icq" };
+
+		ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row");
+		sourcerow = gtk_tree_row_reference_get_path(ref);
+
+		if (!sourcerow)
+			return;
+
+		gtk_tree_model_get_iter(GTK_TREE_MODEL(editor->im_model), &iter,
+								sourcerow);
+
+		gtk_tree_model_get(GTK_TREE_MODEL(editor->im_model), &iter,
+						   COLUMN_IM_SERVICE_FIELD, &service_field,
+						   COLUMN_IM_SCREENNAME, &screenname,
+						   -1);
+
+		alias = e_contact_get_const(editor->contact, E_CONTACT_FULL_NAME);
+
+		protocol = protocols[service_field - E_CONTACT_IM_AIM];
+
+		str = g_string_new(NULL);
+
+		g_string_printf(str,
+			"MIME-Version: 1.0\r\n"
+			"Content-Type: application/x-im-contact\r\n"
+			"X-IM-Protocol: %s\r\n"
+			"X-IM-Username: %s\r\n",
+			protocol,
+			screenname);
+
+		if (alias && *alias)
+			g_string_append_printf(str, "X-IM-Alias: %s\r\n", alias);
+
+		str = g_string_append(str, "\r\n");
+
+		mime_str = g_string_free(str, FALSE);
+
+		gtk_selection_data_set(data,
+			gdk_atom_intern("application/x-im-contact", FALSE),
+			8,
+			mime_str,
+			strlen(mime_str) + 1);
+
+		g_free(mime_str);
+		gtk_tree_path_free(sourcerow);
+	}
+}
+
+static void
+im_treeview_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc,
+							 guint x, guint y, GtkSelectionData *sd,
+							 guint info, guint t, EContactEditor *editor)
+{
+	if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE) && sd->data) {
+		CamelMimeParser *parser;
+		CamelStream *stream;
+		char *buffer;
+		char *username = NULL;
+		char *protocol = NULL;
+		int len;
+		int state;
+
+		parser = camel_mime_parser_new();
+
+		stream = camel_stream_mem_new_with_buffer(sd->data, sd->length);
+
+		if (camel_mime_parser_init_with_stream(parser, stream) == -1) {
+			g_warning("Unable to create parser for stream");
+			return;
+		}
+
+		while ((state = camel_mime_parser_step(parser, &buffer, &len)) != CAMEL_MIME_PARSER_STATE_EOF) {
+			if (state == CAMEL_MIME_PARSER_STATE_HEADER) {
+				const char *temp;
+				char *temp2;
+
+				if ((temp = camel_mime_parser_header(parser, "X-IM-Username", NULL)) != NULL) {
+					temp2 = g_strdup(temp);
+					username = g_strdup(g_strstrip(temp2));
+					g_free(temp2);
+				}
+
+				if ((temp = camel_mime_parser_header(parser, "X-IM-Protocol", NULL)) != NULL) {
+					temp2 = g_strdup(temp);
+					protocol = g_strdup(g_strstrip(temp2));
+					g_free(temp2);
+				}
+
+				break;
+			}
+		}
+
+		camel_object_unref(parser);
+
+		if (username != NULL && protocol != NULL) {
+			GList *old_list, *new_list = NULL, *l;
+			EContactField field;
+			gboolean found = FALSE;
+
+			if (!strcmp(protocol, "aim"))
+				field = E_CONTACT_IM_AIM;
+			else if (!strcmp(protocol, "icq"))
+				field = E_CONTACT_IM_ICQ;
+			else if (!strcmp(protocol, "yahoo"))
+				field = E_CONTACT_IM_YAHOO;
+			else if (!strcmp(protocol, "msn"))
+				field = E_CONTACT_IM_MSN;
+			else if (!strcmp(protocol, "jabber"))
+				field = E_CONTACT_IM_JABBER;
+			else {
+				g_free(username);
+				g_free(protocol);
+				gtk_drag_finish(dc, FALSE, (dc->action == GDK_ACTION_MOVE), t);
+				return;
+			}
+
+			old_list = e_contact_get(editor->contact, field);
+
+			for (l = old_list; l != NULL; l = l->next) {
+				const char *name = (const char *)l->data;
+
+				if (!strcmp(name, username)) {
+					found = TRUE;
+					break;
+				}
+
+				new_list = g_list_append(new_list, g_strdup(l->data));
+			}
+
+			if (!found) {
+				new_list = g_list_append(new_list, g_strdup(username));
+
+				e_contact_set(editor->contact, field, new_list);
+			}
+
+			if (new_list != NULL) {
+				g_list_foreach(new_list, (GFunc)g_free, NULL);
+				g_list_free(new_list);
+			}
+
+			set_im_fields(editor);
+		}
+
+		if (username != NULL)
+			g_free(username);
+
+		if (protocol != NULL)
+			g_free(protocol);
+
+		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+	}
+}
+
+static void
+setup_im_treeview(EContactEditor *editor)
+{
+	GtkWidget *treeview;
+	GtkTreeSelection *selection;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	GtkTargetEntry gte[] = {{"application/x-im-contact", 0, 0}};
+
+	treeview = glade_xml_get_widget(editor->gui, "treeview-im");
+
+	if (!treeview || !GTK_IS_TREE_VIEW(treeview))
+		return;
+
+	editor->im_model = gtk_list_store_new(NUM_IM_COLUMNS,
+										  GDK_TYPE_PIXBUF, G_TYPE_STRING,
+										  G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
+
+	gtk_tree_view_set_model(GTK_TREE_VIEW(treeview),
+							GTK_TREE_MODEL(editor->im_model));
+
+	g_signal_connect(G_OBJECT(treeview), "button-press-event",
+					 G_CALLBACK(im_button_press_cb), editor);
+
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(column, _("Service"));
+	gtk_tree_view_insert_column(GTK_TREE_VIEW(treeview), column, -1);
+
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start(column, renderer, FALSE);
+	gtk_tree_view_column_add_attribute(column, renderer,
+									   "pixbuf", COLUMN_IM_ICON);
+
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(column, renderer, TRUE);
+	gtk_tree_view_column_add_attribute(column, renderer,
+									   "text", COLUMN_IM_SERVICE);
+
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_column_set_title(column, _("Account Name"));
+	gtk_tree_view_insert_column(GTK_TREE_VIEW(treeview), column, -1);
+
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(column, renderer, TRUE);
+	gtk_tree_view_column_add_attribute(column, renderer,
+									   "text", COLUMN_IM_SCREENNAME);
+
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+	g_signal_connect(G_OBJECT(selection), "changed",
+					 G_CALLBACK(im_selected_cb), editor);
+
+	/* Setup drag-and-drop */
+	gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(treeview),
+										   GDK_BUTTON1_MASK, gte, 1,
+										   GDK_ACTION_COPY);
+	gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(treeview),
+										 gte, 1,
+										 GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+	g_signal_connect(G_OBJECT(treeview), "drag-data-get",
+					 G_CALLBACK(im_treeview_drag_data_get_cb), editor);
+	g_signal_connect(G_OBJECT(treeview), "drag-data-received",
+					 G_CALLBACK(im_treeview_drag_data_rcv_cb), editor);
+}
+
+static void
 wants_html_changed (GtkWidget *widget, EContactEditor *editor)
 {
 	gboolean wants_html;
@@ -881,6 +1335,7 @@
 	gtk_widget_destroy(GTK_WIDGET(dialog));
 }
 
+
 typedef struct {
 	EContactEditor *ce;
 	gboolean should_close;
@@ -1314,6 +1769,8 @@
 	connect_arrow_button_signals(e_contact_editor);
 	set_entry_changed_signals(e_contact_editor);
 
+	setup_im_treeview(e_contact_editor);
+
 	wants_html = glade_xml_get_widget(e_contact_editor->gui, "checkbutton-htmlmail");
 	if (wants_html && GTK_IS_TOGGLE_BUTTON(wants_html))
 		g_signal_connect (wants_html, "toggled",
@@ -1339,6 +1796,22 @@
 		g_signal_connect (widget, "clicked",
 				  G_CALLBACK (categories_clicked), e_contact_editor);
 
+	widget = glade_xml_get_widget(e_contact_editor->gui, "button-im-add");
+	if (widget && GTK_IS_BUTTON(widget))
+		g_signal_connect (widget, "clicked",
+				  G_CALLBACK (add_im_clicked), e_contact_editor);
+
+	widget = glade_xml_get_widget(e_contact_editor->gui, "button-im-edit");
+	if (widget && GTK_IS_BUTTON(widget))
+		g_signal_connect (widget, "clicked",
+				  G_CALLBACK (edit_im_clicked), e_contact_editor);
+
+	widget = glade_xml_get_widget(e_contact_editor->gui, "button-im-remove");
+	if (widget && GTK_IS_BUTTON(widget))
+		g_signal_connect (widget, "clicked",
+				  G_CALLBACK (remove_im_clicked), e_contact_editor);
+
+
 	/* Construct the app */
 	bonobo_win = bonobo_window_new ("contact-editor-dialog", _("Contact Editor"));
 
@@ -2006,6 +2479,62 @@
 }
 
 static void
+add_im_field(EContactEditor *editor, EContactField field, const char *service,
+			 const char *desc)
+{
+	GList *list;
+	GList *l;
+	GtkTreeIter iter;
+	GdkPixbuf *pixbuf;
+	GdkPixbuf *scale = NULL;
+	char *icon_path;
+	char *buf;
+
+	list = e_contact_get(editor->contact, field);
+
+	buf = g_strdup_printf("im-%s.png", service);
+	icon_path = g_concat_dir_and_file(EVOLUTION_IMAGESDIR, buf);
+	pixbuf = gdk_pixbuf_new_from_file(icon_path, NULL);
+	g_free(icon_path);
+	g_free(buf);
+
+	if (pixbuf != NULL)
+		scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR);
+
+	for (l = list; l != NULL; l = l->next)
+	{
+		const char *account_name = (const char *)l->data;
+
+		gtk_list_store_append(editor->im_model, &iter);
+
+		gtk_list_store_set(editor->im_model, &iter,
+						   COLUMN_IM_ICON, scale,
+						   COLUMN_IM_SERVICE,  desc,
+						   COLUMN_IM_SCREENNAME, account_name,
+						   COLUMN_IM_SERVICE_FIELD, field,
+						   -1);
+	}
+
+	if (scale != NULL)
+		g_object_unref(G_OBJECT(scale));
+
+	if (pixbuf != NULL)
+		g_object_unref(G_OBJECT(pixbuf));
+}
+
+static void
+set_im_fields(EContactEditor *editor)
+{
+	gtk_list_store_clear(editor->im_model);
+
+	add_im_field(editor, E_CONTACT_IM_AIM,    "aim",    _("AIM"));
+	add_im_field(editor, E_CONTACT_IM_JABBER, "jabber", _("Jabber"));
+	add_im_field(editor, E_CONTACT_IM_YAHOO,  "yahoo",  _("Yahoo"));
+	add_im_field(editor, E_CONTACT_IM_MSN,    "msn",    _("MSN"));
+	add_im_field(editor, E_CONTACT_IM_ICQ,    "icq",    _("ICQ"));
+}
+
+static void
 set_address_field(EContactEditor *editor, int result)
 {
 #if notyet
@@ -2412,6 +2941,8 @@
 		e_contact_date_free (bday);
 
 		set_fields(editor);
+
+		set_im_fields(editor);
 	}
 }
 
Index: addressbook/gui/contact-editor/e-contact-editor.h
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/contact-editor/e-contact-editor.h,v
retrieving revision 1.36
diff -u -r1.36 e-contact-editor.h
--- addressbook/gui/contact-editor/e-contact-editor.h	7 Nov 2003 05:51:33 -0000	1.36
+++ addressbook/gui/contact-editor/e-contact-editor.h	4 Dec 2003 07:32:31 -0000
@@ -28,6 +28,9 @@
 #include <libebook/e-book-async.h>
 #include <libebook/e-contact.h>
 
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkliststore.h>
+
 G_BEGIN_DECLS
 
 /* EContactEditor - A dialog displaying information about a contact.
@@ -75,6 +78,8 @@
 	EContactName *name;
 	char *company;
 
+	GtkListStore *im_model;
+
 	EContactField email_choice;
 	EContactField phone_choice[4];
 	EContactField address_choice;
Index: art/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/art/Makefile.am,v
retrieving revision 1.109
diff -u -r1.109 Makefile.am
--- art/Makefile.am	2 Dec 2003 17:04:04 -0000	1.109
+++ art/Makefile.am	4 Dec 2003 07:32:31 -0000
@@ -75,6 +75,30 @@
 	ico-weather.png			\
 	import.png			\
 	import.xpm			\
+	im.png \
+	im-activebuddy.png \
+	im-admin.png \
+	im-aim.png \
+	im-aol.png \
+	im-away.png \
+	im-dnd.png \
+	im-extendedaway.png \
+	im-freeforchat.png \
+	im-game.png \
+	im-hiptop.png \
+	im-icq.png \
+	im-invisible.png \
+	im-jabber.png \
+	im-login.png \
+	im-logout.png \
+	im-msn.png \
+	im-na.png \
+	im-notauthorized.png \
+	im-occupied.png \
+	im-offline.png \
+	im-secure.png \
+	im-wireless.png \
+	im-yahoo.png \
 	inbox.png			\
 	inbox-mini.png			\
 	ldap-mini.png			\

Attachment: evolution-im-20031202-2332.tar.gz
Description: GNU Zip compressed data

Attachment: pgpzH5xHe28SY.pgp
Description: PGP signature



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