Switched to use e_contact_quick_add_free_form. Removed debugging code,

2001-03-08  Jon Trowbridge  <trow@ximian.com>

	* gui/component/select-names/e-select-names-popup.c
	(quick_add_cb): Switched to use e_contact_quick_add_free_form.
	Removed debugging code, hopefully without introducing any bugs
	in the process.

	* gui/component/select-names/e-select-names-text-model.c
	(e_select_names_text_model_insert_length): Fix bug with commas
	inside of name/address combos.  As long as the comma is inside of
	quotes, it will be treated as part of the name rather than as a
	break between addresses.

	* gui/component/select-names/e-select-names-completion.c
	(match_nickname): Use e_card_name_to_string for nickname match
	strings.
	(match_email): Use e_card_name_to_string for email match strings.
	(e_select_names_completion_begin): Strip quotes out of query text,
	so we don't produce malformed sexps.
	Added William Blake quote easter egg.

	* contact-editor/e-contact-quick-add.c: Further attempts to fix...
	mostly unsuccessful.
	(e_contact_quick_add_free_form): Added.  Takes a single string
	and tries to parse out (using some simple, loose rules) the
	name and e-mail -- then calls e_contact_quick_add.  An attempt to
	get the computer to automatically Do The Right Thing.

	* backend/ebook/e-book.c: Fixed some broken indentation.  Yes, I'm
	anal.

	* gui/component/GNOME_Evolution_Addressbook.oafinfo: Added oaf_server
	info for EAddressWidget.

	* gui/component/GNOME_Evolution_Addressbook.oaf.in: Added oaf_server
	info for EAddressWidget.

	* gui/component/addressbook-factory.c (main): Add call to
	e_address_widget_factory_init.

	* gui/component/e-address-widget.h:
	* gui/component/e-address-widget.c: Added.  A little widget (and a
	Bonobo control, BTW) for displaying addresses, with a left-click
	menu.  Used to display addresses in the mail viewer (as embedded
	GtkHTML objects, replacing the text previously used).  Still quite
	incomplete.


2001-03-08  Jon Trowbridge  <trow@ximian.com>

	* mail-format.c (write_field_row_begin): Added.  Table row HTML
	broken out into its own function.
	(write_subject): Added.  Emits the proper HTML for the subject
	line.
	(write_field_to_stream): #ifdef-ed out of existence.
	(write_address): Take a CamelInternetAddress and spit out an
	<object> tag with the appropriate <param>s.

	* mail-display.c (on_object_requested): Check for an "address"
	object.  If found, call...
	(handle_embedded_address_object): ...this function, which creates
	an AddressWidget bonobo control and passes in the necessary info.
	I never really realized just quite how much GtkHTML kicks ass
	until I figured out how to make this work.

svn path=/trunk/; revision=8607
This commit is contained in:
Jon Trowbridge
2001-03-08 23:15:20 +00:00
committed by Jon Trowbridge
parent a9c279d8a6
commit afe6fc18fc
18 changed files with 1102 additions and 178 deletions

View File

@ -1,3 +1,50 @@
2001-03-08 Jon Trowbridge <trow@ximian.com>
* gui/component/select-names/e-select-names-popup.c
(quick_add_cb): Switched to use e_contact_quick_add_free_form.
Removed debugging code, hopefully without introducing any bugs
in the process.
* gui/component/select-names/e-select-names-text-model.c
(e_select_names_text_model_insert_length): Fix bug with commas
inside of name/address combos. As long as the comma is inside of
quotes, it will be treated as part of the name rather than as a
break between addresses.
* gui/component/select-names/e-select-names-completion.c
(match_nickname): Use e_card_name_to_string for nickname match
strings.
(match_email): Use e_card_name_to_string for email match strings.
(e_select_names_completion_begin): Strip quotes out of query text,
so we don't produce malformed sexps.
Added William Blake quote easter egg.
* contact-editor/e-contact-quick-add.c: Further attempts to fix...
mostly unsuccessful.
(e_contact_quick_add_free_form): Added. Takes a single string
and tries to parse out (using some simple, loose rules) the
name and e-mail -- then calls e_contact_quick_add. An attempt to
get the computer to automatically Do The Right Thing.
* backend/ebook/e-book.c: Fixed some broken indentation. Yes, I'm
anal.
* gui/component/GNOME_Evolution_Addressbook.oafinfo: Added oaf_server
info for EAddressWidget.
* gui/component/GNOME_Evolution_Addressbook.oaf.in: Added oaf_server
info for EAddressWidget.
* gui/component/addressbook-factory.c (main): Add call to
e_address_widget_factory_init.
* gui/component/e-address-widget.h:
* gui/component/e-address-widget.c: Added. A little widget (and a
Bonobo control, BTW) for displaying addresses, with a left-click
menu. Used to display addresses in the mail viewer (as embedded
GtkHTML objects, replacing the text previously used). Still quite
incomplete.
2001-03-08 Ettore Perazzoli <ettore@ximian.com>
* gui/component/addressbook-component.c (factory_fn): Specify a

View File

