2004-09-06 [colin] 0.9.12cvs94.1
authorColin Leroy <colin@colino.net>
Mon, 6 Sep 2004 09:53:05 +0000 (09:53 +0000)
committerColin Leroy <colin@colino.net>
Mon, 6 Sep 2004 09:53:05 +0000 (09:53 +0000)
* src/addressbook.c
* src/addressitem.h
* src/addritem.c
* src/addritem.h
Sync with HEAD (addressbook DnD)

ChangeLog-gtk2.claws
PATCHSETS
configure.ac
src/addressbook.c
src/addressitem.h
src/addritem.c
src/addritem.h

index c5b32503cef79bbad894342c29a20d1c2395cdce..ceaffc0493c4c26c2fcf69ceef245f0348ac1e63 100644 (file)
@@ -1,3 +1,11 @@
+2004-09-06 [colin]     0.9.12cvs94.1
+
+       * src/addressbook.c
+       * src/addressitem.h
+       * src/addritem.c
+       * src/addritem.h
+               Sync with HEAD (addressbook DnD)
+
 2004-09-03 [colin]     0.9.12cvs93.1
 
        * src/summaryview.c
index 35340070b4f5aaa3473f956f678938fcb05cda5a..a57ad08f4a612573b7eb8f4418a9761bd445fd8a 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.4.4 -r 1.1.4.5 src/common/xml.c; ) > 0.9.12cvs91.2.patchset
 ( cvs diff -u -r 1.204.2.19 -r 1.204.2.20 src/prefs_common.c; cvs diff -u -r 1.103.2.8 -r 1.103.2.9 src/prefs_common.h; cvs diff -u -r 1.395.2.29 -r 1.395.2.30 src/summaryview.c; ) > 0.9.12cvs92.1.patchset
 ( cvs diff -u -r 1.395.2.30 -r 1.395.2.31 src/summaryview.c; ) > 0.9.12cvs93.1.patchset
+( cvs diff -u -r 1.60.2.9 -r 1.60.2.10 src/addressbook.c; cvs diff -u -r 1.5 -r 1.6 src/addressitem.h; cvs diff -u -r 1.13.2.1 -r 1.13.2.2 src/addritem.c; cvs diff -u -r 1.12.2.1 -r 1.12.2.2 src/addritem.h; ) > 0.9.12cvs94.1.patchset
index 6c6f5a0f415c830126cb48c6f3dbe8ede0e47fc6..876e3b035fa628cc0a4161b58df4144f51652c49 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=9
 MICRO_VERSION=12
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=93
+EXTRA_VERSION=94
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=.1
 
index bf72457046c60a8eb5d6e569570966cd9fe6e53b..588fcd7353eef6e392ecfe67c2c0b887e2df6005 100644 (file)
@@ -284,6 +284,8 @@ static void addressbook_treenode_remove_item        ( void );
 
 static AddressDataSource *addressbook_find_datasource
                                                (GtkCTreeNode   *node );
+static AddressDataSource *addressbook_find_datasource_for_object
+                                               ( AddrItemObject *ao );
 
 static AddressBookFile *addressbook_get_book_file(void);
 
@@ -364,6 +366,42 @@ static void addressbook_mail_to_cb         ( void );
 static void addressbook_browse_entry_cb                ( void );
 #endif
 
+static void addressbook_start_drag(GtkWidget *widget, gint button, 
+                                  GdkEvent *event,
+                                  void *data);
+static void addressbook_drag_data_get(GtkWidget        *widget,
+                                    GdkDragContext   *drag_context,
+                                    GtkSelectionData *selection_data,
+                                    guint             info,
+                                    guint             time,
+                                    void             *data);
+static gboolean addressbook_drag_motion_cb(GtkWidget      *widget,
+                                         GdkDragContext *context,
+                                         gint            x,
+                                         gint            y,
+                                         guint           time,
+                                         void           *data);
+static void addressbook_drag_leave_cb(GtkWidget      *widget,
+                                    GdkDragContext *context,
+                                    guint           time,
+                                    void           *data);
+static void addressbook_drag_received_cb(GtkWidget        *widget,
+                                       GdkDragContext   *drag_context,
+                                       gint              x,
+                                       gint              y,
+                                       GtkSelectionData *data,
+                                       guint             info,
+                                       guint             time,
+                                       void             *pdata);
+
+static GtkTargetEntry addressbook_drag_types[] =
+{
+       {"text/plain", GTK_TARGET_SAME_APP, TARGET_DUMMY}
+};
+
+static GtkTargetList *addressbook_target_list = NULL;
+
+
 static GtkItemFactoryEntry addressbook_entries[] =
 {
        {N_("/_File"),                  NULL,           NULL, 0, "<Branch>"},
@@ -635,6 +673,7 @@ static void addressbook_create(void)
        GList *nodeIf;
 
        gchar *titles[N_COLS];
+       gchar *dummy_titles[1];
        gchar *text;
        gint i;
 
@@ -643,6 +682,7 @@ static void addressbook_create(void)
        titles[COL_NAME]    = _("Name");
        titles[COL_ADDRESS] = _("E-Mail address");
        titles[COL_REMARKS] = _("Remarks");
+       dummy_titles[0]     = "";
 
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), _("Address book"));
@@ -677,7 +717,7 @@ static void addressbook_create(void)
        gtk_widget_set_size_request(ctree_swin, COL_FOLDER_WIDTH + 40, -1);
 
        /* Address index */
