1 /* $Id: smsview.c,v 1.14 2008/02/27 20:02:08 dforsi Exp $ */
2 
3 #include <gtk/gtk.h>
4 #include <gdk/gdkkeysyms.h>
5 #include <glade/glade.h>
6 #include <gnokii.h>
7 #include <string.h>
8 
9 #include "gnocky.h"
10 #include "utils.h"
11 #include "phonebookview.h"
12 
13 extern GtkWidget *window;
14 extern GSList *sms_list;
15 extern GMutex *sms_mutex;
16 extern gboolean sms_updated;
17 extern GSList *phonebook_list;
18 extern GMutex *phonebook_mutex;
19 extern GdkPixbuf *me_pixbuf;
20 extern GdkPixbuf *sm_pixbuf;
21 
22 static GladeXML *sms_xml = NULL;
23 static GladeXML *new_sms_xml = NULL;
24 static GtkListStore *store;
25 static GtkTreeIter iter;
26 
27 enum {
28 	COL_SENDER,
29 	COL_DATE,
30 	COL_MEMORY,
31 	COL_POINTER
32 };
33 
34 enum {
35 	COL_TYPE,
36 	COL_NAME,
37 	COL_PB_POINTER
38 };
39 
gnocky_sms_create_model()40 static GtkTreeModel *gnocky_sms_create_model()
41 {
42   /* create list store */
43   store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
44 
45   return GTK_TREE_MODEL (store);
46 }
47 
gnocky_sms_sort_date_column(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer user_data)48 static gint gnocky_sms_sort_date_column(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
49 {
50 	gn_sms *smsa, *smsb;
51 	gint ret;
52 
53 	gtk_tree_model_get (model, a, COL_POINTER, &smsa, -1);
54 	gtk_tree_model_get (model, b, COL_POINTER, &smsb, -1);
55 
56 	/* this ignores smsc_time.timezone */
57 	ret = smsa->smsc_time.year - smsb->smsc_time.year;
58 	if (ret) return ret;
59 	ret = smsa->smsc_time.month - smsb->smsc_time.month;
60 	if (ret) return ret;
61 	ret = smsa->smsc_time.day - smsb->smsc_time.day;
62 	if (ret) return ret;
63 	ret = smsa->smsc_time.hour - smsb->smsc_time.hour;
64 	if (ret) return ret;
65 	ret = smsa->smsc_time.minute - smsb->smsc_time.minute;
66 	if (ret) return ret;
67 	ret = smsa->smsc_time.second - smsb->smsc_time.second;
68 
69 	return ret;
70 }
71 
gnocky_sms_add_columns(GtkTreeView * treeview)72 static void gnocky_sms_add_columns(GtkTreeView *treeview)
73 {
74 	GtkCellRenderer *renderer;
75 	GtkTreeViewColumn *column;
76 	GtkTreeModel *model = gtk_tree_view_get_model (treeview);
77 
78 	renderer = gtk_cell_renderer_text_new ();
79 	column = gtk_tree_view_column_new_with_attributes (_("Sender"),
80 						     renderer,
81 						     "text",
82 						     COL_SENDER,
83 						     NULL);
84 	gtk_tree_view_column_set_sort_column_id (column, COL_SENDER);
85 	gtk_tree_view_append_column (treeview, column);
86 
87 	renderer = gtk_cell_renderer_text_new ();
88 	column = gtk_tree_view_column_new_with_attributes (_("Date"),
89 						     renderer,
90 						     "text",
91 						     COL_DATE,
92 						     NULL);
93 	gtk_tree_view_column_set_sort_column_id (column, COL_DATE);
94 	gtk_tree_view_append_column (treeview, column);
95 
96 	renderer = gtk_cell_renderer_text_new ();
97 	column = gtk_tree_view_column_new_with_attributes (_("Memory"),
98 						     renderer,
99 						     "text",
100 						     COL_MEMORY,
101 						     NULL);
102 	gtk_tree_view_column_set_sort_column_id (column, COL_MEMORY);
103 	gtk_tree_view_append_column (treeview, column);
104 
105 	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(model), COL_DATE, gnocky_sms_sort_date_column, NULL, NULL);
106 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(model), COL_DATE, GTK_SORT_DESCENDING);
107 }
108 
gnocky_new_sms_count_characters(GtkWidget * widget,GdkEventKey * event,gpointer user_data)109 gboolean gnocky_new_sms_count_characters(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
110 {
111 	GtkTextBuffer *buffer;
112 	GtkWidget *w;
113 	gint char_count;
114 	gchar *tmp;
115 
116 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
117 	char_count = gtk_text_buffer_get_char_count (buffer);
118 
119 	if (char_count > GN_SMS_MAX_LENGTH) {
120 		GtkTextIter start, end;
121 		gchar *text;
122 
123 		gtk_text_buffer_get_start_iter(buffer, &start);
124 		gtk_text_buffer_get_end_iter(buffer, &end);
125 
126 		text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
127 		gtk_text_buffer_set_text(buffer, text, GN_SMS_MAX_LENGTH);
128 		g_free(text);
129 		char_count = GN_SMS_MAX_LENGTH;
130 	}
131 	w = glade_xml_get_widget(new_sms_xml, "chars_label");
132 	tmp = g_strdup_printf(_("%d left"), GN_SMS_MAX_LENGTH - char_count);
133 	gtk_label_set_markup(GTK_LABEL(w), tmp);
134 	g_free(tmp);
135 
136 	return FALSE;
137 }
138 
gnocky_sms_phone_search_model()139 static GtkTreeModel *gnocky_sms_phone_search_model()
140 {
141 	GtkListStore *store;
142   	/* create list store */
143   	store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
144 
145 	return GTK_TREE_MODEL (store);
146 }
147 
gnocky_phone_search_add_columns(GtkTreeView * treeview)148 static void gnocky_phone_search_add_columns(GtkTreeView *treeview)
149 {
150 	GtkCellRenderer *renderer;
151 	GtkTreeViewColumn *column;
152 	GtkTreeModel *model = gtk_tree_view_get_model (treeview);
153 
154 	renderer = gtk_cell_renderer_pixbuf_new ();
155 	column = gtk_tree_view_column_new_with_attributes (_("Type"),
156 						     renderer,
157 						     "pixbuf",
158 						     COL_TYPE,
159 						     NULL);
160 	gtk_tree_view_column_set_sort_column_id (column, COL_TYPE);
161 	gtk_tree_view_append_column (treeview, column);
162 
163 	renderer = gtk_cell_renderer_text_new ();
164 	column = gtk_tree_view_column_new_with_attributes (_("Name"),
165 						     renderer,
166 						     "text",
167 						     COL_NAME,
168 						     NULL);
169 	gtk_tree_view_column_set_sort_column_id (column, COL_NAME);
170 	gtk_tree_view_append_column (treeview, column);
171 
172 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(model), COL_NAME, GTK_SORT_ASCENDING);
173 }
174 
pbs_clicked(GtkWidget * widget,GdkEventButton * ev,gpointer user_data)175 gboolean pbs_clicked(GtkWidget *widget, GdkEventButton *ev, gpointer user_data)
176 {
177 	if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) {
178 		GtkWidget *dialog;
179 		GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
180 		GtkTreeViewColumn *treevc = NULL;
181 		GtkTreePath *treepath = NULL;
182 		GtkTreeIter iter;
183 		gn_phonebook_entry *en;
184 
185 		if (!gtk_tree_view_get_path_at_pos
186 		    (GTK_TREE_VIEW(widget), ev->x, ev->y, &treepath, &treevc, NULL, NULL))
187 			return FALSE;
188 		gtk_tree_model_get_iter(model, &iter, treepath);
189 		gtk_tree_path_free(treepath);
190 		gtk_tree_model_get(model, &iter, COL_PB_POINTER, &en, -1);
191 		if (en) {
192 		    dialog = gtk_widget_get_ancestor(widget, GTK_TYPE_DIALOG);
193 		    gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
194 		}
195 	}
196 	return FALSE;
197 }
198 
gnocky_sms_phonebook_search_clicked(GtkWidget * widget,gpointer user_data)199 void gnocky_sms_phonebook_search_clicked(GtkWidget *widget, gpointer user_data)
200 {
201 	GtkWidget *phone_search;
202 	GtkWidget *phone_tree;
203 	GtkTreeModel *model;
204 	int res;
205  	GladeXML *phone_search_xml = create_gladexml("gnocky-phonebook-list-dialog.glade", "phonebook_list_dialog");
206 
207 	if (!phone_search_xml)
208 		g_error("Cannot create phone search view!\n");
209 
210 	phone_search = glade_xml_get_widget(phone_search_xml, "phonebook_list_dialog");
211 	glade_xml_signal_autoconnect(phone_search_xml);
212 
213 	model = gnocky_sms_phone_search_model();
214 	phone_tree = glade_xml_get_widget(phone_search_xml, "phonebook_treeview");
215 	gtk_tree_view_set_model(GTK_TREE_VIEW(phone_tree), model);
216 
217 	gnocky_phone_search_add_columns(GTK_TREE_VIEW(phone_tree));
218 
219 	if (g_mutex_trylock(phonebook_mutex)) {
220 		GSList *tmp = phonebook_list;
221 		while (tmp) {
222 			gn_phonebook_entry *en = (gn_phonebook_entry *) tmp->data;
223 			gchar *number_string = g_strdup("");
224 			gchar *name = g_locale_to_utf8(en->name, -1, NULL, NULL, NULL);
225 
226 			if (en->subentries_count) {
227 				gint i;
228 				gchar *tmp;
229 
230 				for (i = 0;i<en->subentries_count;i++) {
231 					tmp = g_strdup_printf("%s %s", number_string, en->subentries[i].data.number);
232 					g_free(number_string);
233 					number_string = tmp;
234 				}
235 			} else {
236 				g_free(number_string);
237 				number_string = g_strdup(en->number);
238 			}
239 
240 			gtk_list_store_append (GTK_LIST_STORE(model), &iter);
241 			gtk_list_store_set (GTK_LIST_STORE(model), &iter, COL_NAME, name, COL_PB_POINTER, en, -1);
242 
243 			g_free(name);
244 			g_free(number_string);
245 
246 			switch (en->memory_type) {
247 				case GN_MT_ME:
248 					gtk_list_store_set (GTK_LIST_STORE(model), &iter, COL_TYPE, me_pixbuf, -1);
249 					break;
250 				case GN_MT_SM:
251 					gtk_list_store_set (GTK_LIST_STORE(model), &iter, COL_TYPE, sm_pixbuf, -1);
252 					break;
253 				default:
254 					break;
255 			}
256 			tmp = tmp->next;
257 		}
258 	}
259 	g_mutex_unlock(phonebook_mutex);
260 
261 	gtk_window_set_transient_for (GTK_WINDOW (phone_search), GTK_WINDOW (((GnockyNewSmsInfo *) user_data)->parent));
262 	res = gtk_dialog_run(GTK_DIALOG(phone_search));
263 	if (res == GTK_RESPONSE_OK) {
264 		GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(phone_tree));
265 		GtkTreeIter iter;
266 		GList *rows, *tmp;
267 		gn_phonebook_entry *en;
268 
269 		rows = gtk_tree_selection_get_selected_rows(selection, NULL);
270 		tmp = rows;
271 		while (tmp) {
272 			gtk_tree_model_get_iter(model, &iter, tmp->data);
273 			gtk_tree_model_get(model, &iter, COL_PB_POINTER, &en, -1);
274 			/* this needs to be fixed when multipile selection
275 			    will be allowed */
276 			if (en)
277 			    gtk_entry_set_text(GTK_ENTRY(((GnockyNewSmsInfo *) user_data)->sms_number), en->number);
278 			tmp = tmp->next;
279 		}
280 		g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
281 		g_list_free (rows);
282 
283 /*		GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
284 		GtkTreeViewColumn *treevc = NULL;
285 		GtkTreePath *treepath = NULL;
286 		GtkTreeIter iter;
287 		gn_phonebook_entry *en;
288 
289 		if (!gtk_tree_view_get_path_at_pos
290 		    (GTK_TREE_VIEW(widget), ev->x, ev->y, &treepath, &treevc, NULL, NULL))
291 			return FALSE;
292 		gtk_tree_model_get_iter(model, &iter, treepath);
293 		gtk_tree_model_get(model, &iter, COL_PB_POINTER, &en, -1);
294 */
295 	}
296 	gtk_widget_destroy(phone_search);
297 	g_object_unref(phone_search_xml);
298 	g_object_unref (model);
299 
300 }
301 
gnocky_new_sms_clicked(GtkWidget * widget,gpointer data)302 void gnocky_new_sms_clicked(GtkWidget *widget, gpointer data)
303 {
304 	GtkWidget *new_sms;
305 	GtkWidget *phonebook_search_button;
306 	GtkWidget *sms_number;
307 	GnockyNewSmsInfo new_sms_info;
308 	int res;
309 
310 	new_sms_xml = create_gladexml("gnocky-new-sms.glade", "new_sms_dialog");
311 
312 	if (!new_sms_xml)
313 		g_error("Cannot create new sms view!\n");
314 
315 	new_sms = glade_xml_get_widget(new_sms_xml, "new_sms_dialog");
316 	glade_xml_signal_autoconnect(new_sms_xml);
317 
318 	/* set signal by hand... */
319 	phonebook_search_button = glade_xml_get_widget(new_sms_xml, "phonebook_search_button");
320 	new_sms_info.sms_number = glade_xml_get_widget(new_sms_xml, "sms_number");
321 	new_sms_info.parent = GTK_WINDOW(new_sms);
322 	g_signal_connect(G_OBJECT(phonebook_search_button), "clicked",
323 			 G_CALLBACK(gnocky_sms_phonebook_search_clicked), &new_sms_info);
324 
325 	gtk_window_set_transient_for (GTK_WINDOW (new_sms), GTK_WINDOW (window));
326 	res = gtk_dialog_run(GTK_DIALOG(new_sms));
327 
328 	gnocky_new_sms_count_characters(glade_xml_get_widget(new_sms_xml, "sms_text"), NULL, NULL);
329 
330 	if (res == GTK_RESPONSE_OK) {
331 		GtkWidget *entry;
332 		gchar *number, *text, *sms_text;
333 		GtkTextBuffer *buffer;
334 		GtkTextIter start, end;
335 		gn_sms *sms;
336 
337 		entry = glade_xml_get_widget(new_sms_xml, "sms_number");
338 		number = g_locale_from_utf8(gtk_entry_get_text(GTK_ENTRY(entry)), -1, NULL, NULL, NULL);
339 
340 		entry = glade_xml_get_widget(new_sms_xml, "sms_text");
341 		buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry));
342 
343 		gtk_text_buffer_get_start_iter(buffer, &start);
344 		gtk_text_buffer_get_iter_at_offset(buffer, &end, GN_SMS_MAX_LENGTH);
345 
346 		text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
347 		sms_text = g_locale_from_utf8(text, -1, NULL, NULL, NULL);
348 		g_free(text);
349 
350 		sms = g_new0(gn_sms, 1);
351 		gn_sms_default_submit(sms);
352 		strncpy(sms->remote.number, number, sizeof(sms->remote.number) - 1);
353 		if (number[0] == '+') {
354 			sms->remote.type = GN_GSM_NUMBER_International;
355 		} else {
356 			sms->remote.type = GN_GSM_NUMBER_Unknown;
357 		}
358 		strncpy(sms->user_data[0].u.text, sms_text, strlen(sms_text));
359 		sms->user_data[0].length = strlen(sms_text);
360 
361 		sms->user_data[0].type = GN_SMS_DATA_Text;
362 		if (!gn_char_def_alphabet(sms->user_data[0].u.text))
363 			sms->dcs.u.general.alphabet = GN_SMS_DCS_UCS2;
364 		sms->user_data[1].type = GN_SMS_DATA_None;
365 		g_free(number);
366 		g_free(sms_text);
367 
368 		gnocky_event_push(GNOCKY_EVENT_SEND_SMS, sms);
369 	}
370 
371 	gtk_widget_destroy(new_sms);
372 	g_object_unref(new_sms_xml);
373 	new_sms_xml = NULL;
374 }
375 
gnocky_sms_load_from_phone_clicked(GtkWidget * widget,gpointer data)376 void gnocky_sms_load_from_phone_clicked(GtkWidget *widget, gpointer data)
377 {
378 	gnocky_event_push(GNOCKY_EVENT_READ_SMS_LIST, NULL);
379 }
380 
sms_pressed(GtkWidget * widget,GdkEventKey * ev,gpointer user_data)381 gboolean sms_pressed(GtkWidget *widget, GdkEventKey *ev, gpointer user_data)
382 {
383 	if (ev->keyval == GDK_Delete) {
384 		GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
385 		GtkTreePath *treepath = NULL;
386 		GtkTreeIter iter;
387 		GtkWidget *dialog;
388 		gint res;
389 		gn_sms *sms;
390 
391 		gtk_tree_view_get_cursor (GTK_TREE_VIEW(widget), &treepath, NULL);
392 		if (!treepath) return FALSE;
393 		gtk_tree_model_get_iter(model, &iter, treepath);
394 		gtk_tree_model_get(model, &iter, COL_POINTER, &sms, -1);
395 
396 		dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
397                                              GTK_BUTTONS_OK_CANCEL,
398 					     _("Do you want to delete this SMS?"));
399 
400 		res = gtk_dialog_run(GTK_DIALOG(dialog));
401 		if (res == GTK_RESPONSE_OK) {
402 			gnocky_event_push(GNOCKY_EVENT_DELETE_SMS, sms);
403 		}
404 		gtk_tree_path_free(treepath);
405 
406 		gtk_widget_destroy(dialog);
407 	}
408 	return FALSE;
409 }
410 
sms_clicked(GtkWidget * treeview,GdkEventButton * ev,gpointer user_data)411 static gboolean sms_clicked(GtkWidget *treeview, GdkEventButton *ev, gpointer user_data)
412 {
413 	GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
414 	GtkTreePath *treepath = NULL;
415 	GtkTreeIter iter;
416 	GtkWidget *widget;
417 	GtkTextBuffer *buffer;
418 	gn_sms *sms;
419 	gchar *tmp, *sender;
420 	gchar *utf_body;
421 
422 	gtk_tree_view_get_cursor (GTK_TREE_VIEW(treeview), &treepath, NULL);
423 	if (!treepath) return FALSE;
424 	gtk_tree_model_get_iter(model, &iter, treepath);
425 	gtk_tree_path_free(treepath);
426 	gtk_tree_model_get(model, &iter, COL_POINTER, &sms, -1);
427 
428 	widget = glade_xml_get_widget(sms_xml, "sms_body");
429 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
430 	utf_body = g_locale_to_utf8(sms->user_data[0].u.text, -1, NULL, NULL, NULL);
431 	gtk_text_buffer_set_text (buffer, utf_body, -1);
432 	g_free(utf_body);
433 
434 	widget = glade_xml_get_widget(sms_xml, "from_label");
435 
436 	sender = gnocky_pb_get_name(sms->remote.number);
437 
438 	if (!sender) {
439 		tmp = g_strdup(sms->remote.number);
440 	} else {
441 		gchar *utf_sender = g_locale_to_utf8(sender, -1, NULL, NULL, NULL);
442 		tmp = g_strdup_printf("<b>%s</b> (%s)", utf_sender, sms->remote.number);
443 		g_free(sender);
444 		g_free(utf_sender);
445 	}
446 
447 	gtk_label_set_markup(GTK_LABEL(widget), tmp);
448 	g_free(tmp);
449 
450 	widget = glade_xml_get_widget(sms_xml, "date_label");
451 	tmp = g_strdup_printf("<b>%02d/%02d/%04d %02d:%02d</b>",
452 				sms->smsc_time.day, sms->smsc_time.month, sms->smsc_time.year, sms->smsc_time.hour, sms->smsc_time.minute);
453 	gtk_label_set_markup(GTK_LABEL(widget), tmp);
454 	g_free(tmp);
455 
456 	return FALSE;
457 }
458 
gnocky_sms_view_destroy(GtkWidget * sms_view)459 void gnocky_sms_view_destroy(GtkWidget *sms_view)
460 {
461 	if (sms_view)
462 		gtk_widget_destroy(sms_view);
463 	if (sms_xml)
464 		g_object_unref(sms_xml);
465 }
466 
gnocky_sms_view_create()467 GtkWidget *gnocky_sms_view_create()
468 {
469 	GtkTreeModel *model;
470 	GtkWidget *sms_tree;
471 	GtkWidget *sv;
472 	GtkTreeSelection *selection;
473 
474 	sms_xml = create_gladexml("gnocky-sms-view.glade", "sms_view");
475 
476 	if (!sms_xml) {
477 		g_error("Cannot create sms view!\n");
478 		gnocky_main_quit();
479 	}
480 
481 	glade_xml_signal_autoconnect(sms_xml);
482 
483 	sv = glade_xml_get_widget(sms_xml, "sms_view");
484 
485 	if (sv == NULL) {
486 		g_error("uhm... sv == NULL!!!\n");
487 	}
488 
489 	model = gnocky_sms_create_model();
490 	sms_tree = glade_xml_get_widget(sms_xml, "sms_tree");
491 	gtk_tree_view_set_model(GTK_TREE_VIEW(sms_tree), model);
492 	g_object_unref (model);
493 
494 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(sms_tree));
495 	g_signal_connect_swapped (G_OBJECT (selection), "changed", G_CALLBACK (sms_clicked), G_OBJECT (sms_tree));
496 
497 	gnocky_sms_add_columns(GTK_TREE_VIEW(sms_tree));
498 
499 	return sv;
500 }
501 
gnocky_sms_view_update(GnockyPhoneMonitor pm)502 void gnocky_sms_view_update(GnockyPhoneMonitor pm)
503 {
504 	if (g_mutex_trylock(sms_mutex)) {
505 		GSList *tmp = sms_list;
506 		if (sms_updated) {
507 			gtk_list_store_clear(store);
508 			while (tmp) {
509 				gn_sms *sms = tmp->data;
510 				gchar *sender;
511 				gchar *date;
512 
513 				sender = gnocky_pb_get_name(sms->remote.number);
514 				if (!sender) {
515 					sender = g_strdup(sms->remote.number);
516 				} else {
517 					gchar *utf_sender = g_locale_to_utf8(sender, -1, NULL, NULL, NULL);
518 					g_free(sender);
519 					sender = utf_sender;
520 				}
521 				date = g_strdup_printf("%02d/%02d/%04d %02d:%02d",
522 				sms->smsc_time.day, sms->smsc_time.month, sms->smsc_time.year, sms->smsc_time.hour, sms->smsc_time.minute);
523 
524 				gtk_list_store_append (store, &iter);
525 				gtk_list_store_set (store, &iter, COL_SENDER, sender, COL_DATE, date, COL_MEMORY, gn_memory_type2str(sms->memory_type), COL_POINTER, sms, -1);
526 
527 				g_free(sender);
528 				g_free(date);
529 				tmp = tmp->next;
530 			}
531 			sms_updated = FALSE;
532 		}
533 		g_mutex_unlock(sms_mutex);
534 	}
535 }
536