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