-       ctree = gtk_ctree_new(1, 0);
+       ctree = gtk_sctree_new_with_titles(1, 0, dummy_titles);
        gtk_container_add(GTK_CONTAINER(ctree_swin), ctree);
        gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);
        gtk_clist_set_column_width(GTK_CLIST(ctree), 0, COL_FOLDER_WIDTH);
@@ -700,6 +740,19 @@ static void addressbook_create(void)
        g_signal_connect(G_OBJECT(ctree), "select_row",
                         G_CALLBACK(addressbook_select_row_tree), NULL);
 
+       gtk_drag_dest_set(ctree, GTK_DEST_DEFAULT_ALL & ~GTK_DEST_DEFAULT_HIGHLIGHT,
+                         addressbook_drag_types, 1,
+                         GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_DEFAULT);
+       g_signal_connect(G_OBJECT(ctree), "drag_motion",
+                        G_CALLBACK(addressbook_drag_motion_cb),
+                        ctree);
+       g_signal_connect(G_OBJECT(ctree), "drag_leave",
+                        G_CALLBACK(addressbook_drag_leave_cb),
+                        ctree);
+       g_signal_connect(G_OBJECT(ctree), "drag_data_received",
+                        G_CALLBACK(addressbook_drag_received_cb),
+                        ctree);
+
        clist_vbox = gtk_vbox_new(FALSE, 4);
 
        clist_swin = gtk_scrolled_window_new(NULL, NULL);
@@ -709,7 +762,7 @@ static void addressbook_create(void)
        gtk_box_pack_start(GTK_BOX(clist_vbox), clist_swin, TRUE, TRUE, 0);
 
        /* Address list */
-       clist = gtk_ctree_new_with_titles(N_COLS, 0, titles);
+       clist = gtk_sctree_new_with_titles(N_COLS, 0, titles);
        gtk_container_add(GTK_CONTAINER(clist_swin), clist);
        gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_EXTENDED);
        gtk_ctree_set_line_style(GTK_CTREE(clist), GTK_CTREE_LINES_NONE);
@@ -742,7 +795,10 @@ static void addressbook_create(void)
                         G_CALLBACK(addressbook_person_expand_node), NULL );
        g_signal_connect(G_OBJECT(clist), "tree_collapse",
                         G_CALLBACK(addressbook_person_collapse_node), NULL );
-
+       g_signal_connect(G_OBJECT(clist), "start_drag",
+                        G_CALLBACK(addressbook_start_drag), NULL);
+       g_signal_connect(G_OBJECT(clist), "drag_data_get",
+                        G_CALLBACK(addressbook_drag_data_get), NULL);  
        hbox = gtk_hbox_new(FALSE, 4);
        gtk_box_pack_start(GTK_BOX(clist_vbox), hbox, FALSE, FALSE, 0);
 
@@ -869,6 +925,8 @@ static void addressbook_create(void)
        addrbook.window  = window;
        addrbook.menubar = menubar;
        addrbook.ctree   = ctree;
+       addrbook.ctree_swin
+                        = ctree_swin;
        addrbook.clist   = clist;
        addrbook.entry   = entry;
        addrbook.statusbar = statusbar;
@@ -1182,7 +1240,7 @@ static void addressbook_to_clicked(GtkButton *button, gpointer data)
        if( ! compose ) return;
 
        /* Nothing selected, but maybe there is something in text entry */
-       addr = gtk_entry_get_text( GTK_ENTRY( addrbook.entry) );
+       addr = (char *)gtk_entry_get_text( GTK_ENTRY( addrbook.entry) );
        if ( addr ) {
                compose_entry_append(
                        compose, addr, (ComposeEntryType)data );
@@ -2506,6 +2564,16 @@ static AddressBookFile *addressbook_get_book_file() {
        return abf;
 }
 
+static AddressBookFile *addressbook_get_book_file_for_node(GtkCTreeNode *node) {
+       AddressBookFile *abf = NULL;
+       AddressDataSource *ds = NULL;
+
+       ds = addressbook_find_datasource( node );
+       if( ds == NULL ) return NULL;
+       if( ds->type == ADDR_IF_BOOK ) abf = ds->rawDataSource;
+       return abf;
+}
+
 static void addressbook_tree_remove_children( GtkCTree *ctree, GtkCTreeNode *parent ) {
        GtkCTreeNode *node;
        GtkCTreeRow *row;
@@ -4433,6 +4501,262 @@ static void addressbook_export_ldif_cb( void ) {
        addressbook_exp_ldif( cache );
 }
 
+static void addressbook_start_drag(GtkWidget *widget, gint button, 
+                                  GdkEvent *event,
+                                  void *data)
+{
+       GdkDragContext *context;
+       if (addressbook_target_list == NULL)
+               addressbook_target_list = gtk_target_list_new(
+                               addressbook_drag_types, 1);
+       context = gtk_drag_begin(widget, addressbook_target_list,
+                                GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_DEFAULT, button, event);
+       gtk_drag_set_icon_default(context);
+}
+
+static ItemPerson *dragged_person = NULL;
+static ItemFolder *dragged_folder = NULL;
+static AddressBookFile *dragged_ab = NULL;
+
+static void addressbook_drag_data_get(GtkWidget        *widget,
+                                    GdkDragContext   *drag_context,
+                                    GtkSelectionData *selection_data,
+                                    guint             info,
+                                    guint             time,
+                                    void             *data)
+{
+       AddrItemObject *aio = NULL;
+       AddressObject *pobj = NULL;
+       AdapterDSource *ads = NULL;
+       AddressDataSource *ds = NULL;
+
+       pobj = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.ctree), addrbook.treeSelected );
+       if( pobj == NULL ) return;
+
+       if( pobj->type == ADDR_DATASOURCE ) {
+               ads = ADAPTER_DSOURCE(pobj);
+               ds = ads->dataSource;
+       } else if (pobj->type == ADDR_ITEM_GROUP) {
+               return;
+       }
+       
+       else if( pobj->type != ADDR_INTERFACE ) {
+               ds = addressbook_find_datasource( addrbook.treeSelected );
+               if (!ds)
+                       return;
+       }
+       if (addrbook.listSelected)
+               aio = gtk_ctree_node_get_row_data( GTK_CTREE(addrbook.clist), 
+                               addrbook.listSelected );
+       
+       while (aio && aio->type != ADDR_ITEM_PERSON) {
+               aio = aio->parent;
+       }
+
+       if (aio && aio->type == ADDR_ITEM_PERSON) {
+               dragged_person = (ItemPerson *)aio;
+               dragged_folder = (ItemFolder *)ADAPTER_FOLDER(pobj)->itemFolder;
+               dragged_ab = addressbook_get_book_file();
+
+               gtk_selection_data_set(selection_data,
+                                      selection_data->target, 8,
+                                      "Dummy_addr", 11);
+               drag_context->actions = GDK_ACTION_MOVE;
+               
+               if (pobj->type == ADDR_DATASOURCE) {
+                       if( ds != NULL) {
+                               dragged_folder = addrindex_ds_get_root_folder( ds );
+                               if (ds->type != ADDR_IF_JPILOT ||
+                                   ds->type != ADDR_IF_LDAP)
+                                   drag_context->action = GDK_ACTION_COPY;
+                       } else {
+                               dragged_folder = NULL;
+                               dragged_person = NULL;
+                               dragged_ab = NULL;
+                       }
+               }
+       } else {
+               dragged_folder = NULL;
+               dragged_person = NULL;
+               dragged_ab = NULL;
+       }
+}
+
+static gboolean addressbook_drag_motion_cb(GtkWidget      *widget,
+                                         GdkDragContext *context,
+                                         gint            x,
+                                         gint            y,
+                                         guint           time,
+                                         void            *data)
+{
+       gint row, column;
+       GtkCTreeNode *node = NULL;
+       gboolean acceptable = FALSE;
+       gint height = addrbook.ctree->allocation.height;
+       gint total_height = addrbook.ctree->requisition.height;
+       GtkAdjustment *pos = gtk_scrolled_window_get_vadjustment(
+                               GTK_SCROLLED_WINDOW(addrbook.ctree_swin));
+       gfloat vpos = pos->value;
+       
+       if (gtk_clist_get_selection_info
+               (GTK_CLIST(widget), x - 24, y - 24, &row, &column)) {
+
+               if (y > height - 24 && height + vpos < total_height)
+                       gtk_adjustment_set_value(pos, (vpos+5 > height ? height : vpos+5));
+
+               if (y < 24 && y > 0)
+                       gtk_adjustment_set_value(pos, (vpos-5 < 0 ? 0 : vpos-5));
+
+               node = gtk_ctree_node_nth(GTK_CTREE(widget), row);
+
+               if (node != NULL) {
+                       AddressObject *obj = gtk_ctree_node_get_row_data(GTK_CTREE(widget), node );
+                       if( obj->type == ADDR_ITEM_FOLDER 
+                       || obj->type == ADDR_ITEM_GROUP)
+                               acceptable = TRUE;
+                       else {
+                               AdapterDSource *ads = NULL;
+                               AddressDataSource *ds = NULL;
+                               ads = ADAPTER_DSOURCE(obj);
+                               if (ads == NULL ) return FALSE;
+                               ds = ads->dataSource;
+                               if (ds == NULL ) return FALSE;
+                               if (obj->type == ADDR_DATASOURCE
+                               &&  !ds->interface->externalQuery)
+                                       acceptable = TRUE;
+
+                       }
+               }
+       }
+
+       
+       if (acceptable) {
+               g_signal_handlers_block_by_func
+                       (G_OBJECT(widget),
+                        G_CALLBACK(addressbook_tree_selected), NULL);
+               gtk_ctree_select(GTK_CTREE(widget), node);
+               g_signal_handlers_unblock_by_func
+                       (G_OBJECT(widget),
+                        G_CALLBACK(addressbook_tree_selected), NULL);
+               gdk_drag_status(context, 
+                                       (context->actions == GDK_ACTION_COPY ?
+                                       GDK_ACTION_COPY : GDK_ACTION_MOVE) , time);
+       } else {
+               gdk_drag_status(context, 0, time);
+       }
+
+       return acceptable;
+}
+
+static void addressbook_drag_leave_cb(GtkWidget      *widget,
+                                    GdkDragContext *context,
+                                    guint           time,
+                                    void           *data)
+{
+       if (addrbook.treeSelected) {
+               g_signal_handlers_block_by_func
+                       (G_OBJECT(widget),
+                        G_CALLBACK(addressbook_tree_selected), NULL);
+               gtk_ctree_select(GTK_CTREE(widget), addrbook.treeSelected);
+               g_signal_handlers_unblock_by_func
+                       (G_OBJECT(widget),
+                        G_CALLBACK(addressbook_tree_selected), NULL);
+       }
+}
+
+static AddressBookFile *get_rawDataSource(ItemFolder *item)
+{
+       AdapterDSource *ads = NULL;
+       AddressDataSource *ds = NULL;
+       ads = ADAPTER_DSOURCE(item);
+       if (ads == NULL ) return NULL;
+       ds = ads->dataSource;
+       if (ds == NULL ) return NULL;
+
+       return ds->rawDataSource;
+}
+
+static void addressbook_drag_received_cb(GtkWidget        *widget,
+                                       GdkDragContext   *drag_context,
+                                       gint              x,
+                                       gint              y,
+                                       GtkSelectionData *data,
+                                       guint             info,
+                                       guint             time,
+                                       void             *pdata)
+{
+       gint row, column;
+       GtkCTreeNode *node;
+       ItemFolder *afolder = NULL;
+       ItemFolder *ofolder = NULL;
+       ItemPerson *person = NULL;
+       
+
+       if (!strcmp(data->data, "Dummy_addr")) {
+               AddressObject *obj = NULL;
+               AdapterDSource *ads = NULL;
+               AddressDataSource *ds = NULL;
+               AddrBookBase *adbase = NULL;
+               AddressCache *cache = NULL;
+
+               
+               if (gtk_clist_get_selection_info
+                       (GTK_CLIST(widget), x - 24, y - 24, &row, &column) == 0) {
+                       return;
+               }
+       
+               node = gtk_ctree_node_nth(GTK_CTREE(widget), row);
+               if( node ) 
+                       obj = gtk_ctree_node_get_row_data(GTK_CTREE(addrbook.ctree), node );
+               if( obj == NULL ) 
+                       return;
+                       
+               
+               
+               person = ( ItemPerson * )dragged_person;
+               
+               if (obj->type == ADDR_ITEM_FOLDER) {
+                       afolder = ADAPTER_FOLDER(obj)->itemFolder;
+
+               } else if (obj->type == ADDR_DATASOURCE) {
+                       ads = ADAPTER_DSOURCE(obj);
+                       if( ads == NULL ) 
+                               return;
+                       ds = ads->dataSource;
+                       if( ds == NULL ||
+                           ds->type == ADDR_IF_JPILOT || 
+                           ds->type == ADDR_IF_LDAP) 
+                               return;         
+                       afolder = addrindex_ds_get_root_folder( ds );
+                       
+               } else {
+                       return;
+               }
+
+               ofolder = dragged_folder;
+               
+               if (afolder && ofolder) {
+                       AddressBookFile *obook = dragged_ab;
+                       AddressBookFile *abook = addressbook_get_book_file_for_node(node);
+                       addritem_folder_remove_person(ofolder, person);
+                       addritem_folder_add_person(afolder, person);
+                       addressbook_list_select_clear();
+                       gtk_ctree_select( GTK_CTREE(addrbook.ctree), addrbook.opened);
+                                                       
+                       if (abook) {
+                               addrbook_set_dirty(abook, TRUE);
+                       }
+                       if (obook) {
+                               addrbook_set_dirty(obook, TRUE);
+                       }
+                       
+                       addressbook_export_to_file();
+               }
+
+               gtk_drag_finish(drag_context, TRUE, TRUE, time);
+       }
+}
+
 /*
 * End of Source.
 */
