aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/gui
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/gui')
-rw-r--r--addressbook/gui/component/addressbook-view.c134
-rw-r--r--addressbook/gui/widgets/Makefile.am2
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c418
-rw-r--r--addressbook/gui/widgets/eab-popup.c278
-rw-r--r--addressbook/gui/widgets/eab-popup.h151
5 files changed, 627 insertions, 356 deletions
diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c
index 84888f3ff5..48d8499a32 100644
--- a/addressbook/gui/component/addressbook-view.c
+++ b/addressbook/gui/component/addressbook-view.c
@@ -60,6 +60,7 @@
#include "addressbook/gui/merging/eab-contact-merging.h"
#include "addressbook/printing/e-contact-print.h"
#include "addressbook/util/eab-book-util.h"
+#include "addressbook/gui/widgets/eab-popup.h"
#define PARENT_TYPE G_TYPE_OBJECT
static GObjectClass *parent_class = NULL;
@@ -614,45 +615,10 @@ load_primary_selection (AddressbookView *view)
}
/* Folder popup menu callbacks */
-
-static void
-add_popup_menu_item (GtkMenu *menu, const char *label, const char *pixmap,
- GCallback callback, gpointer user_data, gboolean sensitive)
-{
- GtkWidget *item, *image;
-
- if (pixmap) {
- item = gtk_image_menu_item_new_with_label (label);
-
- /* load the image */
- if (g_file_test (pixmap, G_FILE_TEST_EXISTS))
- image = gtk_image_new_from_file (pixmap);
- else
- image = gtk_image_new_from_stock (pixmap, GTK_ICON_SIZE_MENU);
-
- if (image) {
- gtk_widget_show (image);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- }
- } else {
- item = gtk_menu_item_new_with_label (label);
- }
-
- if (callback)
- g_signal_connect (G_OBJECT (item), "activate", callback, user_data);
-
- if (!sensitive)
- gtk_widget_set_sensitive (item, FALSE);
-
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-}
-
typedef struct {
AddressbookView *view;
ESource *selected_source;
GtkWidget *toplevel;
- GtkWidget *dialog;
} BookRemovedClosure;
static void
@@ -662,7 +628,6 @@ book_removed (EBook *book, EBookStatus status, gpointer data)
AddressbookView *view = closure->view;
AddressbookViewPrivate *priv = view->priv;
ESource *source = closure->selected_source;
- GtkWidget *dialog = closure->dialog;
GtkWidget *toplevel = closure->toplevel;
g_free (closure);
@@ -685,73 +650,54 @@ book_removed (EBook *book, EBookStatus status, gpointer data)
"addressbook:remove-addressbook",
NULL);
}
-
- gtk_widget_destroy (dialog);
}
static void
-delete_addressbook_cb (GtkWidget *widget, AddressbookView *view)
+delete_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data)
{
+ AddressbookView *view = data;
AddressbookViewPrivate *priv = view->priv;
ESource *selected_source;
- GtkWidget *dialog;
EBook *book;
GError *error = NULL;
+ GtkWindow *toplevel;
selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
if (!selected_source)
return;
- /* Create the confirmation dialog */
- dialog = gtk_message_dialog_new (
- GTK_WINDOW (gtk_widget_get_toplevel (widget)),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- _("Address book '%s' will be removed. Are you sure you want to continue?"),
- e_source_peek_name (selected_source));
-#if !GTK_CHECK_VERSION (2,4,0)
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-#endif
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_YES) {
- gtk_widget_destroy (dialog);
+ toplevel = (GtkWindow *)gtk_widget_get_toplevel(ep->target->widget);
+
+ if (e_error_run(toplevel, "addressbook:ask-delete-addressbook", e_source_peek_name(selected_source)) != GTK_RESPONSE_YES)
return;
- }
/* Remove local data */
book = e_book_new (selected_source, &error);
if (book) {
BookRemovedClosure *closure = g_new (BookRemovedClosure, 1);
- closure->toplevel = gtk_widget_get_toplevel (widget);
+ closure->toplevel = (GtkWidget *)toplevel;
closure->view = view;
closure->selected_source = selected_source;
- closure->dialog = dialog;
if (e_book_async_remove (book, book_removed, closure)) {
- e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
- "addressbook:remove-addressbook",
- NULL);
-
+ e_error_run (toplevel, "addressbook:remove-addressbook", NULL);
g_free (closure);
-
g_object_unref (book);
}
}
-
- gtk_widget_set_sensitive (dialog, FALSE);
}
static void
-new_addressbook_cb (GtkWidget *widget, AddressbookView *view)
+new_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data)
{
- addressbook_config_create_new_source (gtk_widget_get_toplevel (widget));
+ addressbook_config_create_new_source (gtk_widget_get_toplevel(ep->target->widget));
}
static void
-edit_addressbook_cb (GtkWidget *widget, AddressbookView *view)
+edit_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data)
{
+ AddressbookView *view = data;
AddressbookViewPrivate *priv = view->priv;
ESource *selected_source;
const char *uid;
@@ -769,7 +715,7 @@ edit_addressbook_cb (GtkWidget *widget, AddressbookView *view)
char *uid_copy = g_strdup (uid);
closure = g_new (EditorUidClosure, 1);
- closure->editor = addressbook_config_edit_source (gtk_widget_get_toplevel (widget), selected_source);
+ closure->editor = addressbook_config_edit_source (gtk_widget_get_toplevel(ep->target->widget), selected_source);
closure->uid = uid_copy;
closure->view = view;
@@ -794,25 +740,41 @@ primary_source_selection_changed_callback (ESourceSelector *selector,
save_primary_selection (view);
}
+static EPopupItem abv_source_popups[] = {
+ { E_POPUP_ITEM, "10.new", N_("New Address Book"), new_addressbook_cb, NULL, NULL, 0 },
+ { E_POPUP_ITEM, "20.delete", N_("Delete"), delete_addressbook_cb, NULL, "stock_delete", EAB_POPUP_SOURCE_USER|EAB_POPUP_SOURCE_PRIMARY },
+ { E_POPUP_ITEM, "30.properties", N_("Properties..."), edit_addressbook_cb, NULL, NULL, EAB_POPUP_SOURCE_PRIMARY },
+};
static void
-fill_popup_menu_callback (ESourceSelector *selector, GtkMenu *menu, AddressbookView *view)
+abv_source_popup_free(EPopup *ep, GSList *list, void *data)
{
- AddressbookViewPrivate *priv = view->priv;
- gboolean sensitive;
- gboolean local_addressbook;
- ESource *selected_source;
- char *uri;
+ g_slist_free(list);
+}
- selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector));
- sensitive = selected_source ? TRUE : FALSE;
+static gboolean
+popup_event_callback(ESourceSelector *selector, ESource *source, GdkEventButton *event, AddressbookView *view)
+{
+ EABPopup *ep;
+ EABPopupTargetSource *t;
+ GSList *menus = NULL;
+ int i;
+ GtkMenu *menu;
- uri = e_source_peek_relative_uri (selected_source);
- local_addressbook = (uri && !strcmp ("system", uri));
-
- add_popup_menu_item (menu, _("New Address Book"), NULL, G_CALLBACK (new_addressbook_cb), view, TRUE);
- add_popup_menu_item (menu, _("Delete"), GTK_STOCK_DELETE, G_CALLBACK (delete_addressbook_cb), view, sensitive && !local_addressbook);
- add_popup_menu_item (menu, _("Properties..."), NULL, G_CALLBACK (edit_addressbook_cb), view, sensitive);
+ ep = eab_popup_new("com.novell.evolution.addressbook.source.popup");
+ t = eab_popup_target_new_source(ep, selector);
+ t->target.widget = (GtkWidget *)view->priv->notebook;
+
+ for (i=0;i<sizeof(abv_source_popups)/sizeof(abv_source_popups[0]);i++)
+ menus = g_slist_prepend(menus, &abv_source_popups[i]);
+
+ e_popup_add_items((EPopup *)ep, menus, abv_source_popup_free, view);
+
+ /* visibility is disabled, we only disable menu items */
+ menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0, t->target.mask);
+ gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
+
+ return TRUE;
}
static gboolean
@@ -978,15 +940,13 @@ selector_tree_drag_data_received (GtkWidget *widget,
{
GtkTreePath *path = NULL;
GtkTreeViewDropPosition pos;
- gpointer source, target = NULL;
+ gpointer target = NULL;
GtkTreeModel *model;
GtkTreeIter iter;
gboolean success = FALSE;
-
EBook *source_book, *target_book;
MergeContext *merge_context;
GList *contactlist;
- GList *l;
if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget),
x, y, &path, &pos))
@@ -1170,8 +1130,8 @@ addressbook_view_init (AddressbookView *view)
g_signal_connect_object (priv->selector, "primary_selection_changed",
G_CALLBACK (primary_source_selection_changed_callback),
G_OBJECT (view), 0);
- g_signal_connect_object (priv->selector, "fill_popup_menu",
- G_CALLBACK (fill_popup_menu_callback),
+ g_signal_connect_object (priv->selector, "popup_event",
+ G_CALLBACK (popup_event_callback),
G_OBJECT (view), 0);
load_primary_selection (view);
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index 6842ce14d5..504702b277 100644
--- a/addressbook/gui/widgets/Makefile.am
+++ b/addressbook/gui/widgets/Makefile.am
@@ -44,6 +44,8 @@ libeabwidgets_la_SOURCES = \
eab-contact-display.h \
eab-gui-util.c \
eab-gui-util.h \
+ eab-popup.c \
+ eab-popup.h \
eab-popup-control.c \
eab-popup-control.h \
eab-vcard-control.c \
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index e4fe2e287a..f716ea8624 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -29,7 +29,6 @@
#include <gtk/gtkscrolledwindow.h>
#include <gal/e-table/e-table-scrolled.h>
#include <gal/e-table/e-table-model.h>
-#include <gal/widgets/e-popup-menu.h>
#include <gal/widgets/e-gui-utils.h>
#include <gal/menus/gal-view-factory-etable.h>
#include <gal/menus/gal-view-etable.h>
@@ -44,6 +43,7 @@
#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 "addressbook/gui/widgets/eab-popup.h"
#include "e-util/e-categories-master-list-wombat.h"
#include "e-util/e-sexp.h"
@@ -771,7 +771,6 @@ get_selection_model (EABView *view)
/* Popup menu stuff */
typedef struct {
EABView *view;
- EPopupMenu *submenu;
gpointer closure;
} ContactAndBook;
@@ -781,371 +780,221 @@ contact_and_book_get_selection_model (ContactAndBook *contact_and_book)
return get_selection_model (contact_and_book->view);
}
-static void
-contact_and_book_free (ContactAndBook *contact_and_book)
-{
- EABView *view = contact_and_book->view;
- ESelectionModel *selection;
-
- if (contact_and_book->submenu)
- gal_view_instance_free_popup_menu (view->view_instance,
- contact_and_book->submenu);
-
- selection = contact_and_book_get_selection_model (contact_and_book);
- if (selection)
- e_selection_model_right_click_up(selection);
-
- g_object_unref (view);
-}
-
-static void
-get_contact_list_1(gint model_row,
- gpointer closure)
-{
- ContactAndBook *contact_and_book;
- GList **list;
- EABView *view;
- EContact *contact;
-
- contact_and_book = closure;
- list = contact_and_book->closure;
- view = contact_and_book->view;
-
- contact = eab_model_get_contact(view->model, model_row);
- *list = g_list_prepend(*list, contact);
-}
-
static GList *
-get_contact_list (ContactAndBook *contact_and_book)
+get_contact_list (EABPopupTargetSelect *t)
{
GList *list = NULL;
- ESelectionModel *selection;
+ int i;
- selection = contact_and_book_get_selection_model (contact_and_book);
-
- if (selection) {
- contact_and_book->closure = &list;
- e_selection_model_foreach (selection, get_contact_list_1, contact_and_book);
- }
+ for (i=0;i<t->cards->len;i++)
+ list = g_list_prepend(list, t->cards->pdata[i]);
return list;
}
static void
-has_email_address_1(gint model_row,
- gpointer closure)
+save_as (EPopup *ep, EPopupItem *pitem, void *data)
{
- ContactAndBook *contact_and_book;
- gboolean *has_email;
- EABView *view;
- const EContact *contact;
- GList *email;
-
- contact_and_book = closure;
- has_email = contact_and_book->closure;
- view = contact_and_book->view;
+ /*ContactAndBook *contact_and_book = data;*/
+ GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target);
- if (*has_email)
- return;
-
- contact = eab_model_contact_at(view->model, model_row);
-
- email = e_contact_get (E_CONTACT (contact), E_CONTACT_EMAIL);
-
- if (g_list_length (email) > 0)
- *has_email = TRUE;
-
- g_list_foreach (email, (GFunc)g_free, NULL);
- g_list_free (email);
-}
-
-static gboolean
-get_has_email_address (ContactAndBook *contact_and_book)
-{
- ESelectionModel *selection;
- gboolean has_email = FALSE;
-
- selection = contact_and_book_get_selection_model (contact_and_book);
-
- if (selection) {
- contact_and_book->closure = &has_email;
- e_selection_model_foreach (selection, has_email_address_1, contact_and_book);
- }
-
- return has_email;
-}
-
-static void
-save_as (GtkWidget *widget, ContactAndBook *contact_and_book)
-{
- GList *contacts = get_contact_list (contact_and_book);
if (contacts) {
eab_contact_list_save(_("Save as VCard..."), contacts, NULL);
- e_free_object_list(contacts);
+ g_list_free(contacts);
}
}
static void
-send_as (GtkWidget *widget, ContactAndBook *contact_and_book)
+send_as (EPopup *ep, EPopupItem *pitem, void *data)
{
- GList *contacts = get_contact_list (contact_and_book);
+ /*ContactAndBook *contact_and_book = data;*/
+ GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target);
+
if (contacts) {
eab_send_contact_list(contacts, EAB_DISPOSITION_AS_ATTACHMENT);
- e_free_object_list(contacts);
+ g_list_free(contacts);
}
}
static void
-send_to (GtkWidget *widget, ContactAndBook *contact_and_book)
-
+send_to (EPopup *ep, EPopupItem *pitem, void *data)
{
- GList *contacts = get_contact_list (contact_and_book);
+ /*ContactAndBook *contact_and_book = data;*/
+ GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target);
if (contacts) {
eab_send_contact_list(contacts, EAB_DISPOSITION_AS_TO);
- e_free_object_list(contacts);
+ g_list_free(contacts);
}
}
static void
-print (GtkWidget *widget, ContactAndBook *contact_and_book)
+print (EPopup *ep, EPopupItem *pitem, void *data)
{
- GList *contacts = get_contact_list (contact_and_book);
- if (contacts) {
- if (contacts->next)
- gtk_widget_show(e_contact_print_contact_list_dialog_new(contacts));
- else
- gtk_widget_show(e_contact_print_contact_dialog_new(contacts->data));
- e_free_object_list(contacts);
- }
-}
+ /*ContactAndBook *contact_and_book = data;*/
+ EABPopupTargetSelect *t = (EABPopupTargetSelect *)ep->target;
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
-static void
-print_envelope (GtkWidget *widget, ContactAndBook *contact_and_book)
-{
- GList *cards = get_card_list (contact_and_book);
- if (cards) {
- gtk_widget_show(e_contact_list_print_envelope_dialog_new(contact_and_book->card));
- e_free_object_list(cards);
+ if (t->cards->len == 1) {
+ gtk_widget_show(e_contact_print_contact_dialog_new(t->cards->pdata[0]));
+ } else {
+ GList *contacts = get_contact_list(t);
+
+ gtk_widget_show(e_contact_print_contact_list_dialog_new(contacts));
+ g_list_free(contacts);
}
}
-#endif
static void
-copy (GtkWidget *widget, ContactAndBook *contact_and_book)
+copy (EPopup *ep, EPopupItem *pitem, void *data)
{
+ ContactAndBook *contact_and_book = data;
+
eab_view_copy (contact_and_book->view);
}
static void
-paste (GtkWidget *widget, ContactAndBook *contact_and_book)
+paste (EPopup *ep, EPopupItem *pitem, void *data)
{
+ ContactAndBook *contact_and_book = data;
+
eab_view_paste (contact_and_book->view);
}
static void
-cut (GtkWidget *widget, ContactAndBook *contact_and_book)
+cut (EPopup *ep, EPopupItem *pitem, void *data)
{
+ ContactAndBook *contact_and_book = data;
+
eab_view_cut (contact_and_book->view);
}
static void
-delete (GtkWidget *widget, ContactAndBook *contact_and_book)
+delete (EPopup *ep, EPopupItem *pitem, void *data)
{
- if (eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(contact_and_book->view->widget)))) {
- EBook *book;
- GList *list = get_contact_list(contact_and_book);
- GList *iterator;
- gboolean bulk_remove = FALSE;
+ ContactAndBook *contact_and_book = data;
- bulk_remove = e_book_check_static_capability (contact_and_book->view->model->book,
- "bulk-remove");
-
- g_object_get(contact_and_book->view->model,
- "book", &book,
- NULL);
-
- if (bulk_remove) {
- GList *ids = NULL;
-
- for (iterator = list; iterator; iterator = iterator->next) {
- EContact *contact = iterator->data;
- ids = g_list_prepend (ids, (char*)e_contact_get_const (contact, E_CONTACT_UID));
- }
-
- /* Remove the cards all at once. */
- /* XXX no callback specified... ugh */
- e_book_async_remove_contacts (book,
- ids,
- NULL,
- NULL);
-
- g_list_free (ids);
- }
- else {
- for (iterator = list; iterator; iterator = iterator->next) {
- EContact *contact = iterator->data;
- /* Remove the card. */
- /* XXX no callback specified... ugh */
- e_book_async_remove_contact (book,
- contact,
- NULL,
- NULL);
- }
- }
- e_free_object_list(list);
- g_object_unref(book);
- }
+ eab_view_delete_selection(contact_and_book->view);
}
static void
-copy_to_folder (GtkWidget *widget, ContactAndBook *contact_and_book)
+copy_to_folder (EPopup *ep, EPopupItem *pitem, void *data)
{
+ ContactAndBook *contact_and_book = data;
+
eab_view_copy_to_folder (contact_and_book->view);
}
static void
-move_to_folder (GtkWidget *widget, ContactAndBook *contact_and_book)
+move_to_folder (EPopup *ep, EPopupItem *pitem, void *data)
{
- eab_view_move_to_folder (contact_and_book->view);
-}
+ ContactAndBook *contact_and_book = data;
-static void
-free_popup_info (GtkWidget *w, ContactAndBook *contact_and_book)
-{
- contact_and_book_free (contact_and_book);
+ eab_view_move_to_folder (contact_and_book->view);
}
static void
-new_card (GtkWidget *widget, ContactAndBook *contact_and_book)
+new_card (EPopup *ep, EPopupItem *pitem, void *data)
{
- EBook *book;
+ /*ContactAndBook *contact_and_book = data;*/
EContact *contact = e_contact_new();
- g_object_get(contact_and_book->view->model,
- "book", &book,
- NULL);
-
- eab_show_contact_editor (book, contact, TRUE, TRUE);
- g_object_unref (book);
+ eab_show_contact_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE);
g_object_unref (contact);
}
static void
-new_list (GtkWidget *widget, ContactAndBook *contact_and_book)
+new_list (EPopup *ep, EPopupItem *pitem, void *data)
{
- EBook *book;
+ /*ContactAndBook *contact_and_book = data;*/
EContact *contact = e_contact_new ();
- g_object_get(contact_and_book->view->model,
- "book", &book,
- NULL);
- eab_show_contact_list_editor (book, contact, TRUE, TRUE);
- g_object_unref(book);
+ eab_show_contact_list_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE);
g_object_unref(contact);
}
-#if 0
+static EPopupItem eabv_popup_items[] = {
+ { E_POPUP_ITEM, "10.new", N_("New Contact..."), new_card, NULL, "stock_contact", EAB_POPUP_SELECT_EDITABLE},
+ { E_POPUP_ITEM, "15.newlist", N_("New Contact List..."), new_list, NULL, "stock_contact-list", EAB_POPUP_SELECT_EDITABLE },
+
+ { E_POPUP_BAR, "20.bar" },
+ { E_POPUP_ITEM, "30.saveas", N_("Save as VCard..."), save_as, NULL, "stock_save-as", EAB_POPUP_SELECT_MANY },
+ { E_POPUP_ITEM, "40.forward", N_("Forward Contact"), send_as, NULL, "stock_mail-forward", EAB_POPUP_SELECT_MANY },
+ { E_POPUP_ITEM, "50.mailto", N_("Send Message to Contact"), send_to, NULL, "stock_mail-send", EAB_POPUP_SELECT_MANY|EAB_POPUP_SELECT_EMAIL },
+ { E_POPUP_ITEM, "60.print", N_("Print"), print, NULL, "stock_print", EAB_POPUP_SELECT_MANY },
+
+ { E_POPUP_BAR, "70.bar" },
+ { E_POPUP_ITEM, "80.copyto", N_("Copy to Address Book..."), copy_to_folder, NULL, NULL, EAB_POPUP_SELECT_MANY },
+ { E_POPUP_ITEM, "90.moveto", N_("Move to Address Book..."), move_to_folder, NULL, NULL, EAB_POPUP_SELECT_MANY|EAB_POPUP_SELECT_EDITABLE },
+
+ { E_POPUP_BAR, "a0.bar" },
+ { E_POPUP_BAR, "b0.cut", N_("Cut"), cut, NULL, "stock_cut", EAB_POPUP_SELECT_MANY|EAB_POPUP_SELECT_EDITABLE },
+ { E_POPUP_ITEM, "c0.copy", N_("Copy"), copy, NULL, "stock_copy", EAB_POPUP_SELECT_MANY },
+ { E_POPUP_ITEM, "d0.paste", N_("Paste"), paste, NULL, "stock_paste", EAB_POPUP_SELECT_EDITABLE },
+ { E_POPUP_ITEM, "e0.delete", N_("Delete"), delete, NULL, "stock_delete", EAB_POPUP_SELECT_EDITABLE|EAB_POPUP_SELECT_MANY },
+};
+
static void
-sources (GtkWidget *widget, ContactAndBook *contact_and_book)
+get_card_1(gint model_row, void *data)
{
- BonoboControl *control;
- GNOME_Evolution_ShellView shell_view;
- CORBA_Environment ev;
+ ContactAndBook *contact_and_book = data;
+ EContact *contact;
- control = g_object_get_data (G_OBJECT (gcal), "control");
- if (control == NULL)
- return;
+ contact = eab_model_get_contact(contact_and_book->view->model, model_row);
+ if (contact)
+ g_ptr_array_add((GPtrArray *)contact_and_book->closure, contact);
+}
- shell_view = get_shell_view_interface (control);
- if (shell_view == CORBA_OBJECT_NIL)
- return;
+static void
+eabv_popup_free(EPopup *ep, GSList *list, void *data)
+{
+ ContactAndBook *cab = data;
+ ESelectionModel *selection;
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_ShellView_showSettings (shell_view, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("control_util_show_settings(): Could not show settings");
+ /* NB: this looks strange to me */
+ selection = contact_and_book_get_selection_model(cab);
+ if (selection)
+ e_selection_model_right_click_up(selection);
- CORBA_exception_free (&ev);
+ g_slist_free(list);
+ g_object_unref(cab->view);
+ g_free(cab);
}
-#endif
-
-#define POPUP_READONLY_MASK 0x1
-#define POPUP_NOSELECTION_MASK 0x2
-#define POPUP_NOEMAIL_MASK 0x4
static void
do_popup_menu(EABView *view, GdkEvent *event)
{
+ EABPopup *ep;
+ EABPopupTargetSelect *t;
+ GSList *menus = NULL;
+ int i;
+ GtkMenu *menu;
+ GPtrArray *cards = g_ptr_array_new();
ContactAndBook *contact_and_book;
- GtkMenu *popup;
- EPopupMenu *submenu = NULL;
ESelectionModel *selection_model;
- gboolean selection = FALSE;
-
- EPopupMenu menu[] = {
- E_POPUP_ITEM (N_("New Contact..."), G_CALLBACK(new_card), POPUP_READONLY_MASK),
- E_POPUP_ITEM (N_("New Contact List..."), G_CALLBACK(new_list), POPUP_READONLY_MASK),
- E_POPUP_SEPARATOR,
-#if 0
- E_POPUP_ITEM (N_("Go to Folder..."), G_CALLBACK (goto_folder), 0),
- E_POPUP_ITEM (N_("Import..."), G_CALLBACK (import), POPUP_READONLY_MASK),
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Search for Contacts..."), G_CALLBACK (search), 0),
- E_POPUP_ITEM (N_("Address Book Sources..."), G_CALLBACK (sources), 0),
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Pilot Settings..."), G_CALLBACK (pilot_settings), 0),
-#endif
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Save as VCard..."), G_CALLBACK(save_as), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Forward Contact"), G_CALLBACK(send_as), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Send Message to Contact"), G_CALLBACK(send_to), POPUP_NOSELECTION_MASK | POPUP_NOEMAIL_MASK),
- E_POPUP_ITEM (N_("Print"), G_CALLBACK(print), POPUP_NOSELECTION_MASK),
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
- E_POPUP_ITEM (N_("Print Envelope"), G_CALLBACK(print_envelope), POPUP_NOSELECTION_MASK),
-#endif
- E_POPUP_SEPARATOR,
-
- E_POPUP_ITEM (N_("Copy to Address Book..."), G_CALLBACK(copy_to_folder), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Move to Address Book..."), G_CALLBACK(move_to_folder), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_SEPARATOR,
-
- E_POPUP_ITEM (N_("Cut"), G_CALLBACK (cut), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Copy"), G_CALLBACK (copy), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Paste"), G_CALLBACK (paste), POPUP_READONLY_MASK),
- E_POPUP_ITEM (N_("Delete"), G_CALLBACK(delete), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_SEPARATOR,
-
-#if 0
- E_POPUP_SUBMENU (N_("Current View"), submenu = gal_view_instance_get_popup_menu (view->view_instance), 0),
-#endif
- E_POPUP_TERMINATOR
- };
contact_and_book = g_new(ContactAndBook, 1);
contact_and_book->view = view;
- contact_and_book->submenu = submenu;
+ g_object_ref(contact_and_book->view);
- g_object_ref (contact_and_book->view);
+ selection_model = contact_and_book_get_selection_model(contact_and_book);
+ if (selection_model) {
+ contact_and_book->closure = cards;
+ e_selection_model_foreach(selection_model, get_card_1, contact_and_book);
+ }
- selection_model = contact_and_book_get_selection_model (contact_and_book);
- if (selection_model)
- selection = e_selection_model_selected_count (selection_model) > 0;
+ ep = eab_popup_new("com.novell.evolution.addressbook.view.popup");
+ t = eab_popup_target_new_select(ep, view->book, !eab_model_editable(view->model), cards);
+ t->target.widget = (GtkWidget *)view;
- popup = e_popup_menu_create (menu,
- 0,
- (eab_model_editable (view->model) ? 0 : POPUP_READONLY_MASK) +
- (selection ? 0 : POPUP_NOSELECTION_MASK) +
- (get_has_email_address (contact_and_book) ? 0 : POPUP_NOEMAIL_MASK),
- contact_and_book);
+ for (i=0;i<sizeof(eabv_popup_items)/sizeof(eabv_popup_items[0]);i++)
+ menus = g_slist_prepend(menus, &eabv_popup_items[i]);
- g_signal_connect (popup, "selection-done",
- G_CALLBACK (free_popup_info), contact_and_book);
- e_popup_menu (popup, event);
+ e_popup_add_items((EPopup *)ep, menus, eabv_popup_free, contact_and_book);
+ /* visibility is disabled, we only disable menu items */
+ /* FIXME: when enable is implemented in e-popup */
+ menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0, t->target.mask);
+ gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button.button:0, event?event->button.time:gtk_get_current_event_time());
}
static void
@@ -1985,12 +1834,43 @@ eab_view_print_preview(EABView *view)
void
eab_view_delete_selection(EABView *view)
{
- ContactAndBook contact_and_book;
+ GList *list, *l;
+
+ if (!eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(view->widget))))
+ return;
+
+ list = get_selected_contacts(view);
+ if (e_book_check_static_capability (view->book, "bulk-remove")) {
+ GList *ids = NULL;
+
+ for (l=list;l;l=g_list_next(l)) {
+ EContact *contact = l->data;
+
+ ids = g_list_prepend (ids, (char*)e_contact_get_const (contact, E_CONTACT_UID));
+ }
- memset (&contact_and_book, 0, sizeof (contact_and_book));
- contact_and_book.view = view;
+ /* Remove the cards all at once. */
+ /* XXX no callback specified... ugh */
+ e_book_async_remove_contacts (view->book,
+ ids,
+ NULL,
+ NULL);
+
+ g_list_free (ids);
+ }
+ else {
+ for (l=list;l;l=g_list_next(l)) {
+ EContact *contact = l->data;
+ /* Remove the card. */
+ /* XXX no callback specified... ugh */
+ e_book_async_remove_contact (view->book,
+ contact,
+ NULL,
+ NULL);
+ }
+ }
- delete (GTK_WIDGET (view), &contact_and_book);
+ e_free_object_list(list);
}
static void
diff --git a/addressbook/gui/widgets/eab-popup.c b/addressbook/gui/widgets/eab-popup.c
new file mode 100644
index 0000000000..d2faa40fc5
--- /dev/null
+++ b/addressbook/gui/widgets/eab-popup.c
@@ -0,0 +1,278 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Michael Zucchi <notzed@ximian.com>
+ *
+ * Copyright 2004 Novell, Inc. (www.novell.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; version 2 of the License.
+ *
+ * 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 Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include "eab-popup.h"
+#include "widgets/misc/e-source-selector.h"
+#include <libebook/e-contact.h>
+
+static GObjectClass *eabp_parent;
+
+static void
+eabp_init(GObject *o)
+{
+ /*EABPopup *eabp = (EABPopup *)o; */
+}
+
+static void
+eabp_finalise(GObject *o)
+{
+ ((GObjectClass *)eabp_parent)->finalize(o);
+}
+
+static void
+eabp_target_free(EPopup *ep, EPopupTarget *t)
+{
+ switch (t->type) {
+ case EAB_POPUP_TARGET_SELECT: {
+ EABPopupTargetSelect *s = (EABPopupTargetSelect *)t;
+ int i;
+
+ for (i=0;i<s->cards->len;i++)
+ g_object_unref(s->cards->pdata[i]);
+ g_ptr_array_free(s->cards, TRUE);
+ g_object_unref(s->book);
+
+ break; }
+ case EAB_POPUP_TARGET_SOURCE: {
+ EABPopupTargetSource *s = (EABPopupTargetSource *)t;
+
+ g_object_unref(s->selector);
+ break; }
+ }
+
+ ((EPopupClass *)eabp_parent)->target_free(ep, t);
+}
+
+static void
+eabp_class_init(GObjectClass *klass)
+{
+ klass->finalize = eabp_finalise;
+ ((EPopupClass *)klass)->target_free = eabp_target_free;
+}
+
+GType
+eab_popup_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof(EABPopupClass),
+ NULL, NULL,
+ (GClassInitFunc)eabp_class_init,
+ NULL, NULL,
+ sizeof(EABPopup), 0,
+ (GInstanceInitFunc)eabp_init
+ };
+ eabp_parent = g_type_class_ref(e_popup_get_type());
+ type = g_type_register_static(e_popup_get_type(), "EABPopup", &info, 0);
+ }
+
+ return type;
+}
+
+EABPopup *eab_popup_new(const char *menuid)
+{
+ EABPopup *eabp = g_object_new(eab_popup_get_type(), 0);
+
+ e_popup_construct(&eabp->popup, menuid);
+
+ return eabp;
+}
+
+/**
+ * eab_popup_target_new_select:
+ * @eabp: Address book popup.
+ * @book: Book the cards belong to.
+ * @readonly: Book is read-only mode. FIXME: Why can't we just get this off the book?
+ * @cards: Cards selected. This will be freed on completion.
+ *
+ * Create a new selection popup target.
+ *
+ * Return value:
+ **/
+EABPopupTargetSelect *
+eab_popup_target_new_select(EABPopup *eabp, struct _EBook *book, int readonly, GPtrArray *cards)
+{
+ EABPopupTargetSelect *t = e_popup_target_new(&eabp->popup, EAB_POPUP_TARGET_SELECT, sizeof(*t));
+ guint32 mask = ~0;
+ int has_email = FALSE, i;
+
+ t->book = book;
+ g_object_ref(book);
+ t->cards = cards;
+
+ for (i=0;i<cards->len && !has_email;i++) {
+ EContact *contact = cards->pdata[i];
+ GList *email;
+
+ email = e_contact_get(E_CONTACT(contact), E_CONTACT_EMAIL);
+ if (email) {
+ has_email = TRUE;
+
+ g_list_foreach(email, (GFunc)g_free, NULL);
+ g_list_free(email);
+ }
+ }
+
+ if (has_email)
+ mask &= ~EAB_POPUP_SELECT_EMAIL;
+
+ if (!readonly)
+ mask &= ~EAB_POPUP_SELECT_EDITABLE;
+
+ if (cards->len == 1)
+ mask &= ~EAB_POPUP_SELECT_ONE;
+
+ if (cards->len >= 1)
+ mask &= ~EAB_POPUP_SELECT_MANY;
+
+ t->target.mask = mask;
+
+ return t;
+}
+
+EABPopupTargetSource *
+eab_popup_target_new_source(EABPopup *eabp, ESourceSelector *selector)
+{
+ EABPopupTargetSource *t = e_popup_target_new(&eabp->popup, EAB_POPUP_TARGET_SOURCE, sizeof(*t));
+ guint32 mask = ~0;
+ const char *source_uri;
+ ESource *source;
+
+ /* TODO: this is duplicated for calendar and tasks too */
+
+ t->selector = selector;
+ g_object_ref(selector);
+
+ /* TODO: perhaps we need to copy this so it doesn't change during the lifecycle */
+ source = e_source_selector_peek_primary_selection(selector);
+ if (source)
+ mask &= ~EAB_POPUP_SOURCE_PRIMARY;
+
+ /* FIXME Gross hack, should have a property or something */
+ source_uri = e_source_peek_relative_uri(source);
+ if (source_uri && !strcmp("system", source_uri))
+ mask &= ~EAB_POPUP_SOURCE_SYSTEM;
+ else
+ mask &= ~EAB_POPUP_SOURCE_USER;
+
+ t->target.mask = mask;
+
+ return t;
+}
+
+/* ********************************************************************** */
+/* Popup menu plugin handler */
+
+/*
+<e-plugin
+ class="com.ximian.mail.plugin.popup:1.0"
+ id="com.ximian.mail.plugin.popup.iteab:1.0"
+ type="shlib"
+ location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
+ name="imap"
+ description="IMAP4 and IMAP4v1 mail store">
+ <hook class="com.ximian.mail.popupMenu:1.0"
+ handler="HandlePopup">
+ <menu id="any" target="select">
+ <iteab
+ type="iteab|toggle|radio|image|submenu|bar"
+ active
+ path="foo/bar"
+ label="label"
+ icon="foo"
+ mask="select_one"
+ activate="eabp_view_eabacs"/>
+ </menu>
+ </extension>
+
+*/
+
+static void *eabph_parent_class;
+#define eabph ((EABPopupHook *)eph)
+
+static const EPopupHookTargetMask eabph_select_masks[] = {
+ { "one", EAB_POPUP_SELECT_ONE },
+ { "many", EAB_POPUP_SELECT_MANY },
+ { 0 }
+};
+
+static const EPopupHookTargetMask eabph_source_masks[] = {
+ { "primary", EAB_POPUP_SOURCE_PRIMARY },
+ { "system", EAB_POPUP_SOURCE_SYSTEM },
+ { 0 }
+};
+
+static const EPopupHookTargetMap eabph_targets[] = {
+ { "select", EAB_POPUP_TARGET_SELECT, eabph_select_masks },
+ { "source", EAB_POPUP_TARGET_SOURCE, eabph_source_masks },
+ { 0 }
+};
+
+static void
+eabph_finalise(GObject *o)
+{
+ /*EPluginHook *eph = (EPluginHook *)o;*/
+
+ ((GObjectClass *)eabph_parent_class)->finalize(o);
+}
+
+static void
+eabph_class_init(EPluginHookClass *klass)
+{
+ int i;
+
+ ((GObjectClass *)klass)->finalize = eabph_finalise;
+ ((EPluginHookClass *)klass)->id = "com.ximian.evolution.addressbook.popup:1.0";
+
+ for (i=0;eabph_targets[i].type;i++)
+ e_popup_hook_class_add_target_map((EPopupHookClass *)klass, &eabph_targets[i]);
+
+ ((EPopupHookClass *)klass)->popup_class = g_type_class_ref(eab_popup_get_type());
+}
+
+GType
+eab_popup_hook_get_type(void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof(EABPopupHookClass), NULL, NULL, (GClassInitFunc) eabph_class_init, NULL, NULL,
+ sizeof(EABPopupHook), 0, (GInstanceInitFunc) NULL,
+ };
+
+ eabph_parent_class = g_type_class_ref(e_popup_hook_get_type());
+ type = g_type_register_static(e_popup_hook_get_type(), "EABPopupHook", &info, 0);
+ }
+
+ return type;
+}
diff --git a/addressbook/gui/widgets/eab-popup.h b/addressbook/gui/widgets/eab-popup.h
new file mode 100644
index 0000000000..996cf78d6d
--- /dev/null
+++ b/addressbook/gui/widgets/eab-popup.h
@@ -0,0 +1,151 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Michael Zucchi <notzed@ximian.com>
+ *
+ * Copyright 2004 Novell, Inc. (www.novell.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; version 2 of the License.
+ *
+ * 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 Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __EAB_POPUP_H__
+#define __EAB_POPUP_H__
+
+#include <glib-object.h>
+
+#include "e-util/e-popup.h"
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+typedef struct _EABPopup EABPopup;
+typedef struct _EABPopupClass EABPopupClass;
+
+/**
+ * enum _eab_popup_target_t - A list of mail popup target types.
+ *
+ * @EAB_POPUP_TARGET_SELECT: A selection of cards
+ * @EAB_POPUP_TARGET_SOURCE: A source selection.
+ *
+ * Defines the value of the targetid for all EABPopup target types.
+ **/
+enum _eab_popup_target_t {
+ EAB_POPUP_TARGET_SELECT,
+ EAB_POPUP_TARGET_SOURCE,
+};
+
+/**
+ * enum _eab_popup_target_select_t - EABPopupTargetSelect qualifiers.
+ *
+ * @EAB_POPUP_SELECT_ONE: Only one item is selected.
+ * @EAB_POPUP_SELECT_MANY: One ore more items are selected.
+ * @EAB_POPUP_SELECT_EDITABLE: Read/writable source.
+ * @EAB_POPUP_SELECT_EMAIL: Has an email address.
+ **/
+enum _eab_popup_target_select_t {
+ EAB_POPUP_SELECT_ONE = 1<<0,
+ EAB_POPUP_SELECT_MANY = 1<<1,
+ EAB_POPUP_SELECT_EDITABLE = 1<<2,
+ EAB_POPUP_SELECT_EMAIL = 1<<3,
+};
+
+/**
+ * enum _eab_popup_target_source_t - EABPopupTargetSource qualifiers.
+ *
+ * @EAB_POPUP_SOURCE_PRIMARY: Has a primary selection.
+ * @EAB_POPUP_SOURCE_SYSTEM: Is a 'system' folder.
+ *
+ **/
+enum _eab_popup_target_source_t {
+ EAB_POPUP_SOURCE_PRIMARY = 1<<0,
+ EAB_POPUP_SOURCE_SYSTEM = 1<<1, /* system folder */
+ EAB_POPUP_SOURCE_USER = 1<<2, /* user folder (!system) */
+};
+
+typedef struct _EABPopupTargetSelect EABPopupTargetSelect;
+typedef struct _EABPopupTargetSource EABPopupTargetSource;
+
+/**
+ * struct _EABPopupTargetSelect - A list of address cards.
+ *
+ * @target: Superclass.
+ * @book: Book the cards belong to.
+ * @cards: All selected cards.
+ *
+ * Used to represent a selection of cards as context for a popup
+ * menu.
+ **/
+struct _EABPopupTargetSelect {
+ EPopupTarget target;
+
+ struct _EBook *book;
+ GPtrArray *cards;
+};
+
+/**
+ * struct _EABPopupTargetSource - A source target.
+ *
+ * @target: Superclass.
+ * @selector: Selector holding the source selection.
+ *
+ * This target is used to represent a source selection.
+ **/
+struct _EABPopupTargetSource {
+ EPopupTarget target;
+
+ struct _ESourceSelector *selector;
+};
+
+typedef struct _EPopupItem EABPopupItem;
+
+/* The object */
+struct _EABPopup {
+ EPopup popup;
+
+ struct _EABPopupPrivate *priv;
+};
+
+struct _EABPopupClass {
+ EPopupClass popup_class;
+};
+
+GType eab_popup_get_type(void);
+
+EABPopup *eab_popup_new(const char *menuid);
+
+EABPopupTargetSelect *eab_popup_target_new_select(EABPopup *eabp, struct _EBook *book, int readonly, GPtrArray *cards);
+EABPopupTargetSource *eab_popup_target_new_source(EABPopup *eabp, struct _ESourceSelector *selector);
+
+/* ********************************************************************** */
+
+typedef struct _EABPopupHook EABPopupHook;
+typedef struct _EABPopupHookClass EABPopupHookClass;
+
+struct _EABPopupHook {
+ EPopupHook hook;
+};
+
+struct _EABPopupHookClass {
+ EPopupHookClass hook_class;
+};
+
+GType eab_popup_hook_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __EAB_POPUP_H__ */