Make double-click open edit dialog also for addressbook datasources.
[claws.git] / src / addressbook.c
index ffd69095bbd9a861b0b9a59cece1d45d46a7f18f..80599f8dce13563f4950430f812ca0812bb857af 100644 (file)
@@ -210,6 +210,9 @@ static void addressbook_person_collapse_node        (GtkCMCTree     *ctree,
                                                 GList          *node,
                                                 gpointer       *data );
 
+static void addressbook_entry_activated                (GtkWidget      *widget,
+                                                gpointer        data);
+
 static gboolean addressbook_list_button_pressed        (GtkWidget      *widget,
                                                 GdkEventButton *event,
                                                 gpointer        data);
@@ -1106,7 +1109,7 @@ static void addressbook_create(void)
        hbox = gtk_hbox_new(FALSE, 4);
        gtk_box_pack_start(GTK_BOX(clist_vbox), hbox, FALSE, FALSE, 0);
 
-       label = gtk_label_new(_("Lookup name:"));
+       label = gtk_label_new(_("Search"));
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
        entry = gtk_entry_new();
@@ -1117,6 +1120,8 @@ static void addressbook_create(void)
        g_signal_connect(G_OBJECT(entry), "key_press_event",
                         G_CALLBACK(addressbook_entry_key_pressed),
                         NULL);