index 8b39df650264f981e662a808b6918d8b176dc258..8af19a6e640cc3ab4b34573d505bc97734762c6f 100644 (file)
@@ -62,6 +62,7 @@ struct _AddressBook_win
        GtkWidget *window;
        GtkWidget *menubar;
        GtkWidget *ctree;
+       GtkWidget *ctree_swin;
        GtkWidget *clist;
        GtkWidget *entry;
        GtkWidget *statusbar;
index fbda06bf0cbf3036a7eea01d48c30dd6350fb8f6..c0d9d70a2433ad2be65c5dca8d5d1318f15ea76f 100644 (file)
@@ -846,6 +846,29 @@ ItemEMail *addritem_group_remove_email( ItemGroup *group, ItemEMail *email ) {
        return NULL;
 }
 
+/**
+ * Remove person object for specified group.
+ * \param  group Group from which to remove address.
+ * \param  email EMail to remove
+ * \return EMail object, or <i>NULL if email not found in group. Note that
+ *         this object is referenced (linked) to a group and should *NOT*
+ *         be freed. An E-Mail object object should only be freed after
+ *         removing from a person.
+ */
+ItemPerson *addritem_folder_remove_person( ItemFolder *group, ItemPerson *person ) {
+       if( group && person ) {
+               GList *node = group->listPerson;
+               while( node ) {
+                       if( node->data == person ) {
+                               group->listPerson = g_list_remove( group->listPerson, person );
+                               return person;
+                       }
+                       node = g_list_next( node );
+               }
+       }
+       return NULL;
+}
+
 /**
  * Remove email address of specified ID for specified group.
  * \param  group Group from which to remove address.
index 6c2fbab2dd877f5d571acc974eed89a823ce40a0..322c8dc9901494a573251fd08d31f0e6e6e58c93 100644 (file)
@@ -178,6 +178,8 @@ ItemEMail *addritem_group_remove_email      ( ItemGroup *group, ItemEMail *email );
 ItemEMail *addritem_group_remove_email_id( ItemGroup *group, const gchar *eid );
 
 gboolean addritem_folder_add_person    ( ItemFolder *folder, ItemPerson *item );
+ItemPerson *addritem_folder_remove_person( ItemFolder *group, ItemPerson *person );
+
 gboolean addritem_folder_add_folder    ( ItemFolder *folder, ItemFolder *item );
 gboolean addritem_folder_add_group     ( ItemFolder *folder, ItemGroup *item );
 void addritem_folder_free_person       ( ItemFolder *folder );