friendlist.c 39.8 KB
Newer Older
aymeric's avatar
aymeric committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
linphone, gtk-glade interface.
Copyright (C) 2008  Simon MORLAT (simon.morlat@linphone.org)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include <gtk/gtk.h>
#include "linphone.h"

static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list);

enum{
	FRIEND_PRESENCE_IMG,
	FRIEND_NAME,
	FRIEND_PRESENCE_STATUS,
	FRIEND_ID,
30
	FRIEND_CHATROOM,
aymeric's avatar
aymeric committed
31
	FRIEND_SIP_ADDRESS,
32
	FRIEND_ICON,
33 34
	FRIEND_CALL,
	FRIEND_CHAT,
aymeric's avatar
aymeric committed
35 36 37 38 39 40 41 42 43
	FRIEND_LIST_NCOL
};

typedef struct _status_picture_tab_t{
	LinphoneOnlineStatus status;
	const char *img;
} status_picture_tab_t;

status_picture_tab_t status_picture_tab[]={
Simon Morlat's avatar
Simon Morlat committed
44 45 46 47 48 49 50 51 52 53 54 55
	{	LinphoneStatusOnline,		"status-green.png"	},
	{	LinphoneStatusBusy,		"status-orange.png"		},
	{	LinphoneStatusBeRightBack,	"status-orange.png"		},
	{	LinphoneStatusAway,		"status-orange.png"		},
	{	LinphoneStatusOnThePhone,	"status-orange.png"		},
	{	LinphoneStatusOutToLunch,	"status-orange.png"		},
	{	LinphoneStatusDoNotDisturb,	"status-red.png"	},
	{	LinphoneStatusMoved,		"status-orange.png"	},
	{	LinphoneStatusAltService,	"status-orange.png"	},
	{	LinphoneStatusOffline,	"status-offline.png"		},
	{	LinphoneStatusPending,	"status-offline.png"		},
	{	LinphoneStatusEnd,		NULL			},
aymeric's avatar
aymeric committed
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
};

static GdkPixbuf *create_status_picture(LinphoneOnlineStatus ss){
	status_picture_tab_t *t=status_picture_tab;
	while(t->img!=NULL){
		if (ss==t->status){
			GdkPixbuf *pixbuf;
			pixbuf = create_pixbuf(t->img);
			return pixbuf;
		}
		++t;
	}
	g_error("No pixmap defined for status %i",ss);
	return NULL;
}

72 73 74 75 76 77
static GdkPixbuf *create_call_picture(){
	GdkPixbuf *pixbuf;
	pixbuf = create_pixbuf("call.png");
	return pixbuf;
}

78 79 80 81 82 83
static GdkPixbuf *create_unread_msg(){
	GdkPixbuf *pixbuf;
	pixbuf = create_pixbuf("active_chat.png");
	return pixbuf;
}

84 85 86 87 88 89
static GdkPixbuf *create_chat_picture(){
	GdkPixbuf *pixbuf;
	pixbuf = create_pixbuf("chat.png");
	return pixbuf;
}

90 91 92 93 94 95 96 97 98 99 100 101
static GdkPixbuf *create_composing_unread_msg(){
	GdkPixbuf *pixbuf;
	pixbuf = create_pixbuf("composing_active_chat.png");
	return pixbuf;
}

static GdkPixbuf *create_composing_chat_picture(){
	GdkPixbuf *pixbuf;
	pixbuf = create_pixbuf("composing_chat.png");
	return pixbuf;
}

102
/*
aymeric's avatar
aymeric committed
103 104 105
void linphone_gtk_set_friend_status(GtkWidget *friendlist , LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){
	GtkTreeIter iter;
	LinphoneFriend *tmp=0;
Simon Morlat's avatar
Simon Morlat committed
106

aymeric's avatar
aymeric committed
107 108 109 110 111 112 113 114 115 116
	GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist));
	if (gtk_tree_model_get_iter_first(model,&iter)) {
		do{
			gtk_tree_model_get(model,&iter,FRIEND_ID,&tmp,-1);
			//printf("tmp=%i, fid=%i",tmp,fid);
			if (fid==tmp) {
				GdkPixbuf *pixbuf;
				gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_STATUS,status,-1);
				pixbuf = create_pixbuf(img);
				if (pixbuf)
Simon Morlat's avatar
Simon Morlat committed
117 118 119
				{
					gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1);
				}
aymeric's avatar
aymeric committed
120 121
			}
		}while(gtk_tree_model_iter_next(model,&iter));
122
	}
aymeric's avatar
aymeric committed
123
}
124
*/
125 126 127 128 129 130 131 132 133 134

gboolean linphone_gtk_friend_list_is_contact(const LinphoneAddress *addr){
	LinphoneFriend *lf;
	char *addr_str=linphone_address_as_string(addr);
	lf=linphone_core_get_friend_by_address(linphone_gtk_get_core(),addr_str);
	if(lf == NULL){
		return FALSE;
	} return TRUE;
}

aymeric's avatar
aymeric committed
135 136 137 138 139 140 141 142 143 144
static void linphone_gtk_set_selection_to_uri_bar(GtkTreeView *treeview){
	GtkTreeSelection *select;
	GtkTreeIter iter;
	GtkTreeModel *model;
	LinphoneFriend *lf=NULL;
	gchar* friend;
	select = gtk_tree_view_get_selection (treeview);
	if (gtk_tree_selection_get_selected (select, &model, &iter))
	{
		gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1);
145
		friend=linphone_address_as_string(linphone_friend_get_address(lf));
aymeric's avatar
aymeric committed
146 147 148 149 150
		gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),friend);
		ms_free(friend);
	}
}

