This commit was manufactured by cvs2svn to create tag 'bp_uc_works1'.
[gnokii.git] / xgnokii / xgnokii_sms.c
1 /*
2
3   X G N O K I I
4
5   A Linux/Unix GUI for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8
9 */
10 #include <unistd.h>
11 #include <locale.h>
12 #include <fcntl.h>
13 #include <pthread.h>
14 #include <time.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <gtk/gtk.h>
19 #include <gdk/gdkkeysyms.h>
20 #include "misc.h"
21 #include "gsm-api.h"
22 #include "gsm-datetime.h"
23 #include "gsm-sms.h"
24 #include "xgnokii_common.h"
25 #include "xgnokii.h"
26 #include "xgnokii_lowlevel.h"
27 #include "xgnokii_contacts.h"
28 #include "xgnokii_sms.h"
29 #include "xpm/Edit.xpm"
30 #include "xpm/Delete.xpm"
31 #include "xpm/Forward.xpm"
32 #include "xpm/Reply.xpm"
33 #include "xpm/Send.xpm"
34 #include "xpm/SendSMS.xpm"
35 #include "xpm/Check.xpm"
36 #include "xpm/Names.xpm"
37 #include "xpm/BCard.xpm"
38 #include "xpm/quest.xpm"
39
40 typedef struct {
41   gint  count;          // Messages count
42   gint  number;         // Number of tail in Long SMS;
43   gint *msgPtr;         // Array of MessageNumber;
44   gint  validity;
45   gint  class;
46   gchar sender[GSM_MAX_SENDER_LENGTH + 1];
47 } MessagePointers;
48
49 typedef struct {
50   gchar *number;
51   gchar *name;
52   gint used:1;
53 } AddressPar;
54
55 typedef struct {
56   GtkWidget *smsClist;
57   GtkWidget *smsText;
58   GSList    *messages;
59   GdkColor   colour;
60   gint       row_i;
61   gint       currentBox;
62 } SMSWidget;
63
64 typedef struct {
65   GtkWidget *SMSSendWindow;
66   GtkWidget *smsSendText;
67   GtkWidget *addr;
68   GtkWidget *status;
69   GtkWidget *report;
70   GtkWidget *longSMS;
71   GtkWidget *class;
72   GtkWidget *smscOptionMenu;
73   GtkTooltips *addrTip;
74   gint       center;
75   GSList    *addressLine;
76 } SendSMSWidget;
77
78 int prev_num_of_folders=0;
79
80 static GtkWidget *GUI_SMSWindow;
81 static SMSWidget SMS = {NULL, NULL, NULL};
82 static SendSMSWidget sendSMS = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL};
83 static ErrorDialog errorDialog = {NULL, NULL};
84 static InfoDialog infoDialog = {NULL, NULL};
85 static QuestMark questMark;
86 static GtkWidget *treeFolderItem[MAX_SMS_FOLDERS], *subTree;
87
88 static inline void Help1 (GtkWidget *w, gpointer data)
89 {
90   gchar *indx = g_strdup_printf ("/%s/gnokii/xgnokii/sms/index.htm", xgnokiiConfig.locale);
91   Help (w, indx);
92   g_free (indx);
93 }
94
95
96 static inline void Help2 (GtkWidget *w, gpointer data)
97 {
98   gchar *indx = g_strdup_printf ("/help/%s/sms_send.html", xgnokiiConfig.locale);
99   Help (w, indx);
100   g_free (indx);
101 }
102
103
104 static inline void CloseSMS (GtkWidget *w, gpointer data)
105 {
106   gtk_widget_hide (GUI_SMSWindow);
107 }
108
109
110 static inline void CloseSMSSend (GtkWidget *w, gpointer data)
111 {
112   gtk_widget_hide (sendSMS.SMSSendWindow);
113 }
114
115
116 static gint CListCompareFunc (GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
117 {
118   gchar *text1 = NULL;
119   gchar *text2 = NULL;
120
121   GtkCListRow *row1 = (GtkCListRow *) ptr1;
122   GtkCListRow *row2 = (GtkCListRow *) ptr2;
123
124   switch (row1->cell[clist->sort_column].type)
125   {
126     case GTK_CELL_TEXT:
127       text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
128       break;
129     case GTK_CELL_PIXTEXT:
130       text1 = GTK_CELL_PIXTEXT (row1->cell[clist->sort_column])->text;
131       break;
132     default:
133       break;
134   }
135   switch (row2->cell[clist->sort_column].type)
136   {
137     case GTK_CELL_TEXT:
138       text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
139       break;
140     case GTK_CELL_PIXTEXT:
141       text2 = GTK_CELL_PIXTEXT (row2->cell[clist->sort_column])->text;
142       break;
143     default:
144       break;
145   }
146
147   if (!text2)
148     return (text1 != NULL);
149
150   if (!text1)
151     return -1;
152
153   if (clist->sort_column == 1 && !SMS.currentBox)
154   {
155     struct tm bdTime;
156     time_t time1, time2;
157
158     bdTime.tm_sec  = atoi (text1 + 15);
159     bdTime.tm_min  = atoi (text1 + 12);
160     bdTime.tm_hour = atoi (text1 + 9);
161     bdTime.tm_mday = atoi (text1);
162     bdTime.tm_mon  = atoi (text1 + 3) - 1;
163     bdTime.tm_year = atoi (text1 + 6);
164     if (bdTime.tm_year < 70)
165       bdTime.tm_year += 100;
166 #ifdef HAVE_TM_GMTON
167     if (text1[17] != '\0')
168       bdTime.tm_gmtoff = atoi (text1 + 18) * 3600;
169 #endif
170     bdTime.tm_isdst = -1;
171
172     time1 = mktime (&bdTime);
173
174     bdTime.tm_sec  = atoi (text2 + 15);
175     bdTime.tm_min  = atoi (text2 + 12);
176     bdTime.tm_hour = atoi (text2 + 9);
177     bdTime.tm_mday = atoi (text2);
178     bdTime.tm_mon  = atoi (text2 + 3) - 1;
179     bdTime.tm_year = atoi (text2 + 6);
180     if (bdTime.tm_year < 70)
181       bdTime.tm_year += 100;
182 #ifdef HAVE_TM_GMTON
183     if (text2[17] != '\0')
184       bdTime.tm_gmtoff = atoi (text2 + 18) * 3600;
185 #endif
186     bdTime.tm_isdst = -1;
187
188     time2 = mktime (&bdTime);
189
190     if (time1 < time2)
191       return (1);
192     else if (time1 > time2)
193       return (-1);
194     else 
195       return 0;
196   }
197
198   return (g_strcasecmp (text1, text2));
199 }
200
201
202 static inline void DestroyMsgPtrs (gpointer data)
203 {
204   g_free (((MessagePointers *) data)->msgPtr);
205   g_free ((MessagePointers *) data);
206 }
207
208
209 static void InsertFolderElement (gpointer d, gpointer userData)
210 {
211   GSM_SMSMessage *data = (GSM_SMSMessage *) d;
212   MessagePointers *msgPtrs;
213   GSM_DateTime *dt;
214
215   if (data->folder == SMS.currentBox)
216   {
217     gchar *row[4];
218
219     if (data->Type == GST_DR)
220     {
221       row[0] = g_strdup (_("report"));
222       dt = &(data->SMSCTime);
223     }
224     else
225     {
226         dt = &(data->Time);
227         switch (data->Status)
228         {
229             case  GSS_SENTREAD:
230                 if (data->folder==0) //GST_INBOX
231                         row[0] = g_strdup (_("read"));
232                 else
233                         row[0] = g_strdup (_("sent"));
234                 break;
235             case  GSS_NOTSENTREAD:
236                 if (data->folder==0) //GST_INBOX
237                         row[0] = g_strdup (_("unread"));
238                 else
239                         row[0] = g_strdup (_("not sent"));
240                 break;
241             case  GSS_UNKNOWN:
242                 row[0] = g_strdup (_("not known :-("));
243                 break;
244             case  GSS_TEMPLATE:
245                 row[0] = g_strdup (_("template"));
246                 break;
247             default:
248                 row[0] = g_strdup (_("unknown"));
249                 break;
250         }
251     }
252
253     if (data->SMSData) {
254       if (dt->Timezone)
255           row[1] = g_strdup_printf ("%s %02d/%02d/%02d %02d:%02d:%02d %c%02d00",
256                                   DayOfWeek(dt->Year, dt->Month, dt->Day),
257                                   dt->Day, dt->Month, dt->Year,
258                                   dt->Hour, dt->Minute, dt->Second,
259                                   dt->Timezone > 0 ? '+' : '-', abs (dt->Timezone));
260       else
261           row[1] = g_strdup_printf ("%s %02d/%02d/%02d %02d:%02d:%02d",
262                                   DayOfWeek(dt->Year, dt->Month, dt->Day),
263                                   dt->Day, dt->Month, dt->Year,
264                                   dt->Hour, dt->Minute, dt->Second);
265     } else {
266       row[1] = g_strdup_printf ("unknown");
267     }
268       
269     row[2] = GUI_GetName (data->Sender);
270     if (row[2] == NULL || row[2][0]==0) row[2] = data->Sender;
271
272     row[3] = data->MessageText;
273
274     msgPtrs = (MessagePointers *) g_malloc (sizeof (MessagePointers));
275     msgPtrs->validity = data->Validity;
276     msgPtrs->class = data->Class;
277     strcpy (msgPtrs->sender, data->Sender);
278
279 //    if (data->UDHType == GSM_ConcatenatedMessages)
280 //    {
281 //      msgPtrs->count = data->UDH[5];
282 //      msgPtrs->number = data->UDH[4];
283 //      msgPtrs->msgPtr = (gint *) g_malloc (msgPtrs->count * sizeof (gint));
284 //      *(msgPtrs->msgPtr + msgPtrs->number - 1) = data->MessageNumber;
285 //    } else {
286       msgPtrs->count = msgPtrs->number = 1;
287       msgPtrs->msgPtr = (gint *) g_malloc (sizeof (gint));
288       *(msgPtrs->msgPtr) = data->MessageNumber;
289
290       gtk_clist_append (GTK_CLIST (SMS.smsClist), row);
291       gtk_clist_set_row_data_full (GTK_CLIST (SMS.smsClist), SMS.row_i++,
292                                    msgPtrs, DestroyMsgPtrs);
293 //    }
294
295     g_free (row[0]);
296     g_free (row[1]);
297   }
298 }
299
300 static inline void RefreshFolder (void)
301 {
302   gtk_clist_freeze (GTK_CLIST (SMS.smsClist));
303
304   gtk_clist_clear (GTK_CLIST (SMS.smsClist));
305
306   SMS.row_i = 0;
307   g_slist_foreach (phoneMonitor.sms.messages, InsertFolderElement, (gpointer) NULL);
308
309   gtk_clist_sort (GTK_CLIST (SMS.smsClist));
310   gtk_clist_thaw (GTK_CLIST (SMS.smsClist));
311 }
312
313
314 inline void GUI_RefreshMessageWindow (void)
315 {
316   if (!GTK_WIDGET_VISIBLE (GUI_SMSWindow))
317     return;
318
319   RefreshFolder();
320 }
321
322
323 static void SelectTreeItem (GtkWidget *item, gpointer data)
324 {
325   SMS.currentBox = GPOINTER_TO_INT (data);
326   GUI_RefreshMessageWindow ();
327 }
328
329
330 static void ClickEntry (GtkWidget      *clist,
331                         gint            row,
332                         gint            column,
333                         GdkEventButton *event,
334                         gpointer        data )
335 {
336   gchar *buf;
337
338   /* FIXME - We must mark SMS as readed */
339   gtk_text_freeze (GTK_TEXT (SMS.smsText));
340
341   gtk_text_set_point (GTK_TEXT (SMS.smsText), 0);
342   gtk_text_forward_delete (GTK_TEXT (SMS.smsText), gtk_text_get_length (GTK_TEXT (SMS.smsText)));
343
344   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.colour), NULL,
345                    _("From: "), -1);
346   gtk_clist_get_text (GTK_CLIST (clist), row, 2, &buf);
347   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.smsText->style->black), NULL,
348                    buf, -1);
349   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.smsText->style->black), NULL,
350                    "\n", -1);
351
352   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.colour), NULL,
353                    _("Date: "), -1);
354   gtk_clist_get_text (GTK_CLIST (clist), row, 1, &buf);
355   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.smsText->style->black), NULL,
356                    buf, -1);
357   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.smsText->style->black), NULL,
358                    "\n\n", -1);
359
360   gtk_clist_get_text (GTK_CLIST (clist), row, 3, &buf);
361   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.smsText->style->black), NULL,
362                    buf, -1);
363
364   gtk_text_thaw (GTK_TEXT (SMS.smsText));
365 }
366
367
368 inline void GUI_ShowSMS (void)
369 {
370   int i,j;
371   
372   GUI_InitSMSFoldersInf();
373   
374   for (i=1;i<folders.number+1;i++) {
375     if (i>prev_num_of_folders) {
376       treeFolderItem[i-1] = gtk_tree_item_new_with_label (_(folders.Folder[i-1].Name));
377       gtk_tree_append (GTK_TREE (subTree), treeFolderItem[i-1]);
378       gtk_signal_connect (GTK_OBJECT (treeFolderItem[i-1]), "select",
379                           GTK_SIGNAL_FUNC (SelectTreeItem), GINT_TO_POINTER (i-1));
380       gtk_widget_show (treeFolderItem[i-1]);
381     } else {
382       gtk_widget_set_name(treeFolderItem[i-1],_(folders.Folder[i-1].Name));
383     }
384   }
385   
386   for (j=i+1;j<prev_num_of_folders;j++)
387     gtk_widget_hide (treeFolderItem[j-1]);
388       
389   prev_num_of_folders=folders.number;
390   
391   gtk_widget_show (GUI_SMSWindow);
392   GUI_RefreshMessageWindow ();
393 }
394
395
396 static void OkDeleteSMSDialog (GtkWidget *widget, gpointer data)
397 {
398   GSM_SMSMessage *message;
399   PhoneEvent *e;
400   GList *sel;
401 //  GSM_Error error;
402   gint row;
403   gint count;
404
405
406   sel = GTK_CLIST (SMS.smsClist)->selection;
407
408   gtk_clist_freeze (GTK_CLIST (SMS.smsClist));
409
410   while (sel != NULL)
411   {
412     row = GPOINTER_TO_INT (sel->data);
413     sel = sel->next;
414     for (count = 0; count < ((MessagePointers *) gtk_clist_get_row_data (GTK_CLIST (SMS.smsClist), row))->count; count++)
415     {
416       message = (GSM_SMSMessage *) g_malloc (sizeof (GSM_SMSMessage));
417       message->Location = *(((MessagePointers *) gtk_clist_get_row_data (GTK_CLIST (SMS.smsClist), row))->msgPtr + count);
418       if (message->Location == -1)
419       {
420         g_free (message);
421         continue;
422       }
423       message->MemoryType = GMT_SM;
424
425       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
426       e->event = Event_DeleteSMSMessage;
427       e->data = message;
428       GUI_InsertEvent (e);
429
430 /*      error = GSM->DeleteSMSMessage(&message);
431
432       if (error != GE_NONE)
433       {
434         if (error == GE_NOTIMPLEMENTED)
435         {
436           gtk_label_set_text(GTK_LABEL(errorDialog.text), _("Function not implemented!"));  
437           gtk_widget_show(errorDialog.dialog);
438         }
439         else
440         {
441           gtk_label_set_text(GTK_LABEL(errorDialog.text), _("Delete SMS failed!"));  
442           gtk_widget_show(errorDialog.dialog);
443         }
444       }
445 */
446     }
447   }
448
449   gtk_widget_hide (GTK_WIDGET (data));
450
451   gtk_clist_thaw (GTK_CLIST (SMS.smsClist));
452 }
453
454 static void ReadFromPhone (void)
455 {
456   GSM_SMSStatus SMSStatus;
457
458   SMSStatus.UnRead = 0;
459   SMSStatus.Number = 0;
460   
461   if (GSM->GetSMSStatus (&SMSStatus) == GE_NONE) {
462     if (phoneMonitor.sms.unRead  != SMSStatus.UnRead ||
463         phoneMonitor.sms.number2 != SMSStatus.Number)
464     {
465       phoneMonitor.working = _("Refreshing SMSes...");
466 #ifdef XDEBUG
467    printf("Refreshing %d SMSes...\n",SMSStatus.Number);
468 #endif
469       RefreshSMS (SMSStatus.Number);
470       phoneMonitor.working = NULL;
471     }
472
473     phoneMonitor.sms.unRead = SMSStatus.UnRead;
474   }
475 }
476
477 static void DeleteSMS (void)
478 {
479   static GtkWidget *dialog = NULL;
480   GtkWidget *button, *hbox, *label, *pixmap;
481
482   if (dialog == NULL)
483   {
484     dialog = gtk_dialog_new();
485     gtk_window_set_title (GTK_WINDOW (dialog), _("Delete SMS"));
486     gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
487     gtk_window_set_modal(GTK_WINDOW (dialog), TRUE);
488     gtk_container_set_border_width (GTK_CONTAINER (dialog), 10);
489     gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
490                         GTK_SIGNAL_FUNC (DeleteEvent), NULL);
491
492     button = gtk_button_new_with_label (_("Ok"));
493     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
494                         button, TRUE, TRUE, 10);
495     gtk_signal_connect (GTK_OBJECT (button), "clicked",
496                         GTK_SIGNAL_FUNC (OkDeleteSMSDialog), (gpointer) dialog);
497     GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
498     gtk_widget_grab_default (button);
499     gtk_widget_show (button);
500     button = gtk_button_new_with_label (_("Cancel"));
501     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
502                         button, TRUE, TRUE, 10);
503     gtk_signal_connect (GTK_OBJECT (button), "clicked",
504                         GTK_SIGNAL_FUNC (CancelDialog), (gpointer) dialog);
505     gtk_widget_show (button);
506
507     gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
508
509     hbox = gtk_hbox_new (FALSE, 0);
510     gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
511     gtk_widget_show (hbox);
512
513     pixmap = gtk_pixmap_new (questMark.pixmap, questMark.mask);
514     gtk_box_pack_start (GTK_BOX (hbox), pixmap, FALSE, FALSE, 10);
515     gtk_widget_show (pixmap);
516
517     label = gtk_label_new (_("Do you want to delete selected SMS?"));
518     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 10);
519     gtk_widget_show (label);
520   }
521
522   gtk_widget_show (GTK_WIDGET (dialog));
523 }
524
525
526 static void SaveToMailbox (void)
527 {
528   gchar buf[255];
529   FILE *f;
530   gint fd;
531   GList *sel;
532   struct tm t, *loctime;
533   struct flock lock;
534   time_t caltime;
535   gint row;
536   gchar *number, *text, *loc;
537
538
539   if ((f = fopen (xgnokiiConfig.mailbox, "a")) == NULL)
540   {
541     snprintf (buf, 255, _("Cannot open mailbox %s for appending!"), xgnokiiConfig.mailbox);
542     gtk_label_set_text (GTK_LABEL (errorDialog.text), buf);
543     gtk_widget_show (errorDialog.dialog);
544     return;
545   }
546
547   fd = fileno (f);
548   lock.l_type = F_WRLCK;
549   lock.l_whence = SEEK_SET;
550   lock.l_start = 0;
551   lock.l_len = 0;
552   
553   if (fcntl (fd, F_GETLK, &lock) != -1 && lock.l_type != F_UNLCK)
554   {
555     snprintf (buf, 255, _("Cannot save to mailbox %s.\n\
556 %s is locked for process %d!"), xgnokiiConfig.mailbox, xgnokiiConfig.mailbox,
557               lock.l_pid);
558     gtk_label_set_text (GTK_LABEL (errorDialog.text), buf);
559     gtk_widget_show (errorDialog.dialog);
560     fclose (f);
561     return;
562   }
563   
564   lock.l_type = F_WRLCK;
565   lock.l_whence = SEEK_SET;
566   lock.l_start = 0;
567   lock.l_len = 0;
568   if (fcntl (fd, F_SETLK, &lock) == -1)
569   {
570     snprintf (buf, 255, _("Cannot lock mailbox %s!"), xgnokiiConfig.mailbox);
571     gtk_label_set_text (GTK_LABEL (errorDialog.text), buf);
572     gtk_widget_show (errorDialog.dialog);
573     fclose (f);
574     return;
575   }
576   
577   sel = GTK_CLIST (SMS.smsClist)->selection;
578
579   while (sel != NULL)
580   {
581     row = GPOINTER_TO_INT (sel->data);
582     sel = sel->next;
583     gtk_clist_get_text (GTK_CLIST (SMS.smsClist), row, 1, &text);
584     t.tm_sec  = atoi (text + 15);
585     t.tm_min  = atoi (text + 12);
586     t.tm_hour = atoi (text + 9);
587     t.tm_mday = atoi (text);
588     t.tm_mon  = atoi (text + 3) - 1;
589     t.tm_year = atoi (text + 6);
590     if (t.tm_year < 70)
591       t.tm_year += 100;
592 #ifdef HAVE_TM_GMTON
593     if (text[17] != '\0')
594       t.tm_gmtoff = atoi (text + 18) * 3600;
595 #endif
596
597     caltime = mktime (&t);
598     loctime = localtime (&caltime);
599
600     gtk_clist_get_text (GTK_CLIST (SMS.smsClist), row, 2, &number);
601     gtk_clist_get_text (GTK_CLIST (SMS.smsClist), row, 3, &text);
602
603     fprintf (f, "From %s@xgnokii %s", number, asctime (loctime));
604     loc = setlocale (LC_ALL, "C");
605     strftime (buf, 255, "Date: %a, %d %b %Y %H:%M:%S %z (%Z)\n", loctime);
606     setlocale (LC_ALL, loc);
607     fprintf (f, "%s", buf);
608     fprintf (f, "From: %s@xgnokii\n", number);
609     strncpy (buf, text, 20);
610     buf[20] = '\0'; 
611     fprintf (f, "Subject: %s\n\n", buf);
612     fprintf (f, "%s\n\n", text);
613   }
614
615   lock.l_type = F_UNLCK;
616   lock.l_whence = SEEK_SET;
617   lock.l_start = 0;
618   lock.l_len = 0;
619   if (fcntl (fd, F_SETLK, &lock) == -1)
620   {
621     snprintf (buf, 255, _("Cannot unlock mailbox %s!"), xgnokiiConfig.mailbox);
622     gtk_label_set_text (GTK_LABEL (errorDialog.text), buf);
623     gtk_widget_show (errorDialog.dialog);
624   }
625
626   fclose (f);
627 }
628
629
630 static inline void RefreshSMSStatus (void)
631 {
632   gchar *buf;
633   guint l, m;
634
635   l = gtk_text_get_length (GTK_TEXT (sendSMS.smsSendText));
636
637   if (l <= GSM_MAX_SMS_LENGTH)
638     buf = g_strdup_printf ("%d/1", l);
639   else
640   {
641     m = l % 153;
642     buf = g_strdup_printf ("%d/%d", l > 0 && !m ? 153 : m, l == 0 ? 1 : ((l - 1) / 153) + 1);
643   }
644
645   gtk_frame_set_label (GTK_FRAME (sendSMS.status), buf);
646   g_free (buf);
647 }
648
649
650 static inline gint RefreshSMSLength (GtkWidget   *widget,
651                                      GdkEventKey *event,
652                                      gpointer     callback_data)
653 {
654   RefreshSMSStatus ();
655   if (GTK_EDITABLE (widget)->editable == FALSE)
656     return (FALSE);
657   if (event->keyval == GDK_BackSpace || event->keyval == GDK_Clear ||
658       event->keyval == GDK_Insert || event->keyval == GDK_Delete ||
659       event->keyval == GDK_Home || event->keyval == GDK_End ||
660       event->keyval == GDK_Left || event->keyval == GDK_Right ||
661       event->keyval == GDK_Up || event->keyval == GDK_Down ||
662       event->keyval == GDK_Return ||
663       (event->keyval >= 0x20 && event->keyval <= 0xFF))
664     return (TRUE);
665   
666   return (FALSE);
667 }
668
669
670 static inline void SetActiveCenter (GtkWidget *item, gpointer data)
671 {
672   sendSMS.center = GPOINTER_TO_INT (data);
673 }
674
675
676 void GUI_RefreshSMSCenterMenu (void)
677 {
678   static GtkWidget *smscMenu = NULL;
679   GtkWidget *item;
680   register gint i;
681
682   if (!sendSMS.smscOptionMenu)
683     return;
684
685   if (smscMenu)
686   {
687     gtk_option_menu_remove_menu (GTK_OPTION_MENU (sendSMS.smscOptionMenu));
688     if (GTK_IS_WIDGET (smscMenu))
689       gtk_widget_destroy (GTK_WIDGET (smscMenu));
690     smscMenu = NULL;
691   }
692
693   smscMenu = gtk_menu_new();
694
695   for (i = 0; i < xgnokiiConfig.smsSets; i++)
696   {
697     if (*(xgnokiiConfig.smsSetting[i].Name) == '\0')
698     {
699       gchar *buf = g_strdup_printf (_("Set %d"), i + 1);
700       item = gtk_menu_item_new_with_label (buf);
701       g_free (buf);
702     }
703     else
704       item = gtk_menu_item_new_with_label (xgnokiiConfig.smsSetting[i].Name);
705
706     gtk_signal_connect (GTK_OBJECT (item), "activate",
707                         GTK_SIGNAL_FUNC (SetActiveCenter),
708                         (gpointer) i);
709
710     gtk_widget_show (item);
711     gtk_menu_append (GTK_MENU (smscMenu), item);
712   }
713   gtk_option_menu_set_menu (GTK_OPTION_MENU (sendSMS.smscOptionMenu), smscMenu);
714 }
715
716
717 static inline void InitAddressLine (gpointer d, gpointer userData)
718 {
719   ((AddressPar *) d)->used = 0;
720 }
721
722
723 #ifdef XDEBUG
724 static inline void PrintAddressLine (gpointer d, gpointer userData)
725 {
726   g_print ("Name: %s\nNumber: %s\nUsed: %d\n",
727            ((AddressPar *) d)->name,
728            ((AddressPar *) d)->number,
729            ((AddressPar *) d)->used);
730 }
731 #endif
732
733
734 static inline gint CompareAddressLineName (gconstpointer a, gconstpointer b)
735 {
736   return strcmp (((AddressPar *) a)->name, ((AddressPar *) b)->name);
737 }
738
739
740 static inline gint CompareAddressLineUsed (gconstpointer a, gconstpointer b)
741 {
742   return !(((AddressPar *) a)->used == ((AddressPar *) b)->used);
743 }
744
745
746 static gint CheckAddressMain (void)
747 {
748   AddressPar aps;
749   GSList *r;
750   register gint i = 0;
751   gint ret = 0;
752   gchar *buf;
753   GString *tooltipBuf;
754   gchar **strings = g_strsplit (gtk_entry_get_text (GTK_ENTRY (sendSMS.addr)), ",", 0);
755
756   tooltipBuf = g_string_new ("");
757   gtk_entry_set_text (GTK_ENTRY (sendSMS.addr), "");
758   g_slist_foreach (sendSMS.addressLine, InitAddressLine, (gpointer) NULL);
759
760   while (strings[i])
761   {
762     g_strstrip (strings[i]);
763     if (*strings[i] == '\0')
764     { 
765       i++;
766       continue;
767     }
768     if ((buf = GUI_GetName (strings[i])) != NULL)
769     {
770       AddressPar *ap = g_malloc (sizeof (AddressPar));
771       ap->number = g_strdup (strings[i]);
772       ap->name = g_strdup (buf);
773       ap->used = 1;
774       sendSMS.addressLine = g_slist_append (sendSMS.addressLine, ap);
775       gtk_entry_append_text (GTK_ENTRY (sendSMS.addr), buf);
776       g_string_append (tooltipBuf, ap->number);
777     }
778     else 
779     if ((buf = GUI_GetNumber (strings[i])) != NULL)
780     {
781       aps.name = strings[i];
782       r = g_slist_find_custom (sendSMS.addressLine, &aps, CompareAddressLineName);
783       if (r)
784       {
785         ((AddressPar *) r->data)->used = 1;
786         g_string_append (tooltipBuf, ((AddressPar *) r->data)->number);
787       }
788       else
789         g_string_append (tooltipBuf, buf);
790       gtk_entry_append_text (GTK_ENTRY (sendSMS.addr), strings[i]);
791     }
792     else
793     {
794       gint len = strlen (strings[i]);
795       gint j;
796
797       for (j = 0; j < len; j++)
798         if (strings[i][j] != '*' && strings[i][j] != '#' && strings[i][j] != '+'
799             && (strings[i][j] < '0' || strings[i][j] > '9'))
800           ret = 1;
801       gtk_entry_append_text (GTK_ENTRY (sendSMS.addr), strings[i]);
802       g_string_append (tooltipBuf, strings[i]);
803     }
804     if (strings[i + 1] != NULL)
805     {
806       gtk_entry_append_text (GTK_ENTRY (sendSMS.addr), ", ");
807       g_string_append (tooltipBuf, ", ");
808     }
809     i++;
810   }
811
812   aps.used = 0;
813   while ((r = g_slist_find_custom (sendSMS.addressLine, &aps, CompareAddressLineUsed)))
814     sendSMS.addressLine = g_slist_remove (sendSMS.addressLine, r->data);
815   
816   if (tooltipBuf->len > 0)
817   {
818     gtk_tooltips_set_tip (sendSMS.addrTip, sendSMS.addr, tooltipBuf->str, NULL);
819     gtk_tooltips_enable (sendSMS.addrTip);
820   }
821   else
822     gtk_tooltips_disable (sendSMS.addrTip);
823
824 #ifdef XDEBUG  
825   g_slist_foreach (sendSMS.addressLine, PrintAddressLine, (gpointer) NULL);
826 #endif
827
828   g_strfreev (strings);
829   g_string_free (tooltipBuf, TRUE);
830
831   return ret;
832 }
833
834
835 static inline void CheckAddress (void)
836 {
837   if (CheckAddressMain ())
838   {
839     gtk_label_set_text(GTK_LABEL(errorDialog.text), _("Address line contains illegal address!"));
840     gtk_widget_show(errorDialog.dialog);
841   }
842 }
843
844
845 static void DeleteSelectContactDialog (GtkWidget *widget, GdkEvent *event,
846                                        SelectContactData *data)
847 {
848   gtk_widget_destroy (GTK_WIDGET (data->clist));
849   gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
850   gtk_widget_destroy (GTK_WIDGET (widget));
851 }
852
853
854 static void CancelSelectContactDialog (GtkWidget *widget,
855                                        SelectContactData *data)
856 {
857   gtk_widget_destroy (GTK_WIDGET (data->clist));
858   gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
859   gtk_widget_destroy (GTK_WIDGET (data->dialog));
860 }
861
862
863 static void OkSelectContactDialog (GtkWidget *widget,
864                                    SelectContactData *data)
865 {
866   GList *sel;
867   PhonebookEntry *pbEntry;
868
869   if ((sel = GTK_CLIST (data->clist)->selection) != NULL)
870     while (sel != NULL)
871     {
872       AddressPar *ap = g_malloc (sizeof (AddressPar));
873       
874       pbEntry = gtk_clist_get_row_data (GTK_CLIST (data->clist),
875                                         GPOINTER_TO_INT (sel->data));
876       ap->number = g_strdup (pbEntry->entry.Number);
877       ap->name = g_strdup (pbEntry->entry.Name);
878       ap->used = 1;
879       sendSMS.addressLine = g_slist_append (sendSMS.addressLine, ap);
880       if (strlen (gtk_entry_get_text (GTK_ENTRY (sendSMS.addr))) > 0)
881         gtk_entry_append_text (GTK_ENTRY (sendSMS.addr), ", ");
882       gtk_entry_append_text (GTK_ENTRY (sendSMS.addr), ap->name);
883
884       sel = sel->next;
885     }
886
887   gtk_widget_destroy (GTK_WIDGET (data->clist));
888   gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
889   gtk_widget_destroy (GTK_WIDGET (data->dialog));
890
891   CheckAddressMain ();
892 }
893
894
895 static void ShowSelectContactsDialog (void)
896 {
897   SelectContactData *r;
898
899   if (!GUI_ContactsIsIntialized ())
900     GUI_ReadContacts ();
901
902   if ((r = GUI_SelectContactDialog ()) == NULL)
903     return;
904
905   gtk_signal_connect (GTK_OBJECT (r->dialog), "delete_event",
906                       GTK_SIGNAL_FUNC (DeleteSelectContactDialog), (gpointer) r);
907
908   gtk_signal_connect (GTK_OBJECT (r->okButton), "clicked",
909                       GTK_SIGNAL_FUNC (OkSelectContactDialog), (gpointer) r);
910   gtk_signal_connect (GTK_OBJECT (r->cancelButton), "clicked",
911                       GTK_SIGNAL_FUNC (CancelSelectContactDialog), (gpointer) r);
912 }
913
914
915 static gint SendSMSCore (GSM_SMSMessage *sms)
916 {
917   GSM_Error error;
918   PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
919   D_SMSMessage *m = (D_SMSMessage *) g_malloc (sizeof (D_SMSMessage));
920   
921   m->sms = sms;
922   e->event = Event_SendSMSMessage;
923   e->data = m;
924   GUI_InsertEvent (e);
925   pthread_mutex_lock (&sendSMSMutex);
926   pthread_cond_wait (&sendSMSCond, &sendSMSMutex);
927   pthread_mutex_unlock (&sendSMSMutex);
928
929 #ifdef XDEBUG
930   g_print ("Address: %s\nText: %s\nDelivery report: %d\nSMS Center: %d\n",
931            sms->Destination,
932            sms->MessageText,
933            GTK_TOGGLE_BUTTON (sendSMS.report)->active,
934            sendSMS.center);
935 #endif
936
937   error = m->status;
938   g_free (m);
939
940   if (error != GE_SMSSENDOK)
941   {
942     gchar *buf = g_strdup_printf (_("SMS send to %s failed\n(error=%d)"),
943                                   sms->Destination, error);
944     gtk_label_set_text (GTK_LABEL(errorDialog.text), buf);
945     gtk_widget_show (errorDialog.dialog);
946     g_free (buf);
947   }
948   else
949     g_print ("Message sent to: %s\n", sms->Destination);
950
951   return (error);
952 }
953
954
955 static void SendSMS (void)
956 {
957   GSM_UDH UDHType;
958   GSM_MultiSMSMessage Multisms;
959   int chars_read;
960   AddressPar aps;
961   GSList *r;
962   gchar *text, *number;
963   gchar **addresses;
964   gchar *buf;
965   gint l;
966   gint longSMS;
967   register gint i = 0, j;
968
969   if (CheckAddressMain ())
970   {
971     gtk_label_set_text(GTK_LABEL(errorDialog.text), _("Address line contains illegal address!"));
972     gtk_widget_show(errorDialog.dialog);
973     return;
974   }
975
976   text = gtk_editable_get_chars (GTK_EDITABLE (sendSMS.smsSendText), 0, -1);
977   l = strlen (text);
978
979   addresses = g_strsplit (gtk_entry_get_text (GTK_ENTRY (sendSMS.addr)), ",", 0);
980
981   longSMS = GTK_TOGGLE_BUTTON (sendSMS.longSMS)->active;
982
983   while (addresses[i])
984   {
985     g_strstrip (addresses[i]);
986     if ((number = GUI_GetNumber (addresses[i])))
987     {
988       aps.name = addresses[i];
989       if ((r = g_slist_find_custom (sendSMS.addressLine, &aps, CompareAddressLineName)))
990         number = ((AddressPar *) r->data)->number;
991     }
992     else
993       number = addresses[i];
994
995     chars_read=strlen(text);
996     UDHType = GSM_NoUDH;
997     if (l > GSM_MAX_SMS_LENGTH && longSMS) UDHType = GSM_ConcatenatedMessages;
998     if (UDHType == GSM_NoUDH && chars_read>160) chars_read=160;
999
1000     GSM_MakeMultiPartSMS2(&Multisms,text,chars_read,UDHType,GSM_Coding_Default);
1001     
1002     for (j=0;j<Multisms.number;j++) {
1003       Multisms.SMS[j].MessageCenter = xgnokiiConfig.smsSetting[sendSMS.center];
1004       Multisms.SMS[j].MessageCenter.No = 0;
1005
1006       if (GTK_TOGGLE_BUTTON (sendSMS.report)->active) Multisms.SMS[j].Type = GST_DR;
1007
1008       if (GTK_TOGGLE_BUTTON (sendSMS.class)->active) Multisms.SMS[j].Class = 0;
1009
1010       Multisms.SMS[j].Validity = Multisms.SMS[j].MessageCenter.Validity;
1011
1012       strncpy (Multisms.SMS[j].Destination, number, GSM_MAX_DESTINATION_LENGTH + 1);
1013       Multisms.SMS[j].Destination[GSM_MAX_DESTINATION_LENGTH] = '\0';      
1014
1015       buf = g_strdup_printf (_("Sending SMS to %s (%d/%d) ...\n"),
1016                                  Multisms.SMS[j].Destination, j + 1, Multisms.number);
1017       gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
1018       gtk_widget_show_now (infoDialog.dialog);
1019       g_free (buf);
1020       GUI_Refresh ();
1021
1022       if (SendSMSCore (&Multisms.SMS[j]) != GE_SMSSENDOK)
1023       {
1024         gtk_widget_hide (infoDialog.dialog);
1025         GUI_Refresh ();
1026         break;
1027       }
1028
1029       gtk_widget_hide (infoDialog.dialog);
1030       GUI_Refresh ();
1031
1032       sleep (1);
1033     }
1034     
1035     i++;
1036   }
1037
1038   g_strfreev (addresses);
1039
1040   g_free (text);
1041 }
1042
1043
1044 static GtkItemFactoryEntry send_menu_items[] = {
1045   { NULL,               NULL,           NULL,           0, "<Branch>"},
1046   { NULL,               "<control>X",   SendSMS,        0, NULL},
1047   { NULL,               "<control>S",   NULL,           0, NULL},
1048   { NULL,               NULL,           NULL,           0, "<Separator>"},
1049   { NULL,               "<control>N",   CheckAddress,   0, NULL},
1050   { NULL,               "<control>C",   ShowSelectContactsDialog, 0, NULL},
1051   { NULL,               NULL,           NULL,           0, "<Separator>"},
1052   { NULL,               "<control>W",   CloseSMSSend,   0, NULL},
1053   { NULL,               NULL,           NULL,           0, "<LastBranch>"},
1054   { NULL,               NULL,           Help2,          0, NULL},
1055   { NULL,               NULL,           GUI_ShowAbout,  0, NULL},
1056 };
1057
1058
1059 static void InitSendMenu (void)
1060 {
1061   send_menu_items[0].path = g_strdup (_("/_File"));
1062   send_menu_items[1].path = g_strdup (_("/File/Sen_d"));
1063   send_menu_items[2].path = g_strdup (_("/File/_Save"));
1064   send_menu_items[3].path = g_strdup (_("/File/Sep1"));
1065   send_menu_items[4].path = g_strdup (_("/File/Check _Names"));
1066   send_menu_items[5].path = g_strdup (_("/File/C_ontacts"));
1067   send_menu_items[6].path = g_strdup (_("/File/Sep2"));
1068   send_menu_items[7].path = g_strdup (_("/File/_Close"));
1069   send_menu_items[8].path = g_strdup (_("/_Help"));
1070   send_menu_items[9].path = g_strdup (_("/Help/_Help"));
1071   send_menu_items[10].path = g_strdup (_("/Help/_About"));
1072 }
1073
1074
1075 static void CreateSMSSendWindow (void)
1076 {
1077   int nmenu_items = sizeof (send_menu_items) / sizeof (send_menu_items[0]);
1078   GtkItemFactory *item_factory;
1079   GtkAccelGroup *accel_group;
1080   GtkWidget *menubar;
1081   GtkWidget *main_vbox;
1082   GtkWidget *hbox, *vbox;
1083   GtkWidget *button;
1084   GtkWidget *pixmap;
1085   GtkWidget *label;
1086   GtkWidget *toolbar;
1087   GtkWidget *scrolledWindow;
1088   GtkTooltips *tooltips;
1089
1090   if (sendSMS.SMSSendWindow)
1091     return;
1092
1093   InitSendMenu ();
1094   sendSMS.SMSSendWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1095
1096   //gtk_widget_set_usize (GTK_WIDGET (sendSMS.SMSSendWindow), 436, 220);
1097   gtk_signal_connect (GTK_OBJECT (sendSMS.SMSSendWindow), "delete_event",
1098                       GTK_SIGNAL_FUNC (DeleteEvent), NULL);
1099   gtk_widget_realize (sendSMS.SMSSendWindow);
1100
1101   accel_group = gtk_accel_group_new ();
1102   item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", 
1103                                        accel_group);
1104
1105   gtk_item_factory_create_items (item_factory, nmenu_items, send_menu_items, NULL);
1106
1107   gtk_accel_group_attach (accel_group, GTK_OBJECT (sendSMS.SMSSendWindow));
1108
1109   /* Finally, return the actual menu bar created by the item factory. */ 
1110   menubar = gtk_item_factory_get_widget (item_factory, "<main>");
1111
1112   main_vbox = gtk_vbox_new (FALSE, 1);
1113   gtk_container_border_width (GTK_CONTAINER (main_vbox), 1);
1114   gtk_container_add (GTK_CONTAINER (sendSMS.SMSSendWindow), main_vbox);
1115   gtk_widget_show (main_vbox);
1116
1117   gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0);
1118   gtk_widget_show (menubar);
1119
1120   /* Create the toolbar */
1121
1122   toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
1123   gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NORMAL);
1124
1125   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Send message"), NULL,
1126                            NewPixmap(SendSMS_xpm, GUI_SMSWindow->window,
1127                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1128                            (GtkSignalFunc) SendSMS, NULL);
1129   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Save message to outbox"), NULL,
1130                            NewPixmap(Send_xpm, GUI_SMSWindow->window,
1131                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1132                            (GtkSignalFunc) NULL, NULL);
1133
1134   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1135
1136   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Check names"), NULL,
1137                            NewPixmap(Check_xpm, GUI_SMSWindow->window,
1138                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1139                            (GtkSignalFunc) CheckAddress, NULL);
1140
1141   gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0);
1142   gtk_widget_show (toolbar);
1143
1144   /* Address line */
1145   hbox = gtk_hbox_new (FALSE, 3);
1146   gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 3);
1147   gtk_widget_show (hbox);
1148
1149   label = gtk_label_new (_("To:"));
1150   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 3);
1151   gtk_widget_show (label);
1152
1153   sendSMS.addr = gtk_entry_new ();
1154   gtk_box_pack_start (GTK_BOX (hbox), sendSMS.addr, TRUE, TRUE, 1);
1155
1156   sendSMS.addrTip = gtk_tooltips_new ();
1157   gtk_tooltips_set_tip (sendSMS.addrTip, sendSMS.addr, "", NULL);
1158   gtk_tooltips_disable (sendSMS.addrTip);
1159
1160   gtk_widget_show (sendSMS.addr);
1161
1162   button = gtk_button_new ();
1163   gtk_signal_connect (GTK_OBJECT (button), "clicked",
1164                       GTK_SIGNAL_FUNC (ShowSelectContactsDialog), (gpointer) NULL);
1165
1166   pixmap = NewPixmap(Names_xpm, sendSMS.SMSSendWindow->window,
1167                      &sendSMS.SMSSendWindow->style->bg[GTK_STATE_NORMAL]);
1168   gtk_container_add (GTK_CONTAINER (button), pixmap);
1169   gtk_widget_show (pixmap);
1170   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 5);
1171
1172   tooltips = gtk_tooltips_new ();
1173   gtk_tooltips_set_tip (tooltips, button, _("Select contacts"), NULL);
1174
1175   gtk_widget_show (button);
1176
1177   hbox = gtk_hbox_new (FALSE, 3);
1178   gtk_box_pack_end (GTK_BOX (main_vbox), hbox, TRUE, TRUE, 3);
1179   gtk_widget_show (hbox);
1180
1181   /* Edit SMS widget */
1182   vbox = gtk_vbox_new (FALSE, 3);
1183   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 3);
1184   gtk_widget_show (vbox);
1185
1186   sendSMS.status = gtk_frame_new ("0/1");
1187   gtk_frame_set_label_align (GTK_FRAME (sendSMS.status), 1.0, 0.0);
1188   gtk_frame_set_shadow_type (GTK_FRAME (sendSMS.status), GTK_SHADOW_OUT);
1189
1190   gtk_box_pack_end (GTK_BOX (vbox), sendSMS.status, TRUE, TRUE, 5);
1191   gtk_widget_show (sendSMS.status);
1192
1193   sendSMS.smsSendText = gtk_text_new (NULL, NULL);
1194   gtk_widget_set_usize (GTK_WIDGET (sendSMS.smsSendText), 0, 120);
1195   gtk_text_set_editable (GTK_TEXT (sendSMS.smsSendText), TRUE);
1196   gtk_text_set_word_wrap (GTK_TEXT (sendSMS.smsSendText), TRUE);
1197   gtk_signal_connect_after (GTK_OBJECT (sendSMS.smsSendText),
1198                       "key_press_event",
1199                       GTK_SIGNAL_FUNC(RefreshSMSLength), (gpointer) NULL);
1200   gtk_signal_connect_after (GTK_OBJECT (sendSMS.smsSendText),
1201                       "button_press_event",
1202                       GTK_SIGNAL_FUNC(RefreshSMSLength), (gpointer) NULL);
1203
1204   scrolledWindow = gtk_scrolled_window_new (NULL, NULL);
1205   gtk_container_set_border_width (GTK_CONTAINER (scrolledWindow), 5);
1206   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
1207                                   GTK_POLICY_NEVER,
1208                                   GTK_POLICY_AUTOMATIC);
1209
1210   gtk_container_add (GTK_CONTAINER (scrolledWindow), sendSMS.smsSendText);
1211   gtk_container_add (GTK_CONTAINER (sendSMS.status), scrolledWindow);
1212
1213   gtk_widget_show (sendSMS.smsSendText);
1214   gtk_widget_show (scrolledWindow);
1215
1216   /* Options widget */
1217   vbox = gtk_vbox_new (FALSE, 3);
1218   gtk_box_pack_end (GTK_BOX (hbox), vbox, FALSE, FALSE, 5);
1219   gtk_widget_show (vbox);
1220
1221   sendSMS.report = gtk_check_button_new_with_label (_("Delivery report"));
1222   gtk_box_pack_start (GTK_BOX (vbox), sendSMS.report, FALSE, FALSE, 3);
1223   gtk_widget_show (sendSMS.report);
1224
1225   sendSMS.longSMS = gtk_check_button_new_with_label (_("Send as Long SMS"));
1226   gtk_box_pack_start (GTK_BOX (vbox), sendSMS.longSMS, FALSE, FALSE, 3);
1227   gtk_widget_show (sendSMS.longSMS);
1228
1229   sendSMS.class = gtk_check_button_new_with_label (_("Send as Flash SMS (Class 0)"));
1230   gtk_box_pack_start (GTK_BOX (vbox), sendSMS.class, FALSE, FALSE, 3);
1231   gtk_widget_show (sendSMS.class);
1232
1233   label = gtk_label_new (_("SMS Center:"));
1234   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 1);
1235   gtk_widget_show (label);
1236
1237   GUI_InitSMSSettings ();
1238   sendSMS.smscOptionMenu = gtk_option_menu_new();
1239
1240   GUIEventSend (GUI_EVENT_SMS_CENTERS_CHANGED);
1241
1242   gtk_box_pack_start (GTK_BOX (vbox), sendSMS.smscOptionMenu, FALSE, FALSE, 1);
1243   gtk_widget_show (sendSMS.smscOptionMenu);
1244 }
1245
1246
1247 static void NewSMS (void)
1248 {
1249   if (!sendSMS.SMSSendWindow)
1250     CreateSMSSendWindow ();
1251
1252   gtk_window_set_title (GTK_WINDOW (sendSMS.SMSSendWindow), _("New Message"));
1253
1254   gtk_tooltips_disable (sendSMS.addrTip);
1255
1256   gtk_text_freeze (GTK_TEXT (sendSMS.smsSendText));
1257   gtk_text_set_point (GTK_TEXT (sendSMS.smsSendText), 0);
1258   gtk_text_forward_delete (GTK_TEXT (sendSMS.smsSendText), gtk_text_get_length (GTK_TEXT (sendSMS.smsSendText)));
1259   gtk_text_thaw (GTK_TEXT (sendSMS.smsSendText));
1260
1261   gtk_entry_set_text (GTK_ENTRY (sendSMS.addr), "");
1262
1263   RefreshSMSStatus ();
1264
1265   gtk_widget_show (sendSMS.SMSSendWindow);
1266 }
1267
1268
1269 static void ForwardSMS (void)
1270 {
1271   gchar *buf;
1272
1273   if (GTK_CLIST (SMS.smsClist)->selection == NULL)
1274     return;
1275
1276   if (!sendSMS.SMSSendWindow)
1277     CreateSMSSendWindow ();
1278
1279   gtk_window_set_title (GTK_WINDOW (sendSMS.SMSSendWindow), _("Forward Message"));
1280
1281   gtk_tooltips_disable (sendSMS.addrTip);
1282
1283   gtk_text_freeze (GTK_TEXT (sendSMS.smsSendText));
1284   gtk_text_set_point (GTK_TEXT (sendSMS.smsSendText), 0);
1285   gtk_text_forward_delete (GTK_TEXT (sendSMS.smsSendText), gtk_text_get_length (GTK_TEXT (sendSMS.smsSendText)));
1286   gtk_clist_get_text (GTK_CLIST (SMS.smsClist),
1287                       GPOINTER_TO_INT(GTK_CLIST (SMS.smsClist)->selection->data),
1288                       3, &buf);
1289
1290   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1291                    buf, -1);
1292
1293   gtk_text_thaw (GTK_TEXT (sendSMS.smsSendText));
1294
1295   gtk_entry_set_text (GTK_ENTRY (sendSMS.addr), "");
1296
1297   RefreshSMSStatus ();
1298
1299   gtk_widget_show (sendSMS.SMSSendWindow);
1300 }
1301
1302
1303 /*
1304 static inline gint CompareSMSMessageLocation (gconstpointer a, gconstpointer b)
1305 {
1306   return !(((GSM_SMSMessage *) a)->Location == ((GSM_SMSMessage *) b)->Location);
1307 }
1308 */
1309
1310
1311 static void ReplySMS (void)
1312 {
1313   gchar *buf;
1314 //  GSList *r;
1315 //  GSM_SMSMessage msg;
1316
1317   if (GTK_CLIST (SMS.smsClist)->selection == NULL)
1318     return;
1319
1320   if (!sendSMS.SMSSendWindow)
1321     CreateSMSSendWindow ();
1322
1323   gtk_window_set_title (GTK_WINDOW (sendSMS.SMSSendWindow), _("Reply Message"));
1324
1325   gtk_text_freeze (GTK_TEXT (sendSMS.smsSendText));
1326   gtk_text_set_point (GTK_TEXT (sendSMS.smsSendText), 0);
1327   gtk_text_forward_delete (GTK_TEXT (sendSMS.smsSendText),
1328                            gtk_text_get_length (GTK_TEXT (sendSMS.smsSendText)));
1329   gtk_clist_get_text (GTK_CLIST (SMS.smsClist),
1330                       GPOINTER_TO_INT(GTK_CLIST (SMS.smsClist)->selection->data),
1331                       3, &buf);
1332
1333   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL,
1334                    &(sendSMS.smsSendText->style->black), NULL, buf, -1);
1335
1336   gtk_text_thaw (GTK_TEXT (sendSMS.smsSendText));
1337
1338   //msg.Location = *(((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
1339   //               GPOINTER_TO_INT (GTK_CLIST (SMS.smsClist)->selection->data)))->msgPtr);
1340
1341   //r = g_slist_find_custom (SMS.messages, &msg, CompareSMSMessageLocation);
1342   //if (r)
1343   gtk_entry_set_text (GTK_ENTRY (sendSMS.addr),
1344                       ((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
1345                       GPOINTER_TO_INT (GTK_CLIST (SMS.smsClist)->selection->data)))->sender);
1346
1347   CheckAddressMain ();
1348   RefreshSMSStatus ();
1349
1350   gtk_widget_show (sendSMS.SMSSendWindow);
1351 }
1352
1353
1354 static void NewBC (void)
1355 {
1356   if (!sendSMS.SMSSendWindow)
1357     CreateSMSSendWindow ();
1358
1359   gtk_window_set_title (GTK_WINDOW (sendSMS.SMSSendWindow), _("Bussiness Card"));
1360
1361   gtk_tooltips_disable (sendSMS.addrTip);
1362
1363   gtk_text_freeze (GTK_TEXT (sendSMS.smsSendText));
1364   gtk_text_set_point (GTK_TEXT (sendSMS.smsSendText), 0);
1365   gtk_text_forward_delete (GTK_TEXT (sendSMS.smsSendText), gtk_text_get_length (GTK_TEXT (sendSMS.smsSendText)));
1366
1367   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(SMS.colour), NULL,
1368                    "Business Card\n", -1);
1369
1370   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1371                    xgnokiiConfig.user.name, -1);
1372
1373   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1374                    ", ", -1);
1375
1376   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1377                    xgnokiiConfig.user.title, -1);
1378
1379   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1380                    "\n", -1);
1381
1382   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1383                    xgnokiiConfig.user.company, -1);
1384
1385   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1386                    "\n\n", -1);
1387
1388   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(SMS.colour), NULL,
1389                    "tel ", -1);
1390
1391   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1392                    xgnokiiConfig.user.telephone, -1);
1393
1394   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1395                    "\n", -1);
1396
1397   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(SMS.colour), NULL,
1398                    "fax ", -1);
1399
1400   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1401                    xgnokiiConfig.user.fax, -1);
1402
1403   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1404                    "\n", -1);
1405
1406   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1407                    xgnokiiConfig.user.email, -1);
1408
1409   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1410                    "\n", -1);
1411
1412   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1413                    xgnokiiConfig.user.address, -1);
1414
1415   gtk_text_insert (GTK_TEXT (sendSMS.smsSendText), NULL, &(sendSMS.smsSendText->style->black), NULL,
1416                    "\n", -1);
1417
1418   gtk_text_thaw (GTK_TEXT (sendSMS.smsSendText));
1419
1420   gtk_entry_set_text (GTK_ENTRY (sendSMS.addr), "");
1421
1422   RefreshSMSStatus ();
1423
1424   gtk_widget_show (sendSMS.SMSSendWindow);
1425 }
1426
1427
1428 static GtkItemFactoryEntry menu_items[] = {
1429   { NULL,               NULL,           NULL,           0, "<Branch>"},
1430   { NULL,               NULL,           ReadFromPhone,  0, NULL},
1431   { NULL,               NULL,           NULL,           0, "<Separator>"},
1432   { NULL,               "<control>S",   NULL,           0, NULL},
1433   { NULL,               "<control>M",   SaveToMailbox,  0, NULL},
1434   { NULL,               NULL,           NULL,           0, "<Separator>"},
1435   { NULL,               "<control>W",   CloseSMS,       0, NULL},
1436   { NULL,               NULL,           NULL,           0, "<Branch>"},
1437   { NULL,               "<control>N",   NewSMS,         0, NULL},
1438   { NULL,               "<control>F",   ForwardSMS,     0, NULL},
1439   { NULL,               "<control>R",   ReplySMS,       0, NULL},
1440   { NULL,               "<control>D",   DeleteSMS,      0, NULL},
1441   { NULL,               NULL,           NULL,           0, "<Separator>"},
1442   { NULL,               "<control>B",   NewBC,          0, NULL},
1443   { NULL,               NULL,           NULL,           0, "<LastBranch>"},
1444   { NULL,               NULL,           Help1,          0, NULL},
1445   { NULL,               NULL,           GUI_ShowAbout,  0, NULL},
1446 };
1447
1448
1449 static void InitMainMenu (void)
1450 {
1451   register gint i = 0;
1452   
1453   menu_items[i++].path = g_strdup (_("/_File"));
1454   menu_items[i++].path = g_strdup (_("/File/Read from phone"));
1455   menu_items[i++].path = g_strdup (_("/File/Sep0"));
1456   menu_items[i++].path = g_strdup (_("/File/_Save"));
1457   menu_items[i++].path = g_strdup (_("/File/Save to mailbo_x"));
1458   menu_items[i++].path = g_strdup (_("/File/Sep1"));
1459   menu_items[i++].path = g_strdup (_("/File/_Close"));
1460   menu_items[i++].path = g_strdup (_("/_Messages"));
1461   menu_items[i++].path = g_strdup (_("/_Messages/_New"));
1462   menu_items[i++].path = g_strdup (_("/_Messages/_Forward"));
1463   menu_items[i++].path = g_strdup (_("/_Messages/_Reply"));
1464   menu_items[i++].path = g_strdup (_("/_Messages/_Delete"));
1465   menu_items[i++].path = g_strdup (_("/Messages/Sep3"));
1466   menu_items[i++].path = g_strdup (_("/_Messages/_Bussiness card"));
1467   menu_items[i++].path = g_strdup (_("/_Help"));
1468   menu_items[i++].path = g_strdup (_("/Help/_Help"));
1469   menu_items[i++].path = g_strdup (_("/Help/_About"));
1470 }
1471
1472
1473 void GUI_CreateSMSWindow (void)
1474 {
1475   int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
1476   GtkItemFactory *item_factory;
1477   GtkAccelGroup *accel_group;
1478   GtkWidget *menubar;
1479   GtkWidget *main_vbox;
1480   GtkWidget *toolbar;
1481   GtkWidget *scrolledWindow;
1482   GtkWidget *vpaned, *hpaned;
1483   GtkWidget *tree, *treeSMSItem;
1484   SortColumn *sColumn;
1485   GdkColormap *cmap;
1486   register gint i;
1487   gchar *titles[4] = { _("Status"), _("Date / Time"), _("Sender"), _("Message")};
1488
1489   InitMainMenu ();
1490   GUI_SMSWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1491   gtk_window_set_title (GTK_WINDOW (GUI_SMSWindow), _("Short Message Service"));
1492   //gtk_widget_set_usize (GTK_WIDGET (GUI_SMSWindow), 436, 220);
1493   gtk_signal_connect (GTK_OBJECT (GUI_SMSWindow), "delete_event",
1494                       GTK_SIGNAL_FUNC (DeleteEvent), NULL);
1495   gtk_widget_realize (GUI_SMSWindow);
1496
1497   accel_group = gtk_accel_group_new ();
1498   item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", 
1499                                        accel_group);
1500
1501   gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
1502
1503   gtk_accel_group_attach (accel_group, GTK_OBJECT (GUI_SMSWindow));
1504
1505   /* Finally, return the actual menu bar created by the item factory. */ 
1506   menubar = gtk_item_factory_get_widget (item_factory, "<main>");
1507
1508   main_vbox = gtk_vbox_new (FALSE, 1);
1509   gtk_container_border_width (GTK_CONTAINER (main_vbox), 1);
1510   gtk_container_add (GTK_CONTAINER (GUI_SMSWindow), main_vbox);
1511   gtk_widget_show (main_vbox);
1512
1513   gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0);
1514   gtk_widget_show (menubar);
1515
1516   /* Create the toolbar */
1517   toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
1518   gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NORMAL);
1519
1520   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("New message"), NULL,
1521                            NewPixmap(Edit_xpm, GUI_SMSWindow->window,
1522                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1523                            (GtkSignalFunc) NewSMS, NULL);
1524   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Forward message"), NULL,
1525                            NewPixmap(Forward_xpm, GUI_SMSWindow->window,
1526                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1527                            (GtkSignalFunc) ForwardSMS, NULL);
1528   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Reply message"), NULL,
1529                            NewPixmap(Reply_xpm, GUI_SMSWindow->window,
1530                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1531                            (GtkSignalFunc) ReplySMS, NULL);
1532
1533   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Bussiness Card"), NULL,
1534                            NewPixmap(BCard_xpm, GUI_SMSWindow->window,
1535                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1536                            (GtkSignalFunc) NewBC, NULL);
1537
1538   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
1539
1540   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Delete message"), NULL,
1541                            NewPixmap(Delete_xpm, GUI_SMSWindow->window,
1542                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
1543                            (GtkSignalFunc) DeleteSMS, NULL);
1544
1545   gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0);
1546   gtk_widget_show (toolbar);
1547
1548   vpaned = gtk_vpaned_new ();
1549   gtk_paned_set_handle_size (GTK_PANED (vpaned), 10);
1550   gtk_paned_set_gutter_size (GTK_PANED (vpaned), 15);
1551   gtk_box_pack_end (GTK_BOX (main_vbox), vpaned, TRUE, TRUE, 0);
1552   gtk_widget_show (vpaned);
1553
1554   hpaned = gtk_hpaned_new ();
1555   gtk_paned_set_handle_size (GTK_PANED (hpaned), 8);
1556   gtk_paned_set_gutter_size (GTK_PANED (hpaned), 10);                       
1557   gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
1558   gtk_widget_show (hpaned);
1559
1560   /* Navigation tree */
1561   tree = gtk_tree_new ();
1562   gtk_tree_set_selection_mode (GTK_TREE (tree), GTK_SELECTION_SINGLE);
1563   gtk_widget_show (tree);
1564
1565   treeSMSItem = gtk_tree_item_new_with_label (_("SMS's"));
1566   gtk_tree_append (GTK_TREE (tree), treeSMSItem);
1567   gtk_widget_show (treeSMSItem);
1568
1569   subTree = gtk_tree_new ();
1570   gtk_tree_set_selection_mode (GTK_TREE (subTree), GTK_SELECTION_SINGLE);
1571   gtk_tree_set_view_mode (GTK_TREE (subTree), GTK_TREE_VIEW_ITEM);
1572   gtk_tree_item_set_subtree (GTK_TREE_ITEM (treeSMSItem), subTree);
1573
1574   scrolledWindow = gtk_scrolled_window_new (NULL, NULL);
1575   gtk_widget_set_usize (scrolledWindow, 75, 80);
1576   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
1577                                   GTK_POLICY_AUTOMATIC,
1578                                   GTK_POLICY_AUTOMATIC);
1579
1580   gtk_paned_add1 (GTK_PANED (hpaned), scrolledWindow);
1581
1582   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledWindow),
1583                                          tree);
1584   gtk_widget_show (scrolledWindow);
1585
1586   /* Message viewer */
1587   SMS.smsText = gtk_text_new (NULL, NULL);
1588   gtk_text_set_editable (GTK_TEXT (SMS.smsText), FALSE);
1589   gtk_text_set_word_wrap (GTK_TEXT (SMS.smsText), TRUE);
1590   //gtk_text_set_line_wrap (GTK_TEXT (SMS.smsText), TRUE);
1591
1592   scrolledWindow = gtk_scrolled_window_new (NULL, NULL);
1593   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
1594                                   GTK_POLICY_NEVER,
1595                                   GTK_POLICY_AUTOMATIC);
1596
1597   gtk_paned_add2 (GTK_PANED (hpaned), scrolledWindow);
1598
1599   gtk_container_add (GTK_CONTAINER (scrolledWindow), SMS.smsText);
1600   gtk_widget_show_all (scrolledWindow);
1601
1602   /* Messages list */
1603   SMS.smsClist = gtk_clist_new_with_titles (4, titles);
1604   gtk_clist_set_shadow_type (GTK_CLIST (SMS.smsClist), GTK_SHADOW_OUT);
1605   gtk_clist_set_compare_func (GTK_CLIST (SMS.smsClist), CListCompareFunc);
1606   gtk_clist_set_sort_column (GTK_CLIST (SMS.smsClist), 1);
1607   gtk_clist_set_sort_type (GTK_CLIST (SMS.smsClist), GTK_SORT_ASCENDING);
1608   gtk_clist_set_auto_sort (GTK_CLIST (SMS.smsClist), FALSE);
1609   gtk_clist_set_selection_mode (GTK_CLIST (SMS.smsClist), GTK_SELECTION_EXTENDED);
1610
1611   gtk_clist_set_column_width (GTK_CLIST (SMS.smsClist), 0, 40);
1612   gtk_clist_set_column_width (GTK_CLIST (SMS.smsClist), 1, 142);
1613   gtk_clist_set_column_width (GTK_CLIST (SMS.smsClist), 2, 135);
1614   //gtk_clist_set_column_justification (GTK_CLIST (SMS.smsClist), 2, GTK_JUSTIFY_CENTER);
1615
1616   for (i = 0; i < 4; i++)
1617   {
1618     if ((sColumn = g_malloc (sizeof (SortColumn))) == NULL)
1619     {
1620       g_print (_("Error: %s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__);
1621       gtk_main_quit ();
1622     }
1623     sColumn->clist = SMS.smsClist;
1624     sColumn->column = i;
1625     gtk_signal_connect (GTK_OBJECT (GTK_CLIST (SMS.smsClist)->column[i].button), "clicked",
1626                         GTK_SIGNAL_FUNC (SetSortColumn), (gpointer) sColumn);
1627   }
1628
1629   gtk_signal_connect (GTK_OBJECT (SMS.smsClist), "select_row",
1630                       GTK_SIGNAL_FUNC (ClickEntry), NULL);
1631
1632   scrolledWindow = gtk_scrolled_window_new (NULL, NULL);
1633   gtk_widget_set_usize (scrolledWindow, 550, 100);
1634   gtk_container_add (GTK_CONTAINER (scrolledWindow), SMS.smsClist);
1635   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
1636                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1637
1638   gtk_paned_add2 (GTK_PANED (vpaned), scrolledWindow);
1639
1640   gtk_widget_show (SMS.smsClist);
1641   gtk_widget_show (scrolledWindow);
1642
1643   CreateErrorDialog (&errorDialog, GUI_SMSWindow);
1644   CreateInfoDialog (&infoDialog, GUI_SMSWindow);
1645
1646   gtk_signal_emit_by_name(GTK_OBJECT (treeSMSItem), "expand");
1647
1648   cmap = gdk_colormap_get_system();
1649   SMS.colour.red = 0xffff;
1650   SMS.colour.green = 0;
1651   SMS.colour.blue = 0;
1652   if (!gdk_color_alloc (cmap, &(SMS.colour)))
1653     g_error (_("couldn't allocate colour"));
1654
1655   questMark.pixmap = gdk_pixmap_create_from_xpm_d (GUI_SMSWindow->window,
1656                          &questMark.mask,
1657                          &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL],
1658                          quest_xpm);
1659
1660   GUIEventAdd (GUI_EVENT_SMS_CENTERS_CHANGED, GUI_RefreshSMSCenterMenu);
1661   GUIEventAdd (GUI_EVENT_SMS_NUMBER_CHANGED, GUI_RefreshMessageWindow);
1662 }