]> sjero.net Git - linphone/commitdiff
gtk-ui: implement friend lookup and sorting
authorSimon Morlat <simon.morlat@linphone.org>
Thu, 12 Jan 2012 16:16:06 +0000 (17:16 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Thu, 12 Jan 2012 16:16:06 +0000 (17:16 +0100)
NEWS
gtk/friendlist.c
gtk/main.ui
mediastreamer2

diff --git a/NEWS b/NEWS
index 15cefbb71370d58e4631b33be2e6b08eec8d454b..a4b134ddfc544607bd471a5b3da9e5c0d43cdd97 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
index 9dacac717882571f03567d4e85c1f051ca615469..d5a056feff907b5bf5249e598d3084cf5e8747c7 100644 (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();
index 7ebe95363508621f0dbdfae5ac27912e05733fb4..fde3a794a62a9ae95fa6c2a22071f08ecc18bda6 100644 (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>
                                     <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>
                                     <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>
                                     <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>
                                         <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"/>
                                     <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>
                                         <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>
                                         <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>
index 668bdcc2c04a487fb94f31b7790ef301908c47b5..c8106487faa8cee02f4dd94b03e4f9185b236b4e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 668bdcc2c04a487fb94f31b7790ef301908c47b5
+Subproject commit c8106487faa8cee02f4dd94b03e4f9185b236b4e