151
void linphone_gtk_add_contact(void){
152 153
	GtkWidget *w=linphone_gtk_create_window("contact");
	int presence_enabled=linphone_gtk_get_ui_config_int("use_subscribe_notify",1);
154

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence")),presence_enabled);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence")),
					presence_enabled);
	gtk_widget_show(w);
}

void linphone_gtk_edit_contact(GtkWidget *button){
	GtkWidget *w=gtk_widget_get_toplevel(button);
	GtkTreeSelection *select;
	GtkTreeIter iter;
	GtkTreeModel *model;
	LinphoneFriend *lf=NULL;
	select = gtk_tree_view_get_selection(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"contact_list")));
	if (gtk_tree_selection_get_selected (select, &model, &iter))
	{
		gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1);
171
		linphone_gtk_show_contact(lf, GTK_WINDOW(w));
172 173 174 175 176 177 178 179 180
	}
}

void linphone_gtk_remove_contact(GtkWidget *button){
	GtkWidget *w=gtk_widget_get_toplevel(button);
	GtkTreeSelection *select;
	GtkTreeIter iter;
	GtkTreeModel *model;
	LinphoneFriend *lf=NULL;
181
	LinphoneChatRoom *cr=NULL;
182 183 184 185 186
	select = gtk_tree_view_get_selection(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"contact_list")));
	if (gtk_tree_selection_get_selected (select, &model, &iter))
	{
		gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1);
		linphone_core_remove_friend(linphone_gtk_get_core(),lf);
187 188
		gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1);
		linphone_chat_room_delete_history(cr);
189 190 191 192
		linphone_gtk_show_friends();
	}
}

Margaux Clerc's avatar
Margaux Clerc committed
193
void linphone_gtk_delete_history(GtkWidget *button){
194
	GtkWidget *w=linphone_gtk_get_main_window();
Margaux Clerc's avatar
Margaux Clerc committed
195 196 197
	GtkTreeSelection *select;
	GtkTreeIter iter;
	GtkTreeModel *model;
198
	GtkWidget *chat_view;
Margaux Clerc's avatar
Margaux Clerc committed
199
	LinphoneFriend *lf=NULL;
200
	GtkWidget *friendlist;
201

202 203 204
	friendlist=linphone_gtk_get_widget(w,"contact_list");
	chat_view=(GtkWidget *)g_object_get_data(G_OBJECT(friendlist),"chatview");
	select = gtk_tree_view_get_selection(GTK_TREE_VIEW(friendlist));
Margaux Clerc's avatar
Margaux Clerc committed
205 206
	if (gtk_tree_selection_get_selected (select, &model, &iter))
	{
Simon Morlat's avatar
Simon Morlat committed
207
		LinphoneChatRoom *cr;
Margaux Clerc's avatar
Margaux Clerc committed
208
		gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1);
209
		gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1);
Simon Morlat's avatar
Simon Morlat committed
210
		linphone_chat_room_delete_history(cr);
211
		if(chat_view!=NULL){
212 213 214
			const LinphoneAddress *from=linphone_gtk_friend_list_get_active_address();
			const LinphoneAddress *addr=linphone_friend_get_address(lf);
			if(linphone_address_weak_equal(from,addr)){
215 216 217 218
				GtkTextView *text_view=GTK_TEXT_VIEW(linphone_gtk_get_widget(chat_view,"textview"));
				GtkTextIter start;
				GtkTextIter end;
				GtkTextBuffer *text_buffer;
219

220 221 222 223 224 225
				text_buffer=gtk_text_view_get_buffer(text_view);
				gtk_text_buffer_get_bounds(text_buffer, &start, &end);
				gtk_text_buffer_delete (text_buffer, &start, &end);
				g_object_set_data(G_OBJECT(chat_view),"from_message",NULL);
			}
		}
Margaux Clerc's avatar
Margaux Clerc committed
226 227 228 229
		linphone_gtk_show_friends();
	}
}

aymeric's avatar
aymeric committed
230 231 232 233 234 235
static void linphone_gtk_call_selected(GtkTreeView *treeview){
	linphone_gtk_set_selection_to_uri_bar(treeview);
	linphone_gtk_start_call(linphone_gtk_get_widget(gtk_widget_get_toplevel(GTK_WIDGET(treeview)),
					"start_call"));
}

Margaux Clerc's avatar
Margaux Clerc committed
236
void linphone_gtk_friend_list_update_chat_picture(){
237 238 239 240
	GtkTreeIter iter;
	GtkWidget *w = linphone_gtk_get_main_window();
	GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list");
	GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist));
Margaux Clerc's avatar
Margaux Clerc committed
241
	LinphoneChatRoom *cr=NULL;
242
	bool_t is_composing;
Margaux Clerc's avatar
Margaux Clerc committed
243
	int nbmsg=0;
244 245
	if (gtk_tree_model_get_iter_first(model,&iter)) {
		do{
Margaux Clerc's avatar
Margaux Clerc committed
246 247
			gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1);
			nbmsg=linphone_chat_room_get_unread_messages_count(cr);
248
			is_composing=linphone_chat_room_is_remote_composing(cr);
Margaux Clerc's avatar
Margaux Clerc committed
249
			if(nbmsg != 0){
250 251 252 253
				if (is_composing == TRUE)
					gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_composing_unread_msg(),-1);
				else
					gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_unread_msg(),-1);
Margaux Clerc's avatar
Margaux Clerc committed
254
			} else {
255 256 257 258
				if (is_composing == TRUE)
					gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_composing_chat_picture(),-1);
				else
					gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_chat_picture(),-1);
Margaux Clerc's avatar
Margaux Clerc committed
259
			}
260 261 262 263
		}while(gtk_tree_model_iter_next(model,&iter));
	}
}

264 265 266 267 268
static gboolean grab_focus(GtkWidget *w){
	gtk_widget_grab_focus(w);
	return FALSE;
}