@ -1008,10 +1008,11 @@ e_book_check_connection (EBook *book)
return TRUE;
}
gboolean e_book_get_cursor (EBook *book,
gchar *query,
EBookCursorCallback cb,
gpointer closure)
gboolean
e_book_get_cursor (EBook *book,
gchar *query,
EBookCursorCallback cb,
gpointer closure)
{
CORBA_Environment ev;
@ -1041,10 +1042,11 @@ gboolean e_book_get_cursor (EBook *book,
return TRUE;
}
gboolean e_book_get_book_view (EBook *book,
gchar *query,
EBookBookViewCallback cb,
gpointer closure)
gboolean
e_book_get_book_view (EBook *book,
gchar *query,
EBookBookViewCallback cb,
gpointer closure)
{
CORBA_Environment ev;
EBookViewListener *listener;
@ -1077,10 +1079,11 @@ gboolean e_book_get_book_view (EBook *book,
return TRUE;
}
gboolean e_book_get_changes (EBook *book,
gchar *changeid,
EBookBookViewCallback cb,
gpointer closure)
gboolean
e_book_get_changes (EBook *book,
gchar *changeid,
EBookBookViewCallback cb,
gpointer closure)
{
CORBA_Environment ev;
EBookViewListener *listener;

View File

@ -26,79 +26,78 @@
*/
#include <config.h>
#include <ctype.h>
#include <gnome.h>
#include <addressbook/backend/ebook/e-book.h>
#include <addressbook/backend/ebook/e-card.h>
#include "e-contact-editor.h"
#include "e-contact-quick-add.h"
static FILE *out = NULL;
static void
e_card_quick_set_name (ECard *card, const gchar *str)
{
ECardSimple *simple;
g_return_if_fail (card && E_IS_CARD (card));
if (str == NULL)
return;
if (out)
fprintf (out, "quick-set name to \"%s\"\n", str);
if (card->name)
e_card_name_free (card->name);
card->name = e_card_name_from_string (str);
simple = e_card_simple_new (card);
e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FULL_NAME, str);
e_card_simple_sync_card (simple);
gtk_object_unref (GTK_OBJECT (simple));
}
static void
e_card_quick_set_email (ECard *card, const gchar *str)
{
ECardSimple *simple;
g_return_if_fail (card && E_IS_CARD (card));
if (str == NULL)
return;
if (out)
fprintf (out, "quick-set email to \"%s\"\n", str);
if (card->email == NULL) {
card->email = e_list_new ((EListCopyFunc) g_strdup,
(EListFreeFunc) g_free,
NULL);
e_list_append (card->email, str);
} else {
EIterator *iter = e_list_get_iterator (card->email);
e_iterator_reset (iter);
if (e_iterator_is_valid (iter)) {
e_iterator_set (iter, str);
}
}
simple = e_card_simple_new (card);
e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_EMAIL, str);
e_card_simple_sync_card (simple);
gtk_object_unref (GTK_OBJECT (simple));
}
static void
book_ready_cb (EBook *book, EBookStatus status, gpointer user_data)
{
if (status == E_BOOK_STATUS_SUCCESS)
e_book_add_card (book, E_CARD (user_data), NULL, NULL);
gtk_object_unref (GTK_OBJECT (book));
ECard *card = E_CARD (user_data);
EContactQuickAddCallback cb = gtk_object_get_data (GTK_OBJECT (card), "e-contact-quick-add-cb");
gpointer cb_user_data = gtk_object_get_data (GTK_OBJECT (card), "e-contact-quick-add-user-data");
if (status == E_BOOK_STATUS_SUCCESS) {
e_book_add_card (book, card, NULL, NULL);
if (cb)
cb (card, cb_user_data);
} else {
/* Something went wrong... */
if (cb)
cb (NULL, cb_user_data);
gtk_object_unref (GTK_OBJECT (book));
}
}
static void
add_card (ECard *card)
{
EBook *book = e_book_new ();
gchar *filename, *uri;
filename = gnome_util_prepend_user_home ("evolution/local/Contacts/addressbook.db");
uri = g_strdup_printf ("file://%s", filename);
e_book_load_uri (book, uri, book_ready_cb, card);
g_free (filename);
g_free (uri);
e_book_load_local_address_book (book, book_ready_cb, card);
}
/*
* Raise a contact editor with all fields editable, and hook up all signals accordingly.
*/
static void
add_card_cb (EContactEditor *ce, ECard *card, gpointer user_data)
{
@ -108,11 +107,54 @@ add_card_cb (EContactEditor *ce, ECard *card, gpointer user_data)
static void
editor_closed_cb (GtkWidget *w, gpointer user_data)
{
/* w is the contact editor, user_data is an ECard. */
if (user_data)
gtk_object_unref (user_data);
gtk_object_unref (GTK_OBJECT (w));
}
static void
ce_book_found_fields (EBook *book, EBookStatus status, EList *fields, gpointer user_data)
{
ECard *card = E_CARD (user_data);
EContactEditor *contact_editor;
if (status != E_BOOK_STATUS_SUCCESS) {
g_warning ("Couldn't find supported fields for local address book.");
return;
}
contact_editor = e_contact_editor_new (card, TRUE, fields);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"add_card",
GTK_SIGNAL_FUNC (add_card_cb),
NULL);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"editor_closed",
GTK_SIGNAL_FUNC (editor_closed_cb),
user_data);
e_contact_editor_raise (contact_editor);
}
static void
ce_book_ready (EBook *book, EBookStatus status, gpointer user_data)
{
if (status != E_BOOK_STATUS_SUCCESS) {
g_warning ("Couldn't open local address book.");
return;
}
e_book_get_supported_fields (book, ce_book_found_fields, user_data);
}
static void
edit_card (ECard *card)
{
e_book_load_local_address_book (e_book_new (), ce_book_ready, card);
}
static void
clicked_cb (GtkWidget *w, gint button, gpointer user_data)
{
@ -149,19 +191,7 @@ clicked_cb (GtkWidget *w, gint button, gpointer user_data)
} else if (button == 1) {
/* EDIT FULL */
EContactEditor *contact_editor;
contact_editor = e_contact_editor_new (card, TRUE, NULL);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"add_card",
GTK_SIGNAL_FUNC (add_card_cb),
NULL);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"editor_closed",
GTK_SIGNAL_FUNC (editor_closed_cb),
user_data);
e_contact_editor_raise (contact_editor);
edit_card (card);
} else {
/* CANCEL */
@ -249,16 +279,6 @@ e_contact_quick_add (const gchar *name, const gchar *email,
ECard *new_card;
GtkWidget *dialog;
if (out == NULL) {
out = fopen ("/tmp/barnass", "w");
if (out)
setvbuf (out, NULL, _IONBF, 0);
}
if (out)
fprintf (out, "\n name: %s\nemail: %s\n", name, email);
/* We need to have *something* to work with. */
if (name == NULL && email == NULL) {
if (cb)
@ -280,3 +300,85 @@ e_contact_quick_add (const gchar *name, const gchar *email,
gtk_widget_show_all (dialog);
}
void
e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer user_data)
{
gchar *name=NULL, *email=NULL;
const gchar *last_at, *s;
gboolean in_quote;
if (text == NULL) {
e_contact_quick_add (NULL, NULL, cb, user_data);
return;
}
/* Look for things that look like e-mail addresses embedded in text */
in_quote = FALSE;
last_at = NULL;
for (s = text; *s; ++s) {
if (*s == '@' && !in_quote)
last_at = s;
else if (*s == '"')
in_quote = !in_quote;
}
if (last_at == NULL) {
/* No at sign, so we treat it all as the name */
name = g_strdup (text);
} else {
gboolean bad_char = FALSE;
/* walk backwards to whitespace or a < or a quote... */
while (last_at >= text && !bad_char
&& !(isspace ((gint) *last_at) || *last_at == '<' || *last_at == '"')) {
/* Check for some stuff that can't appear in a legal e-mail address. */
if (*last_at == '['
|| *last_at == ']'
|| *last_at == '('
|| *last_at == ')')
bad_char = TRUE;
--last_at;
}
if (last_at < text)
last_at = text;
/* ...and then split the text there */
if (!bad_char) {
if (text < last_at)
name = g_strndup (text, last_at-text);
email = g_strdup (last_at);
}
}
/* If all else has failed, make it the name. */
if (name == NULL && email == NULL)
name = g_strdup (text);
/* Clean up name */
if (name && *name)
g_strstrip (name);
/* Clean up email, remove bracketing <>s */
if (email && *email) {
gboolean changed = FALSE;
g_strstrip (email);
if (*email == '<') {
*email = ' ';
changed = TRUE;
}
if (email[strlen (email)-1] == '>') {
email[strlen (email)-1] = ' ';
changed = TRUE;
}
if (changed)
g_strstrip (email);
}
e_contact_quick_add (name, email, cb, user_data);
g_free (name);
g_free (email);
}

View File

@ -36,5 +36,7 @@ typedef void (*EContactQuickAddCallback) (ECard *new_card, gpointer user_data);
void e_contact_quick_add (const gchar *name, const gchar *email,
EContactQuickAddCallback cb, gpointer user_data);
void e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer user_data);
#endif /* __E_CONTACT_QUICK_ADD_H__ */

View File

@ -87,6 +87,34 @@
<oaf_attribute name="evolution:shell-component-icon" type="string"
value="evolution-contacts.png"/>
</oaf_server>
<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidgetFactory"
type="exe"
location="evolution-addressbook">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/ObjectFactory:1.0"/>
</oaf_attribute>
<oaf_attribute name="description" type="string"
_value="Factory for the Addressbook's address displayer"/>
</oaf_server>
<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidget"
type="factory"
location="OAFIID:GNOME_Evolution_Addressbook_AddressWidgetFactory">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/address-widget:1.0"/>
<item value="IDL:GNOME/Control:1.0"/>
</oaf_attribute>
<oaf_attribute name="description" type="string"
_value="A Bonobo control for displaying an address."/>
</oaf_server>
</oaf_info>

View File

@ -89,4 +89,31 @@
value="evolution-contacts.png"/>
</oaf_server>
<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidgetFactory"
type="exe"
location="evolution-addressbook">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/ObjectFactory:1.0"/>
</oaf_attribute>
<oaf_attribute name="description" type="string"
value="Factory for the Addressbook's address displayer"/>
</oaf_server>
<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidget"
type="factory"
location="OAFIID:GNOME_Evolution_Addressbook_AddressWidgetFactory">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/address-widget:1.0"/>
<item value="IDL:GNOME/Control:1.0"/>
</oaf_attribute>
<oaf_attribute name="description" type="string"
value="A Bonobo control for displaying an address."/>
</oaf_server>
</oaf_info>

View File

@ -36,7 +36,9 @@ evolution_addressbook_SOURCES = \
addressbook.c \
addressbook.h \
e-cardlist-model.c \
e-cardlist-model.h
e-cardlist-model.h \
e-address-widget.h \
e-address-widget.c
evolution_addressbook_LDADD = \
select-names/libeselectnames.la \

View File

@ -18,6 +18,7 @@
#include "addressbook.h"
#include "addressbook-component.h"
#include "e-address-widget.h"
#include "addressbook/gui/widgets/e-minicard-control.h"
#include "select-names/e-select-names-factory.h"
@ -63,6 +64,8 @@ main (int argc, char **argv)
e_minicard_control_factory_init ();
e_address_widget_factory_init ();
e_cursors_init();
unicode_init();

View File

@ -0,0 +1,414 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* e-address-widget.c
*
* Copyright (C) 2001 Ximian, Inc.
*
* Developed by Jon Trowbridge <trow@ximian.com>
*/
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
#include <config.h>
#include <bonobo/bonobo-control.h>
#include <bonobo/bonobo-property-bag.h>
#include <bonobo/bonobo-generic-factory.h>
#include <addressbook/contact-editor/e-contact-quick-add.h>
#include "e-address-widget.h"
static void e_address_widget_class_init (EAddressWidgetClass *klass);
static void e_address_widget_init (EAddressWidget *obj);
static void e_address_widget_destroy (GtkObject *obj);
static gint e_address_widget_button_press_handler (GtkWidget *w, GdkEventButton *ev);
static void e_address_widget_popup (EAddressWidget *, GdkEventButton *ev);
static GtkObjectClass *parent_class;
static void
e_address_widget_class_init (EAddressWidgetClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *) klass;
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
parent_class = GTK_OBJECT_CLASS (gtk_type_class (gtk_event_box_get_type ()));
object_class->destroy = e_address_widget_destroy;
widget_class->button_press_event = e_address_widget_button_press_handler;
}
static void
e_address_widget_init (EAddressWidget *addr)
{
}
static void
e_address_widget_destroy (GtkObject *obj)
{
EAddressWidget *addr = E_ADDRESS_WIDGET (obj);
g_free (addr->name);
g_free (addr->email);
if (addr->card)
gtk_object_unref (GTK_OBJECT (addr->card));
}
static gint
e_address_widget_button_press_handler (GtkWidget *w, GdkEventButton *ev)
{
EAddressWidget *addr = E_ADDRESS_WIDGET (w);
if (ev->button == 3 && ev->state == 0) {
e_address_widget_popup (addr, ev);
return TRUE;
}
return FALSE;
}
GtkType
e_address_widget_get_type (void)
{
static GtkType aw_type = 0;
if (!aw_type) {
GtkTypeInfo aw_info = {
"EAddressWidget",
sizeof (EAddressWidget),
sizeof (EAddressWidgetClass),
(GtkClassInitFunc) e_address_widget_class_init,
(GtkObjectInitFunc) e_address_widget_init,
NULL, NULL, /* reserved... but for what sinister purpose? */
(GtkClassInitFunc) NULL
};
aw_type = gtk_type_unique (gtk_event_box_get_type (), &aw_info);
}
return aw_type;
}
static void
gtk_widget_visible (GtkWidget *w, gboolean x)
{
if (x)
gtk_widget_show (w);
else
gtk_widget_hide (w);
}
static void
e_address_widget_refresh (EAddressWidget *addr)
{
gchar *str;
gboolean have_name, have_email;
g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
have_name = addr->name && *addr->name;
have_email = addr->email && *addr->email;
gtk_label_set_text (GTK_LABEL (addr->name_widget), have_name ? addr->name : "");
gtk_widget_visible (addr->name_widget, have_name);
if (have_email) {
str = g_strdup_printf (have_name ? "<%s>" : "%s", addr->email);
gtk_label_set_text (GTK_LABEL (addr->email_widget), str);
g_free (str);
} else {
gtk_label_set_text (GTK_LABEL (addr->email_widget), "");
}
gtk_widget_visible (addr->email_widget, have_email);
gtk_widget_visible (addr->spacer, have_name && have_email);
/* Launch a query to find the appropriate card, if necessary. */
addr->querying = TRUE;
}
void
e_address_widget_set_name (EAddressWidget *addr, const gchar *name)
{
g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
g_free (addr->name);
addr->name = g_strdup (name);
e_address_widget_refresh (addr);
}
void
e_address_widget_set_email (EAddressWidget *addr, const gchar *email)
{
g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
g_free (addr->email);
addr->email = g_strdup (email);
e_address_widget_refresh (addr);
}
void
e_address_widget_set_text (EAddressWidget *addr, const gchar *text)
{
g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
e_address_widget_set_email (addr, text); /* CRAP */
}
void
e_address_widget_construct (EAddressWidget *addr)
{
GtkWidget *box;
g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
box = gtk_hbox_new (FALSE, 2);
addr->name_widget = gtk_label_new ("");
addr->spacer = gtk_label_new (" ");
addr->email_widget = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (box), addr->name_widget, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), addr->spacer, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), addr->email_widget, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (addr), box);
gtk_widget_show (box);
gtk_widget_show (addr->name_widget);
gtk_widget_show (addr->email_widget);
}
GtkWidget *
e_address_widget_new (void)
{
EAddressWidget *addr = gtk_type_new (e_address_widget_get_type ());
e_address_widget_construct (addr);
return GTK_WIDGET (addr);
}
/*
*
* Popup Menu
*
*/
#define ARBITRARY_UIINFO_LIMIT 64
static GtkWidget *
popup_menu_card (EAddressWidget *addr)
{
ECard *card = E_CARD (addr->card);
g_return_val_if_fail (card != NULL, NULL);
return NULL;
}
static void
add_contacts_cb (GtkWidget *w, gpointer user_data)
{
EAddressWidget *addr = E_ADDRESS_WIDGET (user_data);
e_contact_quick_add (addr->name, addr->email, NULL, NULL);
}
static GtkWidget *
popup_menu_nocard (EAddressWidget *addr)
{
GnomeUIInfo uiinfo[ARBITRARY_UIINFO_LIMIT];
GtkWidget *pop;
gint i=0, dead;
memset (uiinfo, 0, sizeof (uiinfo));
if (addr->name) {
uiinfo[i].type = GNOME_APP_UI_ITEM;
uiinfo[i].label = addr->name;
++i;
}
if (addr->email) {
uiinfo[i].type = GNOME_APP_UI_ITEM;
uiinfo[i].label = addr->email;
++i;
}
dead = i;
uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
++i;
uiinfo[i].type = GNOME_APP_UI_ITEM;
uiinfo[i].label = N_("Add to Contacts");
uiinfo[i].moreinfo = add_contacts_cb;
++i;
uiinfo[i].type = GNOME_APP_UI_ENDOFINFO;
pop = gnome_popup_menu_new (uiinfo);
for (i=0; i<dead; ++i)
dead_item (GTK_ITEM (uiinfo[i].widget));
return pop;
}
static void
e_address_widget_popup (EAddressWidget *addr, GdkEventButton *ev)
{
GtkWidget *pop;
g_return_if_fail (addr && E_IS_ADDRESS_WIDGET (addr));
pop = addr->card ? popup_menu_card (addr) : popup_menu_nocard (addr);
if (pop)
gnome_popup_menu_do_popup (pop, NULL, NULL, ev, addr);
}
/*
*
* Bonobo Control Magic
*
*/
enum {
ADDRESS_PROPERTY_NAME,
ADDRESS_PROPERTY_EMAIL,
ADDRESS_PROPERTY_TEXT,
ADDRESS_PROPERTY_BACKGROUND_RGB
};
static void
get_prop (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
{
EAddressWidget *addr = E_ADDRESS_WIDGET (user_data);
switch (arg_id) {
case ADDRESS_PROPERTY_NAME:
BONOBO_ARG_SET_STRING (arg, addr->name ? addr->name :"");
break;
case ADDRESS_PROPERTY_EMAIL:
BONOBO_ARG_SET_STRING (arg, addr->email ? addr->email : "");
break;
case ADDRESS_PROPERTY_TEXT:
BONOBO_ARG_SET_STRING (arg, "?");
break;
}
}
static void
set_prop (BonoboPropertyBag *bag, const BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
{
EAddressWidget *addr = E_ADDRESS_WIDGET (user_data);
switch (arg_id) {
case ADDRESS_PROPERTY_NAME:
e_address_widget_set_name (addr, BONOBO_ARG_GET_STRING (arg));
break;
case ADDRESS_PROPERTY_EMAIL:
e_address_widget_set_email (addr, BONOBO_ARG_GET_STRING (arg));
break;
case ADDRESS_PROPERTY_TEXT:
e_address_widget_set_text (addr, BONOBO_ARG_GET_STRING (arg));
break;
case ADDRESS_PROPERTY_BACKGROUND_RGB:
{
gint bg = BONOBO_ARG_GET_INT (arg);
GdkColor color;
color.red = (bg & 0xff0000) >> 8;
color.green = (bg & 0x00ff00);
color.blue = (bg & 0x0000ff) << 8;
if (gdk_colormap_alloc_color (gtk_widget_get_colormap (GTK_WIDGET (addr)), &color, FALSE, TRUE)) {
GtkStyle *style = gtk_style_copy (gtk_widget_get_style (GTK_WIDGET (addr)));
style->bg[0] = color;
gtk_widget_set_style (GTK_WIDGET (addr), style);
}
}
break;
}
}
static BonoboControl *
e_address_widget_factory_new_control (void)
{
BonoboControl *control;
BonoboPropertyBag *bag;
GtkWidget *w;
w = e_address_widget_new ();
gtk_widget_show (w);
control = bonobo_control_new (w);
bag = bonobo_property_bag_new (get_prop, set_prop, w);
bonobo_property_bag_add (bag, "name", ADDRESS_PROPERTY_NAME,
BONOBO_ARG_STRING, NULL, NULL,
BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
bonobo_property_bag_add (bag, "email", ADDRESS_PROPERTY_EMAIL,
BONOBO_ARG_STRING, NULL, NULL,
BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
bonobo_property_bag_add (bag, "text", ADDRESS_PROPERTY_TEXT,
BONOBO_ARG_STRING, NULL, NULL,
BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
bonobo_property_bag_add (bag, "background_rgb", ADDRESS_PROPERTY_BACKGROUND_RGB,
BONOBO_ARG_INT, NULL, NULL,
BONOBO_PROPERTY_WRITEABLE);
bonobo_control_set_properties (control, bag);
bonobo_object_unref (BONOBO_OBJECT (bag));
return control;
}
static BonoboObject *
e_address_widget_factory (BonoboGenericFactory *factory, gpointer user_data)
{
return BONOBO_OBJECT (e_address_widget_factory_new_control ());
}
void
e_address_widget_factory_init (void)
{
static BonoboGenericFactory *factory = NULL;
if (factory != NULL)
return;
factory = bonobo_generic_factory_new ("OAFIID:GNOME_Evolution_Addressbook_AddressWidgetFactory",
e_address_widget_factory, NULL);
if (factory == NULL)
g_error ("I could not register an AddressWidget factory.");
}

View File

@ -0,0 +1,81 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* e-address-widget.h
*
* Copyright (C) 2001 Ximian, Inc.
*
* Developed by Jon Trowbridge <trow@ximian.com>
*/
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
#ifndef __E_ADDRESS_WIDGET_H__
#define __E_ADDRESS_WIDGET_H__
#include <gtk/gtk.h>
#include <libgnome/gnome-defs.h>
#include <addressbook/backend/ebook/e-card.h>
BEGIN_GNOME_DECLS
#define E_ADDRESS_WIDGET_TYPE (e_address_widget_get_type ())
#define E_ADDRESS_WIDGET(o) (GTK_CHECK_CAST ((o), E_ADDRESS_WIDGET_TYPE, EAddressWidget))
#define E_ADDRESS_WIDGET_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), E_ADDRESS_WIDGET_TYPE, EAddressWidgetClass))
#define E_IS_ADDRESS_WIDGET(o) (GTK_CHECK_TYPE ((o), E_ADDRESS_WIDGET_TYPE))
#define E_IS_ADDRESS_WIDGET_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESS_WIDGET_TYPE))
typedef struct _EAddressWidget EAddressWidget;
typedef struct _EAddressWidgetClass EAddressWidgetClass;
struct _EAddressWidget {
GtkEventBox parent;
gchar *name;
gchar *email;
GtkWidget *name_widget;
GtkWidget *email_widget;
GtkWidget *spacer;
gboolean querying;
ECard *card;
};
struct _EAddressWidgetClass {
GtkHBoxClass parent_class;
};
GtkType e_address_widget_get_type (void);
void e_address_widget_set_name (EAddressWidget *, const gchar *name);
void e_address_widget_set_email (EAddressWidget *, const gchar *email);
void e_address_widget_set_text (EAddressWidget *, const gchar *text);
void e_address_widget_construct (EAddressWidget *);
GtkWidget *e_address_widget_new (void);
void e_address_widget_factory_init (void);
END_GNOME_DECLS
#endif /* __E_ADDRESS_WIDGET_H__ */

View File

@ -97,11 +97,14 @@ match_nickname (ESelectNamesCompletion *comp, EDestination *dest, double *score)
if (card->nickname
&& !g_strncasecmp (comp->priv->query_text, card->nickname, len)) {
gchar *name = e_card_name_to_string (card->name);
gchar *str;
*score = len * 10; /* nickname gives 10 points per matching character */
return g_strdup_printf ("(%s) %s %s", card->nickname, card->name->given, card->name->family);
str = g_strdup_printf ("(%s) %s", card->nickname, name);
g_free (name);
return str;
}
return NULL;
@ -125,8 +128,12 @@ match_email (ESelectNamesCompletion *comp, EDestination *dest, double *score)
const gchar *email = e_destination_get_email (dest);
if (email && !g_strncasecmp (comp->priv->query_text, email, len)) {
gchar *name, *str;
*score = len * 2; /* 2 points for each matching character */
return g_strdup_printf ("<%s> %s %s", email, card->name->given, card->name->family);
name = e_card_name_to_string (card->name);
str = g_strdup_printf ("<%s> %s", email, name);
g_free (name);
return str;
}
return NULL;
@ -693,7 +700,9 @@ struct _SearchOverride {
const gchar *text[4];
};
static SearchOverride override[] = {
{ "easter egg", { "This is the sample", "Easter Egg text for", "Evolution.", NULL } },
{ "why?", { "\"I must create a system, or be enslaved by another man's.\"",
" -- Wiliam Blake, \"Jerusalem\"",
NULL } },
{ NULL, { NULL } } };
static gboolean
@ -711,6 +720,7 @@ e_select_names_completion_begin (ECompletion *comp, const gchar *text, gint pos,
ESelectNamesCompletion *selcomp = E_SELECT_NAMES_COMPLETION (comp);
const gchar *str;
gint index, j;
gchar *s, *t;
g_return_if_fail (comp != NULL);
g_return_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp));
@ -751,6 +761,18 @@ e_select_names_completion_begin (ECompletion *comp, const gchar *text, gint pos,
g_free (selcomp->priv->pending_query_text);
selcomp->priv->pending_query_text = g_strdup (str);
/* Strip problematic characters out of query text. */
s = t = selcomp->priv->pending_query_text;
while (*s) {
if (*s != ',' && *s != '"') {
if (s != t)
*t = *s;
++t;
}
++s;
}
*t = '\0';
e_select_names_completion_do_query (selcomp);
}

View File

@ -31,8 +31,6 @@
#include <addressbook/contact-editor/e-contact-quick-add.h>
#include "e-select-names-popup.h"
static FILE *out = NULL;
typedef struct _PopupInfo PopupInfo;
struct _PopupInfo {
ESelectNamesModel *model;
@ -64,9 +62,6 @@ popup_info_free (PopupInfo *info)
{
if (info) {
if (out)
fprintf (out, "popup_info_free\n");
if (info->model)
gtk_object_unref (GTK_OBJECT (info->model));
@ -103,8 +98,6 @@ change_email_num_cb (GtkWidget *w, gpointer user_data)
return;
n = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (w), "number"));
if (out)
fprintf (out, "replacing %d\n", n);
if (n != e_destination_get_email_num (info->dest)) {
dest = e_destination_new ();
@ -157,9 +150,6 @@ popup_menu_card (PopupInfo *info)
EIterator *iterator;
gchar *name_str;
if (out)
fprintf (out, "popup_menu_card\n");
/*
* Build up our GnomeUIInfo array.
*/
@ -236,9 +226,6 @@ popup_menu_card (PopupInfo *info)
}
}
if (out)
fprintf (out, "leaving popup_menu_card\n");
return pop;
}
@ -246,8 +233,7 @@ static void
quick_add_cb (GtkWidget *w, gpointer user_data)
{
PopupInfo *info = (PopupInfo *) user_data;
e_contact_quick_add (NULL, e_destination_get_string (info->dest),
NULL, NULL);
e_contact_quick_add_free_form (e_destination_get_string (info->dest), NULL, NULL);
}
static GtkWidget *
@ -301,15 +287,6 @@ e_select_names_popup (ESelectNamesModel *model, GdkEventButton *ev, gint pos)
g_return_if_fail (ev);
g_return_if_fail (0 <= pos);
if (out == NULL) {
out = fopen ("/tmp/evo-debug-select-names-popup", "w");
if (out)
setvbuf (out, NULL, _IONBF, 0);
}
if (out)
fprintf (out, "\n\ne_select_names_popup\n");
e_select_names_model_text_pos (model, pos, &index, NULL, NULL);
if (index < 0 || index >= e_select_names_model_count (model))
return;
@ -328,9 +305,6 @@ e_select_names_popup (ESelectNamesModel *model, GdkEventButton *ev, gint pos)
GTK_SIGNAL_FUNC (popup_info_cleanup),
info);
if (out)
fprintf (out, "doing popup\n");
gnome_popup_menu_do_popup (popup, NULL, NULL, ev, info);
} else {
@ -338,8 +312,4 @@ e_select_names_popup (ESelectNamesModel *model, GdkEventButton *ev, gint pos)
popup_info_free (info);
}
if (out)
fprintf (out, "leaving e_select_names_popup\n\n");
}

