diff --git a/linphone/coreapi/plugins/buddylookup/INSTALL b/linphone/coreapi/plugins/buddylookup/INSTALL
old mode 100755
new mode 100644
diff --git a/linphone/coreapi/plugins/buddylookup/src/lookup.c b/linphone/coreapi/plugins/buddylookup/src/lookup.c
index 01a905511..488a2146d 100644
--- a/linphone/coreapi/plugins/buddylookup/src/lookup.c
+++ b/linphone/coreapi/plugins/buddylookup/src/lookup.c
@@ -81,8 +81,8 @@ static void fill_item(GHashTable *ht , const char *name, char *dest, size_t dest
}else ms_warning("no field named '%s'", name);
}
-static void fill_buddy_info(BuddyInfo *bi, GHashTable *ht){
- char tmp[128];
+static void fill_buddy_info(BuddyLookupState *s, BuddyInfo *bi, GHashTable *ht){
+ char tmp[256];
fill_item(ht,"first_name",bi->firstname,sizeof(bi->firstname));
fill_item(ht,"last_name",bi->lastname,sizeof(bi->lastname));
fill_item(ht,"display_name",bi->displayname,sizeof(bi->displayname));
@@ -98,9 +98,28 @@ static void fill_buddy_info(BuddyInfo *bi, GHashTable *ht){
fill_item(ht,"city",bi->address.town,sizeof(bi->address.town));
fill_item(ht,"country",bi->address.country,sizeof(bi->address.country));
fill_item(ht,"email",bi->email,sizeof(bi->email));
+ tmp[0]='\0';
+ fill_item(ht,"image",tmp,sizeof(tmp));
+ if (tmp[0]!='\0'){
+ SoupMessage *msg;
+ guint status;
+ ms_message("This buddy has an image, let's download it: %s",tmp);
+ msg=soup_message_new("GET",tmp);
+ if ((status=soup_session_send_message(s->session,msg))==200){
+ SoupMessageBody *body=msg->response_body;
+ ms_message("Received %i bytes",body->length);
+ strncpy(bi->image_type,"png",sizeof(bi->image_type));
+ bi->image_length=body->length;
+ bi->image_data=ms_malloc(body->length+4); /*add padding bytes*/
+ memcpy(bi->image_data,body->data,bi->image_length);
+ }else{
+ ms_error("Fail to fetch the image %i",status);
+ }
+ }
+
}
-static MSList * make_buddy_list(GValue *retval){
+static MSList * make_buddy_list(BuddyLookupState *s, GValue *retval){
MSList *ret=NULL;
if (G_VALUE_TYPE(retval)==G_TYPE_VALUE_ARRAY){
GValueArray *array=(GValueArray*)g_value_get_boxed(retval);
@@ -110,8 +129,8 @@ static MSList * make_buddy_list(GValue *retval){
gelem=g_value_array_get_nth(array,i);
if (G_VALUE_TYPE(gelem)==G_TYPE_HASH_TABLE){
GHashTable *ht=(GHashTable*)g_value_get_boxed(gelem);
- BuddyInfo *bi=ms_new0(BuddyInfo,1);
- fill_buddy_info(bi,ht);
+ BuddyInfo *bi=buddy_info_new();
+ fill_buddy_info(s,bi,ht);
ret=ms_list_append(ret,bi);
}else{
ms_error("Element is not a hash table");
@@ -139,7 +158,7 @@ static int xml_rpc_parse_response(SipSetupContext *ctx, SoupMessage *sm){
s->status=BuddyLookupFailure;
}else{
ms_message("Extracting values from return type...");
- s->results=make_buddy_list(&retval);
+ s->results=make_buddy_list(s,&retval);
g_value_unset(&retval);
s->status=BuddyLookupDone;
}
diff --git a/linphone/coreapi/sipsetup.c b/linphone/coreapi/sipsetup.c
index 84c221105..738e273db 100644
--- a/linphone/coreapi/sipsetup.c
+++ b/linphone/coreapi/sipsetup.c
@@ -176,7 +176,7 @@ const char ** sip_setup_context_get_domains(SipSetupContext *ctx){
void sip_setup_context_free_results(MSList *results){
- ms_list_for_each(results,(void (*)(void*))&ms_free);
+ ms_list_for_each(results,(void (*)(void*))&buddy_info_free);
ms_list_free(results);
}
@@ -193,3 +193,14 @@ void sip_setup_context_free(SipSetupContext *ctx){
}
ms_free(ctx);
}
+
+
+BuddyInfo *buddy_info_new(){
+ return ms_new0(BuddyInfo,1);
+}
+
+void buddy_info_free(BuddyInfo *info){
+ if (info->image_data!=NULL)
+ ms_free(info->image_data);
+ ms_free(info);
+}
diff --git a/linphone/coreapi/sipsetup.h b/linphone/coreapi/sipsetup.h
index d0840e915..6e3443953 100644
--- a/linphone/coreapi/sipsetup.h
+++ b/linphone/coreapi/sipsetup.h
@@ -68,6 +68,9 @@ typedef struct _BuddyInfo{
char sip_uri[128];
char email[128];
BuddyAddress address;
+ char image_type[32];
+ uint8_t *image_data;
+ int image_length;
}BuddyInfo;
@@ -100,6 +103,10 @@ typedef struct _SipSetup SipSetup;
extern "C"{
#endif
+BuddyInfo *buddy_info_new();
+void buddy_info_free(BuddyInfo *info);
+
+
void sip_setup_register(SipSetup *ss);
void sip_setup_register_all(void);
SipSetup *sip_setup_lookup(const char *type_name);
diff --git a/linphone/gtk-glade/buddylookup.c b/linphone/gtk-glade/buddylookup.c
index 9518a2a70..8aa5479a9 100644
--- a/linphone/gtk-glade/buddylookup.c
+++ b/linphone/gtk-glade/buddylookup.c
@@ -26,6 +26,7 @@ enum {
LOOKUP_RESULT_NAME,
LOOKUP_RESULT_SIP_URI,
LOOKUP_RESULT_ADDRESS,
+ LOOKUP_RESULT_ICON,
LOOKUP_RESULT_NCOL
};
@@ -48,41 +49,71 @@ static void disable_add_buddy_button(GtkWidget *w){
gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),FALSE);
}
+static void buddy_selection_changed(GtkWidget *w){
+ GtkWidget *results=linphone_gtk_get_widget(w,"search_results");
+ GtkTreeSelection *select;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ enable_add_buddy_button(w);
+
+ select = gtk_tree_view_get_selection(GTK_TREE_VIEW(results));
+ if (gtk_tree_selection_get_selected (select, &model, &iter))
+ {
+ GtkTreePath *path=gtk_tree_model_get_path(model,&iter);
+ gtk_tree_view_collapse_all(GTK_TREE_VIEW(results));
+ gtk_tree_view_expand_row(GTK_TREE_VIEW(results),path,FALSE);
+ gtk_tree_path_free(path);
+ }
+}
+
GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
- GtkListStore *store;
- GtkCellRenderer *renderer;
+ GtkTreeStore *store;
+ GtkCellRenderer *renderer,*pbuf_renderer;
GtkTreeViewColumn *column;
GtkTreeSelection *select;
GtkWidget *w=linphone_gtk_create_window("buddylookup");
GtkWidget *results=linphone_gtk_get_widget(w,"search_results");
GtkProgressBar *pb=GTK_PROGRESS_BAR(linphone_gtk_get_widget(w,"progressbar"));
- store = gtk_list_store_new(LOOKUP_RESULT_NCOL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ store = gtk_tree_store_new(LOOKUP_RESULT_NCOL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF);
+ /*gtk_tree_view_set_hover_expand(GTK_TREE_VIEW(results),TRUE);*/
gtk_tree_view_set_model(GTK_TREE_VIEW(results),GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("Firstname, Lastname"),
renderer,
- "text", LOOKUP_RESULT_NAME,
+ "markup", LOOKUP_RESULT_NAME,
NULL);
g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (results), column);
+
+ pbuf_renderer=gtk_cell_renderer_pixbuf_new();
+ g_object_set(G_OBJECT(renderer),"is-expander",TRUE,NULL);
+ gtk_tree_view_column_pack_start(column,pbuf_renderer,FALSE);
+ gtk_tree_view_column_add_attribute (column,pbuf_renderer,
+ "pixbuf",
+ LOOKUP_RESULT_ICON);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (results), column);
+
+/*
column = gtk_tree_view_column_new_with_attributes (_("SIP address"),
renderer,
"text", LOOKUP_RESULT_SIP_URI,
NULL);
g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (results), column);
-
+*/
+
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (results));
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
- g_signal_connect_swapped(G_OBJECT(select),"changed",(GCallback)enable_add_buddy_button,w);
+ g_signal_connect_swapped(G_OBJECT(select),"changed",(GCallback)buddy_selection_changed,w);
+/*
#if GTK_CHECK_VERSION(2,12,0)
gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(results),LOOKUP_RESULT_ADDRESS);
#endif
+*/
g_object_set_data(G_OBJECT(w),"SipSetupContext",ctx);
g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_buddy_lookup_window_destroyed,w);
//g_signal_connect_swapped(G_OBJECT(w),"destroy",(GCallback)linphone_gtk_buddy_lookup_window_destroyed,w);
@@ -181,23 +212,45 @@ void linphone_gtk_keyword_changed(GtkEditable *e){
}
static void linphone_gtk_display_lookup_results(GtkWidget *w, const MSList *results){
- GtkListStore *store;
+ GtkTreeStore *store;
GtkTreeIter iter;
gchar *tmp;
const MSList *elem;
- store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
- gtk_list_store_clear(store);
+ store=GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
+ gtk_tree_store_clear(store);
disable_add_buddy_button(gtk_widget_get_toplevel(w));
for(elem=results;elem!=NULL;elem=elem->next){
BuddyInfo *bi=(BuddyInfo*)elem->data;
- gtk_list_store_append(store,&iter);
+ GdkPixbuf *pbuf;
+ GtkTreeIter depth1;
+ gtk_tree_store_append(store,&iter,NULL);
tmp=g_strdup_printf("%s, %s (%s)",bi->firstname,bi->lastname,bi->displayname);
- gtk_list_store_set(store,&iter,LOOKUP_RESULT_NAME, tmp,-1);
+ gtk_tree_store_set(store,&iter,LOOKUP_RESULT_NAME, tmp,-1);
g_free(tmp);
- gtk_list_store_set(store,&iter,LOOKUP_RESULT_SIP_URI, bi->sip_uri,-1);
+ gtk_tree_store_set(store,&iter,LOOKUP_RESULT_SIP_URI, bi->sip_uri,-1);
tmp=g_strdup_printf("%s, %s %s\n%s",bi->address.street, bi->address.zip, bi->address.town, bi->address.country);
- gtk_list_store_set(store,&iter,LOOKUP_RESULT_ADDRESS, tmp,-1);
+ gtk_tree_store_set(store,&iter,LOOKUP_RESULT_ADDRESS, tmp,-1);
g_free(tmp);
+ if (bi->image_data!=NULL){
+ pbuf=_gdk_pixbuf_new_from_memory_at_scale(bi->image_data,bi->image_length,-1,40,TRUE);
+ if (pbuf) {
+ gtk_tree_store_set(store,&iter,LOOKUP_RESULT_ICON,pbuf,-1);
+ g_object_unref(G_OBJECT(pbuf));
+ }
+ }
+ gtk_tree_store_append(store,&depth1,&iter);
+ tmp=g_strdup_printf("%s, %s (%s)\n%s, %s %s\n%s\n%s",
+ bi->firstname,bi->lastname,bi->displayname,bi->address.street,
+ bi->address.zip, bi->address.town, bi->address.country,bi->sip_uri);
+ gtk_tree_store_set(store,&depth1,LOOKUP_RESULT_NAME,tmp,-1);
+ g_free(tmp);
+ if (bi->image_data!=NULL){
+ pbuf=_gdk_pixbuf_new_from_memory_at_scale(bi->image_data,bi->image_length,-1,-1,TRUE);
+ if (pbuf) {
+ gtk_tree_store_set(store,&depth1,LOOKUP_RESULT_ICON,pbuf,-1);
+ g_object_unref(G_OBJECT(pbuf));
+ }
+ }
}
}
diff --git a/linphone/gtk-glade/buddylookup.glade b/linphone/gtk-glade/buddylookup.glade
index 8265f7bde..2e6eb96bd 100644
--- a/linphone/gtk-glade/buddylookup.glade
+++ b/linphone/gtk-glade/buddylookup.glade
@@ -116,6 +116,8 @@
+ False
+ False
3
diff --git a/linphone/gtk-glade/linphone.h b/linphone/gtk-glade/linphone.h
index 83e4c1da6..d1ba99459 100644
--- a/linphone/gtk-glade/linphone.h
+++ b/linphone/gtk-glade/linphone.h
@@ -43,6 +43,9 @@ GdkPixbuf * create_pixbuf(const gchar *filename);
GdkPixbufAnimation *create_pixbuf_animation(const gchar *filename);
void add_pixmap_directory(const gchar *directory);
GtkWidget*create_pixmap(const gchar *filename);
+GtkWidget *_gtk_image_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio);
+GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio);
+
GtkWidget *linphone_gtk_create_window(const char *window_name);
GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name);
LinphoneCore *linphone_gtk_get_core(void);
diff --git a/linphone/gtk-glade/utils.c b/linphone/gtk-glade/utils.c
index 97f263a8d..0c9fdd204 100644
--- a/linphone/gtk-glade/utils.c
+++ b/linphone/gtk-glade/utils.c
@@ -92,3 +92,24 @@ gchar *linphone_gtk_get_display_name(const char *sip_uri){
return ret;
}
+GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio){
+ GInputStream *stream=g_memory_input_stream_new_from_data (data,len,NULL);
+ GError *error=NULL;
+
+ GdkPixbuf *pbuf=gdk_pixbuf_new_from_stream_at_scale (stream,w,h,preserve_ratio,NULL,&error);
+ g_input_stream_close(stream,NULL,NULL);
+ g_object_unref(G_OBJECT(stream));
+ if (pbuf==NULL){
+ g_warning("Could not open image from memory");
+ }
+ return pbuf;
+}
+
+GtkWidget * _gtk_image_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio){
+ GtkWidget *image;
+ GdkPixbuf *pbuf=_gdk_pixbuf_new_from_memory_at_scale(data,len,w,h,preserve_ratio);
+ if (pbuf==NULL) return NULL;
+ image=gtk_image_new_from_pixbuf(pbuf);
+ g_object_unref(G_OBJECT(pbuf));
+ return image;
+}