269 270 271 272 273 274 275 276 277 278 279 280 281 282
void linphone_gtk_friend_list_set_active_address(const LinphoneAddress *addr){
	GtkWidget *w=linphone_gtk_get_main_window();
	GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list");
	LinphoneAddress *old_addr=(LinphoneAddress*)g_object_get_data(G_OBJECT(friendlist),"from");
	g_object_set_data(G_OBJECT(friendlist),"from", addr ? linphone_address_clone(addr) : NULL);
	if (old_addr) linphone_address_unref(old_addr);
}

const LinphoneAddress *linphone_gtk_friend_list_get_active_address(void){
	GtkWidget *w=linphone_gtk_get_main_window();
	GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list");
	return (const LinphoneAddress*)g_object_get_data(G_OBJECT(friendlist),"from");
}

Margaux Clerc's avatar
Margaux Clerc committed
283
void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la){
Margaux Clerc's avatar
Margaux Clerc committed
284
	GtkTreeIter iter;
285 286 287 288 289 290
	GtkListStore *store=NULL;
	GtkWidget *w = linphone_gtk_get_main_window();
	GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list");
	GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist));
	GtkWidget *chat_view=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
	LinphoneFriend *lf=NULL;
291 292
	LinphoneChatRoom *cr=NULL;
	GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(w,"viewswitch");
293

294
	lf=linphone_core_find_friend(linphone_gtk_get_core(),la);
295 296
	if(lf==NULL){
		cr=linphone_gtk_create_chatroom(la);
297
		linphone_gtk_friend_list_set_active_address(la);
298 299 300 301 302 303 304
		if(chat_view==NULL){
			chat_view=linphone_gtk_init_chatroom(cr,la);
			g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)chat_view);
		} else {
			linphone_gtk_load_chatroom(cr,la,chat_view);
		}
		gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,chat_view));
Margaux Clerc's avatar
Margaux Clerc committed
305
		linphone_gtk_friend_list_update_chat_picture();
306 307 308 309 310 311
		g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(chat_view,"text_entry"));
	} else {
		store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)));
		if (gtk_tree_model_get_iter_first(model,&iter)) {
			do{
				const LinphoneAddress *uri;
312
				gtk_tree_model_get(model, &iter,FRIEND_ID , &lf, -1);
313
				uri=linphone_friend_get_address(lf);
314
				if (linphone_address_weak_equal(uri,la)){
315 316 317 318 319
					gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1);
					if(cr==NULL){
						cr=linphone_gtk_create_chatroom(uri);
						gtk_list_store_set(store,&iter,FRIEND_CHATROOM,cr,-1);
					}
320
					linphone_gtk_friend_list_set_active_address(uri);
321 322 323
					if(chat_view==NULL){
						chat_view=linphone_gtk_init_chatroom(cr,uri);
						g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)chat_view);
Margaux Clerc's avatar
Margaux Clerc committed
324
					} else {
325
						linphone_gtk_load_chatroom(cr,uri,chat_view);
Margaux Clerc's avatar
Margaux Clerc committed
326
					}
327
					gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,chat_view));
Margaux Clerc's avatar
Margaux Clerc committed
328
					linphone_gtk_friend_list_update_chat_picture();
329 330
					g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(chat_view,"text_entry"));
					break;
Margaux Clerc's avatar
Margaux Clerc committed
331
				}
332 333
			}while(gtk_tree_model_iter_next(model,&iter));
		}
334
	}
335 336 337 338 339 340 341
}

void linphone_gtk_notebook_tab_select(GtkNotebook *notebook,GtkWidget *page,guint page_num, gpointer data){
	GtkWidget *w=linphone_gtk_get_main_window();
	GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list");
	GtkWidget *chat_view;
	LinphoneChatRoom *cr=NULL;
Margaux Clerc's avatar
Margaux Clerc committed
342 343 344 345 346 347
 	chat_view=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
 	if(page != NULL){
 		notebook=(GtkNotebook *)linphone_gtk_get_widget(w,"viewswitch");
 		if(gtk_notebook_page_num(notebook,page)==gtk_notebook_page_num(notebook,chat_view)){
 			cr=g_object_get_data(G_OBJECT(chat_view),"cr");
 			if(cr!=NULL){
348
				linphone_chat_room_mark_as_read(cr);
Margaux Clerc's avatar
Margaux Clerc committed
349
 				linphone_gtk_show_friends();
350
			}
Margaux Clerc's avatar
Margaux Clerc committed
351
 		}
Margaux Clerc's avatar
Margaux Clerc committed
352
	}
353 354
}

355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
void linphone_gtk_chat_selected(GtkWidget *item){
	GtkWidget *w=gtk_widget_get_toplevel(item);
	GtkTreeSelection *select;
	GtkListStore *store=NULL;
	GtkTreeIter iter;
	GtkTreeModel *model;
	LinphoneFriend *lf=NULL;
	LinphoneChatRoom *cr=NULL;
	GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list");
	GtkWidget *page;

	select=gtk_tree_view_get_selection(GTK_TREE_VIEW(friendlist));
	store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(item)));
	if (gtk_tree_selection_get_selected (select, &model, &iter)){
		GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(w,"viewswitch");
		const LinphoneAddress *uri;
		gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1);
Margaux Clerc's avatar
Margaux Clerc committed
372
		gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1);
373
		uri=linphone_friend_get_address(lf);
Margaux Clerc's avatar
Margaux Clerc committed
374
		if(cr==NULL){
375
			cr=linphone_gtk_create_chatroom(uri);
Margaux Clerc's avatar
Margaux Clerc committed
376
			gtk_list_store_set(store,&iter,FRIEND_CHATROOM,cr,-1);
377
		}
378
		page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
379
		linphone_gtk_friend_list_set_active_address(uri);
380 381 382 383 384 385
		if(page==NULL){
			page=linphone_gtk_init_chatroom(cr,uri);
			g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)page);
		} else {
			linphone_gtk_load_chatroom(cr,uri,page);
		}