View File

@ -125,7 +125,7 @@ dump_model (ESelectNamesTextModel *text_model)
if (out == NULL)
return;
fprintf (out, "\n*** Model State: count=%d\n", e_select_names_model_count (model));
for (i=0; i<e_select_names_model_count (model); ++i)
@ -297,6 +297,7 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
for (i = 0; i < length && text[i]; ++i) {
gint index, start_pos, text_len;
gboolean inside_quote = FALSE;
if (out)
fprintf (out, "processing [%c]\n", text[i]);
@ -306,8 +307,26 @@ e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gcha
if (out)
fprintf (out, "index=%d start_pos=%d text_len=%d\n", index, start_pos, text_len);
if (text[i] == ',' && index >= 0) { /* Is this a quoted or an unquoted comma we are dealing with? */
const EDestination *dest = e_select_names_model_get_destination (source, index);
if (dest) {
const gchar *str = e_destination_get_string (dest);
gint j;
if (out)
fprintf (out, "str=%s pos=%d\n", str, pos);
for (j=0; j<pos-start_pos && str[j]; ++j)
if (str[j] == '"') {
inside_quote = !inside_quote;
if (out)
fprintf (out, "flip to %d at %d\n", start_pos+j, inside_quote);
}
}
if (out)
fprintf (out, inside_quote ? "inside quote\n" : "not inside quote\n");
}
if (text[i] == ',') {
if (text[i] == ',' && !inside_quote) {
/* This is the case of hitting , first thing in an empty entry */
if (index == -1) {

View File

@ -26,79 +26,78 @@
*/
#include <config.h>
#include <ctype.h>
#include <gnome.h>
#include <addressbook/backend/ebook/e-book.h>
#include <addressbook/backend/ebook/e-card.h>
#include "e-contact-editor.h"
#include "e-contact-quick-add.h"
static FILE *out = NULL;
static void
e_card_quick_set_name (ECard *card, const gchar *str)
{
ECardSimple *simple;
g_return_if_fail (card && E_IS_CARD (card));
if (str == NULL)
return;
if (out)
fprintf (out, "quick-set name to \"%s\"\n", str);
if (card->name)
e_card_name_free (card->name);
card->name = e_card_name_from_string (str);
simple = e_card_simple_new (card);
e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FULL_NAME, str);
e_card_simple_sync_card (simple);
gtk_object_unref (GTK_OBJECT (simple));
}
static void
e_card_quick_set_email (ECard *card, const gchar *str)
{
ECardSimple *simple;
g_return_if_fail (card && E_IS_CARD (card));
if (str == NULL)
return;
if (out)
fprintf (out, "quick-set email to \"%s\"\n", str);
if (card->email == NULL) {
card->email = e_list_new ((EListCopyFunc) g_strdup,
(EListFreeFunc) g_free,
NULL);
e_list_append (card->email, str);
} else {
EIterator *iter = e_list_get_iterator (card->email);
e_iterator_reset (iter);
if (e_iterator_is_valid (iter)) {
e_iterator_set (iter, str);
}
}
simple = e_card_simple_new (card);
e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_EMAIL, str);
e_card_simple_sync_card (simple);
gtk_object_unref (GTK_OBJECT (simple));
}
static void
book_ready_cb (EBook *book, EBookStatus status, gpointer user_data)
{
if (status == E_BOOK_STATUS_SUCCESS)
e_book_add_card (book, E_CARD (user_data), NULL, NULL);
gtk_object_unref (GTK_OBJECT (book));
ECard *card = E_CARD (user_data);
EContactQuickAddCallback cb = gtk_object_get_data (GTK_OBJECT (card), "e-contact-quick-add-cb");
gpointer cb_user_data = gtk_object_get_data (GTK_OBJECT (card), "e-contact-quick-add-user-data");
if (status == E_BOOK_STATUS_SUCCESS) {
e_book_add_card (book, card, NULL, NULL);
if (cb)
cb (card, cb_user_data);
} else {
/* Something went wrong... */
if (cb)
cb (NULL, cb_user_data);
gtk_object_unref (GTK_OBJECT (book));
}
}
static void
add_card (ECard *card)
{
EBook *book = e_book_new ();
gchar *filename, *uri;
filename = gnome_util_prepend_user_home ("evolution/local/Contacts/addressbook.db");
uri = g_strdup_printf ("file://%s", filename);
e_book_load_uri (book, uri, book_ready_cb, card);
g_free (filename);
g_free (uri);
e_book_load_local_address_book (book, book_ready_cb, card);
}
/*
* Raise a contact editor with all fields editable, and hook up all signals accordingly.
*/
static void
add_card_cb (EContactEditor *ce, ECard *card, gpointer user_data)
{
@ -108,11 +107,54 @@ add_card_cb (EContactEditor *ce, ECard *card, gpointer user_data)
static void
editor_closed_cb (GtkWidget *w, gpointer user_data)
{
/* w is the contact editor, user_data is an ECard. */
if (user_data)
gtk_object_unref (user_data);
gtk_object_unref (GTK_OBJECT (w));
}
static void
ce_book_found_fields (EBook *book, EBookStatus status, EList *fields, gpointer user_data)
{
ECard *card = E_CARD (user_data);
EContactEditor *contact_editor;
if (status != E_BOOK_STATUS_SUCCESS) {
g_warning ("Couldn't find supported fields for local address book.");
return;
}
contact_editor = e_contact_editor_new (card, TRUE, fields);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"add_card",
GTK_SIGNAL_FUNC (add_card_cb),
NULL);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"editor_closed",
GTK_SIGNAL_FUNC (editor_closed_cb),
user_data);
e_contact_editor_raise (contact_editor);
}
static void
ce_book_ready (EBook *book, EBookStatus status, gpointer user_data)
{
if (status != E_BOOK_STATUS_SUCCESS) {
g_warning ("Couldn't open local address book.");
return;
}
e_book_get_supported_fields (book, ce_book_found_fields, user_data);
}
static void
edit_card (ECard *card)
{
e_book_load_local_address_book (e_book_new (), ce_book_ready, card);
}
static void
clicked_cb (GtkWidget *w, gint button, gpointer user_data)
{
@ -149,19 +191,7 @@ clicked_cb (GtkWidget *w, gint button, gpointer user_data)
} else if (button == 1) {
/* EDIT FULL */
EContactEditor *contact_editor;
contact_editor = e_contact_editor_new (card, TRUE, NULL);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"add_card",
GTK_SIGNAL_FUNC (add_card_cb),
NULL);
gtk_signal_connect (GTK_OBJECT (contact_editor),
"editor_closed",
GTK_SIGNAL_FUNC (editor_closed_cb),
user_data);
e_contact_editor_raise (contact_editor);
edit_card (card);
} else {
/* CANCEL */
@ -249,16 +279,6 @@ e_contact_quick_add (const gchar *name, const gchar *email,
ECard *new_card;
GtkWidget *dialog;
if (out == NULL) {
out = fopen ("/tmp/barnass", "w");
if (out)
setvbuf (out, NULL, _IONBF, 0);
}
if (out)
fprintf (out, "\n name: %s\nemail: %s\n", name, email);
/* We need to have *something* to work with. */
if (name == NULL && email == NULL) {
if (cb)
@ -280,3 +300,85 @@ e_contact_quick_add (const gchar *name, const gchar *email,
gtk_widget_show_all (dialog);
}
void
e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer user_data)
{
gchar *name=NULL, *email=NULL;
const gchar *last_at, *s;
gboolean in_quote;
if (text == NULL) {
e_contact_quick_add (NULL, NULL, cb, user_data);
return;
}
/* Look for things that look like e-mail addresses embedded in text */
in_quote = FALSE;
last_at = NULL;
for (s = text; *s; ++s) {
if (*s == '@' && !in_quote)
last_at = s;
else if (*s == '"')
in_quote = !in_quote;
}
if (last_at == NULL) {
/* No at sign, so we treat it all as the name */
name = g_strdup (text);
} else {
gboolean bad_char = FALSE;
/* walk backwards to whitespace or a < or a quote... */
while (last_at >= text && !bad_char
&& !(isspace ((gint) *last_at) || *last_at == '<' || *last_at == '"')) {
/* Check for some stuff that can't appear in a legal e-mail address. */
if (*last_at == '['
|| *last_at == ']'
|| *last_at == '('
|| *last_at == ')')
bad_char = TRUE;
--last_at;
}
if (last_at < text)
last_at = text;
/* ...and then split the text there */
if (!bad_char) {
if (text < last_at)
name = g_strndup (text, last_at-text);
email = g_strdup (last_at);
}
}
/* If all else has failed, make it the name. */
if (name == NULL && email == NULL)
name = g_strdup (text);
/* Clean up name */
if (name && *name)
g_strstrip (name);
/* Clean up email, remove bracketing <>s */
if (email && *email) {
gboolean changed = FALSE;
g_strstrip (email);
if (*email == '<') {
*email = ' ';
changed = TRUE;
}
if (email[strlen (email)-1] == '>') {
email[strlen (email)-1] = ' ';
changed = TRUE;
}
if (changed)
g_strstrip (email);
}
e_contact_quick_add (name, email, cb, user_data);
g_free (name);
g_free (email);
}

View File

@ -36,5 +36,7 @@ typedef void (*EContactQuickAddCallback) (ECard *new_card, gpointer user_data);
void e_contact_quick_add (const gchar *name, const gchar *email,
EContactQuickAddCallback cb, gpointer user_data);
void e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer user_data);
#endif /* __E_CONTACT_QUICK_ADD_H__ */

View File

@ -1,3 +1,20 @@
2001-03-08 Jon Trowbridge <trow@ximian.com>
* mail-format.c (write_field_row_begin): Added. Table row HTML
broken out into its own function.
(write_subject): Added. Emits the proper HTML for the subject
line.
(write_field_to_stream): #ifdef-ed out of existence.
(write_address): Take a CamelInternetAddress and spit out an
<object> tag with the appropriate <param>s.
* mail-display.c (on_object_requested): Check for an "address"
object. If found, call...
(handle_embedded_address_object): ...this function, which creates
an AddressWidget bonobo control and passes in the necessary info.
I never really realized just quite how much GtkHTML kicks ass
until I figured out how to make this work.
2001-03-08 Jeffrey Stedfast <fejj@ximian.com>
* mail-vtrash.[c,h]: Removed from cvs

View File

@ -603,6 +603,33 @@ get_embedded_for_component (const char *iid, MailDisplay *md)
return embedded;
}
static void
handle_embedded_address_object (GtkHTMLEmbedded *eb)
{
const gchar *name, *email;
GtkWidget *w;
w = bonobo_widget_new_control ("OAFIID:GNOME_Evolution_Addressbook_AddressWidget",
CORBA_OBJECT_NIL);
name = gtk_html_embedded_get_parameter (eb, "name");
email = gtk_html_embedded_get_parameter (eb, "email");
bonobo_widget_set_property (BONOBO_WIDGET (w),
"name", name,
"email", email,
/* Hackish: this is the bg color defined for the HTML table
in mail-format.c. If you change it there, you'd better
change it here as well. */
"background_rgb", 0xeeeeee,
NULL);
gtk_widget_show (w);
gtk_container_add (GTK_CONTAINER (eb), w);
gtk_html_embedded_set_descent (eb, 0);
}
static gboolean
on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
{
@ -621,6 +648,12 @@ on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
char *cid;
cid = eb->classid;
if (!strcmp (cid, "address")) {
handle_embedded_address_object (eb);
return TRUE;
}
if (!strncmp (cid, "popup:", 6))
cid += 6;
if (strncmp (cid, "cid:", 4) != 0)

View File

@ -574,10 +574,43 @@ enum {
WRITE_BOLD=1,
};
static void
write_field_row_begin (const char *description, gint flags, GtkHTML *html, GtkHTMLStream *stream)
{
char *encoded_desc;
int bold = (flags & WRITE_BOLD) == WRITE_BOLD;
encoded_desc = e_utf8_from_gtk_string (GTK_WIDGET (html), description);
mail_html_write (html, stream, "<tr><%s align=right> %s </%s>",
bold ? "th" : "td", encoded_desc, bold ? "th" : "td");
g_free (encoded_desc);
}
static void
write_subject (const char *subject, int flags, GtkHTML *html, GtkHTMLStream *stream)
{
char *encoded_subj;
if (subject)
encoded_subj = e_text_to_html (subject, E_TEXT_TO_HTML_CONVERT_NL | E_TEXT_TO_HTML_CONVERT_URLS);
else
encoded_subj = "";
write_field_row_begin (_("Subject:"), flags, html, stream);
mail_html_write (html, stream, "<td> %s </td> </tr>", encoded_subj);
if (subject)
g_free (encoded_subj);
}
#ifdef USE_OBSOLETE_UNUSED_STUFF_AND_GET_COMPILER_WARNINGS
static void
write_field_to_stream(const char *description, const char *value, int flags, GtkHTML *html, GtkHTMLStream *stream)
{
char *encoded_desc, *encoded_value;
char *encoded_desc, *encoded_value, *embedded_object;
int bold = (flags&WRITE_BOLD) == WRITE_BOLD;
/* The description comes from gettext... */
@ -590,26 +623,45 @@ write_field_to_stream(const char *description, const char *value, int flags, Gtk
mail_html_write(html, stream,
"<tr valign=top><%s align=right>%s</%s>"
"<td>%s</td></tr>", bold ? "th" : "td",
"<td> %s </td></tr>", bold ? "th" : "td",
encoded_desc, bold ? "th" : "td", encoded_value);
g_free (encoded_desc);
g_free (embedded_object);
if (value)
g_free(encoded_value);
}
#endif
static void
write_address(MailDisplay *md, const CamelInternetAddress *addr, const char *name, int flags)
write_address(MailDisplay *md, const CamelInternetAddress *addr, const char *field_name, int flags)
{
char *string;
const char *name, *email;
gint i;
if (addr == NULL)
if (addr == NULL || !camel_internet_address_get (addr, 0, NULL, NULL))
return;
string = camel_address_format((CamelAddress *)addr);
if (string && string[0]) {
write_field_to_stream(name, string, flags, md->html, md->stream);
write_field_row_begin (field_name, flags, md->html, md->stream);
i = 0;
while (camel_internet_address_get (addr, i, &name, &email)) {
if ((name && *name) || (email && *email)) {
mail_html_write (md->html, md->stream, i ? ", " : "<td>");
mail_html_write (md->html, md->stream, "<object classid=\"address\">");
if (name && *name)
mail_html_write (md->html, md->stream, "<param name=\"name\" value=\"%s\"/>", name);
if (email && *email)
mail_html_write (md->html, md->stream, "<param name=\"email\" value=\"%s\"/>", email);
mail_html_write (md->html, md->stream, "</object>");
}
++i;
}
g_free(string);
mail_html_write (md->html, md->stream, "</td></tr>"); /* Finish up the table row */
}
@ -632,9 +684,7 @@ write_headers (CamelMimeMessage *message, MailDisplay *md)
write_address(md, camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_CC),
_("Cc:"), WRITE_BOLD);
write_field_to_stream (_("Subject:"),
camel_mime_message_get_subject (message),
TRUE, md->html, md->stream);
write_subject (camel_mime_message_get_subject (message), WRITE_BOLD, md->html, md->stream);
mail_html_write (md->html, md->stream,
"</table></td></tr></table></td></tr></table></font>");