aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Hammond <chipx86@gnupdate.org>2004-01-12 11:35:25 +0800
committerJP Rosevear <jpr@src.gnome.org>2004-01-12 11:35:25 +0800
commit54e2fae377ffccc0ae3c3987a8a15d2b47e98575 (patch)
tree28d57589dbf532e3e5a26762e9012574b99ae2fd
parent9ed71d9c171dd28a9ae43302517b2bdd505eddeb (diff)
downloadgsoc2013-evolution-54e2fae377ffccc0ae3c3987a8a15d2b47e98575.tar
gsoc2013-evolution-54e2fae377ffccc0ae3c3987a8a15d2b47e98575.tar.gz
gsoc2013-evolution-54e2fae377ffccc0ae3c3987a8a15d2b47e98575.tar.bz2
gsoc2013-evolution-54e2fae377ffccc0ae3c3987a8a15d2b47e98575.tar.lz
gsoc2013-evolution-54e2fae377ffccc0ae3c3987a8a15d2b47e98575.tar.xz
gsoc2013-evolution-54e2fae377ffccc0ae3c3987a8a15d2b47e98575.tar.zst
gsoc2013-evolution-54e2fae377ffccc0ae3c3987a8a15d2b47e98575.zip
Added a dialog for adding a new IM account. Added the previously mentioned
2004-01-11 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 svn path=/trunk/; revision=24162
-rw-r--r--addressbook/ChangeLog23
-rw-r--r--addressbook/conduit/.cvsignore2
-rw-r--r--addressbook/gui/component/.cvsignore1
-rw-r--r--addressbook/gui/contact-editor/Makefile.am5
-rw-r--r--addressbook/gui/contact-editor/contact-editor.glade311
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-im.c487
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-im.h76
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.c526
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.h5
-rw-r--r--addressbook/gui/contact-editor/im.glade202
10 files changed, 1595 insertions, 43 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index 13f6e5b972..d66f783e6e 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,14 @@
+2004-01-11 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
+
2004-01-09 Ross Burton <ross@burtonini.com>
* gui/component/select-names/e-select-names-completion.c:
@@ -377,6 +388,18 @@
* gui/widgets/e-addressbook-view.etspec: Clean up and sync with
current model columns.
+2003-12-04 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.
+
2003-12-03 Ettore Perazzoli <ettore@ximian.com>
* gui/component/addressbook.c
diff --git a/addressbook/conduit/.cvsignore b/addressbook/conduit/.cvsignore
index 87b35d3be5..594beaac72 100644
--- a/addressbook/conduit/.cvsignore
+++ b/addressbook/conduit/.cvsignore
@@ -6,4 +6,4 @@ Makefile
libeaddress_conduit.la
e-address-conduit-control-applet
e-address-conduit-control-applet.desktop
-e-address.conduit
+e-address*.conduit
diff --git a/addressbook/gui/component/.cvsignore b/addressbook/gui/component/.cvsignore
index 5639d4fc22..847efaf29c 100644
--- a/addressbook/gui/component/.cvsignore
+++ b/addressbook/gui/component/.cvsignore
@@ -12,3 +12,4 @@ GNOME_Evolution_Addressbook*.server
GNOME_Evolution_Addressbook*.server.in
addressbook-marshal.c
addressbook-marshal.h
+*.schemas \ No newline at end of file
diff --git a/addressbook/gui/contact-editor/Makefile.am b/addressbook/gui/contact-editor/Makefile.am
index 685004dabb..22504b04f5 100644
--- a/addressbook/gui/contact-editor/Makefile.am
+++ b/addressbook/gui/contact-editor/Makefile.am
@@ -6,6 +6,8 @@ INCLUDES = \
-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)"\" \
@@ -19,6 +21,8 @@ noinst_LTLIBRARIES = \
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 \
@@ -32,6 +36,7 @@ MARSHAL_GENERATED = e-contact-editor-marshal.c e-contact-editor-marshal.h
@EVO_MARSHAL_RULE@
glade_DATA = \
+ im.glade \
contact-editor.glade \
fulladdr.glade \
fullname.glade
diff --git a/addressbook/gui/contact-editor/contact-editor.glade b/addressbook/gui/contact-editor/contact-editor.glade
index 8b1aa1ef3b..5e14686329 100644
--- a/addressbook/gui/contact-editor/contact-editor.glade
+++ b/addressbook/gui/contact-editor/contact-editor.glade
@@ -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>
@@ -2180,6 +2180,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>
diff --git a/addressbook/gui/contact-editor/e-contact-editor-im.c b/addressbook/gui/contact-editor/e-contact-editor-im.c
new file mode 100644
index 0000000000..f4932a79f2
--- /dev/null
+++ b/addressbook/gui/contact-editor/e-contact-editor-im.c
@@ -0,0 +1,487 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * e-contact-editor-im.c
+ * Copyright (C) 2003 Ximian, Inc.
+ * Author: Christian Hammond <chipx86@gnupdate.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "e-contact-editor-im.h"
+#include <libgnomeui/gnome-window-icon.h>
+#include <libgnome/gnome-util.h>
+#include <libgnome/gnome-i18n.h>
+#include <gtk/gtkbox.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtksizegroup.h>
+#include <gtk/gtkstock.h>
+#include <string.h>
+
+static void e_contact_editor_im_init (EContactEditorIm *card);
+static void e_contact_editor_im_class_init (EContactEditorImClass *klass);
+static void e_contact_editor_im_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void e_contact_editor_im_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void e_contact_editor_im_dispose (GObject *object);
+
+static void fill_in_info(EContactEditorIm *editor);
+static void extract_info(EContactEditorIm *editor);
+
+static GtkDialogClass *parent_class = NULL;
+
+/* The arguments we take */
+enum {
+ PROP_0,
+ PROP_SERVICE,
+ PROP_LOCATION,
+ PROP_USERNAME,
+ PROP_EDITABLE
+};
+
+#define FIRST_IM_TYPE E_CONTACT_IM_AIM
+#define LAST_IM_TYPE E_CONTACT_IM_ICQ
+
+static const char *im_labels[] = {
+ N_("AOL Instant Messenger"),
+ N_("Jabber"),
+ N_("Yahoo Messenger"),
+ N_("MSN Messenger"),
+ N_("ICQ")
+};
+
+static const char *im_images[] = {
+ "im-aim.png",
+ "im-jabber.png",
+ "im-yahoo.png",
+ "im-msn.png",
+ "im-icq.png"
+};
+
+GType
+e_contact_editor_im_get_type (void)
+{
+ static GType contact_editor_im_type = 0;
+
+ if (!contact_editor_im_type) {
+ static const GTypeInfo contact_editor_im_info = {
+ sizeof (EContactEditorImClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) e_contact_editor_im_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EContactEditorIm),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) e_contact_editor_im_init,
+ };
+
+ contact_editor_im_type = g_type_register_static (GTK_TYPE_DIALOG, "EContactEditorIm", &contact_editor_im_info, 0);
+ }
+
+ return contact_editor_im_type;
+}
+
+static void
+e_contact_editor_im_class_init (EContactEditorImClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (GTK_TYPE_DIALOG);
+
+ object_class->set_property = e_contact_editor_im_set_property;
+ object_class->get_property = e_contact_editor_im_get_property;
+ object_class->dispose = e_contact_editor_im_dispose;
+
+ g_object_class_install_property (object_class, PROP_SERVICE,
+ g_param_spec_int ("service",
+ _("Service"),
+ /*_( */"XXX blurb" /*)*/,
+ FIRST_IM_TYPE,
+ LAST_IM_TYPE,
+ FIRST_IM_TYPE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_LOCATION,
+ g_param_spec_string ("location",
+ _("Location"),
+ /*_( */"XXX blurb" /*)*/,
+ "HOME",
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_USERNAME,
+ g_param_spec_string ("username",
+ _("Username"),
+ /*_( */"XXX blurb" /*)*/,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_EDITABLE,
+ g_param_spec_boolean ("editable",
+ _("Editable"),
+ /*_( */"XXX blurb" /*)*/,
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+service_changed_cb(GtkWidget *optmenu, EContactEditorIm *editor)
+{
+ editor->service = gtk_option_menu_get_history(GTK_OPTION_MENU(optmenu)) + FIRST_IM_TYPE;
+}
+
+static void
+location_changed_cb(GtkWidget *optmenu, EContactEditorIm *editor)
+{
+ int i = gtk_option_menu_get_history(GTK_OPTION_MENU(optmenu));
+
+ if (editor->location != NULL)
+ g_free(editor->location);
+
+ if (i == 0)
+ editor->location = g_strdup("HOME");
+ else if (i == 1)
+ editor->location = g_strdup("WORK");
+ else
+ editor->location = NULL;
+}
+
+static void
+setup_service_optmenu(EContactEditorIm *editor)
+{
+ GtkWidget *optmenu;
+ GtkWidget *menu;
+ GtkWidget *hbox;
+ GtkWidget *item;
+ GtkWidget *label;
+ GtkWidget *image;
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *scale;
+ GList *p;
+ GtkSizeGroup *sg;
+ char *icon_path;
+ int i;
+
+ optmenu = glade_xml_get_widget(editor->gui, "optmenu-service");
+ g_signal_connect(G_OBJECT(optmenu), "changed",
+ G_CALLBACK(service_changed_cb), editor);
+
+ menu = gtk_menu_new();
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu);
+ gtk_widget_show(menu);
+
+ sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+ for (i = 0; i < G_N_ELEMENTS(im_labels); i++) {
+ item = gtk_menu_item_new();
+
+ hbox = gtk_hbox_new(FALSE, 4);
+ gtk_container_add(GTK_CONTAINER(item), hbox);
+ gtk_widget_show(hbox);
+
+ icon_path = g_concat_dir_and_file(EVOLUTION_IMAGESDIR, im_images[i]);
+ pixbuf = gdk_pixbuf_new_from_file(icon_path, NULL);
+ g_free(icon_path);
+
+ if (pixbuf != NULL) {
+ scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR);
+ image = gtk_image_new_from_pixbuf(scale);
+
+ g_object_unref(G_OBJECT(pixbuf));
+ g_object_unref(G_OBJECT(scale));
+ }
+ else
+ image = gtk_image_new();
+
+ gtk_size_group_add_widget(sg, image);
+
+ gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
+ gtk_widget_show(image);
+
+ label = gtk_label_new(im_labels[i]);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ gtk_widget_show(item);
+ }
+}
+
+static void
+setup_location_optmenu(EContactEditorIm *editor)
+{
+ GtkWidget *item;
+ GtkWidget *optmenu;
+ GtkWidget *menu;
+
+ optmenu = glade_xml_get_widget(editor->gui, "optmenu-location");
+
+ g_signal_connect(G_OBJECT(optmenu), "changed",
+ G_CALLBACK(location_changed_cb), editor);
+
+ menu = gtk_menu_new();
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu);
+ gtk_widget_show(menu);
+
+ item = gtk_menu_item_new_with_label(_("Home"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ gtk_widget_show(item);
+
+ item = gtk_menu_item_new_with_label(_("Work"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ gtk_widget_show(item);
+
+ item = gtk_menu_item_new_with_label(_("Other"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ gtk_widget_show(item);
+}
+
+static void
+e_contact_editor_im_init (EContactEditorIm *e_contact_editor_im)
+{
+ GladeXML *gui;
+ GtkWidget *widget;
+ char *icon_path;
+
+ gtk_dialog_add_buttons (GTK_DIALOG (e_contact_editor_im),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ gtk_window_set_resizable(GTK_WINDOW(e_contact_editor_im), TRUE);
+
+ e_contact_editor_im->service = FIRST_IM_TYPE;
+ e_contact_editor_im->location = g_strdup("HOME");
+ e_contact_editor_im->username = NULL;
+ gui = glade_xml_new (EVOLUTION_GLADEDIR "/im.glade", NULL, NULL);
+ e_contact_editor_im->gui = gui;
+
+ widget = glade_xml_get_widget(gui, "dialog-im");
+ gtk_window_set_title (GTK_WINDOW (e_contact_editor_im),
+ GTK_WINDOW (widget)->title);
+
+ widget = glade_xml_get_widget(gui, "table-im");
+ g_object_ref(widget);
+ gtk_container_remove(GTK_CONTAINER(widget->parent), widget);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (e_contact_editor_im)->vbox), widget, TRUE, TRUE, 0);
+ g_object_unref(widget);
+
+ setup_service_optmenu(e_contact_editor_im);
+ setup_location_optmenu(e_contact_editor_im);
+
+ gtk_widget_grab_focus(glade_xml_get_widget(gui, "entry-username"));
+
+ icon_path = g_concat_dir_and_file (EVOLUTION_IMAGESDIR, "evolution-contacts-mini.png");
+ gnome_window_icon_set_from_file (GTK_WINDOW (e_contact_editor_im), icon_path);
+ g_free (icon_path);
+}
+
+void
+e_contact_editor_im_dispose (GObject *object)
+{
+ EContactEditorIm *e_contact_editor_im = E_CONTACT_EDITOR_IM(object);
+
+ if (e_contact_editor_im->gui) {
+ g_object_unref(e_contact_editor_im->gui);
+ e_contact_editor_im->gui = NULL;
+ }
+
+ if (e_contact_editor_im->location) {
+ g_free(e_contact_editor_im->location);
+ e_contact_editor_im->location = NULL;
+ }
+
+ if (e_contact_editor_im->username) {
+ g_free(e_contact_editor_im->username);
+ e_contact_editor_im->username = NULL;
+ }
+
+ if (G_OBJECT_CLASS (parent_class)->dispose)
+ (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+}
+
+GtkWidget*
+e_contact_editor_im_new (EContactField service, const char *location, const char *username)
+{
+ GtkWidget *widget = g_object_new (E_TYPE_CONTACT_EDITOR_IM, NULL);
+ g_object_set (widget,
+ "service", GINT_TO_POINTER(service),
+ "location", location,
+ "username", username,
+ NULL);
+ return widget;
+}
+
+static void
+e_contact_editor_im_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ EContactEditorIm *e_contact_editor_im;
+ const char *str;
+
+ e_contact_editor_im = E_CONTACT_EDITOR_IM (object);
+
+ switch (prop_id){
+ case PROP_SERVICE:
+ e_contact_editor_im->service = g_value_get_int(value);
+ fill_in_info(e_contact_editor_im);
+ break;
+
+ case PROP_LOCATION:
+ if (e_contact_editor_im->location != NULL)
+ g_free(e_contact_editor_im->location);
+
+ str = g_value_get_string(value);
+
+ if (str == NULL)
+ e_contact_editor_im->location = NULL;
+ else if (!g_ascii_strcasecmp(str, "HOME"))
+ e_contact_editor_im->location = g_strdup("HOME");
+ else if (!g_ascii_strcasecmp(str, "WORK"))
+ e_contact_editor_im->location = g_strdup("WORK");
+ else
+ e_contact_editor_im->location = NULL;
+
+ fill_in_info(e_contact_editor_im);
+ break;
+
+ case PROP_USERNAME:
+ if (e_contact_editor_im->username != NULL)
+ g_free(e_contact_editor_im->username);
+
+ e_contact_editor_im->username = g_strdup(g_value_get_string(value));
+ fill_in_info(e_contact_editor_im);
+ break;
+
+ case PROP_EDITABLE: {
+ int i;
+ char *widget_names[] = {
+ "optmenu-service",
+ "optmenu-location",
+ "entry-username",
+ "label-service",
+ "label-location",
+ "label-username",
+ NULL
+ };
+ e_contact_editor_im->editable = g_value_get_boolean (value) ? TRUE : FALSE;
+ for (i = 0; widget_names[i] != NULL; i ++) {
+ GtkWidget *w = glade_xml_get_widget(e_contact_editor_im->gui, widget_names[i]);
+ if (GTK_IS_ENTRY (w)) {
+ gtk_editable_set_editable (GTK_EDITABLE (w),
+ e_contact_editor_im->editable);
+ }
+ else {
+ gtk_widget_set_sensitive (w, e_contact_editor_im->editable);
+ }
+ }
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+e_contact_editor_im_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ EContactEditorIm *e_contact_editor_im;
+
+ e_contact_editor_im = E_CONTACT_EDITOR_IM (object);
+
+ switch (prop_id) {
+ case PROP_SERVICE:
+ g_value_set_int (value, e_contact_editor_im->service);
+ break;
+ case PROP_LOCATION:
+ g_value_set_string (value, e_contact_editor_im->location);
+ break;
+ case PROP_USERNAME:
+ extract_info(e_contact_editor_im);
+ g_value_set_string (value, e_contact_editor_im->username);
+ break;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, e_contact_editor_im->editable ? TRUE : FALSE);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+fill_in_field(EContactEditorIm *editor, char *field, char *string)
+{
+ GtkEntry *entry = GTK_ENTRY(glade_xml_get_widget(editor->gui, field));
+ if (entry) {
+ if (string)
+ gtk_entry_set_text(entry, string);
+ else
+ gtk_entry_set_text(entry, "");
+ }
+}
+
+static void
+fill_in_info(EContactEditorIm *editor)
+{
+ GtkWidget *optmenu;
+
+ fill_in_field(editor, "entry-username", editor->username);
+
+ optmenu = glade_xml_get_widget(editor->gui, "optmenu-service");
+
+ if (optmenu != NULL)
+ gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), editor->service - FIRST_IM_TYPE);
+
+ optmenu = glade_xml_get_widget(editor->gui, "optmenu-location");
+
+ if (optmenu != NULL)
+ gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu),
+ (editor->location == NULL ? 2 :
+ !strcmp(editor->location, "WORK") ? 1 : 0));
+}
+
+static char *
+extract_field(EContactEditorIm *editor, char *field)
+{
+ GtkEntry *entry = GTK_ENTRY(glade_xml_get_widget(editor->gui, field));
+ if (entry)
+ return g_strdup (gtk_entry_get_text(entry));
+ else
+ return NULL;
+}
+
+static void
+extract_info(EContactEditorIm *editor)
+{
+ if (editor->username != NULL)
+ g_free(editor->username);
+
+ editor->username = extract_field(editor, "entry-username");
+
+ /*
+ * NOTE: We don't need to handle the option menus.
+ * These are set by the callbacks.
+ */
+}
diff --git a/addressbook/gui/contact-editor/e-contact-editor-im.h b/addressbook/gui/contact-editor/e-contact-editor-im.h
new file mode 100644
index 0000000000..da5bd652b2
--- /dev/null
+++ b/addressbook/gui/contact-editor/e-contact-editor-im.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-contact-editor-add-im.h
+ * Copyright (C) 2003 Ximian, Inc.
+ * Author: Christian Hammond <chipx86@gnupdate.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __E_CONTACT_EDITOR_IM_H__
+#define __E_CONTACT_EDITOR_IM_H__
+
+#include <gtk/gtkdialog.h>
+#include <glade/glade.h>
+#include <libebook/e-contact.h>
+
+G_BEGIN_DECLS
+
+/* EContactEditorIm - A dialog allowing the user to add an IM account to a contact.
+ *
+ * The following arguments are available:
+ *
+ * name type read/write description
+ * --------------------------------------------------------------------------------
+ * service EContactField RW The field of the IM service.
+ * location char * RW The location type.
+ * username char * RW The username of the account.
+ */
+
+#define E_TYPE_CONTACT_EDITOR_IM (e_contact_editor_im_get_type ())
+#define E_CONTACT_EDITOR_IM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_EDITOR_IM, EContactEditorIm))
+#define E_CONTACT_EDITOR_IM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_EDITOR_IM, EContactEditorImClass))
+#define E_IS_CONTACT_EDITOR_IM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_EDITOR_IM))
+#define E_IS_CONTACT_EDITOR_IM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONTACT_EDITOR_IM))
+
+
+typedef struct _EContactEditorIm EContactEditorIm;
+typedef struct _EContactEditorImClass EContactEditorImClass;
+
+struct _EContactEditorIm
+{
+ GtkDialog parent;
+
+ /* item specific fields */
+ EContactField service;
+ char *location;
+ char *username;
+ GladeXML *gui;
+
+ /* Whether the dialog will accept modifications */
+ guint editable : 1;
+};
+
+struct _EContactEditorImClass
+{
+ GtkDialogClass parent_class;
+};
+
+
+GtkWidget *e_contact_editor_im_new(EContactField service, const char *location, const char *username);
+GType e_contact_editor_im_get_type (void);
+
+G_END_DECLS
+
+#endif /* __E_CONTACT_EDITOR_IM_H__ */
+
diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c
index 13a1f39d51..a3ea73d957 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/addressbook/gui/contact-editor/e-contact-editor.c
@@ -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>
@@ -49,6 +50,8 @@
#include <e-util/e-categories-master-list-wombat.h>
+#include <camel/camel.h>
+
#include "addressbook/gui/component/addressbook.h"
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/printing/e-contact-print-envelope.h"
@@ -62,6 +65,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"
@@ -74,6 +78,17 @@ enum {
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);
@@ -83,6 +98,7 @@ static void e_contact_editor_dispose (GObject *object);
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);
#if 0
static void find_address_mailing (EContactEditor *editor);
#endif
@@ -297,6 +313,439 @@ connect_arrow_button_signals (EContactEditor *editor)
}
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);
+
+ widget_changed(NULL, editor);
+ }
+
+ 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);
+
+ g_list_foreach(new_list, (GFunc)g_free, NULL);
+ 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);
+
+ g_list_foreach(new_list, (GFunc)g_free, NULL);
+ g_list_free(new_list);
+ }
+
+ set_im_fields(editor);
+
+ widget_changed(NULL, editor);
+ }
+
+ 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);
+
+ if (new_list != NULL)
+ {
+ g_list_foreach(new_list, (GFunc)g_free, NULL);
+ g_list_free(new_list);
+ }
+
+ gtk_list_store_remove(editor->im_model, &iter);
+
+ widget_changed(NULL, editor);
+}
+
+
+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;
@@ -1003,6 +1452,7 @@ categories_clicked(GtkWidget *button, EContactEditor *editor)
gtk_widget_destroy(GTK_WIDGET(dialog));
}
+
typedef struct {
EContactEditor *ce;
gboolean should_close;
@@ -1488,6 +1938,8 @@ e_contact_editor_init (EContactEditor *e_contact_editor)
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",
@@ -1517,6 +1969,22 @@ e_contact_editor_init (EContactEditor *e_contact_editor)
g_signal_connect (widget, "source_selected",
G_CALLBACK (source_selected), 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"));
@@ -2288,6 +2756,62 @@ set_fields(EContactEditor *editor)
}
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)
{
GtkWidget *text, *check;
@@ -2704,6 +3228,8 @@ fill_in_info(EContactEditor *editor)
e_contact_date_free (bday);
set_fields(editor);
+
+ set_im_fields(editor);
}
}
diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h
index 56a41dfb2a..ddb4ad3a5f 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.h
+++ b/addressbook/gui/contact-editor/e-contact-editor.h
@@ -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.
@@ -76,6 +79,8 @@ struct _EContactEditor
EContactName *name;
char *company;
+ GtkListStore *im_model;
+
EContactField email_choice;
EContactField phone_choice[4];
EContactField address_choice;
diff --git a/addressbook/gui/contact-editor/im.glade b/addressbook/gui/contact-editor/im.glade
new file mode 100644
index 0000000000..04f1e6915d
--- /dev/null
+++ b/addressbook/gui/contact-editor/im.glade
@@ -0,0 +1,202 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+<requires lib="gnome"/>
+
+<widget class="GtkDialog" id="dialog-im">
+ <property name="title" translatable="yes">Add IM Account</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">False</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table-im">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="label-service">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">IM Service:</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">1</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</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">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkOptionMenu" id="optmenu-service">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="history">-1</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label-username">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Account name:</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">1</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="entry-username">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label-location">
+ <property name="label" translatable="yes">Location:</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">1</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkOptionMenu" id="optmenu-location">
+ <property name="can_focus">True</property>
+ <property name="history">-1</property>
+ </widget>
+ <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="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>