aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/ChangeLog68
-rw-r--r--addressbook/gui/component/addressbook.c709
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c287
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h17
4 files changed, 693 insertions, 388 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index 76fe653bc8..43b7337b7b 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,71 @@
+2003-12-17 Chris Toshok <toshok@ximian.com>
+
+ * gui/widgets/e-addressbook-view.c (eab_view_class_init): install
+ the "source" property.
+ (eab_view_init): init eav->source to NULL.
+ (eab_view_dispose): disconnect the ecml_changed_id and unref
+ source.
+ (eab_view_new): create the search bar here.
+ (view_preview): c&p the mailer's code mostly for this - this is
+ the toggle listener for the Preview Pane menuitem.
+ (setup_menus): add a listener for the ContactsViewPreview toggle.
+ (eab_view_set_property): sensitize the search bar based on whether
+ or not we have a book set. This makes it so you can't search
+ until the book is loaded. Also add handling for the "source"
+ attribute and print a warning when it's set multiple times
+ (something that's not supported at the moment.)
+ (eab_view_get_property): add "source" case.
+ (search_activated, query_changed, compare_subitems, make_subitems,
+ ecml_changed, get_master_list, connect_master_list_changed): move
+ this here from addressbook.c
+ (eab_view_show_contact_preview): implement - just show or hide the
+ scrolled window.
+ (eab_view_setup_menus): call e_search_bar_set_ui_component here,
+ kind of a hack.
+
+ * gui/widgets/e-addressbook-view.h: make this inherit from GtkVBox
+ instead of GtkEventBox since we'll be packing children. Add a
+ prototype for eab_view_show_contact_preview.
+
+ * gui/component/addressbook.c (get_current_view): return the
+ EABView associated with the active notebook page.
+ (save_contact_cb): use the current view.
+ (view_contact_cb): same.
+ (search_cb): same.
+ (delete_contact_cb): same.
+ (print_cb): same.
+ (print_preview_cb): same.
+ (stop_loading_cb): same.
+ (cut_contacts_cb): same.
+ (copy_contacts_cb): same.
+ (paste_contacts_cb): same.
+ (select_all_contacts_cb): same.
+ (send_contact_cb): same.
+ (send_contact_to_cb): same.
+ (copy_contact_to_cb): same.
+ (move_contact_to_cb): same.
+ (update_command_state): same.
+ (change_view_type): nuke, nothing uses this.
+ (control_activate): use the current view.
+ (control_activate_cb): same.
+ (source_list_changed_cb): new function, remove the notebook pages
+ (and destroy the EABView's) for sources that no longer exist.
+ (addressbook_view_clear): dispose of the uid_to_view hash.
+ (book_open_cb): store the ESource on the EABView too. this
+ function now takes a struct containing both EABView and ESource
+ since we can't store either in the AddressbookView.
+ (set_prop): if we have a view already for this uid, bring it up.
+ otherwise create a new one and start the book loading.
+ (addressbook_search_activated): nuked - this is being moved to
+ e-addressbook-view.
+ (addressbook_query_changed): same.
+ (compare_subitems, make_subitems, ecml_changed,
+ connect_master_list_changed): same.
+ (addressbook_new_control): simplify things a bunch. create a
+ notebook to store the views in. the search/vbox stuff is gone.
+ use e_source_list_new_for_gconf_default, and handle the source
+ list's "changed" signal.
+
2003-12-17 Rodney Dawes <dobey@ximian.com>
* gui/component/autocompletion-config.c:
diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c
index 7d67f447a2..c9c028f5bd 100644
--- a/addressbook/gui/component/addressbook.c
+++ b/addressbook/gui/component/addressbook.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <glib.h>
#include <gtk/gtkvbox.h>
+#include <gtk/gtknotebook.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkmessagedialog.h>
#include <libgnome/gnome-i18n.h>
@@ -37,8 +38,6 @@
#include <bonobo/bonobo-property-bag.h>
#include <gal/util/e-util.h>
-#include "e-util/e-categories-master-list-wombat.h"
-#include "e-util/e-sexp.h"
#include "e-util/e-passwords.h"
#include "evolution-shell-component-utils.h"
@@ -54,8 +53,6 @@
#include "addressbook/util/eab-book-util.h"
#include <libebook/e-book-async.h>
-#include <widgets/misc/e-search-bar.h>
-#include <widgets/misc/e-filter-bar.h>
/* This is used for the addressbook status bar */
#define EVOLUTION_CONTACTS_PROGRESS_IMAGE "evolution-contacts-mini.png"
@@ -69,20 +66,14 @@ static GdkPixbuf *progress_icon = NULL;
typedef struct {
gint refs;
- EABView *view;
- ESearchBar *search;
- gint ecml_changed_id;
- GtkWidget *vbox;
+ GHashTable *uid_to_view;
+ GtkWidget *notebook;
EBook *book;
guint activity_id;
BonoboControl *control;
BonoboPropertyBag *properties;
- GConfClient *gconf_client;
ESourceList *source_list;
- ESource *source;
char *passwd;
- gboolean ignore_search_changes;
- gboolean failed_to_load;
} AddressbookView;
static void addressbook_view_ref (AddressbookView *);
@@ -92,127 +83,149 @@ static void addressbook_authenticate (EBook *book, gboolean previous_failure,
ESource *source, EBookCallback cb, gpointer closure);
static void book_open_cb (EBook *book, EBookStatus status, gpointer closure);
+static void set_status_message (EABView *eav, const char *message, AddressbookView *view);
+static void search_result (EABView *eav, EBookViewStatus status, AddressbookView *view);
+
+static EABView *
+get_current_view (AddressbookView *view)
+{
+ return EAB_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK (view->notebook),
+ gtk_notebook_get_current_page (GTK_NOTEBOOK (view->notebook))));
+}
static void
save_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_save_as(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_save_as(v);
}
static void
view_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_view(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_view(v);
}
static void
search_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
-
- if (view->view)
- gtk_widget_show(eab_search_dialog_new(view->view));
+ EABView *v = get_current_view (view);
+ if (v)
+ gtk_widget_show(eab_search_dialog_new(v));
}
static void
delete_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view) {
- eab_view_delete_selection(view->view);
- }
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_delete_selection(v);
}
static void
print_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_print(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_print(v);
}
static void
print_preview_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_print_preview(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_print_preview(v);
}
static void
stop_loading_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_stop(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_stop(v);
}
static void
cut_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_cut(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_cut(v);
}
static void
copy_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_copy(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_copy(v);
}
static void
paste_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_paste(view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_paste(v);
}
static void
select_all_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_select_all (view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_select_all (v);
}
static void
send_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_send (view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_send (v);
}
static void
send_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_send_to (view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_send_to (v);
}
static void
copy_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_copy_to_folder (view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_copy_to_folder (v);
}
static void
move_contact_to_cb (BonoboUIComponent *uih, void *user_data, const char *path)
{
AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- eab_view_move_to_folder (view->view);
+ EABView *v = get_current_view (view);
+ if (v)
+ eab_view_move_to_folder (v);
}
static void
@@ -222,11 +235,81 @@ forget_passwords_cb (BonoboUIComponent *uih, void *user_data, const char *path)
}
static void
+set_status_message (EABView *eav, const char *message, AddressbookView *view)
+{
+ EActivityHandler *activity_handler = addressbook_component_peek_activity_handler (addressbook_component_peek ());
+
+ if (!message || !*message) {
+ if (view->activity_id != 0) {
+ e_activity_handler_operation_finished (activity_handler, view->activity_id);
+ view->activity_id = 0;
+ }
+ } else if (view->activity_id == 0) {
+ char *clientid = g_strdup_printf ("%p", view);
+
+ if (progress_icon == NULL)
+ progress_icon = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CONTACTS_PROGRESS_IMAGE, NULL);
+
+ view->activity_id = e_activity_handler_operation_started (activity_handler, clientid,
+ progress_icon, message, TRUE);
+
+ g_free (clientid);
+ } else {
+ e_activity_handler_operation_progressing (activity_handler, view->activity_id, message, -1.0);
+ }
+
+}
+
+
+static void
+search_result (EABView *eav, EBookViewStatus status, AddressbookView *view)
+{
+ char *str = NULL;
+
+ switch (status) {
+ case E_BOOK_VIEW_STATUS_OK:
+ return;
+ case E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED:
+ str = _("More cards matched this query than either the server is \n"
+ "configured to return or Evolution is configured to display.\n"
+ "Please make your search more specific or raise the result limit in\n"
+ "the directory server preferences for this addressbook.");
+ break;
+ case E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED:
+ str = _("The time to execute this query exceeded the server limit or the limit\n"
+ "you have configured for this addressbook. Please make your search\n"
+ "more specific or raise the time limit in the directory server\n"
+ "preferences for this addressbook.");
+ break;
+ case E_BOOK_VIEW_ERROR_INVALID_QUERY:
+ str = _("The backend for this addressbook was unable to parse this query.");
+ break;
+ case E_BOOK_VIEW_ERROR_QUERY_REFUSED:
+ str = _("The backend for this addressbook refused to perform this query.");
+ break;
+ case E_BOOK_VIEW_ERROR_OTHER_ERROR:
+ str = _("This query did not complete successfully.");
+ break;
+ }
+
+ if (str) {
+ GtkWidget *dialog;
+ dialog = gtk_message_dialog_new (NULL,
+ 0,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK,
+ str);
+ g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
+ gtk_widget_show (dialog);
+ }
+}
+
+static void
update_command_state (EABView *eav, AddressbookView *view)
{
BonoboUIComponent *uic;
- if (view->view == NULL)
+ if (eav != get_current_view (view))
return;
addressbook_view_ref (view);
@@ -237,82 +320,76 @@ update_command_state (EABView *eav, AddressbookView *view)
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSaveAsVCard",
"sensitive",
- eab_view_can_save_as (view->view) ? "1" : "0", NULL);
+ eab_view_can_save_as (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsView",
"sensitive",
- eab_view_can_view (view->view) ? "1" : "0", NULL);
+ eab_view_can_view (eav) ? "1" : "0", NULL);
/* Print Contact */
bonobo_ui_component_set_prop (uic,
"/commands/ContactsPrint",
"sensitive",
- eab_view_can_print (view->view) ? "1" : "0", NULL);
+ eab_view_can_print (eav) ? "1" : "0", NULL);
/* Print Contact */
bonobo_ui_component_set_prop (uic,
"/commands/ContactsPrintPreview",
"sensitive",
- eab_view_can_print (view->view) ? "1" : "0", NULL);
+ eab_view_can_print (eav) ? "1" : "0", NULL);
/* Delete Contact */
bonobo_ui_component_set_prop (uic,
"/commands/ContactDelete",
"sensitive",
- eab_view_can_delete (view->view) ? "1" : "0", NULL);
+ eab_view_can_delete (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsCut",
"sensitive",
- eab_view_can_cut (view->view) ? "1" : "0", NULL);
+ eab_view_can_cut (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsCopy",
"sensitive",
- eab_view_can_copy (view->view) ? "1" : "0", NULL);
+ eab_view_can_copy (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsPaste",
"sensitive",
- eab_view_can_paste (view->view) ? "1" : "0", NULL);
+ eab_view_can_paste (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSelectAll",
"sensitive",
- eab_view_can_select_all (view->view) ? "1" : "0", NULL);
+ eab_view_can_select_all (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSendContactToOther",
"sensitive",
- eab_view_can_send (view->view) ? "1" : "0", NULL);
+ eab_view_can_send (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsSendMessageToContact",
"sensitive",
- eab_view_can_send_to (view->view) ? "1" : "0", NULL);
+ eab_view_can_send_to (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsMoveToFolder",
"sensitive",
- eab_view_can_move_to_folder (view->view) ? "1" : "0", NULL);
+ eab_view_can_move_to_folder (eav) ? "1" : "0", NULL);
bonobo_ui_component_set_prop (uic,
"/commands/ContactsCopyToFolder",
"sensitive",
- eab_view_can_copy_to_folder (view->view) ? "1" : "0", NULL);
+ eab_view_can_copy_to_folder (eav) ? "1" : "0", NULL);
/* Stop */
bonobo_ui_component_set_prop (uic,
"/commands/ContactStop",
"sensitive",
- eab_view_can_stop (view->view) ? "1" : "0", NULL);
+ eab_view_can_stop (eav) ? "1" : "0", NULL);
}
addressbook_view_unref (view);
}
-static void
-change_view_type (AddressbookView *view, EABViewType view_type)
-{
- g_object_set (view->view, "type", view_type, NULL);
-}
-
static BonoboUIVerb verbs [] = {
BONOBO_UI_UNSAFE_VERB ("ContactsPrint", print_cb),
BONOBO_UI_UNSAFE_VERB ("ContactsPrintPreview", print_preview_cb),
@@ -333,6 +410,7 @@ static BonoboUIVerb verbs [] = {
BONOBO_UI_UNSAFE_VERB ("ContactsMoveToFolder", move_contact_to_cb),
BONOBO_UI_UNSAFE_VERB ("ContactsCopyToFolder", copy_contact_to_cb),
BONOBO_UI_UNSAFE_VERB ("ContactsForgetPasswords", forget_passwords_cb),
+ /* ContactsViewPreview is a toggle */
BONOBO_UI_VERB_END
};
@@ -361,13 +439,12 @@ control_activate (BonoboControl *control,
AddressbookView *view)
{
Bonobo_UIContainer remote_ui_container;
+ EABView *v = get_current_view (view);
remote_ui_container = bonobo_control_get_remote_ui_container (control, NULL);
bonobo_ui_component_set_container (uic, remote_ui_container, NULL);
bonobo_object_release_unref (remote_ui_container, NULL);
- e_search_bar_set_ui_component (view->search, uic);
-
bonobo_ui_component_add_verb_list_with_data (
uic, verbs, view);
@@ -377,13 +454,15 @@ control_activate (BonoboControl *control,
EVOLUTION_UIDIR "/evolution-addressbook.xml",
"evolution-addressbook", NULL);
- eab_view_setup_menus (view->view, uic);
+ if (v)
+ eab_view_setup_menus (v, uic);
e_pixmaps_update (uic, pixmaps);
bonobo_ui_component_thaw (uic, NULL);
- update_command_state (view->view, view);
+ if (v)
+ update_command_state (v, view);
}
static void
@@ -392,39 +471,63 @@ control_activate_cb (BonoboControl *control,
AddressbookView *view)
{
BonoboUIComponent *uic;
+ EABView *v = get_current_view (view);
uic = bonobo_control_get_ui_component (control);
g_assert (uic != NULL);
if (activate) {
control_activate (control, uic, view);
- if (activate && view->view && view->view->model)
- eab_model_force_folder_bar_message (view->view->model);
-
- /* if the book failed to load, we kick off another
- load here */
-
- if (view->failed_to_load && view->source) {
- EBook *book;
-
- book = e_book_new ();
-
- addressbook_load_source (book, view->source, book_open_cb, view);
- }
+ if (activate && v && v->model)
+ eab_model_force_folder_bar_message (v->model);
} else {
bonobo_ui_component_unset_container (uic, NULL);
- eab_view_discard_menus (view->view);
+ eab_view_discard_menus (v);
}
}
-static ECategoriesMasterList *
-get_master_list (void)
+static void
+gather_uids_foreach (char *key,
+ gpointer value,
+ GList **list)
{
- static ECategoriesMasterList *category_list = NULL;
+ (*list) = g_list_prepend (*list, key);
+}
+
+static void
+source_list_changed_cb (ESourceList *source_list, AddressbookView *view)
+{
+ GList *uids, *l;
+ EABView *v;
+
+ uids = NULL;
+ g_hash_table_foreach (view->uid_to_view, (GHFunc)gather_uids_foreach, &uids);
- if (category_list == NULL)
- category_list = e_categories_master_list_wombat_new ();
- return category_list;
+ for (l = uids; l; l = l->next) {
+ char *uid = l->data;
+ if (e_source_list_peek_source_by_uid (source_list, uid)) {
+ /* the source still exists, do nothing */
+ }
+ else {
+ /* the source no longer exists, remove the
+ view and remove it from our hash table. */
+ v = g_hash_table_lookup (view->uid_to_view,
+ uid);
+ g_hash_table_remove (view->uid_to_view, uid);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (view->notebook),
+ gtk_notebook_page_num (GTK_NOTEBOOK (view->notebook),
+ GTK_WIDGET (v)));
+ g_object_unref (v);
+ }
+ }
+
+ /* make sure we've got the current view selected and updated
+ properly */
+ v = get_current_view (view);
+ if (v) {
+ eab_view_setup_menus (v, bonobo_control_get_ui_component (view->control));
+ update_command_state (v, view);
+ }
}
static void
@@ -448,10 +551,9 @@ addressbook_view_clear (AddressbookView *view)
view->source_list = NULL;
}
- if (view->ecml_changed_id != 0) {
- g_signal_handler_disconnect (get_master_list(),
- view->ecml_changed_id);
- view->ecml_changed_id = 0;
+ if (view->uid_to_view) {
+ g_hash_table_destroy (view->uid_to_view);
+ view->uid_to_view = NULL;
}
}
@@ -536,22 +638,37 @@ addressbook_show_load_error_dialog (GtkWidget *parent, ESource *source, EBookSta
g_free (uri);
}
+typedef struct {
+ EABView *view;
+ ESource *source;
+} BookOpenData;
+
static void
book_open_cb (EBook *book, EBookStatus status, gpointer closure)
{
- AddressbookView *view = closure;
+ BookOpenData *data = closure;
+ EABView *view = data->view;
+ ESource *source = data->source;
+
+ g_free (data);
+
+ /* we always set the "source" property on the EABView, since
+ we use it to reload a previously failed book. */
+ g_object_set(view,
+ "source", source,
+ NULL);
if (status == E_BOOK_ERROR_OK) {
- view->failed_to_load = FALSE;
- g_object_set(view->view,
+ g_object_set(view,
"book", book,
NULL);
- view->book = book;
}
else {
- view->failed_to_load = TRUE;
- addressbook_show_load_error_dialog (NULL /* XXX */, view->source, status);
+ addressbook_show_load_error_dialog (NULL /* XXX */, source, status);
}
+
+
+ g_object_unref (source);
}
static void
@@ -561,29 +678,6 @@ destroy_callback(gpointer data, GObject *where_object_was)
addressbook_view_unref (view);
}
-static void
-get_prop (BonoboPropertyBag *bag,
- BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- AddressbookView *view = user_data;
-
- switch (arg_id) {
-
- case PROPERTY_SOURCE_UID_IDX:
- if (view && view->source)
- BONOBO_ARG_SET_STRING (arg, e_source_peek_uid (view->source));
- else
- BONOBO_ARG_SET_STRING (arg, "");
- break;
-
- default:
- g_warning ("Unhandled arg %d\n", arg_id);
- }
-}
-
typedef struct {
EBookCallback cb;
ESource *source;
@@ -765,261 +859,147 @@ set_prop (BonoboPropertyBag *bag,
gpointer user_data)
{
AddressbookView *view = user_data;
- const gchar *uid;
switch (arg_id) {
- case PROPERTY_SOURCE_UID_IDX:
- if (view->book) {
- g_object_unref (view->book);
- view->source = NULL;
- }
-
- view->book = e_book_new ();
-
- view->failed_to_load = FALSE;
+ case PROPERTY_SOURCE_UID_IDX: {
+ ESource *source;
+ const gchar *uid;
uid = BONOBO_ARG_GET_STRING (arg);
- view->source = e_source_list_peek_source_by_uid (view->source_list, uid);
- if (view->source)
- addressbook_load_source (view->book, view->source, book_open_cb, view);
- else
- g_warning ("Could not find source by UID '%s'!", uid);
+ source = e_source_list_peek_source_by_uid (view->source_list, uid);
- break;
-
- default:
- g_warning ("Unhandled arg %d\n", arg_id);
- break;
- }
-}
-
-enum {
- ESB_FULL_NAME,
- ESB_EMAIL,
- ESB_CATEGORY,
- ESB_ANY,
- ESB_ADVANCED
-};
-
-static ESearchBarItem addressbook_search_option_items[] = {
- { N_("Name begins with"), ESB_FULL_NAME, NULL },
- { N_("Email begins with"), ESB_EMAIL, NULL },
- { N_("Category is"), ESB_CATEGORY, NULL }, /* We attach subitems below */
- { N_("Any field contains"), ESB_ANY, NULL },
- { N_("Advanced..."), ESB_ADVANCED, NULL },
- { NULL, -1, NULL }
-};
-
-static void
-addressbook_search_activated (ESearchBar *esb, AddressbookView *view)
-{
- ECategoriesMasterList *master_list;
- char *search_word, *search_query;
- const char *category_name;
- int search_type, subid;
-
- if (view->ignore_search_changes) {
- return;
- }
-
- g_object_get(esb,
- "text", &search_word,
- "item_id", &search_type,
- NULL);
-
- if (search_type == ESB_ADVANCED) {
- gtk_widget_show(eab_search_dialog_new(view->view));
- }
- else {
- if ((search_word && strlen (search_word)) || search_type == ESB_CATEGORY) {
- GString *s = g_string_new ("");
- e_sexp_encode_string (s, search_word);
- switch (search_type) {
- case ESB_ANY:
- search_query = g_strdup_printf ("(contains \"x-evolution-any-field\" %s)",
- s->str);
- break;
- case ESB_FULL_NAME:
- search_query = g_strdup_printf ("(beginswith \"full_name\" %s)",
- s->str);
- break;
- case ESB_EMAIL:
- search_query = g_strdup_printf ("(beginswith \"email\" %s)",
- s->str);
- break;
- case ESB_CATEGORY:
- subid = e_search_bar_get_subitem_id (esb);
-
- if (subid < 0 || subid == G_MAXINT) {
- /* match everything */
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
- } else {
- master_list = get_master_list ();
- category_name = e_categories_master_list_nth (master_list, subid);
- search_query = g_strdup_printf ("(is \"category\" \"%s\")", category_name);
+ if (source) {
+ GtkWidget *uid_view;
+ EBook *book;
+ BookOpenData *data;
+
+ uid_view = g_hash_table_lookup (view->uid_to_view, uid);
+
+ if (uid_view) {
+ /* there is a view for this uid. make
+ sure that the view actually
+ contains an EBook (if it doesn't
+ contain an EBook a previous load
+ failed. try to load it again */
+ g_object_get (uid_view,
+ "book", &book,
+ NULL);
+
+ if (book) {
+ g_object_unref (book);
+ }
+ else {
+ book = e_book_new ();
+
+ g_object_get (uid_view,
+ "source", &source,
+ NULL);
+
+ /* source can be NULL here, if
+ a previous load hasn't
+ actually made it to
+ book_open_cb yet. */
+ if (source) {
+ data = g_new (BookOpenData, 1);
+ data->view = g_object_ref (uid_view);
+ data->source = source; /* transfer the ref we get back from g_object_get */
+
+ addressbook_load_source (book, source, book_open_cb, data);
+ }
}
- break;
- default:
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
- break;
}
- g_string_free (s, TRUE);
- } else
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
+ else {
+ /* we don't have a view for this uid already
+ set up. */
+ GtkWidget *label = gtk_label_new (uid);
- if (search_query)
- g_object_set (view->view,
- "query", search_query,
- NULL);
+ uid_view = eab_view_new ();
- g_free (search_query);
- }
+ gtk_widget_show (uid_view);
+ gtk_widget_show (label);
- g_free (search_word);
-}
+ g_object_set (uid_view, "type", EAB_VIEW_TABLE, NULL);
-static void
-addressbook_query_changed (ESearchBar *esb, AddressbookView *view)
-{
- int search_type;
+ gtk_notebook_append_page (GTK_NOTEBOOK (view->notebook),
+ uid_view,
+ label);
- g_object_get(esb,
- "item_id", &search_type,
- NULL);
+ g_hash_table_insert (view->uid_to_view, g_strdup (uid), uid_view);
- if (search_type == ESB_ADVANCED) {
- gtk_widget_show(eab_search_dialog_new(view->view));
- }
-}
+ g_signal_connect (uid_view, "status_message",
+ G_CALLBACK(set_status_message), view);
-static void
-set_status_message (EABView *eav, const char *message, AddressbookView *view)
-{
- EActivityHandler *activity_handler = addressbook_component_peek_activity_handler (addressbook_component_peek ());
+ g_signal_connect (uid_view, "search_result",
+ G_CALLBACK(search_result), view);
- if (!message || !*message) {
- if (view->activity_id != 0) {
- e_activity_handler_operation_finished (activity_handler, view->activity_id);
- view->activity_id = 0;
- }
- } else if (view->activity_id == 0) {
- char *clientid = g_strdup_printf ("%p", view);
+ g_signal_connect (uid_view, "command_state_change",
+ G_CALLBACK(update_command_state), view);
- if (progress_icon == NULL)
- progress_icon = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CONTACTS_PROGRESS_IMAGE, NULL);
+ book = e_book_new ();
- view->activity_id = e_activity_handler_operation_started (activity_handler, clientid,
- progress_icon, message, TRUE);
+ data = g_new (BookOpenData, 1);
+ data->view = g_object_ref (uid_view);
+ data->source = g_object_ref (source);
- g_free (clientid);
- } else {
- e_activity_handler_operation_progressing (activity_handler, view->activity_id, message, -1.0);
- }
+ addressbook_load_source (book, source, book_open_cb, data);
+ }
-}
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (view->notebook),
+ gtk_notebook_page_num (GTK_NOTEBOOK (view->notebook),
+ uid_view));
-static void
-search_result (EABView *eav, EBookViewStatus status, AddressbookView *view)
-{
- char *str = NULL;
+ /* change menus/toolbars to reflect the new view */
+ eab_view_setup_menus (EAB_VIEW (uid_view), bonobo_control_get_ui_component (view->control));
+ update_command_state (EAB_VIEW (uid_view), view);
+ }
+ else {
+ g_warning ("Could not find source by UID '%s'!", uid);
+ }
- switch (status) {
- case E_BOOK_VIEW_STATUS_OK:
- return;
- case E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED:
- str = _("More cards matched this query than either the server is \n"
- "configured to return or Evolution is configured to display.\n"
- "Please make your search more specific or raise the result limit in\n"
- "the directory server preferences for this addressbook.");
- break;
- case E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED:
- str = _("The time to execute this query exceeded the server limit or the limit\n"
- "you have configured for this addressbook. Please make your search\n"
- "more specific or raise the time limit in the directory server\n"
- "preferences for this addressbook.");
- break;
- case E_BOOK_VIEW_ERROR_INVALID_QUERY:
- str = _("The backend for this addressbook was unable to parse this query.");
- break;
- case E_BOOK_VIEW_ERROR_QUERY_REFUSED:
- str = _("The backend for this addressbook refused to perform this query.");
- break;
- case E_BOOK_VIEW_ERROR_OTHER_ERROR:
- str = _("This query did not complete successfully.");
break;
}
-
- if (str) {
- GtkWidget *dialog;
- dialog = gtk_message_dialog_new (NULL,
- 0,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_OK,
- str);
- g_signal_connect (dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
- gtk_widget_show (dialog);
+ default:
+ g_warning ("Unhandled arg %d\n", arg_id);
+ break;
}
}
-static int
-compare_subitems (const void *a, const void *b)
-{
- const ESearchBarSubitem *subitem_a = a;
- const ESearchBarSubitem *subitem_b = b;
-
- return strcoll (subitem_a->text, subitem_b->text);
-}
-
static void
-make_suboptions (AddressbookView *view)
+get_prop (BonoboPropertyBag *bag,
+ BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
{
- ESearchBarSubitem *subitems, *s;
- ECategoriesMasterList *master_list;
- gint i, N;
+ AddressbookView *view = user_data;
+ EABView *v = get_current_view (view);
+ ESource *source = NULL;
- master_list = get_master_list ();
- N = e_categories_master_list_count (master_list);
- subitems = g_new (ESearchBarSubitem, N+2);
+ switch (arg_id) {
- subitems[0].id = G_MAXINT;
- subitems[0].text = g_strdup (_("Any Category"));
- subitems[0].translate = FALSE;
+ case PROPERTY_SOURCE_UID_IDX:
+ if (v) {
+ g_object_get (v,
+ "source", &source,
+ NULL);
+ }
- for (i=0; i<N; ++i) {
- const char *category = e_categories_master_list_nth (master_list, i);
+ if (source) {
+ BONOBO_ARG_SET_STRING (arg, e_source_peek_uid (source));
- subitems[i+1].id = i;
- subitems[i+1].text = g_strdup (category);
- subitems[i+1].translate = FALSE;
- }
- subitems[N+1].id = -1;
- subitems[N+1].text = NULL;
-
- qsort (subitems + 1, N, sizeof (subitems[0]), compare_subitems);
+ g_object_unref (source);
+ }
+ else {
+ BONOBO_ARG_SET_STRING (arg, "");
+ }
- e_search_bar_set_suboption (view->search, ESB_CATEGORY, subitems);
+ break;
- for (s = subitems; s->id != -1; s++) {
- if (s->text)
- g_free (s->text);
+ default:
+ g_warning ("Unhandled arg %d\n", arg_id);
}
- g_free (subitems);
-}
-
-static void
-ecml_changed (ECategoriesMasterList *ecml, AddressbookView *view)
-{
- make_suboptions (view);
-}
-
-static void
-connect_master_list_changed (AddressbookView *view)
-{
- view->ecml_changed_id =
- g_signal_connect (get_master_list(), "changed",
- G_CALLBACK (ecml_changed), view);
}
BonoboControl *
@@ -1029,36 +1009,18 @@ addressbook_new_control (void)
view = g_new0 (AddressbookView, 1);
view->refs = 1;
- view->ignore_search_changes = FALSE;
- view->vbox = gtk_vbox_new (FALSE, 0);
+ view->uid_to_view = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL);
- g_object_weak_ref (G_OBJECT (view->vbox), destroy_callback, view);
+ view->notebook = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (view->notebook), FALSE);
- /* Create the control. */
- view->control = bonobo_control_new (view->vbox);
-
- view->search = E_SEARCH_BAR (e_search_bar_new (NULL, addressbook_search_option_items));
- make_suboptions (view);
- connect_master_list_changed (view);
-
- gtk_box_pack_start (GTK_BOX (view->vbox), GTK_WIDGET (view->search),
- FALSE, FALSE, 0);
- g_signal_connect (view->search, "query_changed",
- G_CALLBACK (addressbook_query_changed), view);
- g_signal_connect (view->search, "search_activated",
- G_CALLBACK (addressbook_search_activated), view);
-
- view->view = EAB_VIEW(eab_view_new());
- gtk_box_pack_start (GTK_BOX (view->vbox), GTK_WIDGET (view->view),
- TRUE, TRUE, 0);
+ g_object_weak_ref (G_OBJECT (view->notebook), destroy_callback, view);
- /* create the initial view */
- change_view_type (view, EAB_VIEW_TABLE);
+ /* Create the control. */
+ view->control = bonobo_control_new (view->notebook);
- gtk_widget_show (view->vbox);
- gtk_widget_show (GTK_WIDGET(view->view));
- gtk_widget_show (GTK_WIDGET(view->search));
+ gtk_widget_show (view->notebook);
view->properties = bonobo_property_bag_new (get_prop, set_prop, view);
@@ -1071,19 +1033,10 @@ addressbook_new_control (void)
bonobo_object_corba_objref (BONOBO_OBJECT (view->properties)),
NULL);
- g_signal_connect (view->view, "status_message",
- G_CALLBACK(set_status_message), view);
-
- g_signal_connect (view->view, "search_result",
- G_CALLBACK(search_result), view);
-
- g_signal_connect (view->view, "command_state_change",
- G_CALLBACK(update_command_state), view);
-
- view->gconf_client = gconf_client_get_default ();
- view->source_list = e_source_list_new_for_gconf (view->gconf_client,
- "/apps/evolution/addressbook/sources");
- view->source = NULL;
+ view->source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources");
+ g_signal_connect (view->source_list,
+ "changed",
+ G_CALLBACK (source_list_changed_cb), view);
g_signal_connect (view->control, "activate",
G_CALLBACK (control_activate_cb), view);
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index 5303b279be..14179c15af 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -1,8 +1,9 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * e-table-field-chooser.c
+ * e-addressbook-view.c
* Copyright (C) 2000 Ximian, Inc.
* Author: Chris Lahey <clahey@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -42,6 +43,10 @@
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/printing/e-contact-print-envelope.h"
+#include "addressbook/gui/search/e-addressbook-search-dialog.h"
+
+#include "e-util/e-categories-master-list-wombat.h"
+#include "e-util/e-sexp.h"
#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW
#include <gal/widgets/e-treeview-selection-model.h>
@@ -99,13 +104,20 @@ static void selection_get (GtkWidget *invisible, GtkSelectionData *selection_dat
guint info, guint time_stamp, EABView *view);
static void invisible_destroyed (gpointer data, GObject *where_object_was);
-#define PARENT_TYPE GTK_TYPE_EVENT_BOX
-static GtkEventBoxClass *parent_class = NULL;
+static void make_suboptions (EABView *view);
+static void query_changed (ESearchBar *esb, EABView *view);
+static void search_activated (ESearchBar *esb, EABView *view);
+static void connect_master_list_changed (EABView *view);
+static ECategoriesMasterList *get_master_list (void);
+
+#define PARENT_TYPE GTK_TYPE_VBOX
+static GtkVBoxClass *parent_class = NULL;
/* The arguments we take */
enum {
PROP_0,
PROP_BOOK,
+ PROP_SOURCE,
PROP_QUERY,
PROP_TYPE,
};
@@ -133,6 +145,23 @@ static GdkAtom clipboard_atom = GDK_NONE;
static GalViewCollection *collection = NULL;
+enum {
+ ESB_FULL_NAME,
+ ESB_EMAIL,
+ ESB_CATEGORY,
+ ESB_ANY,
+ ESB_ADVANCED
+};
+
+static ESearchBarItem addressbook_search_option_items[] = {
+ { N_("Name begins with"), ESB_FULL_NAME, NULL },
+ { N_("Email begins with"), ESB_EMAIL, NULL },
+ { N_("Category is"), ESB_CATEGORY, NULL }, /* We attach subitems below */
+ { N_("Any field contains"), ESB_ANY, NULL },
+ { N_("Advanced..."), ESB_ADVANCED, NULL },
+ { NULL, -1, NULL }
+};
+
GType
eab_view_get_type (void)
{
@@ -179,6 +208,13 @@ eab_view_class_init (EABViewClass *klass)
E_TYPE_BOOK,
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_SOURCE,
+ g_param_spec_object ("source",
+ _("Source"),
+ /*_( */"XXX blurb" /*)*/,
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE));
+
g_object_class_install_property (object_class, PROP_QUERY,
g_param_spec_string ("query",
_("Query"),
@@ -252,6 +288,7 @@ eab_view_init (EABView *eav)
eav->uic = NULL;
eav->book = NULL;
+ eav->source = NULL;
eav->query = NULL;
eav->invisible = NULL;
@@ -277,6 +314,11 @@ eab_view_dispose (GObject *object)
eav->book = NULL;
}
+ if (eav->source) {
+ g_object_unref (eav->source);
+ eav->source = NULL;
+ }
+
if (eav->query) {
g_free(eav->query);
eav->query = NULL;
@@ -305,6 +347,12 @@ eab_view_dispose (GObject *object)
eav->invisible = NULL;
}
+ if (eav->ecml_changed_id != 0) {
+ g_signal_handler_disconnect (get_master_list(),
+ eav->ecml_changed_id);
+ eav->ecml_changed_id = 0;
+ }
+
if (G_OBJECT_CLASS(parent_class)->dispose)
G_OBJECT_CLASS(parent_class)->dispose(object);
}
@@ -334,9 +382,21 @@ eab_view_new (void)
eav->editable = FALSE;
eav->query = g_strdup (SHOW_ALL_SEARCH);
+ /* create our search bar */
+ eav->search = E_SEARCH_BAR (e_search_bar_new (NULL, addressbook_search_option_items));
+ make_suboptions (eav);
+ connect_master_list_changed (eav);
+ g_signal_connect (eav->search, "query_changed",
+ G_CALLBACK (query_changed), eav);
+ g_signal_connect (eav->search, "search_activated",
+ G_CALLBACK (search_activated), eav);
+ gtk_box_pack_start (GTK_BOX (eav), GTK_WIDGET (eav->search), FALSE, FALSE, 0);
+ gtk_widget_show (GTK_WIDGET (eav->search));
+ gtk_widget_set_sensitive (GTK_WIDGET (eav->search), FALSE);
+
/* create the paned window and contact display */
eav->paned = gtk_vpaned_new ();
- gtk_container_add (GTK_CONTAINER (eav), eav->paned);
+ gtk_box_pack_start (GTK_BOX (eav), eav->paned, TRUE, TRUE, 0);
eav->widget = gtk_label_new ("empty label here");
gtk_container_add (GTK_CONTAINER (eav->paned), eav->widget);
@@ -451,6 +511,26 @@ display_view(GalViewInstance *instance,
}
static void
+view_preview(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, const char *state, void *data)
+{
+ GConfClient *gconf;
+ EABView *view = EAB_VIEW (data);
+
+ if (type != Bonobo_UIComponent_STATE_CHANGED)
+ return;
+
+#if 0
+ gconf = mail_config_get_gconf_client ();
+ gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_preview", state[0] != '0', NULL);
+
+ if (camel_object_meta_set(emfv->folder, "evolution:show_preview", state))
+ camel_object_state_write(emfv->folder);
+#endif
+
+ eab_view_show_contact_preview(view, state[0] != '0');
+}
+
+static void
setup_menus (EABView *view)
{
if (view->book && view->view_instance == NULL) {
@@ -467,6 +547,9 @@ setup_menus (EABView *view)
g_signal_connect(view->view_instance, "display_view",
G_CALLBACK (display_view), view);
}
+
+
+ bonobo_ui_component_add_listener(view->uic, "ContactsViewPreview", view_preview, view);
}
static void
@@ -482,9 +565,12 @@ eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GPar
if (g_value_get_object (value)) {
eav->book = E_BOOK(g_value_get_object (value));
g_object_ref (eav->book);
+ gtk_widget_set_sensitive (GTK_WIDGET (eav->search), TRUE);
}
- else
+ else {
eav->book = NULL;
+ gtk_widget_set_sensitive (GTK_WIDGET (eav->search), FALSE);
+ }
if (eav->view_instance) {
g_object_unref (eav->view_instance);
@@ -498,6 +584,20 @@ eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GPar
setup_menus (eav);
break;
+ case PROP_SOURCE:
+ if (eav->source) {
+ g_warning ("EABView at present does not support multiple writes on the \"source\" property.");
+ break;
+ }
+ else {
+ if (g_value_get_object (value)) {
+ eav->source = E_SOURCE(g_value_get_object (value));
+ g_object_ref (eav->source);
+ }
+ else {
+ eav->source = NULL;
+ }
+ }
case PROP_QUERY:
#if 0 /* This code will mess up ldap a bit. We need to think about the ramifications of this more. */
if ((g_value_get_string (value) == NULL && !strcmp (eav->query, SHOW_ALL_SEARCH)) ||
@@ -533,6 +633,13 @@ eab_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
else
g_value_set_object (value, NULL);
break;
+ case PROP_SOURCE:
+ if (eav->source)
+ g_value_set_object (value, eav->source);
+ else
+ g_value_set_object (value, NULL);
+ break;
+
case PROP_QUERY:
g_value_set_string (value, eav->query);
break;
@@ -1313,6 +1420,159 @@ change_view_type (EABView *view, EABViewType view_type)
command_state_change (view);
}
+
+
+static void
+search_activated (ESearchBar *esb, EABView *v)
+{
+ ECategoriesMasterList *master_list;
+ char *search_word, *search_query;
+ const char *category_name;
+ int search_type, subid;
+
+ g_message ("in search_activated");
+
+ g_object_get(esb,
+ "text", &search_word,
+ "item_id", &search_type,
+ NULL);
+
+ if (search_type == ESB_ADVANCED) {
+ gtk_widget_show(eab_search_dialog_new(v));
+ }
+ else {
+ if ((search_word && strlen (search_word)) || search_type == ESB_CATEGORY) {
+ GString *s = g_string_new ("");
+ e_sexp_encode_string (s, search_word);
+ switch (search_type) {
+ case ESB_ANY:
+ search_query = g_strdup_printf ("(contains \"x-evolution-any-field\" %s)",
+ s->str);
+ break;
+ case ESB_FULL_NAME:
+ search_query = g_strdup_printf ("(beginswith \"full_name\" %s)",
+ s->str);
+ break;
+ case ESB_EMAIL:
+ search_query = g_strdup_printf ("(beginswith \"email\" %s)",
+ s->str);
+ break;
+ case ESB_CATEGORY:
+ subid = e_search_bar_get_subitem_id (esb);
+
+ if (subid < 0 || subid == G_MAXINT) {
+ /* match everything */
+ search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
+ } else {
+ master_list = get_master_list ();
+ category_name = e_categories_master_list_nth (master_list, subid);
+ search_query = g_strdup_printf ("(is \"category\" \"%s\")", category_name);
+ }
+ break;
+ default:
+ search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
+ break;
+ }
+ g_string_free (s, TRUE);
+ } else
+ search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
+
+ if (search_query)
+ g_object_set (v,
+ "query", search_query,
+ NULL);
+
+ g_free (search_query);
+ }
+
+ g_free (search_word);
+}
+
+static void
+query_changed (ESearchBar *esb, EABView *view)
+{
+ int search_type;
+
+ g_object_get(esb,
+ "item_id", &search_type,
+ NULL);
+
+ if (search_type == ESB_ADVANCED) {
+ gtk_widget_show(eab_search_dialog_new(view));
+ }
+}
+
+static int
+compare_subitems (const void *a, const void *b)
+{
+ const ESearchBarSubitem *subitem_a = a;
+ const ESearchBarSubitem *subitem_b = b;
+
+ return strcoll (subitem_a->text, subitem_b->text);
+}
+
+static void
+make_suboptions (EABView *view)
+{
+ ESearchBarSubitem *subitems, *s;
+ ECategoriesMasterList *master_list;
+ gint i, N;
+
+ master_list = get_master_list ();
+ N = e_categories_master_list_count (master_list);
+ subitems = g_new (ESearchBarSubitem, N+2);
+
+ subitems[0].id = G_MAXINT;
+ subitems[0].text = g_strdup (_("Any Category"));
+ subitems[0].translate = FALSE;
+
+ for (i=0; i<N; ++i) {
+ const char *category = e_categories_master_list_nth (master_list, i);
+
+ subitems[i+1].id = i;
+ subitems[i+1].text = g_strdup (category);
+ subitems[i+1].translate = FALSE;
+ }
+ subitems[N+1].id = -1;
+ subitems[N+1].text = NULL;
+
+ qsort (subitems + 1, N, sizeof (subitems[0]), compare_subitems);
+
+ e_search_bar_set_suboption (view->search, ESB_CATEGORY, subitems);
+
+ for (s = subitems; s->id != -1; s++) {
+ if (s->text)
+ g_free (s->text);
+ }
+ g_free (subitems);
+}
+
+static void
+ecml_changed (ECategoriesMasterList *ecml, EABView *view)
+{
+ make_suboptions (view);
+}
+
+static ECategoriesMasterList *
+get_master_list (void)
+{
+ static ECategoriesMasterList *category_list = NULL;
+
+ if (category_list == NULL)
+ category_list = e_categories_master_list_wombat_new ();
+ return category_list;
+}
+
+static void
+connect_master_list_changed (EABView *view)
+{
+ view->ecml_changed_id =
+ g_signal_connect (get_master_list(), "changed",
+ G_CALLBACK (ecml_changed), view);
+}
+
+
+
typedef struct {
GtkWidget *table;
GObject *printable;
@@ -1391,8 +1651,19 @@ e_contact_print_button(GtkDialog *dialog, gint response, gpointer data)
}
void
+eab_view_show_contact_preview (EABView *view, gboolean show)
+{
+ g_return_if_fail (view && E_IS_ADDRESSBOOK_VIEW (view));
+
+ if (show)
+ gtk_widget_show (view->scrolled);
+ else
+ gtk_widget_hide (view->scrolled);
+}
+
+void
eab_view_setup_menus (EABView *view,
- BonoboUIComponent *uic)
+ BonoboUIComponent *uic)
{
g_return_if_fail (view != NULL);
@@ -1405,6 +1676,10 @@ eab_view_setup_menus (EABView *view,
view->uic = uic;
setup_menus (view);
+
+ /* XXX toshok - yeah this really doesn't belong here, but it
+ needs to happen at the same time and takes the uic */
+ e_search_bar_set_ui_component (view->search, uic);
}
/**
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index f819704550..c03c1e3d00 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -20,13 +20,15 @@
#ifndef __EAB_VIEW_H__
#define __EAB_VIEW_H__
-#include <gtk/gtkeventbox.h>
+#include <gtk/gtkvbox.h>
#include <bonobo/bonobo-ui-component.h>
#include <gal/menus/gal-view-instance.h>
#include <libebook/e-book.h>
#include "e-addressbook-model.h"
#include "eab-contact-display.h"
#include "widgets/menus/gal-view-menus.h"
+#include "widgets/misc/e-search-bar.h"
+#include "widgets/misc/e-filter-bar.h"
G_BEGIN_DECLS
@@ -59,7 +61,7 @@ typedef struct _EABViewClass EABViewClass;
struct _EABView
{
- GtkEventBox parent;
+ GtkVBox parent;
/* item specific fields */
EABViewType view_type;
@@ -70,6 +72,7 @@ struct _EABView
GList *clipboard_contacts;
EBook *book;
+ ESource *source;
char *query;
guint editable : 1;
@@ -85,11 +88,16 @@ struct _EABView
GalViewMenus *view_menus;
GalView *current_view;
BonoboUIComponent *uic;
+
+ /* the search bar and related machinery */
+ ESearchBar *search;
+ gint ecml_changed_id;
+
};
struct _EABViewClass
{
- GtkEventBoxClass parent_class;
+ GtkVBoxClass parent_class;
/*
* Signals
@@ -103,9 +111,10 @@ struct _EABViewClass
GtkWidget *eab_view_new (void);
GType eab_view_get_type (void);
+void eab_view_show_contact_preview (EABView *view, gboolean show);
+
void eab_view_setup_menus (EABView *view,
BonoboUIComponent *uic);
-
void eab_view_discard_menus (EABView *view);
void eab_view_save_as (EABView *view);