aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Petter Jansson <hpj@ximian.com>2003-12-17 12:23:36 +0800
committerHans Petter <hansp@src.gnome.org>2003-12-17 12:23:36 +0800
commit216085f3c1c253bb9c3418af484ff571c8111414 (patch)
treea75ab1da17079ff8b8aa37d79d052f765ee2c29a
parent0a13fd3702b265298268ece517c3c99e519c7b79 (diff)
downloadgsoc2013-evolution-216085f3c1c253bb9c3418af484ff571c8111414.tar
gsoc2013-evolution-216085f3c1c253bb9c3418af484ff571c8111414.tar.gz
gsoc2013-evolution-216085f3c1c253bb9c3418af484ff571c8111414.tar.bz2
gsoc2013-evolution-216085f3c1c253bb9c3418af484ff571c8111414.tar.lz
gsoc2013-evolution-216085f3c1c253bb9c3418af484ff571c8111414.tar.xz
gsoc2013-evolution-216085f3c1c253bb9c3418af484ff571c8111414.tar.zst
gsoc2013-evolution-216085f3c1c253bb9c3418af484ff571c8111414.zip
Make a public function that shows an error dialog, which can be used when
2003-12-16 Hans Petter Jansson <hpj@ximian.com> * gui/component/addressbook.c (addressbook_show_load_error_dialog): Make a public function that shows an error dialog, which can be used when a source fails to load. (book_open_cb): Call addressbook_show_load_error_dialog () on error. (set_prop): Don't reuse the book when loading a new source. This was confusing the contact-editor, which gets the book passed in. * gui/contact-editor/e-contact-editor.c (e_contact_editor_class_init): Make "source_book" and "target_book" distinct properties. (new_target_cb): Implement. (source_selected): Implement. (contact_moved_cb): Implement. (contact_added_cb): Handle the case where source_book != target_book as a move - if the add was successful, remove contact from source book. (save_contact): Handle case where source_book != target_book. (delete_cb): "book" renamed to "source_book". (e_contact_editor_init): Set up source_selected signal. (e_contact_editor_dispose): Dispose of both source and target books. (e_contact_editor_new): "book" renamed to "source_book". (e_contact_editor_set_property): If a source book is set, and we don't have a target book, make target_book == source_book. Allow setting target book, and base editability on that. If we're editing an existing contact, treat book change as a change, and update command state. (e_contact_editor_get_property): Allow getting target book. (set_source_field): Indicate the selected book. svn path=/trunk/; revision=23958
-rw-r--r--addressbook/ChangeLog28
-rw-r--r--addressbook/gui/component/addressbook.c129
-rw-r--r--addressbook/gui/component/addressbook.h1
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.c191
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.h3
5 files changed, 259 insertions, 93 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index 8b6e1b0f79..4f2d70de5c 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,5 +1,33 @@
2003-12-16 Hans Petter Jansson <hpj@ximian.com>
+ * gui/component/addressbook.c (addressbook_show_load_error_dialog):
+ Make a public function that shows an error dialog, which can be used
+ when a source fails to load.
+ (book_open_cb): Call addressbook_show_load_error_dialog () on error.
+ (set_prop): Don't reuse the book when loading a new source. This was
+ confusing the contact-editor, which gets the book passed in.
+
+ * gui/contact-editor/e-contact-editor.c (e_contact_editor_class_init):
+ Make "source_book" and "target_book" distinct properties.
+ (new_target_cb): Implement.
+ (source_selected): Implement.
+ (contact_moved_cb): Implement.
+ (contact_added_cb): Handle the case where source_book != target_book as
+ a move - if the add was successful, remove contact from source book.
+ (save_contact): Handle case where source_book != target_book.
+ (delete_cb): "book" renamed to "source_book".
+ (e_contact_editor_init): Set up source_selected signal.
+ (e_contact_editor_dispose): Dispose of both source and target books.
+ (e_contact_editor_new): "book" renamed to "source_book".
+ (e_contact_editor_set_property): If a source book is set, and we don't
+ have a target book, make target_book == source_book. Allow setting
+ target book, and base editability on that. If we're editing an existing
+ contact, treat book change as a change, and update command state.
+ (e_contact_editor_get_property): Allow getting target book.
+ (set_source_field): Indicate the selected book.
+
+2003-12-16 Hans Petter Jansson <hpj@ximian.com>
+
* gui/contact-editor/e-contact-editor.c (set_source_field): Implement.
Makes the source menu reflect the source for the current book.
diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c
index f415c903e9..7d67f447a2 100644
--- a/addressbook/gui/component/addressbook.c
+++ b/addressbook/gui/component/addressbook.c
@@ -473,6 +473,69 @@ addressbook_view_unref (AddressbookView *view)
}
}
+void
+addressbook_show_load_error_dialog (GtkWidget *parent, ESource *source, EBookStatus status)
+{
+ char *label_string;
+ GtkWidget *warning_dialog;
+ GtkWidget *href = NULL;
+ gchar *uri;
+
+ g_return_if_fail (source != NULL);
+
+ uri = e_source_get_uri (source);
+
+ if (!strncmp (uri, "file:", 5)) {
+ label_string =
+ _("We were unable to open this addressbook. Please check that the\n"
+ "path exists and that you have permission to access it.");
+ }
+ else if (!strncmp (uri, "ldap:", 5)) {
+ /* special case for ldap: contact folders so we can tell the user about openldap */
+#if HAVE_LDAP
+ label_string =
+ _("We were unable to open this addressbook. This either\n"
+ "means you have entered an incorrect URI, or the LDAP server\n"
+ "is unreachable.");
+#else
+ label_string =
+ _("This version of Evolution does not have LDAP support\n"
+ "compiled in to it. If you want to use LDAP in Evolution\n"
+ "you must compile the program from the CVS sources after\n"
+ "retrieving OpenLDAP from the link below.\n");
+ href = gnome_href_new ("http://www.openldap.org/", "OpenLDAP at http://www.openldap.org/");
+#endif
+ } else {
+ /* other network folders */
+ label_string =
+ _("We were unable to open this addressbook. This either\n"
+ "means you have entered an incorrect URI, or the server\n"
+ "is unreachable.");
+ }
+
+ warning_dialog = gtk_message_dialog_new (parent ? GTK_WINDOW (parent) : NULL,
+ 0,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CLOSE,
+ label_string,
+ NULL);
+
+ g_signal_connect (warning_dialog,
+ "response",
+ G_CALLBACK (gtk_widget_destroy),
+ warning_dialog);
+
+ gtk_window_set_title (GTK_WINDOW (warning_dialog), _("Unable to open addressbook"));
+
+ if (href)
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (warning_dialog)->vbox),
+ href, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (warning_dialog);
+
+ g_free (uri);
+}
+
static void
book_open_cb (EBook *book, EBookStatus status, gpointer closure)
{
@@ -486,65 +549,8 @@ book_open_cb (EBook *book, EBookStatus status, gpointer closure)
view->book = book;
}
else {
- char *label_string;
- GtkWidget *warning_dialog;
- GtkWidget *href = NULL;
- gchar *uri;
-
view->failed_to_load = TRUE;
-
- uri = e_source_get_uri (view->source);
-
- if (!strncmp (uri, "file:", 5)) {
- label_string =
- _("We were unable to open this addressbook. Please check that the\n"
- "path exists and that you have permission to access it.");
- }
- else if (!strncmp (uri, "ldap:", 5)) {
- /* special case for ldap: contact folders so we can tell the user about openldap */
-#if HAVE_LDAP
- label_string =
- _("We were unable to open this addressbook. This either\n"
- "means you have entered an incorrect URI, or the LDAP server\n"
- "is unreachable.");
-#else
- label_string =
- _("This version of Evolution does not have LDAP support\n"
- "compiled in to it. If you want to use LDAP in Evolution\n"
- "you must compile the program from the CVS sources after\n"
- "retrieving OpenLDAP from the link below.\n");
- href = gnome_href_new ("http://www.openldap.org/", "OpenLDAP at http://www.openldap.org/");
-#endif
- } else {
- /* other network folders */
- label_string =
- _("We were unable to open this addressbook. This either\n"
- "means you have entered an incorrect URI, or the server\n"
- "is unreachable.");
- }
-
- warning_dialog = gtk_message_dialog_new (
- NULL /* XXX */,
- 0,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_CLOSE,
- label_string,
- NULL);
-
- g_signal_connect (warning_dialog,
- "response",
- G_CALLBACK (gtk_widget_destroy),
- warning_dialog);
-
- gtk_window_set_title (GTK_WINDOW (warning_dialog), _("Unable to open addressbook"));
-
- if (href)
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (warning_dialog)->vbox),
- href, FALSE, FALSE, 0);
-
- gtk_widget_show_all (warning_dialog);
-
- g_free (uri);
+ addressbook_show_load_error_dialog (NULL /* XXX */, view->source, status);
}
}
@@ -765,13 +771,12 @@ set_prop (BonoboPropertyBag *bag,
case PROPERTY_SOURCE_UID_IDX:
if (view->book) {
- /* we've already had a uri set on this view, so unload it */
- e_book_async_unload_uri (view->book);
+ g_object_unref (view->book);
view->source = NULL;
- } else {
- view->book = e_book_new ();
}
+ view->book = e_book_new ();
+
view->failed_to_load = FALSE;
uid = BONOBO_ARG_GET_STRING (arg);
diff --git a/addressbook/gui/component/addressbook.h b/addressbook/gui/component/addressbook.h
index fb05287133..16395789e2 100644
--- a/addressbook/gui/component/addressbook.h
+++ b/addressbook/gui/component/addressbook.h
@@ -14,6 +14,7 @@ void addressbook_load_uri (EBook *book, const char *uri, EBook
#endif
void addressbook_load_source (EBook *book, ESource *source, EBookCallback cb, gpointer closure);
void addressbook_load_default_book (EBookCallback open_response, gpointer closure);
+void addressbook_show_load_error_dialog (GtkWidget *parent, ESource *source, EBookStatus status);
BonoboControl *addressbook_new_control (void);
diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c
index 517d21b9bb..71ac2949d9 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/addressbook/gui/contact-editor/e-contact-editor.c
@@ -49,6 +49,7 @@
#include <e-util/e-categories-master-list-wombat.h>
+#include "addressbook/gui/component/addressbook.h"
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/printing/e-contact-print-envelope.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
@@ -105,7 +106,8 @@ static guint contact_editor_signals[LAST_SIGNAL];
/* The arguments we take */
enum {
PROP_0,
- PROP_BOOK,
+ PROP_SOURCE_BOOK,
+ PROP_TARGET_BOOK,
PROP_CONTACT,
PROP_IS_NEW_CONTACT,
PROP_EDITABLE,
@@ -184,9 +186,16 @@ e_contact_editor_class_init (EContactEditorClass *klass)
object_class->get_property = e_contact_editor_get_property;
object_class->dispose = e_contact_editor_dispose;
- g_object_class_install_property (object_class, PROP_BOOK,
- g_param_spec_object ("book",
- _("Book"),
+ g_object_class_install_property (object_class, PROP_SOURCE_BOOK,
+ g_param_spec_object ("source_book",
+ _("Source Book"),
+ /*_( */"XXX blurb" /*)*/,
+ E_TYPE_BOOK,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_TARGET_BOOK,
+ g_param_spec_object ("target_book",
+ _("Target Book"),
/*_( */"XXX blurb" /*)*/,
E_TYPE_BOOK,
G_PARAM_READWRITE));
@@ -503,6 +512,41 @@ address_mailing_changed (GtkWidget *widget, EContactEditor *editor)
#endif
}
+static void
+new_target_cb (EBook *new_book, EBookStatus status, EContactEditor *editor)
+{
+ if (status != E_BOOK_ERROR_OK || new_book == NULL) {
+ GtkWidget *source_option_menu;
+
+ addressbook_show_load_error_dialog (NULL, e_book_get_source (new_book), status);
+
+ source_option_menu = glade_xml_get_widget (editor->gui, "source-option-menu-source");
+ e_source_option_menu_select (E_SOURCE_OPTION_MENU (source_option_menu),
+ e_book_get_source (editor->target_book));
+ g_object_unref (new_book);
+ return;
+ }
+
+ g_object_set (editor, "target_book", new_book, NULL);
+ g_object_unref (new_book);
+}
+
+static void
+source_selected (GtkWidget *source_option_menu, ESource *source, EContactEditor *editor)
+{
+ EBook *new_book;
+
+ if (e_source_equal (e_book_get_source (editor->target_book), source))
+ return;
+
+ if (e_source_equal (e_book_get_source (editor->source_book), source)) {
+ g_object_set (editor, "target_book", editor->source_book, NULL);
+ return;
+ }
+
+ new_book = e_book_new ();
+ addressbook_load_source (new_book, source, (EBookCallback) new_target_cb, editor);
+}
/* This function tells you whether name_to_style will make sense. */
static gboolean
@@ -961,10 +1005,11 @@ categories_clicked(GtkWidget *button, EContactEditor *editor)
typedef struct {
EContactEditor *ce;
gboolean should_close;
+ gchar *new_id;
} EditorCloseStruct;
static void
-contact_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs)
+contact_moved_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
{
EContactEditor *ce = ecs->ce;
gboolean should_close = ecs->should_close;
@@ -972,7 +1017,47 @@ contact_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseSt
gtk_widget_set_sensitive (ce->app, TRUE);
ce->in_async_call = FALSE;
- e_contact_set (ce->contact, E_CONTACT_UID, (char*)id);
+ e_contact_set (ce->contact, E_CONTACT_UID, ecs->new_id);
+
+ g_signal_emit (ce, contact_editor_signals[CONTACT_DELETED], 0,
+ status, ce->contact);
+
+ ce->is_new_contact = FALSE;
+
+ if (should_close) {
+ close_dialog (ce);
+ }
+ else {
+ ce->changed = FALSE;
+
+ g_object_ref (ce->target_book);
+ g_object_unref (ce->source_book);
+ ce->source_book = ce->target_book;
+
+ command_state_changed (ce);
+ }
+
+ g_object_unref (ce);
+ g_free (ecs->new_id);
+ g_free (ecs);
+}
+
+static void
+contact_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs)
+{
+ EContactEditor *ce = ecs->ce;
+ gboolean should_close = ecs->should_close;
+
+ if (ce->source_book != ce->target_book && status == E_BOOK_ERROR_OK &&
+ ce->is_new_contact == FALSE) {
+ ecs->new_id = g_strdup (id);
+ e_book_async_remove_contact (ce->source_book, ce->contact,
+ (EBookCallback) contact_moved_cb, ecs);
+ return;
+ }
+
+ gtk_widget_set_sensitive (ce->app, TRUE);
+ ce->in_async_call = FALSE;
g_signal_emit (ce, contact_editor_signals[CONTACT_ADDED], 0,
status, ce->contact);
@@ -1023,23 +1108,31 @@ contact_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
static void
save_contact (EContactEditor *ce, gboolean should_close)
{
+ EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1);
+
extract_info (ce);
+ if (!ce->target_book)
+ return;
- if (ce->book) {
- EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1);
-
- ecs->ce = ce;
- g_object_ref (ecs->ce);
+ ecs->ce = ce;
+ g_object_ref (ecs->ce);
- ecs->should_close = should_close;
+ ecs->should_close = should_close;
- gtk_widget_set_sensitive (ce->app, FALSE);
- ce->in_async_call = TRUE;
+ gtk_widget_set_sensitive (ce->app, FALSE);
+ ce->in_async_call = TRUE;
+ if (ce->source_book != ce->target_book) {
+ /* Two-step move; add to target, then remove from source */
+ eab_merging_book_add_contact (ce->target_book, ce->contact,
+ (EBookIdCallback) contact_added_cb, ecs);
+ } else {
if (ce->is_new_contact)
- eab_merging_book_add_contact (ce->book, ce->contact, (EBookIdCallback)contact_added_cb, ecs);
+ eab_merging_book_add_contact (ce->target_book, ce->contact,
+ (EBookIdCallback) contact_added_cb, ecs);
else
- eab_merging_book_commit_contact (ce->book, ce->contact, (EBookCallback)contact_modified_cb, ecs);
+ eab_merging_book_commit_contact (ce->target_book, ce->contact,
+ (EBookCallback) contact_modified_cb, ecs);
}
}
@@ -1192,11 +1285,11 @@ delete_cb (GtkWidget *widget, gpointer data)
extract_info (ce);
- if (!ce->is_new_contact && ce->book) {
+ if (!ce->is_new_contact && ce->source_book) {
gtk_widget_set_sensitive (ce->app, FALSE);
ce->in_async_call = TRUE;
- e_book_async_remove_contact (ce->book, contact, (EBookCallback)contact_deleted_cb, ce);
+ e_book_async_remove_contact (ce->source_book, contact, (EBookCallback)contact_deleted_cb, ce);
}
}
@@ -1415,6 +1508,10 @@ e_contact_editor_init (EContactEditor *e_contact_editor)
if (widget && GTK_IS_BUTTON(widget))
g_signal_connect (widget, "clicked",
G_CALLBACK (categories_clicked), e_contact_editor);
+ widget = glade_xml_get_widget (e_contact_editor->gui, "source-option-menu-source");
+ if (widget && E_IS_SOURCE_OPTION_MENU (widget))
+ g_signal_connect (widget, "source_selected",
+ G_CALLBACK (source_selected), e_contact_editor);
/* Construct the app */
bonobo_win = bonobo_window_new ("contact-editor-dialog", _("Contact Editor"));
@@ -1520,9 +1617,14 @@ e_contact_editor_dispose (GObject *object) {
e_contact_editor->contact = NULL;
}
- if (e_contact_editor->book) {
- g_object_unref(e_contact_editor->book);
- e_contact_editor->book = NULL;
+ if (e_contact_editor->source_book) {
+ g_object_unref(e_contact_editor->source_book);
+ e_contact_editor->source_book = NULL;
+ }
+
+ if (e_contact_editor->target_book) {
+ g_object_unref(e_contact_editor->target_book);
+ e_contact_editor->target_book = NULL;
}
if (e_contact_editor->name) {
@@ -1605,7 +1707,7 @@ e_contact_editor_new (EBook *book,
gtk_object_sink (GTK_OBJECT (ce));
g_object_set (ce,
- "book", book,
+ "source_book", book,
"contact", contact,
"is_new_contact", is_new_contact,
"editable", editable,
@@ -1625,11 +1727,33 @@ e_contact_editor_set_property (GObject *object, guint prop_id, const GValue *val
editor = E_CONTACT_EDITOR (object);
switch (prop_id){
- case PROP_BOOK:
- if (editor->book)
- g_object_unref(editor->book);
- editor->book = E_BOOK(g_value_get_object (value));
- g_object_ref (editor->book);
+ case PROP_SOURCE_BOOK:
+ if (editor->source_book)
+ g_object_unref(editor->source_book);
+ editor->source_book = E_BOOK (g_value_get_object (value));
+ g_object_ref (editor->source_book);
+
+ if (!editor->target_book) {
+ editor->target_book = editor->source_book;
+ g_object_ref (editor->target_book);
+ }
+
+ /* XXX more here about editable/etc. */
+ break;
+ case PROP_TARGET_BOOK:
+ if (editor->target_book)
+ g_object_unref(editor->target_book);
+ editor->target_book = E_BOOK (g_value_get_object (value));
+ g_object_ref (editor->target_book);
+
+ e_book_async_get_supported_fields (editor->target_book,
+ (EBookFieldsCallback) supported_fields_cb, editor);
+
+ if (!editor->changed && !editor->is_new_contact) {
+ editor->changed = TRUE;
+ command_state_changed (editor);
+ }
+
/* XXX more here about editable/etc. */
break;
case PROP_CONTACT:
@@ -1691,8 +1815,12 @@ e_contact_editor_get_property (GObject *object, guint prop_id, GValue *value, GP
e_contact_editor = E_CONTACT_EDITOR (object);
switch (prop_id) {
- case PROP_BOOK:
- g_value_set_object (value, e_contact_editor->book);
+ case PROP_SOURCE_BOOK:
+ g_value_set_object (value, e_contact_editor->source_book);
+ break;
+
+ case PROP_TARGET_BOOK:
+ g_value_set_object (value, e_contact_editor->target_book);
break;
case PROP_CONTACT:
@@ -2041,8 +2169,11 @@ set_source_field (EContactEditor *editor)
GtkWidget *source_menu;
ESource *source;
+ if (!editor->target_book)
+ return;
+
source_menu = glade_xml_get_widget (editor->gui, "source-option-menu-source");
- source = e_book_get_source (editor->book);
+ source = e_book_get_source (editor->target_book);
e_source_option_menu_select (E_SOURCE_OPTION_MENU (source_menu), source);
}
diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h
index 7b404945f8..497d6d3a2a 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.h
+++ b/addressbook/gui/contact-editor/e-contact-editor.h
@@ -54,7 +54,8 @@ struct _EContactEditor
GtkObject object;
/* item specific fields */
- EBook *book;
+ EBook *source_book;
+ EBook *target_book;
EContact *contact;
/* UI handler */