386
		linphone_chat_room_mark_as_read(cr);
387
		gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,page));
Margaux Clerc's avatar
Margaux Clerc committed
388
		linphone_gtk_friend_list_update_chat_picture();
389
		g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(page,"text_entry"));
390 391 392
	}
}

aymeric's avatar
aymeric committed
393 394 395 396 397
void linphone_gtk_contact_activated(GtkTreeView     *treeview,
                                    GtkTreePath     *path,
                                    GtkTreeViewColumn *column,
                                        gpointer         user_data)
{
398
	//linphone_gtk_call_selected(treeview);
smorlat's avatar
smorlat committed
399 400 401
}

void linphone_gtk_contact_clicked(GtkTreeView     *treeview){
aymeric's avatar
aymeric committed
402
	linphone_gtk_set_selection_to_uri_bar(treeview);
403 404 405 406 407 408 409 410
	if(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview),"numcol"))==1){
		linphone_gtk_call_selected(treeview);
	} else {
		if(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview),"numcol"))==2){
			linphone_gtk_chat_selected(GTK_WIDGET(treeview));
		}
	}
	g_object_set_data(G_OBJECT(treeview),"numcol",GINT_TO_POINTER(0));
411 412 413 414 415 416 417 418 419 420 421 422 423
}


void linphone_gtk_add_button_clicked(void){
	linphone_gtk_add_contact();
}

void linphone_gtk_edit_button_clicked(GtkWidget *button){
	linphone_gtk_edit_contact(button);
}

void linphone_gtk_remove_button_clicked(GtkWidget *button){
	linphone_gtk_remove_contact(button);
aymeric's avatar
aymeric committed
424 425 426 427 428 429 430 431
}

static GtkWidget * create_presence_menu(){
	GtkWidget *menu=gtk_menu_new();
	GtkWidget *menu_item;
	GdkPixbuf *pbuf;
	status_picture_tab_t *t;
	for(t=status_picture_tab;t->img!=NULL;++t){
Simon Morlat's avatar
Simon Morlat committed
432
		if (t->status==LinphoneStatusPending){
aymeric's avatar
aymeric committed
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
			continue;
		}
		menu_item=gtk_image_menu_item_new_with_label(linphone_online_status_to_string(t->status));
		pbuf=create_status_picture(t->status);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),
						gtk_image_new_from_pixbuf(pbuf));
		g_object_unref(G_OBJECT(pbuf));
		gtk_widget_show(menu_item);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
		g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_set_my_presence,GINT_TO_POINTER(t->status));
	}
	return menu;
}

void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss){
	GtkWidget *button=linphone_gtk_get_widget(linphone_gtk_get_main_window(),"presence_button");
	GdkPixbuf *pbuf=create_status_picture(ss);
	GtkWidget *image=gtk_image_new_from_pixbuf(pbuf);
	GtkWidget *menu;
	g_object_unref(G_OBJECT(pbuf));
453
	gtk_widget_set_tooltip_text(button,linphone_online_status_to_string(ss));
aymeric's avatar
aymeric committed
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
	gtk_button_set_image(GTK_BUTTON(button),image);
	/*prepare menu*/
	menu=(GtkWidget*)g_object_get_data(G_OBJECT(button),"presence_menu");
	if (menu==NULL){
		menu=create_presence_menu();
		/*the menu is destroyed when the button is destroyed*/
		g_object_weak_ref(G_OBJECT(button),(GWeakNotify)gtk_widget_destroy,menu);
		g_object_set_data(G_OBJECT(button),"presence_menu",menu);
	}
	linphone_core_set_presence_info(linphone_gtk_get_core(),0,NULL,ss);
}

void linphone_gtk_my_presence_clicked(GtkWidget *button){
	GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(button),"presence_menu");
	gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,
			gtk_get_current_event_time());
	gtk_widget_show(menu);
}

473
static void icon_press_handler(GtkEntry *entry){
474
	GtkWidget *w = gtk_widget_get_toplevel(GTK_WIDGET(entry));
475 476
	const char *text=gtk_entry_get_text(entry);
	if (text && strlen(text)>0){
477
		LinphoneAddress *addr;
478
		LinphoneFriend *lf;
479 480 481
		char *uri;
		addr=linphone_core_interpret_url(linphone_gtk_get_core(),text);
		if (addr==NULL){
482 483
			return ;
		}
484
		uri=linphone_address_as_string_uri_only(addr);
485
		lf=linphone_core_get_friend_by_address(linphone_gtk_get_core(),uri);
486
		ms_free(uri);
487
		if (lf==NULL)
488
			lf=linphone_friend_new();
489
		if (lf!=NULL){
490
			linphone_friend_set_address(lf,addr);
491
			linphone_gtk_show_contact(lf, GTK_WINDOW(w));
492
		}
493
		linphone_address_destroy(addr);
494 495 496 497 498 499 500 501 502 503
	}
}

static void update_star(GtkEntry *entry, gboolean is_known){
	GdkPixbuf *active,*starred,*unstarred;
	active=gtk_entry_get_icon_pixbuf(entry,GTK_ENTRY_ICON_SECONDARY);
	starred=g_object_get_data(G_OBJECT(entry),"starred_icon");
	unstarred=g_object_get_data(G_OBJECT(entry),"unstarred_icon");
	if (is_known && (active==unstarred)){
		gtk_entry_set_icon_from_pixbuf(entry,GTK_ENTRY_ICON_SECONDARY,starred);
504
		gtk_entry_set_icon_tooltip_text(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,NULL);
505
	}else if ((!is_known) && (active==starred)){
506
		gtk_entry_set_icon_tooltip_text(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,_("Add to addressbook"));
507 508 509 510 511 512 513 514
		gtk_entry_set_icon_from_pixbuf(entry,GTK_ENTRY_ICON_SECONDARY,unstarred);
	}
}

