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:
committed by
Jon Trowbridge
parent
a9c279d8a6
commit
afe6fc18fc
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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__ */
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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 \
|
||||
|
||||
@ -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();
|
||||
|
||||
414
addressbook/gui/component/e-address-widget.c
Normal file
414
addressbook/gui/component/e-address-widget.c
Normal 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.");
|
||||
}
|
||||
81
addressbook/gui/component/e-address-widget.h
Normal file
81
addressbook/gui/component/e-address-widget.h
Normal 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__ */
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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__ */
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>");
|
||||
|
||||
Reference in New Issue
Block a user