]> sjero.net Git - linphone/blob - gtk/buddylookup.c
Aac-eld add missing header according to RFC3640 3.3.6
[linphone] / gtk / buddylookup.c
1 /*
2 linphone, gtk-glade interface.
3 Copyright (C) 2008  Simon MORLAT (simon.morlat@linphone.org)
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 */
19
20 #include "linphone.h"
21 #include "sipsetup.h"
22
23 static void linphone_gtk_display_lookup_results(GtkWidget *w, const MSList *results);
24
25 enum {
26         LOOKUP_RESULT_NAME,
27         LOOKUP_RESULT_SIP_URI,
28         LOOKUP_RESULT_ADDRESS,
29         LOOKUP_RESULT_ICON,
30         LOOKUP_RESULT_NCOL
31 };
32
33 void linphone_gtk_buddy_lookup_window_destroyed(GtkWidget *w){
34         guint tid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"typing_timeout"));
35         if (tid!=0){
36                 g_source_remove(tid);
37         }
38         tid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"buddylookup_processing"));
39         if (tid!=0){
40                 g_source_remove(tid);
41         }
42 }
43
44 static void enable_add_buddy_button(GtkWidget *w){
45         gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),TRUE);
46 }
47
48 static void disable_add_buddy_button(GtkWidget *w){
49         gtk_widget_set_sensitive(linphone_gtk_get_widget(w,"add_buddy"),FALSE);
50 }
51
52 static void buddy_selection_changed(GtkWidget *w){
53         GtkWidget *results=linphone_gtk_get_widget(w,"search_results");
54         GtkTreeSelection *select;
55         GtkTreeIter iter;
56         GtkTreeModel *model;
57         enable_add_buddy_button(w);
58         
59         select = gtk_tree_view_get_selection(GTK_TREE_VIEW(results));
60         if (gtk_tree_selection_get_selected (select, &model, &iter))
61         {
62                 GtkTreePath *path=gtk_tree_model_get_path(model,&iter);
63                 gtk_tree_view_collapse_all(GTK_TREE_VIEW(results));
64                 gtk_tree_view_expand_row(GTK_TREE_VIEW(results),path,FALSE);
65                 gtk_tree_path_free(path);
66         }
67 }
68
69 GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){
70         GtkTreeStore *store;
71         GtkCellRenderer *renderer,*pbuf_renderer;
72         GtkTreeViewColumn *column;
73         GtkTreeSelection *select;
74         GtkWidget *w=linphone_gtk_create_window("buddylookup");
75         GtkWidget *results=linphone_gtk_get_widget(w,"search_results");
76         GtkProgressBar *pb=GTK_PROGRESS_BAR(linphone_gtk_get_widget(w,"progressbar"));
77         
78         store = gtk_tree_store_new(LOOKUP_RESULT_NCOL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF);
79         
80         /*gtk_tree_view_set_hover_expand(GTK_TREE_VIEW(results),TRUE);*/
81         gtk_tree_view_set_model(GTK_TREE_VIEW(results),GTK_TREE_MODEL(store));
82         g_object_unref(G_OBJECT(store));
83
84         renderer = gtk_cell_renderer_text_new ();
85         column = gtk_tree_view_column_new_with_attributes (_("Firstname, Lastname"),
86                                                    renderer,
87                                                    "markup", LOOKUP_RESULT_NAME,
88                                                    NULL);
89         g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
90         
91
92         pbuf_renderer=gtk_cell_renderer_pixbuf_new();
93         g_object_set(G_OBJECT(renderer),"is-expander",TRUE,NULL);
94         gtk_tree_view_column_pack_start(column,pbuf_renderer,FALSE);
95         gtk_tree_view_column_add_attribute  (column,pbuf_renderer,
96                                                          "pixbuf",
97                                                          LOOKUP_RESULT_ICON);
98         gtk_tree_view_append_column (GTK_TREE_VIEW (results), column);
99         
100 /*
101         column = gtk_tree_view_column_new_with_attributes (_("SIP address"),
102                                                    renderer,
103                                                    "text", LOOKUP_RESULT_SIP_URI,
104                                                    NULL);
105         g_object_set (G_OBJECT(column), "resizable", TRUE, NULL);
106         gtk_tree_view_append_column (GTK_TREE_VIEW (results), column);
107 */
108
109         select = gtk_tree_view_get_selection (GTK_TREE_VIEW (results));
110         gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
111         g_signal_connect_swapped(G_OBJECT(select),"changed",(GCallback)buddy_selection_changed,w);
112 /*
113 #if GTK_CHECK_VERSION(2,12,0)
114         gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(results),LOOKUP_RESULT_ADDRESS);
115 #endif
116 */
117         g_object_set_data(G_OBJECT(w),"SipSetupContext",ctx);
118         g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_buddy_lookup_window_destroyed,w);
119         //g_signal_connect_swapped(G_OBJECT(w),"destroy",(GCallback)linphone_gtk_buddy_lookup_window_destroyed,w);
120         gtk_progress_bar_set_fraction(pb,0);
121         gtk_progress_bar_set_text(pb,NULL);
122         gtk_dialog_add_button(GTK_DIALOG(w),GTK_STOCK_CLOSE,GTK_RESPONSE_CLOSE);
123         g_object_set_data(G_OBJECT(w),"last_state",GINT_TO_POINTER(-1));
124
125         gtk_widget_show(w);
126         return w;
127 }
128
129
130 void linphone_gtk_buddy_lookup_set_keyword(GtkWidget *w, const char *kw){
131         gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"keyword")),kw);
132 }
133
134 static gboolean linphone_gtk_process_buddy_lookup(GtkWidget *w){
135         BuddyLookupStatus bls;
136         SipSetupContext *ctx;
137         int last_state;
138         gchar *tmp;
139         MSList *results=NULL;
140         GtkProgressBar *pb=GTK_PROGRESS_BAR(linphone_gtk_get_widget(w,"progressbar"));
141         BuddyLookupRequest *req=(BuddyLookupRequest*)g_object_get_data(G_OBJECT(w),"buddylookup_request");
142
143         ctx=(SipSetupContext*)g_object_get_data(G_OBJECT(w),"SipSetupContext"); 
144         last_state=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"last_state"));
145
146         if (req==NULL) {
147                 g_object_set_data(G_OBJECT(w),"buddylookup_processing",GINT_TO_POINTER(0));
148                 return FALSE;
149         }
150         bls=req->status;
151         if (last_state==bls) return TRUE;
152         
153         switch(bls){
154                 case BuddyLookupNone:
155                         gtk_progress_bar_set_fraction(pb,0);
156                         gtk_progress_bar_set_text(pb,NULL);
157                         break;
158                 case BuddyLookupFailure:
159                         gtk_progress_bar_set_fraction(pb,0);
160                         gtk_progress_bar_set_text(pb,_("Error communicating with server."));
161                         break;
162                 case BuddyLookupConnecting:
163                         gtk_progress_bar_set_fraction(pb,0.2);
164                         gtk_progress_bar_set_text(pb,_("Connecting..."));
165                         break;
166                 case BuddyLookupConnected:
167                         gtk_progress_bar_set_fraction(pb,0.4);
168                         gtk_progress_bar_set_text(pb,_("Connected"));
169                         break;
170                 case BuddyLookupReceivingResponse:
171                         gtk_progress_bar_set_fraction(pb,0.8);
172                         gtk_progress_bar_set_text(pb,_("Receiving data..."));
173                         break;
174                 case BuddyLookupDone:
175                         results=req->results;
176                         linphone_gtk_display_lookup_results(
177                                         linphone_gtk_get_widget(w,"search_results"),
178                                         results);
179                         gtk_progress_bar_set_fraction(pb,1);
180                         tmp=g_strdup_printf(ngettext("Found %i contact",
181                         "Found %i contacts", ms_list_size(results)),
182                     ms_list_size(results));
183                         gtk_progress_bar_set_text(pb,tmp);
184                         g_free(tmp);
185                         sip_setup_context_buddy_lookup_free(ctx,req);
186                         g_object_set_data(G_OBJECT(w),"buddylookup_request",NULL);
187                         break;
188         }
189         g_object_set_data(G_OBJECT(w),"last_state",GINT_TO_POINTER(bls));
190         return TRUE;
191 }
192
193 static gboolean keyword_typing_finished(GtkWidget *w){
194         guint tid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"typing_timeout"));
195         const char *keyword;
196         SipSetupContext *ctx;
197         if (tid!=0){
198                 g_source_remove(tid);
199         }
200         keyword=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"keyword")));
201         if (strlen(keyword)>=1){
202                 BuddyLookupRequest *req;
203                 guint tid2;
204                 ctx=(SipSetupContext*)g_object_get_data(G_OBJECT(w),"SipSetupContext");
205                 req=(BuddyLookupRequest*)g_object_get_data(G_OBJECT(w),"buddylookup_request");
206                 if (req!=NULL){
207                         sip_setup_context_buddy_lookup_free(ctx,req);
208                 }
209                 req=sip_setup_context_create_buddy_lookup_request(ctx);
210                 buddy_lookup_request_set_key(req,keyword);
211                 sip_setup_context_buddy_lookup_submit(ctx,req);
212                 g_object_set_data(G_OBJECT(w),"buddylookup_request",req);
213                 if (g_object_get_data(G_OBJECT(w),"buddylookup_processing")==NULL){
214                         tid2=g_timeout_add(20,(GSourceFunc)linphone_gtk_process_buddy_lookup,w);
215                         g_object_set_data(G_OBJECT(w),"buddylookup_processing",GINT_TO_POINTER(tid2));
216                 }
217         }
218         return FALSE;
219 }
220
221 void linphone_gtk_keyword_changed(GtkEditable *e){
222         GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(e));
223         guint tid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"typing_timeout"));
224         if (tid!=0){
225                 g_source_remove(tid);
226         }
227         tid=g_timeout_add(2000,(GSourceFunc)keyword_typing_finished,w);
228         g_object_set_data(G_OBJECT(w),"typing_timeout",GINT_TO_POINTER(tid));
229 }
230
231 static void linphone_gtk_display_lookup_results(GtkWidget *w, const MSList *results){
232         GtkTreeStore *store;
233         GtkTreeIter iter;
234         gchar *tmp;
235         const MSList *elem;
236         store=GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(w)));
237         gtk_tree_store_clear(store);
238         disable_add_buddy_button(gtk_widget_get_toplevel(w));
239         for(elem=results;elem!=NULL;elem=elem->next){
240                 BuddyInfo *bi=(BuddyInfo*)elem->data;
241                 GdkPixbuf *pbuf;
242                 GtkTreeIter depth1;
243                 gtk_tree_store_append(store,&iter,NULL);
244                 tmp=g_strdup_printf("%s, %s (%s)",bi->firstname,bi->lastname,bi->displayname);
245                 gtk_tree_store_set(store,&iter,LOOKUP_RESULT_NAME, tmp,-1);
246                 g_free(tmp);
247                 gtk_tree_store_set(store,&iter,LOOKUP_RESULT_SIP_URI, bi->sip_uri,-1);
248                 tmp=g_strdup_printf("%s, %s %s\n%s",bi->address.street, bi->address.zip, bi->address.town, bi->address.country);
249                 gtk_tree_store_set(store,&iter,LOOKUP_RESULT_ADDRESS, tmp,-1);
250                 g_free(tmp);
251                 if (bi->image_data!=NULL){
252                         pbuf=_gdk_pixbuf_new_from_memory_at_scale(bi->image_data,bi->image_length,-1,40,TRUE);
253                         if (pbuf) {
254                                 gtk_tree_store_set(store,&iter,LOOKUP_RESULT_ICON,pbuf,-1);
255                                 g_object_unref(G_OBJECT(pbuf));
256                         }
257                 }
258                 gtk_tree_store_append(store,&depth1,&iter);
259                 tmp=g_strdup_printf("<big>%s, %s (%s)</big>\n<i>%s</i>, <b>%s</b> %s\n%s\n%s",
260                         bi->firstname,bi->lastname,bi->displayname,bi->address.street,
261                         bi->address.zip, bi->address.town, bi->address.country,bi->sip_uri);
262                 gtk_tree_store_set(store,&depth1,LOOKUP_RESULT_NAME,tmp,-1);
263                 g_free(tmp);
264                 if (bi->image_data!=NULL){
265                         pbuf=_gdk_pixbuf_new_from_memory_at_scale(bi->image_data,bi->image_length,-1,-1,TRUE);
266                         if (pbuf) {
267                                 gtk_tree_store_set(store,&depth1,LOOKUP_RESULT_ICON,pbuf,-1);
268                                 g_object_unref(G_OBJECT(pbuf));
269                         }
270                 }
271         }
272 }
273
274 void linphone_gtk_add_buddy_from_database(GtkWidget *button){
275         GtkWidget *w=gtk_widget_get_toplevel(button);
276         GtkTreeSelection *select;
277         GtkTreeIter iter;
278         GtkTreeModel *model;
279         select = gtk_tree_view_get_selection(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"search_results")));
280         if (gtk_tree_selection_get_selected (select, &model, &iter))
281         {
282                 char *uri;
283                 char *name;
284                 char *addr;
285                 LinphoneFriend *lf;
286                 int presence=linphone_gtk_get_ui_config_int("use_subscribe_notify",1);
287                 gtk_tree_model_get (model, &iter,LOOKUP_RESULT_SIP_URI , &uri,LOOKUP_RESULT_NAME, &name, -1);
288                 addr=g_strdup_printf("%s <%s>",name,uri);
289
290                 lf=linphone_friend_new_with_addr(addr);
291                 linphone_friend_set_inc_subscribe_policy(lf,presence ? LinphoneSPAccept : LinphoneSPDeny);
292                 linphone_friend_send_subscribe(lf,presence);
293                 linphone_core_add_friend(linphone_gtk_get_core(),lf);
294                 linphone_gtk_show_friends();
295                 g_free(addr);
296                 g_free(uri);
297                 g_free(name);
298         }
299 }
300
301 /*called when double clicking on a contact */
302 void linphone_gtk_buddy_lookup_contact_activated(GtkWidget *treeview){
303         linphone_gtk_add_buddy_from_database(treeview);
304         gtk_widget_destroy(gtk_widget_get_toplevel(treeview));
305 }