From b6b0368a00d888ef0c114e63e5c29a0cdd6c2fb0 Mon Sep 17 00:00:00 2001 From: Margaux Clerc Date: Wed, 20 Mar 2013 12:36:12 +0100 Subject: [PATCH] add number of unread messages --- coreapi/chat.c | 1 + coreapi/linphonecore.h | 3 +- coreapi/message_storage.c | 48 +++++++++++++++++--- gtk/calllogs.c | 18 ++++++++ gtk/chat.c | 47 +++++++++++++++----- gtk/friendlist.c | 93 +++++++++++++++++++++++---------------- gtk/linphone.h | 2 +- 7 files changed, 155 insertions(+), 57 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 69893217..c12bb339 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -436,6 +436,7 @@ void linphone_chat_message_destroy(LinphoneChatMessage* msg) { if (msg->message) ms_free(msg->message); if (msg->external_body_url) ms_free(msg->external_body_url); if (msg->from) linphone_address_destroy(msg->from); + if (msg->to) linphone_address_destroy(msg->to); if (msg->custom_headers) sal_custom_header_free(msg->custom_headers); ms_free(msg); } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index de8a05af..ab8836a5 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -678,6 +678,7 @@ void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message); void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr); void linphone_chat_room_delete_history(LinphoneChatRoom *cr); +int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr); LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr); void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud); void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr); @@ -685,6 +686,7 @@ void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr); LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message); const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state); LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* message); +void linphone_chat_message_destroy(LinphoneChatMessage* msg); void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from); const LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message); const LinphoneAddress* linphone_chat_message_get_to(const LinphoneChatMessage* message); @@ -1430,7 +1432,6 @@ void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp); int linphone_core_get_video_dscp(const LinphoneCore *lc); - #ifdef __cplusplus } #endif diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index c62fa1dd..0c41c20d 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -78,11 +78,12 @@ static int callback(void *data, int argc, char **argv, char **colName){ } void linphone_sql_request_message(sqlite3 *db,const char *stmt,LinphoneChatRoom *cr){ - char* errmsg; + char* errmsg=NULL; int ret; ret=sqlite3_exec(db,stmt,callback,cr,&errmsg); if(ret != SQLITE_OK) { printf("Error in creation: %s.\n", errmsg); + sqlite3_free(errmsg); } } @@ -99,7 +100,7 @@ void linphone_sql_request(sqlite3* db,const char *stmt){ void linphone_chat_message_store(LinphoneChatMessage *msg){ LinphoneCore *lc=linphone_chat_room_get_lc(msg->chat_room); if (lc->db){ - const char *peer=msg->chat_room->peer; + char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room)); char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg)); char datebuf[26]; char *buf=sqlite3_mprintf("insert into history values(NULL,%Q,%Q,%i,%Q,%Q,%i,%i);", @@ -107,6 +108,7 @@ void linphone_chat_message_store(LinphoneChatMessage *msg){ linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(local_contact); + ms_free(peer); } } @@ -127,19 +129,45 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){ if (lc->db==NULL) return ; + char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); char *buf=sqlite3_mprintf("update history set read=%i where remoteContact = %Q;", - read,cr->peer); + read,peer); linphone_sql_request(lc->db,buf); sqlite3_free(buf); + ms_free(peer); +} + +int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ + LinphoneCore *lc=linphone_chat_room_get_lc(cr); + int numrows=0; + + if (lc->db==NULL) return 0; + + char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); + char *buf=sqlite3_mprintf("select count(*) from history where remoteContact = %Q and read = 0;",peer); + sqlite3_stmt *selectStatement; + int returnValue = sqlite3_prepare_v2(lc->db,buf,-1,&selectStatement,NULL); + if (returnValue == SQLITE_OK){ + if(sqlite3_step(selectStatement) == SQLITE_ROW){ + numrows= sqlite3_column_int(selectStatement, 0); + } + } + sqlite3_finalize(selectStatement); + sqlite3_free(buf); + ms_free(peer); + return numrows; } void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ LinphoneCore *lc=cr->lc; if (lc->db==NULL) return ; - char *buf=sqlite3_mprintf("delete from history where remoteContact = %Q;",cr->peer); + + char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); + char *buf=sqlite3_mprintf("delete from history where remoteContact = %Q;",peer); linphone_sql_request(lc->db,buf); sqlite3_free(buf); + ms_free(peer); } MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ @@ -147,13 +175,14 @@ MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ MSList *ret; if (lc->db==NULL) return NULL; - + char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); cr->messages_hist = NULL; - char *buf=sqlite3_mprintf("select * from history where remoteContact = %Q order by id DESC limit %i ;",cr->peer,nb_message); + char *buf=sqlite3_mprintf("select * from history where remoteContact = %Q order by id DESC limit %i ;",peer,nb_message); linphone_sql_request_message(lc->db,buf,cr); sqlite3_free(buf); ret=cr->messages_hist; cr->messages_hist=NULL; + ms_free(peer); return ret; } @@ -162,12 +191,13 @@ void linphone_close_storage(sqlite3* db){ } void linphone_create_table(sqlite3* db){ - char* errmsg; + char* errmsg=NULL; int ret; ret=sqlite3_exec(db,"CREATE TABLE if not exists history (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT, time TEXT NOT NULL, read INTEGER, status INTEGER);", 0,0,&errmsg); if(ret != SQLITE_OK) { printf("Error in creation: %s.\n", errmsg); + sqlite3_free(errmsg); } } @@ -216,4 +246,8 @@ void linphone_core_message_storage_init(LinphoneCore *lc){ void linphone_core_message_storage_close(LinphoneCore *lc){ } +int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr){ + return 0; +} + #endif diff --git a/gtk/calllogs.c b/gtk/calllogs.c index 45a61611..ce4695dd 100644 --- a/gtk/calllogs.c +++ b/gtk/calllogs.c @@ -33,10 +33,25 @@ static void fill_renderers(GtkTreeView *v){ gtk_tree_view_append_column (v,c); } +void call_log_selection_changed(GtkTreeView *v){ + GtkTreeSelection *select; + GtkTreeIter iter; + GtkTreeModel *model; + + select = gtk_tree_view_get_selection(v); + if (gtk_tree_selection_get_selected (select, &model, &iter)){ + GtkTreePath *path=gtk_tree_model_get_path(model,&iter); + gtk_tree_view_collapse_all(v); + gtk_tree_view_expand_row(v,path,TRUE); + gtk_tree_path_free(path); + } +} + void linphone_gtk_call_log_update(GtkWidget *w){ GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(w,"logs_view")); GtkTreeStore *store; const MSList *logs; + GtkTreeSelection *select; store=(GtkTreeStore*)gtk_tree_view_get_model(v); if (store==NULL){ @@ -44,6 +59,9 @@ void linphone_gtk_call_log_update(GtkWidget *w){ gtk_tree_view_set_model(v,GTK_TREE_MODEL(store)); g_object_unref(G_OBJECT(store)); fill_renderers(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"logs_view"))); + select=gtk_tree_view_get_selection(v); + gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE); + g_signal_connect_swapped(G_OBJECT(select),"changed",(GCallback)call_log_selection_changed,v); // gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"call_back_button")), // create_pixmap (linphone_gtk_get_ui_config("callback_button","status-green.png"))); } diff --git a/gtk/chat.c b/gtk/chat.c index 6a65cd9f..7f7e26a5 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -65,7 +65,7 @@ void linphone_gtk_quit_chatroom(LinphoneChatRoom *cr) { g_return_if_fail(w!=NULL); gtk_notebook_remove_page(GTK_NOTEBOOK(nb),idx); - linphone_gtk_create_chat_picture(FALSE); + //linphone_gtk_create_chat_picture(FALSE); g_object_set_data(G_OBJECT(friendlist),"chatview",NULL); g_object_set_data(G_OBJECT(w),"from_message",NULL); g_object_set_data(G_OBJECT(w),"cr",NULL); @@ -265,6 +265,15 @@ void linphone_gtk_send_text(){ } } +static void linphone_gtk_chat_message_destroy(LinphoneChatMessage *msg){ + linphone_chat_message_destroy(msg); +} + +void linphone_gtk_free_list(MSList *messages){ + ms_list_for_each(messages,(void (*)(void*))linphone_gtk_chat_message_destroy); + ms_list_free(messages); +} + void display_history_message(GtkWidget *chat_view,MSList *messages,const LinphoneAddress *with){ if(messages != NULL){ MSList *it; @@ -282,6 +291,7 @@ void display_history_message(GtkWidget *chat_view,MSList *messages,const Linphon g_object_set_data(G_OBJECT(chat_view),"from_message",NULL); ms_free(from_str); ms_free(with_str); + linphone_gtk_free_list(messages); } } @@ -306,7 +316,7 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres colorb.red = 56832; colorb.green = 60928; colorb.blue = 61952; - + with_str=linphone_address_as_string_uri_only(with); linphone_chat_room_mark_as_read(cr); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text),GTK_WRAP_WORD_CHAR); @@ -354,12 +364,14 @@ LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with){ void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,GtkWidget *chat_view){ GtkWidget *main_window=linphone_gtk_get_main_window (); LinphoneChatRoom *cr2=(LinphoneChatRoom *)g_object_get_data(G_OBJECT(chat_view),"cr"); - char *from_str=linphone_address_as_string(linphone_chat_room_get_peer_address (cr2)); + const LinphoneAddress *from=linphone_chat_room_get_peer_address(cr2); + char *from_str=linphone_address_as_string_uri_only(from); char *uri_str=linphone_address_as_string(uri); + char *uri_only=linphone_address_as_string_uri_only(uri); MSList *messages=NULL; linphone_chat_room_mark_as_read(cr); - if(g_strcmp0(from_str,uri_str)!=0){ + if(g_strcmp0(from_str,uri_only)!=0){ GtkTextView *text_view=GTK_TEXT_VIEW(linphone_gtk_get_widget(chat_view,"textview")); GtkTextIter start; GtkTextIter end; @@ -371,7 +383,7 @@ void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri, udpate_tab_chat_header(chat_view,uri,cr); g_object_set_data(G_OBJECT(chat_view),"cr",cr); g_object_set_data(G_OBJECT(linphone_gtk_get_widget(main_window,"contact_list")),"chatview",(gpointer)chat_view); - messages = linphone_chat_room_get_history(cr,NB_MSG_HIST); + messages=linphone_chat_room_get_history(cr,NB_MSG_HIST); g_object_set_data(G_OBJECT(chat_view),"from_message",uri_str); display_history_message(chat_view,messages,uri); } @@ -394,15 +406,22 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg){ GtkWidget *main_window=linphone_gtk_get_main_window(); GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list"); - GtkWidget *w; + GtkWidget *w; + gboolean send=TRUE; + char *from=linphone_address_as_string(linphone_chat_message_get_from(msg)); w=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); if(w!=NULL){ - linphone_gtk_load_chatroom(room,linphone_chat_message_get_from(msg),w); + char *from_chatview=(char *)g_object_get_data(G_OBJECT(w),"from"); + if(g_strcmp0(from,from_chatview)==0){ + send=TRUE; + } else { + send=FALSE; + } + ms_free(from_chatview); } else { w=linphone_gtk_init_chatroom(room,linphone_chat_message_get_from(msg)); g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)w); - char *from=linphone_address_as_string(linphone_chat_message_get_from(msg)); g_object_set_data(G_OBJECT(friendlist),"from",from); } get_display_name(linphone_chat_message_get_from(msg)); @@ -419,9 +438,17 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, } } #endif - linphone_gtk_push_text(w,linphone_chat_message_get_from(msg), + if(send){ + linphone_gtk_push_text(w,linphone_chat_message_get_from(msg), FALSE,room,msg,FALSE); - linphone_gtk_update_chat_picture(); + } else { + linphone_gtk_show_friends(); + //linphone_gtk_friend_list_update_message(msg); + } + ms_free(from); + //linphone_gtk_update_chat_picture(); + //TODO: update la zone de notification dans les contacts (problème : lors du refresh de la liste + //connaitre tous les contacts qui ont des messages non lus ... //gtk_window_present(GTK_WINDOW(w)); /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/ } diff --git a/gtk/friendlist.c b/gtk/friendlist.c index be6a4c3c..e1012f7c 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -32,7 +32,7 @@ enum{ FRIEND_ICON, FRIEND_CALL, FRIEND_CHAT, - FRIEND_CHAT_CONVERSATION, + FRIEND_NB_UNREAD_MSG, FRIEND_LIST_NCOL }; @@ -253,9 +253,11 @@ void linphone_gtk_chat_selected(GtkWidget *item){ GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(w,"viewswitch"); const LinphoneAddress *uri; gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); + gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1); uri=linphone_friend_get_address(lf); - if(cr == NULL){ + if(cr==NULL){ cr=linphone_gtk_create_chatroom(uri); + gtk_list_store_set(store,&iter,FRIEND_CHATROOM,cr,-1); } page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); g_object_set_data(G_OBJECT(friendlist),"from",linphone_address_as_string(uri)); @@ -269,6 +271,7 @@ void linphone_gtk_chat_selected(GtkWidget *item){ linphone_gtk_create_chat_picture(FALSE); g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(page,"text_entry")); gtk_list_store_set(store,&iter,FRIEND_CHAT,create_active_chat_picture(),-1); + gtk_list_store_set(store,&iter,FRIEND_NB_UNREAD_MSG,"",-1); } } @@ -541,7 +544,8 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist){ linphone_gtk_init_bookmark_icon(); store = gtk_list_store_new(FRIEND_LIST_NCOL,GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, - G_TYPE_POINTER, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF, G_TYPE_STRING); + G_TYPE_POINTER, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF, + G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(friendlist),GTK_TREE_MODEL(store)); g_object_unref(G_OBJECT(store)); @@ -579,9 +583,13 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist){ gtk_tree_view_column_set_clickable(column,TRUE); gtk_tree_view_column_set_expand(column,TRUE); gtk_tree_view_column_set_max_width(column,60); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start(column,renderer,TRUE); + gtk_tree_view_column_add_attribute (column,renderer,"text",FRIEND_NB_UNREAD_MSG); + gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); - /* Call column*/ renderer = gtk_cell_renderer_pixbuf_new(); column = gtk_tree_view_column_new_with_attributes (_("Call"),renderer,"pixbuf",FRIEND_CALL,NULL); @@ -669,6 +677,7 @@ void linphone_gtk_show_friends(void){ //const gchar *search=NULL; //gboolean lookup=FALSE; MSList *sorted; + LinphoneChatRoom *cr=NULL; linphone_gtk_show_directory_search(); @@ -693,6 +702,9 @@ void linphone_gtk_show_friends(void){ const char *name=linphone_address_get_display_name(f_uri); const char *display=name; char *escaped=NULL; + char buf[26]={0}; + int nbmsg=0; + /*if (lookup){ if (strstr(uri,search)==NULL){ ms_free(uri); @@ -709,9 +721,25 @@ void linphone_gtk_show_friends(void){ FRIEND_PRESENCE_IMG, send_subscribe ? create_status_picture(linphone_friend_get_status(lf)) : NULL, -1); + gtk_tree_model_get(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)),&iter,FRIEND_CHATROOM,&cr,-1); + if(cr!=NULL){ + nbmsg=linphone_chat_room_get_unread_messages_count(cr); + if(nbmsg != 0){ + sprintf(buf,"%i",nbmsg); + } + } else { + cr=linphone_gtk_create_chatroom(f_uri); + gtk_list_store_set(store,&iter,FRIEND_CHATROOM,cr,-1); + nbmsg=linphone_chat_room_get_unread_messages_count(cr); + if(nbmsg != 0){ + sprintf(buf,"%i",nbmsg); + } + + } + gtk_list_store_set(store,&iter,FRIEND_CALL,create_call_picture(),-1); gtk_list_store_set(store,&iter,FRIEND_CHAT,create_chat_picture(),-1); - + gtk_list_store_set(store,&iter,FRIEND_NB_UNREAD_MSG,buf,-1); escaped=g_markup_escape_text(uri,-1); gtk_list_store_set(store,&iter,FRIEND_SIP_ADDRESS,escaped,-1); g_free(escaped); @@ -912,52 +940,41 @@ gboolean linphone_gtk_popup_contact_menu(GtkWidget *list, GdkEventButton *event) } gint get_col_number_from_tree_view_column (GtkTreeViewColumn *col){ - GList *cols; - gint num; - g_return_val_if_fail ( col != NULL, -1 ); - g_return_val_if_fail ( col->tree_view != NULL, -1 ); - cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view)); - num = g_list_index(cols, (gpointer) col); - g_list_free(cols); - - return num; -} + GList *cols; + gint num; + g_return_val_if_fail ( col != NULL, -1 ); + g_return_val_if_fail ( col->tree_view != NULL, -1 ); + cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view)); + num = g_list_index(cols, (gpointer) col); + g_list_free(cols); -int longueur_list (GtkTreeView *tree_view){ - GtkTreeIter iter; - int i=0; - GtkTreeModel *model=gtk_tree_view_get_model(tree_view); - if (gtk_tree_model_get_iter_first(model,&iter)) { - do{ - i++; - }while(gtk_tree_model_iter_next(model,&iter)); - } - return i; + return num; } static gint tree_view_get_cell_from_pos(GtkTreeView *view, guint x, guint y){ GtkTreeViewColumn *col = NULL; GList *node, *columns; gint colx = 0; - gint coly = longueur_list(view); - gint height=0; + GtkTreePath *path; + GtkTreeViewDropPosition pos; g_return_val_if_fail ( view != NULL, 0 ); columns = gtk_tree_view_get_columns(view); - for (node = columns; node != NULL && col == NULL; node = node->next){ - GtkTreeViewColumn *checkcol = (GtkTreeViewColumn*) node->data; - gtk_tree_view_column_cell_get_size(checkcol,NULL,NULL,NULL,NULL,&height); - if (x >= colx && x < (colx + checkcol->width) && y < (height+2)*coly){ - col = checkcol; - gint num = get_col_number_from_tree_view_column(col); + gtk_tree_view_get_dest_row_at_pos(view,x,y,&path,&pos); + if(path != NULL){ + for (node = columns; node != NULL && col == NULL; node = node->next){ + GtkTreeViewColumn *checkcol = (GtkTreeViewColumn*) node->data; + if (x >= colx && x < (colx + checkcol->width)){ + col = checkcol; + gint num = get_col_number_from_tree_view_column(col); return num; - } - else { - colx += checkcol->width; + } else { + colx += checkcol->width; } - } - g_list_free(columns); + } + } + g_list_free(columns); return 0; } diff --git a/gtk/linphone.h b/gtk/linphone.h index aaa021a2..a7d7da50 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -152,4 +152,4 @@ void linphone_gtk_monitor_usb(void); void linphone_gtk_unmonitor_usb(void); gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_conference); - +void linphone_gtk_friend_list_update_message(LinphoneChatMessage *msg); -- 2.39.2