static void check_contact(GtkEditable *editable, LinphoneCore *lc){
	char *tmp=gtk_editable_get_chars(editable,0,-1);
	if (tmp!=NULL){
		if (strlen(tmp)>0){
515 516 517
			LinphoneAddress *addr=linphone_core_interpret_url(lc,tmp);
			if (addr){
				char *uri=linphone_address_as_string_uri_only(addr);
518 519
				LinphoneFriend *lf=linphone_core_get_friend_by_address(lc,uri);
				ms_free(uri);
520
				linphone_address_destroy(addr);
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
				if (lf) {
					update_star(GTK_ENTRY(editable),TRUE);
					g_free(tmp);
					return;
				}
			}
		}
		g_free(tmp);
	}
	update_star(GTK_ENTRY(editable),FALSE);
}

static void linphone_gtk_init_bookmark_icon(void){
	GtkWidget *mw=linphone_gtk_get_main_window();
	GtkWidget *entry=linphone_gtk_get_widget(mw,"uribar");
	GdkPixbuf *pbuf=create_pixbuf("contact_unstarred.png");
	gtk_entry_set_icon_from_pixbuf(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,pbuf);
	g_object_set_data_full(G_OBJECT(entry),"unstarred_icon",pbuf,g_object_unref);
	pbuf=create_pixbuf("contact_starred.png");
	g_object_set_data_full(G_OBJECT(entry),"starred_icon",pbuf,g_object_unref);
	gtk_entry_set_icon_activatable(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,TRUE);
	g_signal_connect(G_OBJECT(entry),"icon-release",(GCallback)icon_press_handler,NULL);
	g_signal_connect(G_OBJECT(GTK_EDITABLE(entry)),"changed",(GCallback)check_contact,linphone_gtk_get_core());
}
aymeric's avatar
aymeric committed
545

546 547 548 549 550 551 552 553
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){
Margaux Clerc's avatar
Margaux Clerc committed
554 555 556 557 558
		gchar *uname=g_utf8_casefold(name,-1); /* need that to perform case-insensitive search in utf8 */
		gchar *ukey=g_utf8_casefold(key,-1);
		ret=strstr(uname,ukey)==NULL;
		g_free(uname);
		g_free(ukey);
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
		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;
586

587 588 589 590 591 592 593 594 595 596
	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;
597 598
	LinphoneCore *lc=linphone_gtk_get_core();
	LinphoneChatRoom *cr=linphone_core_get_chat_room(lc,linphone_friend_get_address(lf));
599

600 601 602
	if (cr && linphone_chat_room_get_unread_messages_count(cr)>0){
		w+=2000;
	}
603

604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
	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;
}

static void on_presence_column_clicked(GtkTreeModel *model){
	GtkSortType st;
	gint column;
652

653 654 655 656 657 658 659 660
	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);
}

661 662 663 664
void create_button(){
	GtkWidget *main_window = linphone_gtk_get_main_window ();
	GtkWidget *button_add = linphone_gtk_get_widget(main_window,"add_button");
	GtkWidget *image;
665

666
	image=gtk_image_new_from_stock(GTK_STOCK_ADD,GTK_ICON_SIZE_MENU);
667
	gtk_container_add (GTK_CONTAINER (button_add), image);
668 669 670
}

static void linphone_gtk_friend_list_init(GtkWidget *friendlist){
aymeric's avatar
aymeric committed
671 672 673 674
	GtkListStore *store;
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *column;
	GtkTreeSelection *select;
675 676

	linphone_gtk_init_bookmark_icon();
677

678
	store = gtk_list_store_new(FRIEND_LIST_NCOL,GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_POINTER,
679
								G_TYPE_POINTER, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF);
680

aymeric's avatar
aymeric committed
681 682
	gtk_tree_view_set_model(GTK_TREE_VIEW(friendlist),GTK_TREE_MODEL(store));
	g_object_unref(G_OBJECT(store));
683

684
	/* Tree specification*/
685
	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(friendlist),FALSE);
686 687 688
	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);
689

690 691
	/*Name and presence column*/
	renderer = gtk_cell_renderer_text_new ();
aymeric's avatar
aymeric committed
692 693 694 695 696
	column = gtk_tree_view_column_new_with_attributes (_("Presence status"),
                                                   renderer,
                                                   "text", FRIEND_PRESENCE_STATUS,
                                                   NULL);
	g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
697
	g_signal_connect_swapped(G_OBJECT(column),"clicked",(GCallback)on_presence_column_clicked,GTK_TREE_MODEL(store));
698
	gtk_tree_view_column_set_clickable(column,TRUE);
smorlat's avatar
smorlat committed
699
	gtk_tree_view_column_set_visible(column,linphone_gtk_get_ui_config_int("friendlist_status",1));
700
	gtk_tree_view_column_set_min_width(column,50);
701

702
	renderer = gtk_cell_renderer_pixbuf_new();
703
	gtk_tree_view_column_pack_start(column,renderer,TRUE);
704 705 706 707 708
	gtk_tree_view_column_add_attribute  (column,renderer,
                                                         "pixbuf",
                                                         FRIEND_PRESENCE_IMG);
	gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column);

709 710 711 712 713 714 715 716 717 718
	renderer = gtk_cell_renderer_text_new ();
	column = gtk_tree_view_column_new_with_attributes (_("Name"),
                                                   renderer,
                                                   "text", FRIEND_NAME,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);
	gtk_tree_view_column_set_expand(column,TRUE);
	gtk_tree_view_column_set_max_width(column,60);
	gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column);
719 720 721 722 723

	/* Call column*/
	renderer = gtk_cell_renderer_pixbuf_new();
	column = gtk_tree_view_column_new_with_attributes (_("Call"),renderer,"pixbuf",FRIEND_CALL,NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column);
