Commit a343889b authored by Julien Bonjean's avatar Julien Bonjean

Improved contacts list

 - Performance : now handle only last search
 - Added waiting image
 - Optimized query (only get contacts with at least one phone number)
parent 54d9c5a0
......@@ -31,6 +31,7 @@
#include "eds.h"
typedef struct _Handler_And_Data {
int search_id;
SearchAsyncHandler handler;
gpointer user_data;
GList *hits;
......@@ -95,6 +96,7 @@ create_query (const char* s)
GArray *parts = split_query_string (s);
EBookQuery ***field_queries;
EBookQuery **q;
EBookQuery **phone;
guint j;
int i;
......@@ -110,13 +112,19 @@ create_query (const char* s)
}
g_array_free (parts, TRUE);
query = e_book_query_or (n_search_fields, q, TRUE);
phone = g_new0 (EBookQuery *, 3);
phone[0] = e_book_query_field_exists (E_CONTACT_PHONE_BUSINESS);
phone[1] = e_book_query_field_exists (E_CONTACT_PHONE_HOME);
phone[2] = e_book_query_field_exists (E_CONTACT_PHONE_MOBILE);
query = e_book_query_andv (e_book_query_or (n_search_fields, q, FALSE), e_book_query_or (3, phone, FALSE));
for (i = 0; i < n_search_fields; i++) {
g_free (field_queries[i]);
}
g_free (field_queries);
g_free (q);
g_free (phone);
return query;
}
......@@ -188,30 +196,66 @@ init (void)
}
}
current_search_id = 0;
g_object_unref (source_list);
}
/**
* Final callback after all books have been processed.
*/
static void
view_finish (EBookView *book_view, Handler_And_Data *had)
{
GList *i;
SearchAsyncHandler had_handler = had->handler;
GList *had_hits = had->hits;
gpointer had_user_data = had->user_data;
int search_id = had->search_id;
g_free (had);
g_return_if_fail (book_view != NULL);
g_object_unref (book_view);
if(search_id == current_search_id)
{
// Reinitialize search id to prevent overflow
if(current_search_id > 5000)
current_search_id = 0;
// Call display callback
had_handler (had_hits, had_user_data);
}
else
{
// Some hits could have been processed but will not be used
for (i = had_hits; i != NULL; i = i->next)
{
Hit *entry;
entry = i->data;
free_hit(entry);
}
g_list_free(had_hits);
}
}
/**
* Callback called after each ebook search completed.
* Used to store book search results.
*/
static void
view_contacts_added_cb (EBookView *book_view, GList *contacts, gpointer user_data)
{
GdkPixbuf *photo;
Handler_And_Data *had = (Handler_And_Data *) user_data;
if(had->search_id != current_search_id)
{
e_book_view_stop (book_view);
return;
}
if (had->max_results_remaining <= 0) {
e_book_view_stop (book_view);
had->book_views_remaining--;
......@@ -261,6 +305,10 @@ view_contacts_added_cb (EBookView *book_view, GList *contacts, gpointer user_dat
}
}
/**
* Callback called after each ebook search completed.
* Used to call final callback when all books have been read.
*/
static void
view_completed_cb (EBookView *book_view, EBookViewStatus status, gpointer user_data)
{
......@@ -271,17 +319,30 @@ view_completed_cb (EBookView *book_view, EBookViewStatus status, gpointer user_d
}
}
void
search_async (const char *query,
int max_results,
SearchAsyncHandler handler,
gpointer user_data)
{
GSList *iter;
// Increment search id
current_search_id++;
EBookQuery* book_query = create_query (query);
// If query is null
if(strlen(query) < 1)
{
// If data displayed (from previous search), directly call callback
handler(NULL, user_data);
return;
}
GSList *iter;
EBookQuery* book_query = create_query (query);
Handler_And_Data *had = g_new (Handler_And_Data, 1);
had->search_id = current_search_id;
had->handler = handler;
had->user_data = user_data;
had->hits = NULL;
......
......@@ -35,6 +35,8 @@
G_BEGIN_DECLS
int current_search_id;
/**
* Reprsent a contact entry
*/
......
......@@ -104,6 +104,8 @@ static void handler_async_search (GList *hits, gpointer user_data) {
}
g_list_free(hits);
// Deactivate waiting image
deactivateWaitingLayer();
}
void filter_entry_changed (GtkEntry* entry UNUSED, gchar* arg1 UNUSED, gpointer data UNUSED) {
......@@ -117,8 +119,12 @@ void filter_entry_changed (GtkEntry* entry UNUSED, gchar* arg1 UNUSED, gpointer
/* We want to search in the contact list */
if (active_calltree == contacts) {
// Activate waiting layer
activateWaitingLayer();
// Load the address book parameters
addressbook_load_parameters (&addressbook_config);
// Start the asynchronous search as soon as we have an entry */
search_async (gtk_entry_get_text (GTK_ENTRY (filter_entry)), addressbook_config->max_results, &handler_async_search, addressbook_config);
}
......@@ -147,6 +153,22 @@ GtkWidget* create_filter_entry() {
g_signal_connect(GTK_ENTRY(filter_entry), "grab-focus", G_CALLBACK(clear_filter_entry_if_default), NULL);
gtk_box_pack_start(GTK_BOX(ret), filter_entry, TRUE, TRUE, 0);
// Create waiting icon
waitingPixOn = gdk_pixbuf_animation_new_from_file(ICONS_DIR "/throbber.gif", NULL);
waitingPixOff = gdk_pixbuf_new_from_file(ICONS_DIR "/throbber.png", NULL);
waitingLayer = gtk_image_new_from_pixbuf(waitingPixOff);
gtk_box_pack_end(GTK_BOX(ret), waitingLayer, TRUE, TRUE, 0);
return ret;
}
void activateWaitingLayer() {
gtk_image_set_from_animation(GTK_IMAGE(waitingLayer),waitingPixOn);
}
void deactivateWaitingLayer() {
gtk_image_set_from_pixbuf (GTK_IMAGE(waitingLayer),waitingPixOff);
}
......@@ -26,10 +26,20 @@
#include <gtk/gtk.h>
#include <libsexy/sexy-icon-entry.h>
GtkWidget *waitingLayer;
GdkPixbufAnimation *waitingPixOn;
GdkPixbuf *waitingPixOff;
GtkTreeModel* create_filter(GtkTreeModel* child);
gboolean is_visible(GtkTreeModel* model, GtkTreeIter* iter, gpointer data);
GtkWidget* create_filter_entry();
void activateWaitingLayer();
void deactivateWaitingLayer();
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment