? test-contact-store ? test-name-selector Index: e-name-selector-dialog.c =================================================================== RCS file: /cvs/gnome/evolution-data-server/libedataserverui/e-name-selector-dialog.c,v retrieving revision 1.11 diff -u -u -r1.11 e-name-selector-dialog.c --- e-name-selector-dialog.c 23 Feb 2005 18:52:12 -0000 1.11 +++ e-name-selector-dialog.c 22 Mar 2005 21:40:12 -0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,12 @@ #include #include "e-name-selector-dialog.h" +enum { + ENAME_DND_CONTACT, + ENAME_DND_NTARGETS +}; + + typedef struct { gchar *name; @@ -63,6 +70,7 @@ static void destination_column_formatter (GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, ENameSelectorDialog *name_selector_dialog); +static void sort_iter_to_contact_store_iter (ENameSelectorDialog *name_selector_dialog, GtkTreeIter *iter, gint *email_n); /* ------------------ * * Class/object setup * @@ -83,6 +91,122 @@ } static void +data_get_callback (GtkWidget *tree_view G_GNUC_UNUSED, + GdkDragContext *context G_GNUC_UNUSED, + GtkSelectionData *selection_data, + guint info, + guint32 time G_GNUC_UNUSED, + ENameSelectorDialog *name_selector_dialog) +{ + EContactStore *contact_store; + EDestinationStore *destination_store; + EContact *contact; + GtkTreeSelection *selection; + GtkTreeIter iter; + gint email_n; + gint section_index; + char *uid; + + + + contact_store = e_name_selector_model_peek_contact_store (name_selector_dialog->name_selector_model); + if (name_selector_dialog->sections->len == 0) + return; + + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); + + if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) { + return; + } + + /* Is a destination or the main store? */ + section_index = find_section_by_tree_view (name_selector_dialog, tree_view); + if (section_index >= 0) { + EDestinationStore *destination_store; + EDestination *destination; + Section *section; + + section = &g_array_index (name_selector_dialog->sections, Section, section_index); + if (!e_name_selector_model_peek_section (name_selector_dialog->name_selector_model, + section->name, NULL, &destination_store)) { + g_warning ("ENameSelectorDialog has a section unknown to the model!"); + return; + } + + destination = e_destination_store_get_destination (destination_store, &iter); + g_assert (destination); + contact = e_destination_get_contact (destination); + + /* deleting it here is a little bit hacky */ + e_destination_store_remove_destination (destination_store, destination); + } else { + + sort_iter_to_contact_store_iter (name_selector_dialog, &iter, &email_n); + + contact = e_contact_store_get_contact (contact_store, &iter); + if (!contact) { + g_warning ("ENameSelectorDialog could not get selected contact!"); + return; + } + } + + uid = e_contact_get (contact, E_CONTACT_UID); + gtk_selection_data_set (selection_data, + selection_data->target, + 32, + uid, strlen (uid)); +} + + +static void +got_contact (GtkWidget *widget, GdkDragContext *context, int x, int y, + GtkSelectionData *selection_data, guint info, guint time, + ENameSelectorDialog *name_selector_dialog) +{ + EContact *contact; + EDestination *destination; + EContactStore *contact_store; + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkTreeModel *destination_store; + int section_index; + + g_signal_stop_emission_by_name (widget, "drag_data_received"); + + contact_store = e_name_selector_model_peek_contact_store (name_selector_dialog->name_selector_model); + + if (name_selector_dialog->sections->len == 0) + return; + + e_contact_store_find_contact (contact_store, selection_data->data, &iter); + + contact = e_contact_store_get_contact (contact_store, &iter); + if (!contact) { + g_warning ("ENameSelectorDialog could not get selected contact!"); + return; + } + + /* Is destination or the main store? */ + section_index = find_section_by_tree_view (name_selector_dialog, GTK_TREE_VIEW (widget)); + if (section_index >= 0) { + destination = e_destination_new (); + e_destination_set_contact (destination, contact, 0); + destination_store = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); + e_destination_store_append_destination (destination_store, destination); + g_object_unref (destination); + } +} + +static void +stop_delete (GtkWidget *widget, GdkDragContext *context, int x, int y, + GtkSelectionData *selection_data, guint info, guint time, + gpointer data) +{ + g_signal_stop_emission_by_name (widget, "drag_data_delete"); +} + +static void e_name_selector_dialog_init (ENameSelectorDialog *name_selector_dialog) { GtkTreeSelection *contact_selection; @@ -93,6 +217,10 @@ GtkWidget *label; ESourceList *source_list; + static GtkTargetEntry target_entries[] = { + { "CONTACT", 0, ENAME_DND_CONTACT } + }; + /* Get Glade GUI */ name_selector_dialog->gui = glade_xml_new (E_DATA_SERVER_UI_GLADEDIR "/e-name-selector-dialog.glade", NULL, NULL); @@ -147,6 +275,22 @@ g_signal_connect_swapped (name_selector_dialog->contact_view, "row-activated", G_CALLBACK (contact_activated), name_selector_dialog); + /* Set up DND */ + gtk_drag_source_set (name_selector_dialog->contact_view, GDK_BUTTON1_MASK, + target_entries, ENAME_DND_NTARGETS, GDK_ACTION_MOVE); + + g_signal_connect (G_OBJECT (name_selector_dialog->contact_view), "drag_data_get", + G_CALLBACK (data_get_callback), name_selector_dialog); + gtk_drag_dest_set (name_selector_dialog->contact_view, GTK_DEST_DEFAULT_ALL, target_entries, ENAME_DND_NTARGETS, + GDK_ACTION_COPY|GDK_ACTION_MOVE|GDK_ACTION_LINK); + + + g_signal_connect(name_selector_dialog->contact_view, "drag_data_received", G_CALLBACK (got_contact), name_selector_dialog); + g_signal_connect(name_selector_dialog->contact_view, "drag_data_delete", G_CALLBACK (stop_delete), NULL); + + + + /* Listen for changes to the contact selection */ contact_selection = gtk_tree_view_get_selection (name_selector_dialog->contact_view); @@ -395,6 +539,7 @@ return -1; } + static gint add_section (ENameSelectorDialog *name_selector_dialog, const gchar *name, const gchar *pretty_name, EDestinationStore *destination_store) @@ -405,6 +550,10 @@ GtkWidget *widget; gchar *text; + static GtkTargetEntry target_entries[] = { + { "CONTACT", 0, ENAME_DND_CONTACT } + }; + g_assert (name != NULL); g_assert (pretty_name != NULL); g_assert (E_IS_DESTINATION_STORE (destination_store)); @@ -425,6 +574,21 @@ /* Set up transfer button */ g_signal_connect_swapped (section.transfer_button, "clicked", G_CALLBACK (transfer_button_clicked), name_selector_dialog); + + /* Set up DND */ + gtk_drag_source_set (section.destination_view, GDK_BUTTON1_MASK, + target_entries, ENAME_DND_NTARGETS, GDK_ACTION_MOVE); + + g_signal_connect (G_OBJECT (section.destination_view), "drag_data_get", + G_CALLBACK (data_get_callback), name_selector_dialog); + + + gtk_drag_dest_set (section.destination_view, GTK_DEST_DEFAULT_ALL, target_entries, ENAME_DND_NTARGETS, + GDK_ACTION_COPY|GDK_ACTION_MOVE|GDK_ACTION_LINK); + + + g_signal_connect(section.destination_view, "drag_data_received", G_CALLBACK (got_contact), name_selector_dialog); + g_signal_connect(section.destination_view, "drag_data_delete", G_CALLBACK (stop_delete), NULL); /* Set up view */ column = gtk_tree_view_column_new ();