724

Margaux Clerc's avatar
Margaux Clerc committed
725
	/* Chat column*/
726 727
	renderer = gtk_cell_renderer_pixbuf_new();
	column = gtk_tree_view_column_new_with_attributes (_("Chat"),renderer,"pixbuf",FRIEND_CHAT,NULL);
728
	gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column);
729

aymeric's avatar
aymeric committed
730 731
	select = gtk_tree_view_get_selection (GTK_TREE_VIEW (friendlist));
	gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
732

733
	gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(friendlist),GTK_TREE_VIEW_GRID_LINES_NONE);
smorlat's avatar
smorlat committed
734
#if GTK_CHECK_VERSION(2,12,0)
aymeric's avatar
aymeric committed
735
	gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(friendlist),FRIEND_SIP_ADDRESS);
smorlat's avatar
smorlat committed
736
#endif
737

738
	gtk_widget_set_size_request(friendlist,200,120);
739 740
	/*gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(
					gtk_widget_get_toplevel(friendlist),"show_category")),0);*/
aymeric's avatar
aymeric committed
741 742
}

743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
void linphone_gtk_show_directory_search(void){
	LinphoneProxyConfig *cfg=NULL;
	SipSetupContext * ssc=NULL;
	GtkWidget *mw=linphone_gtk_get_main_window();
	GtkWidget *search_box=linphone_gtk_get_widget(mw,"directory_search_box");

	linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg);
	if (cfg){
		ssc=linphone_proxy_config_get_sip_setup_context(cfg);
		if (ssc!=NULL && sip_setup_context_get_capabilities(ssc) & SIP_SETUP_CAP_BUDDY_LOOKUP){
			GtkWidget *entry=linphone_gtk_get_widget(mw,"directory_search_entry");
			gchar  *tooltip;
			GdkColor grey={0,40000,40000,40000};
			gtk_widget_show(search_box);
			tooltip=g_strdup_printf(_("Search in %s directory"),linphone_proxy_config_get_domain(cfg));
			gtk_widget_modify_text(entry,GTK_STATE_NORMAL,&grey);
			gtk_entry_set_text(GTK_ENTRY(entry),tooltip);
			g_object_set_data(G_OBJECT(entry),"active",GINT_TO_POINTER(0));
			g_free(tooltip);
			return;
		}
	}
	gtk_widget_hide(search_box);
}

gboolean linphone_gtk_directory_search_focus_out(GtkWidget *entry){
	if (gtk_entry_get_text_length(GTK_ENTRY(entry))==0)
		linphone_gtk_show_directory_search();
	return FALSE;
}

gboolean linphone_gtk_directory_search_focus_in(GtkWidget *entry){
	if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(entry),"active"))==0){
		gtk_entry_set_text(GTK_ENTRY(entry),"");
		gtk_widget_modify_text(entry,GTK_STATE_NORMAL,NULL);
		g_object_set_data(G_OBJECT(entry),"active",GINT_TO_POINTER(1));
	}
	return FALSE;
}

void linphone_gtk_directory_search_activate(GtkWidget *entry){
	LinphoneProxyConfig *cfg;
785
	GtkWidget *w;
786
	linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg);
787
	w=linphone_gtk_show_buddy_lookup_window(linphone_proxy_config_get_sip_setup_context(cfg));
smorlat's avatar
smorlat committed
788 789
	if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(entry),"active"))==1)
		linphone_gtk_buddy_lookup_set_keyword(w,gtk_entry_get_text(GTK_ENTRY(entry)));
790 791 792 793 794 795 796
}

void linphone_gtk_directory_search_button_clicked(GtkWidget *button){
	linphone_gtk_directory_search_activate(
		linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"directory_search_entry"));
}

aymeric's avatar
aymeric committed
797 798 799 800 801 802
void linphone_gtk_show_friends(void){
	GtkWidget *mw=linphone_gtk_get_main_window();
	GtkWidget *friendlist=linphone_gtk_get_widget(mw,"contact_list");
	GtkListStore *store=NULL;
	GtkTreeIter iter;
	const MSList *itf;
803
	//GtkWidget *filter=linphone_gtk_get_widget(mw,"search_bar");
aymeric's avatar
aymeric committed
804
	LinphoneCore *core=linphone_gtk_get_core();
805 806
	//const gchar *search=NULL;
	//gboolean lookup=FALSE;
807
	MSList *sorted;
Margaux Clerc's avatar
Margaux Clerc committed
808
	LinphoneChatRoom *cr=NULL;
809

810
	linphone_gtk_show_directory_search();
aymeric's avatar
aymeric committed
811 812 813
	if (gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))==NULL){
		linphone_gtk_friend_list_init(friendlist);
	}
814

aymeric's avatar
aymeric committed
815 816 817
	store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)));
	gtk_list_store_clear(store);

818 819 820 821
	//search=gtk_entry_get_text(GTK_ENTRY(filter));
	//if (search==NULL || search[0]=='\0')
	//	lookup=FALSE;
	//else lookup=TRUE;
aymeric's avatar
aymeric committed
822