+       g_signal_connect(G_OBJECT(entry), "activate",
+                        G_CALLBACK(addressbook_entry_activated), NULL);
 
        if (!prefs_common.addressbook_use_editaddress_dialog) {
                editaddress_vbox = gtk_vbox_new(FALSE, 4);
@@ -2372,13 +2377,11 @@ static void addressbook_list_row_selected( GtkCMCTree *clist,
                                           gint column,
                                           gpointer data )
 {
-       GtkEntry *entry = GTK_ENTRY(addrbook.entry);
        AddrItemObject *aio = NULL;
        AddressObject *pobj = NULL;
        AdapterDSource *ads = NULL;
        AddressDataSource *ds = NULL;
 
-       gtk_entry_set_text( entry, "" );
        addrbook.listSelected = node;
 
        pobj = gtk_cmctree_node_get_row_data( GTK_CMCTREE(addrbook.ctree), addrbook.treeSelected );
@@ -2425,6 +2428,11 @@ static void addressbook_list_row_unselected( GtkCMCTree *ctree,
                addressbook_edit_person_invalidate(NULL, NULL, NULL);
 }
 
+static void addressbook_entry_activated(GtkWidget *widget, gpointer data)
+{
+       addressbook_lup_clicked(NULL, NULL);
+}
+
 static gboolean addressbook_list_button_pressed(GtkWidget *widget,
                                                GdkEventButton *event,
                                                gpointer data)
@@ -2496,7 +2504,8 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
                        if( obj == NULL )
                                return FALSE;
 
-                       if (obj->type == ADDR_ITEM_GROUP) {
+                       if (obj->type == ADDR_ITEM_GROUP ||
+                                       obj->type == ADDR_DATASOURCE) {
                                /* edit group */
                                addressbook_treenode_edit_cb(NULL, NULL);
                        } else {
@@ -2537,6 +2546,7 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
                        canLookup = TRUE;
        }
        if (obj->type == ADDR_DATASOURCE) {
+               canLookup = TRUE;
                ads = ADAPTER_DSOURCE(obj);
                ds = ads->dataSource;
                if( !ds )
@@ -2552,10 +2562,9 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
                }
                canEdit = TRUE;
                canTreeCopy = TRUE;
-               if( iface->externalQuery )
-                       canLookup = TRUE;
        }
        else if (obj->type == ADDR_ITEM_FOLDER) {
+               canLookup = TRUE;
                ds = addressbook_find_datasource( node );
                if( !ds )
                        goto just_set_sens;
@@ -2574,11 +2583,11 @@ static gboolean addressbook_tree_button_pressed(GtkWidget *ctree,
 
                if( iface->externalQuery ) {
                        /* Enable deletion of LDAP folder */
-                       canLookup = TRUE;
                        canDelete = TRUE;
                }
        }
        else if (obj->type == ADDR_ITEM_GROUP) {
+               canLookup = TRUE;
                ds = addressbook_find_datasource( node );
                if( !ds )
                        goto just_set_sens;
@@ -2919,7 +2928,7 @@ static void addressbook_treenode_delete_cb(GtkAction *action, gpointer data)
                                     "If you delete the folder only, the addresses it contains will be moved into the parent folder." ),
                                 obj->name );
                        aval = alertpanel( _("Delete folder"), message,
-                               GTK_STOCK_CANCEL, _("+Delete _folder only"), _("Delete folder and _addresses"));
+                               GTK_STOCK_CANCEL, g_strconcat("+",_("Delete _folder only"), NULL), _("Delete folder and _addresses"));
                        g_free(message);
                        if( aval == G_ALERTALTERNATE ) {
                                delType = ADDRTREE_DEL_FOLDER_ONLY;
@@ -3299,7 +3308,7 @@ static GtkCMCTreeNode *addressbook_find_group_node( GtkCMCTreeNode *parent, Item
                        AddressObject *obj;
 
                        obj = gtk_cmctree_node_get_row_data( GTK_CMCTREE(addrbook.ctree), node );
-                       if( obj->type == ADDR_ITEM_GROUP ) {
+                       if(obj && obj->type == ADDR_ITEM_GROUP ) {
                                ItemGroup *g = ADAPTER_GROUP(obj)->itemGroup;
                                if( g == group ) return node;
                        }
@@ -3521,9 +3530,32 @@ static gchar *addressbook_format_item_clist( ItemPerson *person, ItemEMail *emai
        return str;
 }
 
+static gboolean addressbook_match_item(const gchar *name,
+                                      const gchar *email_alias,
+                                      const gchar *addr,
+                                      const gchar *remarks,
+                                      const gchar *str)
+{
+       if (!name)
+               return FALSE;
+       if (!str || str[0] == '\0')
+               return TRUE;
+       if (strcasestr(name, str))
+               return TRUE;
+       else if (email_alias && strcasestr(email_alias, str))
+               return TRUE;
+       else if (addr && strcasestr(addr, str))
+               return TRUE;
+       else if (remarks && strcasestr(remarks, str))
+               return TRUE;
+
+       return FALSE;
+}
+
 static void addressbook_load_group( GtkCMCTree *clist, ItemGroup *itemGroup ) {
        GList *items = itemGroup->listEMail;
        AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_EMAIL );
+       const gchar *search_str = gtk_entry_get_text(GTK_ENTRY(addrbook.entry));
        for( ; items != NULL; items = g_list_next( items ) ) {
                GtkCMCTreeNode *nodeEMail = NULL;
                gchar *text[N_LIST_COLS];
@@ -3534,6 +3566,13 @@ static void addressbook_load_group( GtkCMCTree *clist, ItemGroup *itemGroup ) {
                if( ! email ) continue;
 
                person = ( ItemPerson * ) ADDRITEM_PARENT(email);
+
+               if( !addressbook_match_item(ADDRITEM_NAME(person),
+                                           ADDRITEM_NAME(email),
+                                           email->address, email->remarks,
+                                           search_str))
+                       continue;
+
                str = addressbook_format_item_clist( person, email );
                if( str ) {
                        text[COL_NAME] = addressbook_set_col_name_guard(str);
@@ -3659,13 +3698,33 @@ static void addressbook_folder_load_person( GtkCMCTree *clist, ItemFolder *itemF
        GList *items;
        AddressTypeControlItem *atci = addrbookctl_lookup( ADDR_ITEM_PERSON );
        AddressTypeControlItem *atciMail = addrbookctl_lookup( ADDR_ITEM_EMAIL );
+       const gchar *search_str;
 
        if( atci == NULL ) return;
        if( atciMail == NULL ) return;
 
+       search_str = gtk_entry_get_text(GTK_ENTRY(addrbook.entry));
+
        /* Load email addresses */
        items = addritem_folder_get_person_list( itemFolder );
        for( ; items != NULL; items = g_list_next( items ) ) {
+               ItemPerson *person;
+               GList *node;
+               ItemEMail *email;
+
+               person = (ItemPerson *)items->data;
+               if (!person)
+                       continue;
+               node = person->listEMail;
+               if (node && node->data) {
+                       email = node->data;
+                       if (!addressbook_match_item(ADDRITEM_NAME(person), ADDRITEM_NAME(email), email->address, email->remarks, search_str))
+                               continue;
+               } else {
+                       if (!addressbook_match_item(ADDRITEM_NAME(person), NULL, NULL, NULL, search_str))
+                               continue;
+               }
+
                addressbook_folder_load_one_person( clist, items->data, atci, atciMail );
        }
        /* Free up the list */
@@ -3718,15 +3777,23 @@ static void addressbook_folder_remove_one_person( GtkCMCTree *clist, ItemPerson
 static void addressbook_folder_load_group( GtkCMCTree *clist, ItemFolder *itemFolder ) {
        GList *items;
        AddressTypeControlItem *atci =  addrbookctl_lookup( ADDR_ITEM_GROUP );
+       const gchar *search_str;
 
        /* Load any groups */
        if( ! atci ) return;
+
+       search_str = gtk_entry_get_text(GTK_ENTRY(addrbook.entry));
+
        items = addritem_folder_get_group_list( itemFolder );
        for( ; items != NULL; items = g_list_next( items ) ) {
                GtkCMCTreeNode *nodeGroup = NULL;
                gchar *text[N_LIST_COLS];
                ItemGroup *group = items->data;
                if( group == NULL ) continue;
+               if( !addressbook_match_item(ADDRITEM_NAME(group),
+                                           NULL, NULL, NULL, search_str) )
+                       continue;
+
                text[COL_NAME] = ADDRITEM_NAME(group);
                text[COL_ADDRESS] = "";
                text[COL_REMARKS] = "";
@@ -4085,22 +4152,26 @@ static gboolean addressbook_convert( AddressIndex *addrIndex ) {
 
 static gboolean migrate_addrbook(const gchar *origdir, const gchar *destdir)
 {
-       DIR *dp;
-       struct dirent *d;
+       GDir *dp;
+       const gchar *d;
        gboolean failed = FALSE;
+       GError *error = NULL;
 
-       if( ( dp = opendir( origdir ) ) == NULL ) {
+       if( ( dp = g_dir_open( origdir, 0, &error ) ) == NULL ) {
+               debug_print("opening '%s' failed: %d (%s)\n", origdir,
+                               error->code, error->message);
+               g_error_free(error);
                return FALSE;
        }
        
-       while( ( d = readdir( dp ) ) != NULL ) {
-               if (strncmp(d->d_name, "addrbook-", strlen("addrbook-")))
+       while( ( d = g_dir_read_name( dp ) ) != NULL ) {
+               if (strncmp(d, "addrbook-", strlen("addrbook-")))
                        continue;
                else {
                        gchar *orig_file = g_strconcat(origdir, G_DIR_SEPARATOR_S, 
-                                       d->d_name, NULL);
+                                       d, NULL);
                        gchar *dest_file = g_strconcat(destdir, G_DIR_SEPARATOR_S, 
-                                       d->d_name, NULL);
+                                       d, NULL);
                        if (copy_file(orig_file, dest_file, FALSE) < 0) {
                                failed = TRUE;
                        }
@@ -4111,24 +4182,27 @@ static gboolean migrate_addrbook(const gchar *origdir, const gchar *destdir)
                        }
                }
        }
+       g_dir_close( dp );
 
-       closedir( dp );
        if (!failed) {
                /* all copies succeeded, we can remove source files */
-               if( ( dp = opendir( origdir ) ) == NULL ) {
+               if( ( dp = g_dir_open( origdir, 0, &error ) ) == NULL ) {
+                       debug_print("opening '%s' failed: %d (%s)\n", origdir,
+                                       error->code, error->message);
+                       g_error_free(error);
                        return FALSE;
                }
-               while( ( d = readdir( dp ) ) != NULL ) {
-                       if (strncmp(d->d_name, "addrbook-", strlen("addrbook-")))
+               while( ( d = g_dir_read_name( dp ) ) != NULL ) {
+                       if (strncmp(d, "addrbook-", strlen("addrbook-")))
                                continue;
                        else {
                                gchar *orig_file = g_strconcat(origdir, G_DIR_SEPARATOR_S, 
-                                               d->d_name, NULL);
+                                               d, NULL);
                                claws_unlink(orig_file);
                                g_free(orig_file);
                        }
                }
-               closedir( dp );
+               g_dir_close( dp );
        }
        
        return !failed;
@@ -4152,7 +4226,7 @@ void addressbook_read_file( void ) {
        if ( !is_dir_exist(indexdir) ) {
                if ( make_dir(indexdir) < 0 ) {
                        addrindex_set_file_path( addrIndex, get_rc_dir() );
-                       g_warning( "couldn't create dir %s\n", indexdir);
+                       g_warning( "couldn't create dir '%s'", indexdir);
                } else {
                        if (!migrate_addrbook(get_rc_dir(), indexdir)) {
                                remove_dir_recursive(indexdir);
@@ -4633,6 +4707,14 @@ static void addressbook_lup_clicked( GtkButton *button, gpointer data ) {
        obj = gtk_cmctree_node_get_row_data( ctree, node );
        if( obj == NULL ) return;
 
+       if (obj->type != ADDR_DATASOURCE ||
+                       ADAPTER_DSOURCE(obj)->subType != ADDR_LDAP) {
+               addressbook_set_clist(
+                               gtk_cmctree_node_get_row_data(GTK_CMCTREE(addrbook.ctree),
+                                       addrbook.treeSelected),
+                               TRUE);
+       }
+
        ds = addressbook_find_datasource( node );
        if( ds == NULL ) return;
 
@@ -4740,7 +4822,7 @@ ItemObjectType addressbook_type2item( AddressObjectType abType ) {
                atci->iconXpm = icon;                           \
                atci->iconXpmOpen = iconopen;                   \
        } else {                                                \
-               g_warning("can't get atci %d\n", id);           \
+               g_warning("can't get atci %d", id);             \
        }                                                       \
 }