gtk-ui: implement friend lookup and sorting

This commit is contained in:
Simon Morlat 2012-01-12 17:16:06 +01:00
parent 02dfee95c5
commit c40cfeb0fe
4 changed files with 136 additions and 58 deletions

3
NEWS
View file

@ -1,3 +1,6 @@
linphone-3.5.1 -- ??
* gtk - implement friend search by typing into the friendlist, and friend sorting
linphone-3.5.0 -- December 22, 2011
* added VP-8 video codec
* added G722 audio codec

View file

@ -239,6 +239,119 @@ static void linphone_gtk_init_bookmark_icon(void){
g_signal_connect(G_OBJECT(GTK_EDITABLE(entry)),"changed",(GCallback)check_contact,linphone_gtk_get_core());
}
static gboolean friend_search_func(GtkTreeModel *model, gint column,
const gchar *key,
GtkTreeIter *iter,
gpointer search_data){
char *name=NULL;
gboolean ret=TRUE;
gtk_tree_model_get(model,iter,FRIEND_NAME,&name,-1);
if (name!=NULL){
ret=strstr(name,key)==NULL;
g_free(name);
}
return ret;
}
static gint friend_sort(GtkTreeModel *model, GtkTreeIter *a,GtkTreeIter *b,gpointer user_data){
char *n1=NULL,*n2=NULL;
int ret;
gtk_tree_model_get(model,a,FRIEND_NAME,&n1,-1);
gtk_tree_model_get(model,b,FRIEND_NAME,&n2,-1);
if (n1 && n2) {
ret=strcmp(n1,n2);
g_free(n1);
g_free(n2);
}else if (n1){
g_free(n1);
ret=-1;
}else if (n2){
g_free(n2);
ret=1;
}else ret=0;
return ret;
}
static void on_name_column_clicked(GtkTreeModel *model){
GtkSortType st;
gint column;
gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(model),&column,&st);
if (column==FRIEND_NAME){
if (st==GTK_SORT_ASCENDING) st=GTK_SORT_DESCENDING;
else st=GTK_SORT_ASCENDING;
}else st=GTK_SORT_ASCENDING;
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),FRIEND_NAME,st);
}
static int get_friend_weight(const LinphoneFriend *lf){
int w=0;
switch(linphone_friend_get_status(lf)){
case LinphoneStatusOnline:
w+=1000;
break;
case LinphoneStatusOffline:
if (linphone_friend_get_send_subscribe(lf))
w+=100;
break;
default:
w+=500;
break;
}
return w;
}
static int friend_compare_func(const LinphoneFriend *lf1, const LinphoneFriend *lf2){
int w1,w2;
w1=get_friend_weight(lf1);
w2=get_friend_weight(lf2);
if (w1==w2){
const char *u1,*u2;
const LinphoneAddress *addr1,*addr2;
addr1=linphone_friend_get_address(lf1);
addr2=linphone_friend_get_address(lf2);
u1=linphone_address_get_username(addr1);
u2=linphone_address_get_username(addr2);
if (u1 && u2) return strcasecmp(u1,u2);
if (u1) return 1;
else return -1;
}
return w2-w1;
}
static gint friend_sort_with_presence(GtkTreeModel *model, GtkTreeIter *a,GtkTreeIter *b,gpointer user_data){
LinphoneFriend *lf1=NULL,*lf2=NULL;
gtk_tree_model_get(model,a,FRIEND_ID,&lf1,-1);
gtk_tree_model_get(model,b,FRIEND_ID,&lf2,-1);
return friend_compare_func(lf1,lf2);
}
static MSList *sort_friend_list(const MSList *friends){
MSList *ret=NULL;
const MSList *elem;
LinphoneFriend *lf;
for(elem=friends;elem!=NULL;elem=elem->next){
lf=(LinphoneFriend*)elem->data;
ret=ms_list_insert_sorted(ret,lf,(MSCompareFunc)friend_compare_func);
}
return ret;
}
static void on_presence_column_clicked(GtkTreeModel *model){
GtkSortType st;
gint column;
gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(model),&column,&st);
if (column==FRIEND_ID){
if (st==GTK_SORT_ASCENDING) st=GTK_SORT_DESCENDING;
else st=GTK_SORT_ASCENDING;
}else st=GTK_SORT_ASCENDING;
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),FRIEND_ID,st);
}
static void linphone_gtk_friend_list_init(GtkWidget *friendlist)
{
GtkListStore *store;
@ -254,12 +367,21 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist)
gtk_tree_view_set_model(GTK_TREE_VIEW(friendlist),GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(friendlist),friend_search_func,NULL,NULL);
gtk_tree_view_set_search_column(GTK_TREE_VIEW(friendlist),FRIEND_NAME);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store),FRIEND_NAME,friend_sort,NULL,NULL);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store),FRIEND_ID,friend_sort_with_presence,NULL,NULL);
renderer = gtk_cell_renderer_pixbuf_new ();
column = gtk_tree_view_column_new_with_attributes (_("Name"),
renderer,
"pixbuf", FRIEND_ICON,
NULL);
g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
g_signal_connect_swapped(G_OBJECT(column),"clicked",(GCallback)on_name_column_clicked,GTK_TREE_MODEL(store));
gtk_tree_view_column_set_clickable(column,TRUE);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start(column,renderer,FALSE);
gtk_tree_view_column_add_attribute (column,renderer,
@ -273,6 +395,8 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist)
"text", FRIEND_PRESENCE_STATUS,
NULL);
g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
g_signal_connect_swapped(G_OBJECT(column),"clicked",(GCallback)on_presence_column_clicked,GTK_TREE_MODEL(store));
gtk_tree_view_column_set_clickable(column,TRUE);
gtk_tree_view_column_set_visible(column,linphone_gtk_get_ui_config_int("friendlist_status",1));
renderer = gtk_cell_renderer_pixbuf_new();
@ -344,52 +468,6 @@ void linphone_gtk_directory_search_button_clicked(GtkWidget *button){
linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"directory_search_entry"));
}
static int get_friend_weight(const LinphoneFriend *lf){
int w=0;
switch(linphone_friend_get_status(lf)){
case LinphoneStatusOnline:
w+=1000;
break;
case LinphoneStatusOffline:
if (linphone_friend_get_send_subscribe(lf))
w+=100;
break;
default:
w+=500;
break;
}
return w;
}
static int friend_compare_func(const LinphoneFriend *lf1, const LinphoneFriend *lf2){
int w1,w2;
w1=get_friend_weight(lf1);
w2=get_friend_weight(lf2);
if (w1==w2){
const char *u1,*u2;
const LinphoneAddress *addr1,*addr2;
addr1=linphone_friend_get_address(lf1);
addr2=linphone_friend_get_address(lf2);
u1=linphone_address_get_username(addr1);
u2=linphone_address_get_username(addr2);
if (u1 && u2) return strcasecmp(u1,u2);
if (u1) return 1;
else return -1;
}
return w2-w1;
}
static MSList *sort_friend_list(const MSList *friends){
MSList *ret=NULL;
const MSList *elem;
LinphoneFriend *lf;
for(elem=friends;elem!=NULL;elem=elem->next){
lf=(LinphoneFriend*)elem->data;
ret=ms_list_insert_sorted(ret,lf,(MSCompareFunc)friend_compare_func);
}
return ret;
}
void linphone_gtk_show_friends(void){
GtkWidget *mw=linphone_gtk_get_main_window();

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.18"/>
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="dummy_conf_window">
<property name="can_focus">False</property>
<child>
@ -652,8 +651,6 @@
<property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
<signal name="activate" handler="linphone_gtk_uri_bar_activate" swapped="no"/>
</object>
<packing>
@ -745,8 +742,6 @@
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
<signal name="changed" handler="linphone_gtk_show_friends" swapped="no"/>
</object>
<packing>
@ -808,10 +803,15 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="reorderable">True</property>
<property name="search_column">0</property>
<signal name="button-press-event" handler="linphone_gtk_contact_list_button_pressed" swapped="no"/>
<signal name="cursor-changed" handler="linphone_gtk_contact_clicked" swapped="no"/>
<signal name="row-activated" handler="linphone_gtk_contact_activated" swapped="no"/>
<signal name="popup-menu" handler="linphone_gtk_popup_contact_menu" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
</object>
</child>
</object>
@ -837,8 +837,6 @@
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
<signal name="activate" handler="linphone_gtk_directory_search_activate" swapped="no"/>
<signal name="icon-press" handler="linphone_gtk_directory_search_activate" swapped="no"/>
<signal name="focus-in-event" handler="linphone_gtk_directory_search_focus_in" swapped="no"/>
@ -1037,6 +1035,9 @@
<property name="headers_visible">False</property>
<signal name="cursor-changed" handler="linphone_gtk_history_row_selected" swapped="no"/>
<signal name="row-activated" handler="linphone_gtk_history_row_activated" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection2"/>
</child>
</object>
</child>
</object>
@ -1540,8 +1541,6 @@
<property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
@ -1556,8 +1555,6 @@
<property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>

@ -1 +1 @@
Subproject commit 668bdcc2c04a487fb94f31b7790ef301908c47b5
Subproject commit c8106487faa8cee02f4dd94b03e4f9185b236b4e