823 824 825
	sorted=sort_friend_list(linphone_core_get_friend_list(core));

	for(itf=sorted;itf!=NULL;itf=ms_list_next(itf)){
aymeric's avatar
aymeric committed
826
		LinphoneFriend *lf=(LinphoneFriend*)itf->data;
827
		const LinphoneAddress *f_uri=linphone_friend_get_address(lf);
828
		char *uri=linphone_address_as_string(f_uri);
829
		const char *name=linphone_address_get_display_name(f_uri);
830
		const char *display=name;
aymeric's avatar
aymeric committed
831
		char *escaped=NULL;
832
		//char buf[26]={0};
Margaux Clerc's avatar
Margaux Clerc committed
833 834
		int nbmsg=0;

835
		/*if (lookup){
aymeric's avatar
aymeric committed
836 837 838 839
			if (strstr(uri,search)==NULL){
				ms_free(uri);
				continue;
			}
840
		}*/
841 842 843
		//BuddyInfo *bi;
		gboolean send_subscribe=linphone_friend_get_send_subscribe(lf);
		if (name==NULL || name[0]=='\0') {
844
			display=linphone_address_get_username(f_uri);
aymeric's avatar
aymeric committed
845
		}
846 847 848
		gtk_list_store_append(store,&iter);
		gtk_list_store_set(store,&iter,FRIEND_NAME, display,FRIEND_ID,lf,
			    FRIEND_PRESENCE_IMG, send_subscribe ? create_status_picture(linphone_friend_get_status(lf)) : NULL,
849 850 851 852 853 854
				FRIEND_CHAT,create_chat_picture(),FRIEND_CALL,create_call_picture(),-1);
		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){
			gtk_list_store_set(store,&iter,FRIEND_CHAT,create_unread_msg(),-1);
Margaux Clerc's avatar
Margaux Clerc committed
855
		}
856 857 858 859 860 861 862 863 864 865 866 867
		escaped=g_markup_escape_text(uri,-1);
		gtk_list_store_set(store,&iter,FRIEND_SIP_ADDRESS,escaped,-1);
		g_free(escaped);
		//bi=linphone_friend_get_info(lf);
		/*if (bi!=NULL && bi->image_data!=NULL){
			GdkPixbuf *pbuf=
				_gdk_pixbuf_new_from_memory_at_scale(bi->image_data,bi->image_length,-1,40,TRUE);
			if (pbuf) {
				//gtk_list_store_set(store,&iter,FRIEND_ICON,pbuf,-1);
				g_object_unref(G_OBJECT(pbuf));
			}
		}*/
aymeric's avatar
aymeric committed
868 869
		ms_free(uri);
	}
870
	ms_list_free(sorted);
aymeric's avatar
aymeric committed
871 872
}

873
void linphone_gtk_show_contact(LinphoneFriend *lf, GtkWindow *parent){
aymeric's avatar
aymeric committed
874
	GtkWidget *w=linphone_gtk_create_window("contact");
875
	char *uri;
876
	const char *name;
877
	const LinphoneAddress *f_uri=linphone_friend_get_address(lf);
878
	uri=linphone_address_as_string_uri_only(f_uri);
879
	name=linphone_address_get_display_name(f_uri);
aymeric's avatar
aymeric committed
880 881 882 883 884 885 886 887 888 889 890 891
	if (uri) {
		gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"sip_address")),uri);
		ms_free(uri);
	}
	if (name){
		gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"name")),name);
	}
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence")),
					linphone_friend_get_send_subscribe(lf));
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence")),
					linphone_friend_get_inc_subscribe_policy(lf)==LinphoneSPAccept);
	g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf);
892 893 894
	
	gtk_window_set_transient_for(GTK_WINDOW(w), parent);
	
aymeric's avatar
aymeric committed
895 896 897 898 899 900 901 902 903 904
	gtk_widget_show(w);
}

void linphone_gtk_contact_cancel(GtkWidget *button){
	gtk_widget_destroy(gtk_widget_get_toplevel(button));
}

void linphone_gtk_contact_ok(GtkWidget *button){
	GtkWidget *w=gtk_widget_get_toplevel(button);
	LinphoneFriend *lf=(LinphoneFriend*)g_object_get_data(G_OBJECT(w),"friend_ref");
905
	LinphoneFriend *lf2;
906
	gboolean show_presence=FALSE,allow_presence=FALSE;
aymeric's avatar
aymeric committed
907
	const gchar *name,*uri;
908
	LinphoneAddress* friend_address;
aymeric's avatar
aymeric committed
909 910
	if (lf==NULL){
		lf=linphone_friend_new();
911 912 913 914 915 916
		if (linphone_gtk_get_ui_config_int("use_subscribe_notify",1)==1){
			show_presence=FALSE;
			allow_presence=FALSE;
		}
		linphone_friend_set_inc_subscribe_policy(lf,allow_presence ? LinphoneSPAccept : LinphoneSPDeny);
		linphone_friend_send_subscribe(lf,show_presence);
aymeric's avatar
aymeric committed
917
	}
Margaux Clerc's avatar
Margaux Clerc committed
918 919 920 921 922

	name = NULL;
	if(gtk_entry_get_text_length(GTK_ENTRY(linphone_gtk_get_widget(w,"name"))) != 0){
		name=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"name")));
	}
aymeric's avatar
aymeric committed
923 924 925
	uri=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"sip_address")));
	show_presence=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence")));
	allow_presence=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence")));
926 927
	friend_address=linphone_core_interpret_url(linphone_gtk_get_core(),uri);
	if (friend_address==NULL){
smorlat's avatar
smorlat committed
928 929 930
		linphone_gtk_display_something(GTK_MESSAGE_WARNING,_("Invalid sip contact !"));
		return ;
	}
Margaux Clerc's avatar
Margaux Clerc committed
931

jehan's avatar
jehan committed
932
	linphone_address_set_display_name(friend_address,name);
Margaux Clerc's avatar
Margaux Clerc committed
933
	linphone_friend_set_name(lf,name);
Ghislain MARY's avatar
Ghislain MARY committed
934
	linphone_friend_set_address(lf,friend_address);
aymeric's avatar
aymeric committed
935 936
	linphone_friend_send_subscribe(lf,show_presence);
	linphone_friend_set_inc_subscribe_policy(lf,allow_presence==TRUE ? LinphoneSPAccept : LinphoneSPDeny);
