aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/ChangeLog52
-rw-r--r--addressbook/gui/component/addressbook.c50
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c236
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h11
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.c7
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.h2
6 files changed, 344 insertions, 14 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index d42d9547c6..1541c6de75 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,55 @@
+2001-05-30 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/addressbook.c (cut_contacts_cb): new function, for
+ the Cut verb.
+ (copy_contacts_cb): new function, for the Copy verb.
+ (paste_contacts_cb): new function, for the Paste verb.
+ (select_all_contacts_cb): new function, for the Select All verb.
+ (update_command_state): add handling for sensitivity of
+ Cut/Copy/Paste/Select All.
+
+ * gui/widgets/e-addressbook-view.c (e_addressbook_view_init): init
+ the invisible and set up selection/destroy signals.
+ (get_selection_model): new function, so we can get the
+ ETableSelectionModel from either view type. makes lots of the
+ other functions easier, since we can get the list of selected
+ cards using the same code regardless of view type.
+ (invisible_destroyed): new function.
+ (selection_get): new function. convert the clipboard list to
+ string.
+ (selection_clear_event): new function - free up the list of
+ ECards.
+ (selection_received): if the selection data is valid and
+ well-formed, add the corresponding cards to the ebook.
+ (add_to_list): new function.
+ (get_selected_cards): new function.
+ (e_addressbook_view_cut): new function, implement in terms of
+ _copy and _delete_selection.
+ (e_addressbook_view_copy): claim ownership of the CLIPBOARD
+ selection after saving the list of selected ECards.
+ (e_addressbook_view_paste): call gtk_selection_convert.
+ (e_addressbook_view_select_all): new function, using
+ e_selection_model_select_all.
+ (e_addressbook_view_can_print): re-implement in terms of
+ get_selection_model.
+ (e_addressbook_view_can_delete): same.
+ (e_addressbook_view_can_cut): new function.
+ (e_addressbook_view_can_copy): new function.
+ (e_addressbook_view_can_paste): new function. hmm, always return
+ TRUE here.
+ (e_addressbook_view_can_select_all): new function.
+
+ * gui/widgets/e-addressbook-view.h (struct _EAddressbookView): add
+ selection stuff - the list of selected cards, and the GtkInvisible
+ selection owner, and add prototypes for
+ e_addressbook_view_[can]_{cut,copy,paste,select_all}.
+
+ * gui/widgets/e-minicard-view-widget.h: add a prototype for
+ e_minicard_view_widget_get_selection_model.
+
+ * gui/widgets/e-minicard-view-widget.c
+ (e_minicard_view_widget_get_selection_model): new function.
+
2001-05-27 Dan Winship <danw@ximian.com>
* gui/component/addressbook.c: #include
diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c
index 5db16cf42b..d489b89f60 100644
--- a/addressbook/gui/component/addressbook.c
+++ b/addressbook/gui/component/addressbook.c
@@ -188,6 +188,34 @@ stop_loading_cb (BonoboUIComponent *uih, void *user_data, const char *path)
}
static void
+cut_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
+{
+ AddressbookView *view = (AddressbookView *) user_data;
+ e_addressbook_view_cut(view->view);
+}
+
+static void
+copy_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
+{
+ AddressbookView *view = (AddressbookView *) user_data;
+ e_addressbook_view_copy(view->view);
+}
+
+static void
+paste_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
+{
+ AddressbookView *view = (AddressbookView *) user_data;
+ e_addressbook_view_paste(view->view);
+}
+
+static void
+select_all_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
+{
+ AddressbookView *view = (AddressbookView *) user_data;
+ e_addressbook_view_select_all (view->view);
+}
+
+static void
update_command_state (EAddressbookView *eav, AddressbookView *view)
{
BonoboUIComponent *uic = bonobo_control_get_ui_component (view->control);
@@ -210,7 +238,24 @@ update_command_state (EAddressbookView *eav, AddressbookView *view)
"sensitive",
e_addressbook_view_can_delete (view->view) ? "1" : "0", NULL);
+ bonobo_ui_component_set_prop (uic,
+ "/commands/ContactsCut",
+ "sensitive",
+ e_addressbook_view_can_cut (view->view) ? "1" : "0", NULL);
+ bonobo_ui_component_set_prop (uic,
+ "/commands/ContactsCopy",
+ "sensitive",
+ e_addressbook_view_can_copy (view->view) ? "1" : "0", NULL);
+ bonobo_ui_component_set_prop (uic,
+ "/commands/ContactsPaste",
+ "sensitive",
+ e_addressbook_view_can_paste (view->view) ? "1" : "0", NULL);
+ bonobo_ui_component_set_prop (uic,
+ "/commands/ContactsSelectAll",
+ "sensitive",
+ e_addressbook_view_can_select_all (view->view) ? "1" : "0", NULL);
+
/* View All Contacts */
#if 0
/* this is always enabled */
@@ -242,6 +287,11 @@ BonoboUIVerb verbs [] = {
BONOBO_UI_UNSAFE_VERB ("ContactDelete", delete_contact_cb),
BONOBO_UI_UNSAFE_VERB ("ContactViewAll", show_all_contacts_cb),
BONOBO_UI_UNSAFE_VERB ("ContactStop", stop_loading_cb),
+
+ BONOBO_UI_UNSAFE_VERB ("ContactsCut", cut_contacts_cb),
+ BONOBO_UI_UNSAFE_VERB ("ContactsCopy", copy_contacts_cb),
+ BONOBO_UI_UNSAFE_VERB ("ContactsPaste", paste_contacts_cb),
+ BONOBO_UI_UNSAFE_VERB ("ContactsSelectAll", select_all_contacts_cb),
BONOBO_UI_VERB_END
};
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index 55443000a0..3491b8e662 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -22,6 +22,8 @@
#include <config.h>
+#include <gtk/gtkinvisible.h>
+
#include <libgnome/gnome-paper.h>
#include <libgnome/gnome-i18n.h>
#include <libgnome/gnome-util.h>
@@ -66,6 +68,14 @@ static void stop_state_changed (GtkObject *object, EAddressbookView *eav);
static void writable_status (GtkObject *object, gboolean writable, EAddressbookView *eav);
static void command_state_change (EAddressbookView *eav);
+static void selection_clear_event (GtkWidget *invisible, GdkEventSelection *event,
+ EAddressbookView *view);
+static void selection_received (GtkWidget *invisible, GtkSelectionData *selection_data,
+ guint time, EAddressbookView *view);
+static void selection_get (GtkWidget *invisible, GtkSelectionData *selection_data,
+ guint info, guint time_stamp, EAddressbookView *view);
+static void invisible_destroyed (GtkWidget *invisible, EAddressbookView *view);
+
static GtkTableClass *parent_class = NULL;
/* The arguments we take */
@@ -93,6 +103,8 @@ static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
static guint e_addressbook_view_signals [LAST_SIGNAL] = {0, };
+static GdkAtom clipboard_atom = GDK_NONE;
+
GtkType
e_addressbook_view_get_type (void)
{
@@ -154,6 +166,9 @@ e_addressbook_view_class_init (EAddressbookViewClass *klass)
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, e_addressbook_view_signals, LAST_SIGNAL);
+
+ if (!clipboard_atom)
+ clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
}
static void
@@ -184,6 +199,26 @@ e_addressbook_view_init (EAddressbookView *eav)
eav->object = NULL;
eav->widget = NULL;
+
+ eav->invisible = gtk_invisible_new ();
+
+ gtk_selection_add_target (eav->invisible,
+ clipboard_atom,
+ GDK_SELECTION_TYPE_STRING,
+ 0);
+
+ gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_get",
+ GTK_SIGNAL_FUNC (selection_get),
+ eav);
+ gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_clear_event",
+ GTK_SIGNAL_FUNC (selection_clear_event),
+ eav);
+ gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_received",
+ GTK_SIGNAL_FUNC (selection_received),
+ eav);
+ gtk_signal_connect (GTK_OBJECT(eav->invisible), "destroyed",
+ GTK_SIGNAL_FUNC (invisible_destroyed),
+ eav);
}
static void
@@ -195,6 +230,15 @@ e_addressbook_view_destroy (GtkObject *object)
gtk_object_unref(GTK_OBJECT(eav->book));
g_free(eav->query);
+ if (eav->clipboard_cards) {
+ g_list_foreach (eav->clipboard_cards, (GFunc)gtk_object_unref, NULL);
+ g_list_free (eav->clipboard_cards);
+ eav->clipboard_cards = NULL;
+ }
+
+ if (eav->invisible)
+ gtk_widget_destroy (eav->invisible);
+
if (GTK_OBJECT_CLASS(parent_class)->destroy)
GTK_OBJECT_CLASS(parent_class)->destroy(object);
}
@@ -1004,6 +1048,16 @@ e_addressbook_view_setup_menus (EAddressbookView *view,
gtk_object_sink(GTK_OBJECT(collection));
}
+static ESelectionModel*
+get_selection_model (EAddressbookView *view)
+{
+ if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD)
+ return e_minicard_view_widget_get_selection_model (E_MINICARD_VIEW_WIDGET(view->object));
+ else
+ return E_SELECTION_MODEL(E_TABLE_SCROLLED(view->widget)->table->selection);
+}
+
+
void
e_addressbook_view_print(EAddressbookView *view)
{
@@ -1053,10 +1107,133 @@ card_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
void
e_addressbook_view_delete_selection(EAddressbookView *view)
{
+ ESelectionModel *model = get_selection_model (view);
+
+ g_return_if_fail (model);
+
if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD)
e_minicard_view_widget_remove_selection (E_MINICARD_VIEW_WIDGET(view->object), card_deleted_cb, NULL);
}
+static void
+invisible_destroyed (GtkWidget *invisible, EAddressbookView *view)
+{
+ view->invisible = NULL;
+}
+
+static void
+selection_get (GtkWidget *invisible,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time_stamp,
+ EAddressbookView *view)
+{
+ char *value;
+
+ value = e_card_list_get_vcard(view->clipboard_cards);
+
+ gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
+ 8, value, strlen (value));
+
+}
+
+static void
+selection_clear_event (GtkWidget *invisible,
+ GdkEventSelection *event,
+ EAddressbookView *view)
+{
+ if (view->clipboard_cards) {
+ g_list_foreach (view->clipboard_cards, (GFunc)gtk_object_unref, NULL);
+ g_list_free (view->clipboard_cards);
+ view->clipboard_cards = NULL;
+ }
+}
+
+static void
+selection_received (GtkWidget *invisible,
+ GtkSelectionData *selection_data,
+ guint time,
+ EAddressbookView *view)
+{
+ if (selection_data->length < 0 || selection_data->type != GDK_SELECTION_TYPE_STRING) {
+ return;
+ }
+ else {
+ /* XXX make sure selection_data->data = \0 terminated */
+ GList *card_list = e_card_load_cards_from_string (selection_data->data);
+ GList *l;
+
+ if (!card_list /* it wasn't a vcard list */)
+ return;
+
+ for (l = card_list; l; l = l->next) {
+ ECard *card = l->data;
+
+ e_book_add_card (view->book, card, NULL /* XXX */, NULL);
+ }
+
+ g_list_foreach (card_list, (GFunc)gtk_object_unref, NULL);
+ g_list_free (card_list);
+ }
+}
+
+static void
+add_to_list (int model_row, gpointer closure)
+{
+ GList **list = closure;
+ *list = g_list_prepend (*list, GINT_TO_POINTER (model_row));
+}
+
+static GList *
+get_selected_cards (EAddressbookView *view)
+{
+ GList *list;
+ GList *iterator;
+ ESelectionModel *selection = get_selection_model (view);
+
+ list = NULL;
+ e_selection_model_foreach (selection, add_to_list, &list);
+
+ for (iterator = list; iterator; iterator = iterator->next) {
+ iterator->data = e_addressbook_model_card_at (view->model, GPOINTER_TO_INT (iterator->data));
+ }
+ list = g_list_reverse (list);
+ return list;
+}
+
+void
+e_addressbook_view_cut (EAddressbookView *view)
+{
+ e_addressbook_view_copy (view);
+ e_addressbook_view_delete_selection (view);
+}
+
+void
+e_addressbook_view_copy (EAddressbookView *view)
+{
+ view->clipboard_cards = get_selected_cards (view);
+
+ gtk_selection_owner_set (view->invisible, clipboard_atom, GDK_CURRENT_TIME);
+}
+
+void
+e_addressbook_view_paste (EAddressbookView *view)
+{
+ gtk_selection_convert (view->invisible, clipboard_atom,
+ GDK_SELECTION_TYPE_STRING,
+ GDK_CURRENT_TIME);
+}
+
+void
+e_addressbook_view_select_all (EAddressbookView *view)
+{
+ ESelectionModel *model = get_selection_model (view);
+
+ g_return_if_fail (model);
+
+ e_selection_model_select_all (model);
+}
+
void
e_addressbook_view_show_all(EAddressbookView *view)
{
@@ -1080,30 +1257,61 @@ e_addressbook_view_can_create (EAddressbookView *view)
gboolean
e_addressbook_view_can_print (EAddressbookView *view)
{
- switch (view->view_type) {
- case E_ADDRESSBOOK_VIEW_TABLE:
- return e_table_selected_count (E_TABLE_SCROLLED(view->widget)->table) != 0;
- case E_ADDRESSBOOK_VIEW_MINICARD:
- return e_minicard_view_widget_selected_count (E_MINICARD_VIEW_WIDGET (view->object)) != 0;
- default:
+ ESelectionModel *selection_model;
+
+ if (!e_addressbook_model_editable (view->model))
return FALSE;
- }
+
+ selection_model = get_selection_model (view);
+ g_return_val_if_fail (selection_model != NULL, FALSE);
+
+ return e_selection_model_selected_count (selection_model) != 0;
}
gboolean
e_addressbook_view_can_delete (EAddressbookView *view)
{
+ ESelectionModel *selection_model;
+
if (!e_addressbook_model_editable (view->model))
return FALSE;
- switch (view->view_type) {
- case E_ADDRESSBOOK_VIEW_TABLE:
- return e_table_selected_count (E_TABLE_SCROLLED(view->widget)->table) != 0;
- case E_ADDRESSBOOK_VIEW_MINICARD:
- return e_minicard_view_widget_selected_count (E_MINICARD_VIEW_WIDGET (view->object)) != 0;
- default:
+ selection_model = get_selection_model (view);
+ g_return_val_if_fail (selection_model != NULL, FALSE);
+
+ return e_selection_model_selected_count (selection_model) != 0;
+}
+
+gboolean
+e_addressbook_view_can_cut (EAddressbookView *view)
+{
+ return (e_addressbook_view_can_copy (view) && e_addressbook_model_editable (view->model));
+}
+
+gboolean
+e_addressbook_view_can_copy (EAddressbookView *view)
+{
+ ESelectionModel *selection_model;
+
+ if (!e_addressbook_model_editable (view->model))
return FALSE;
- }
+
+ selection_model = get_selection_model (view);
+ g_return_val_if_fail (selection_model != NULL, FALSE);
+
+ return e_selection_model_selected_count (selection_model) != 0;
+}
+
+gboolean
+e_addressbook_view_can_paste (EAddressbookView *view)
+{
+ return TRUE;
+}
+
+gboolean
+e_addressbook_view_can_select_all (EAddressbookView *view)
+{
+ return e_addressbook_model_card_count (view->model) != 0;
}
gboolean
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index 19c83474fe..049376c96f 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -64,6 +64,9 @@ struct _EAddressbookView
EAddressbookModel *model;
+ GtkWidget *invisible;
+ GList *clipboard_cards;
+
EBook *book;
char *query;
guint editable : 1;
@@ -93,12 +96,20 @@ void e_addressbook_view_setup_menus (EAddressbookView *view,
void e_addressbook_view_print (EAddressbookView *view);
void e_addressbook_view_delete_selection (EAddressbookView *view);
+void e_addressbook_view_cut (EAddressbookView *view);
+void e_addressbook_view_copy (EAddressbookView *view);
+void e_addressbook_view_paste (EAddressbookView *view);
+void e_addressbook_view_select_all (EAddressbookView *view);
void e_addressbook_view_show_all (EAddressbookView *view);
void e_addressbook_view_stop (EAddressbookView *view);
gboolean e_addressbook_view_can_create (EAddressbookView *view);
gboolean e_addressbook_view_can_print (EAddressbookView *view);
gboolean e_addressbook_view_can_delete (EAddressbookView *view);
+gboolean e_addressbook_view_can_cut (EAddressbookView *view);
+gboolean e_addressbook_view_can_copy (EAddressbookView *view);
+gboolean e_addressbook_view_can_paste (EAddressbookView *view);
+gboolean e_addressbook_view_can_select_all (EAddressbookView *view);
gboolean e_addressbook_view_can_stop (EAddressbookView *view);
#ifdef __cplusplus
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.c b/addressbook/gui/widgets/e-minicard-view-widget.c
index 576f8b3aab..8e9f3c2761 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.c
+++ b/addressbook/gui/widgets/e-minicard-view-widget.c
@@ -329,3 +329,10 @@ void e_minicard_view_widget_jump_to_letter (EMinicardViewWidget *view,
if (view->emv)
e_minicard_view_jump_to_letter(E_MINICARD_VIEW(view->emv), letter);
}
+
+ESelectionModel *
+e_minicard_view_widget_get_selection_model (EMinicardViewWidget *view)
+{
+ if (view->emv)
+ return E_SELECTION_MODEL (E_REFLOW (view->emv)->selection);
+}
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.h b/addressbook/gui/widgets/e-minicard-view-widget.h
index 22156e2588..edfe5135a4 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.h
+++ b/addressbook/gui/widgets/e-minicard-view-widget.h
@@ -69,6 +69,8 @@ void e_minicard_view_widget_jump_to_letter (EMinicardViewWidget *view,
char letter);
GtkWidget *e_minicard_view_widget_new (EAddressbookReflowAdapter *adapter);
+ESelectionModel *e_minicard_view_widget_get_selection_model (EMinicardViewWidget *view);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */