diff options
Diffstat (limited to 'addressbook')
-rw-r--r-- | addressbook/ChangeLog | 23 | ||||
-rw-r--r-- | addressbook/conduit/.cvsignore | 2 | ||||
-rw-r--r-- | addressbook/gui/component/.cvsignore | 1 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/Makefile.am | 5 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/contact-editor.glade | 311 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-editor-im.c | 487 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-editor-im.h | 76 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-editor.c | 526 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/e-contact-editor.h | 5 | ||||
-rw-r--r-- | addressbook/gui/contact-editor/im.glade | 202 |
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> |