smorlat's avatar
smorlat committed
937
	if (linphone_friend_in_list(lf)) {
aymeric's avatar
aymeric committed
938
		linphone_friend_done(lf);
939
	} else {
940 941 942
		char *uri=linphone_address_as_string_uri_only(friend_address);
		lf2=linphone_core_get_friend_by_address(linphone_gtk_get_core(),uri);
		ms_free(uri);
943 944 945
		if(lf2==NULL){
			linphone_core_add_friend(linphone_gtk_get_core(),lf);
		}
aymeric's avatar
aymeric committed
946
	}
947
	linphone_address_destroy(friend_address);
aymeric's avatar
aymeric committed
948 949 950 951 952 953 954 955 956
	linphone_gtk_show_friends();
	gtk_widget_destroy(w);
}

static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){
	GtkWidget *menu=gtk_menu_new();
	GtkWidget *menu_item;
	gchar *call_label=NULL;
	gchar *text_label=NULL;
smorlat's avatar
smorlat committed
957 958
	gchar *edit_label=NULL;
	gchar *delete_label=NULL;
Margaux Clerc's avatar
Margaux Clerc committed
959
	gchar *delete_hist_label=NULL;
aymeric's avatar
aymeric committed
960 961 962 963 964
	gchar *name=NULL;
	GtkTreeSelection *select;
	GtkTreeIter iter;
	GtkTreeModel *model;
	GtkWidget *image;
smorlat's avatar
smorlat committed
965 966 967
	LinphoneCore *lc=linphone_gtk_get_core();
	LinphoneProxyConfig *cfg=NULL;
	SipSetupContext * ssc=NULL;
968

smorlat's avatar
smorlat committed
969 970 971 972
	linphone_core_get_default_proxy(lc,&cfg);
	if (cfg){
		ssc=linphone_proxy_config_get_sip_setup_context(cfg);
	}
smorlat's avatar
smorlat committed
973

aymeric's avatar
aymeric committed
974 975 976 977 978 979
	g_signal_connect(G_OBJECT(menu), "selection-done", G_CALLBACK (gtk_widget_destroy), NULL);
	select = gtk_tree_view_get_selection(GTK_TREE_VIEW(contact_list));
	if (gtk_tree_selection_get_selected (select, &model, &iter)){
		gtk_tree_model_get(model, &iter,FRIEND_NAME , &name, -1);
		call_label=g_strdup_printf(_("Call %s"),name);
		text_label=g_strdup_printf(_("Send text to %s"),name);
smorlat's avatar
smorlat committed
980 981
		edit_label=g_strdup_printf(_("Edit contact '%s'"),name);
		delete_label=g_strdup_printf(_("Delete contact '%s'"),name);
Margaux Clerc's avatar
Margaux Clerc committed
982
		delete_hist_label=g_strdup_printf(_("Delete chat history of '%s'"),name);
aymeric's avatar
aymeric committed
983
		g_free(name);
smorlat's avatar
smorlat committed
984
	}
aymeric's avatar
aymeric committed
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
	if (call_label){
		menu_item=gtk_image_menu_item_new_with_label(call_label);
		image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
		gtk_widget_show(image);
		gtk_widget_show(menu_item);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
		g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_call_selected,contact_list);
	}
	if (text_label){
		menu_item=gtk_image_menu_item_new_with_label(text_label);
		image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
		gtk_widget_show(image);
		gtk_widget_show(menu_item);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
		g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_chat_selected,contact_list);
	}
smorlat's avatar
smorlat committed
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
	if (edit_label){
		menu_item=gtk_image_menu_item_new_with_label(edit_label);
		image=gtk_image_new_from_stock(GTK_STOCK_EDIT,GTK_ICON_SIZE_MENU);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
		gtk_widget_show(image);
		gtk_widget_show(menu_item);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
		g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_edit_contact,contact_list);
	}
	if (delete_label){
		menu_item=gtk_image_menu_item_new_with_label(delete_label);
		image=gtk_image_new_from_stock(GTK_STOCK_DELETE,GTK_ICON_SIZE_MENU);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
		gtk_widget_show(image);
		gtk_widget_show(menu_item);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
		g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_remove_contact,contact_list);
	}
1021

Margaux Clerc's avatar
Margaux Clerc committed
1022 1023 1024 1025 1026 1027 1028 1029 1030
	if (delete_hist_label){
		menu_item=gtk_image_menu_item_new_with_label(delete_hist_label);
		image=gtk_image_new_from_stock(GTK_STOCK_CLEAR,GTK_ICON_SIZE_MENU);
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
		gtk_widget_show(image);
		gtk_widget_show(menu_item);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
		g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_delete_history,contact_list);
	}
smorlat's avatar
smorlat committed
1031

smorlat's avatar
smorlat committed
1032
	if (ssc && (sip_setup_context_get_capabilities(ssc) & SIP_SETUP_CAP_BUDDY_LOOKUP)) {
smorlat's avatar
smorlat committed
1033 1034 1035 1036
		gchar *tmp=g_strdup_printf(_("Add new contact from %s directory"),linphone_proxy_config_get_domain(cfg));
		menu_item=gtk_image_menu_item_new_with_label(tmp);
		g_free(tmp);
		image=gtk_image_new_from_stock(GTK_STOCK_ADD,GTK_ICON_SIZE_MENU);
smorlat's avatar
smorlat committed
1037 1038 1039 1040 1041 1042 1043
		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image);
		gtk_widget_show(image);
		gtk_widget_show(menu_item);
		gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
		g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_show_buddy_lookup_window,ssc);
		gtk_widget_show(menu);
	}
1044

aymeric's avatar
aymeric committed
1045 1046 1047 1048 1049 1050
	menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL);
	gtk_widget_show(menu_item);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
	g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_add_contact,contact_list);
	gtk_widget_show(menu);
	gtk_menu_attach_to_widget (GTK_MENU (menu),