Found in "gnokii-working" directory, some November-patches version
[gnokii.git] / xgnokii / xgnokii_sms.c
index a9726b9..185cc3b 100644 (file)
@@ -3,9 +3,14 @@
   X G N O K I I
 
   A Linux/Unix GUI for Nokia mobile phones.
+  Copyright (C) 1999 Pavel Janík ml., Hugh Blemings
+  & Ján Derfiòák <ja@mail.upjs.sk>.
 
   Released under the terms of the GNU GPL, see file COPYING for more details.
 
+  Last modification: Sun Apr 30 2000
+  Modified by Jan Derfinak
+
 */
 #include <unistd.h>
 #include <locale.h>
@@ -19,8 +24,6 @@
 #include <gdk/gdkkeysyms.h>
 #include "misc.h"
 #include "gsm-api.h"
-#include "gsm-datetime.h"
-#include "gsm-sms.h"
 #include "xgnokii_common.h"
 #include "xgnokii.h"
 #include "xgnokii_lowlevel.h"
@@ -44,6 +47,7 @@ typedef struct {
   gint  validity;
   gint  class;
   gchar sender[GSM_MAX_SENDER_LENGTH + 1];
+  gchar destination[GSM_MAX_DESTINATION_LENGTH + 1];
 } MessagePointers;
 
 typedef struct {
@@ -68,26 +72,23 @@ typedef struct {
   GtkWidget *status;
   GtkWidget *report;
   GtkWidget *longSMS;
-  GtkWidget *class;
   GtkWidget *smscOptionMenu;
   GtkTooltips *addrTip;
   gint       center;
   GSList    *addressLine;
 } SendSMSWidget;
 
-int prev_num_of_folders=0;
-
 static GtkWidget *GUI_SMSWindow;
 static SMSWidget SMS = {NULL, NULL, NULL};
-static SendSMSWidget sendSMS = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL};
+static SendSMSWidget sendSMS = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL};
 static ErrorDialog errorDialog = {NULL, NULL};
 static InfoDialog infoDialog = {NULL, NULL};
 static QuestMark questMark;
-static GtkWidget *treeFolderItem[MAX_SMS_FOLDERS], *subTree;
+
 
 static inline void Help1 (GtkWidget *w, gpointer data)
 {
-  gchar *indx = g_strdup_printf ("/%s/gnokii/xgnokii/sms/index.htm", xgnokiiConfig.locale);
+  gchar *indx = g_strdup_printf ("/help/%s/windows/sms/index.html", xgnokiiConfig.locale);
   Help (w, indx);
   g_free (indx);
 }
@@ -206,105 +207,141 @@ static inline void DestroyMsgPtrs (gpointer data)
 }
 
 
-static void InsertFolderElement (gpointer d, gpointer userData)
+static void InsertInboxElement (gpointer d, gpointer userData)
 {
   GSM_SMSMessage *data = (GSM_SMSMessage *) d;
   MessagePointers *msgPtrs;
   GSM_DateTime *dt;
 
-  if (data->folder == SMS.currentBox)
+  if (data->Type == GST_MT || data->Type == GST_DR)
   {
-    gchar *row[4];
-
-    if (data->Type == GST_DR)
+/*    if (data->Type == GST_MT && data->UDHType == GSM_ConcatenatedMessages)
     {
-      row[0] = g_strdup (_("report"));
-      dt = &(data->SMSCTime);
+      //FIX ME
+
+      msgPtrs = (MessagePointers *) g_malloc (sizeof (MessagePointers));
+      msgPtrs->count = data->UDH[4];
+      msgPtrs->number = data->UDH[5];
+      msgPtrs->validity = data->Validity;
+      msgPtrs->class = data->Class;
+      strcpy (msgPtrs->sender, data->Sender);
+      msgPtrs->msgPtr = (gint *) g_malloc (msgPtrs->count * sizeof (gint));
+      *(msgPtrs->msgPtr + msgPtrs->number - 1) = data->MessageNumber;
     }
-    else
+    else */
     {
+      gchar *row[4];
+
+      if (data->Type == GST_DR)
+      {
+        row[0] = g_strdup (_("report"));
+        dt = &(data->SMSCTime);
+      }
+      else if (data->Status)
+      {
+        row[0] = g_strdup (_("read"));
         dt = &(data->Time);
-       switch (data->Status)
-       {
-            case  GSS_SENTREAD:
-               if (data->folder==0) //GST_INBOX
-                       row[0] = g_strdup (_("read"));
-               else
-                       row[0] = g_strdup (_("sent"));
-                break;
-            case  GSS_NOTSENTREAD:
-               if (data->folder==0) //GST_INBOX
-                       row[0] = g_strdup (_("unread"));
-               else
-                       row[0] = g_strdup (_("not sent"));
-                break;
-            case  GSS_UNKNOWN:
-               row[0] = g_strdup (_("not known :-("));
-                break;
-            case  GSS_TEMPLATE:
-               row[0] = g_strdup (_("template"));
-                break;
-            default:
-               row[0] = g_strdup (_("unknown"));
-                break;
-       }
-    }
+      }
+      else
+      {
+        row[0] = g_strdup (_("unread"));
+        dt = &(data->Time);
+      }
 
-    if (data->SMSData) {
       if (dt->Timezone)
-          row[1] = g_strdup_printf ("%s %02d/%02d/%02d %02d:%02d:%02d %c%02d00",
-                                 DayOfWeek(dt->Year, dt->Month, dt->Day),
+        row[1] = g_strdup_printf ("%02d/%02d/%02d %02d:%02d:%02d %c%02d00",
                                   dt->Day, dt->Month, dt->Year,
                                   dt->Hour, dt->Minute, dt->Second,
                                   dt->Timezone > 0 ? '+' : '-', abs (dt->Timezone));
       else
-          row[1] = g_strdup_printf ("%s %02d/%02d/%02d %02d:%02d:%02d",
-                                 DayOfWeek(dt->Year, dt->Month, dt->Day),
+        row[1] = g_strdup_printf ("%02d/%02d/%02d %02d:%02d:%02d",
                                   dt->Day, dt->Month, dt->Year,
                                   dt->Hour, dt->Minute, dt->Second);
-    } else {
-      row[1] = g_strdup_printf ("unknown");
-    }
-      
-    row[2] = GUI_GetName (data->Sender);
-    if (row[2] == NULL || row[2][0]==0) row[2] = data->Sender;
 
-    row[3] = data->MessageText;
+      row[2] = GUI_GetName (data->Sender);
+      if (row[2] == NULL)
+        row[2] = data->Sender;
+      row[3] = data->MessageText;
 
-    msgPtrs = (MessagePointers *) g_malloc (sizeof (MessagePointers));
-    msgPtrs->validity = data->Validity;
-    msgPtrs->class = data->Class;
-    strcpy (msgPtrs->sender, data->Sender);
-
-//    if (data->UDHType == GSM_ConcatenatedMessages)
-//    {
-//      msgPtrs->count = data->UDH[5];
-//      msgPtrs->number = data->UDH[4];
-//      msgPtrs->msgPtr = (gint *) g_malloc (msgPtrs->count * sizeof (gint));
-//      *(msgPtrs->msgPtr + msgPtrs->number - 1) = data->MessageNumber;
-//    } else {
+      gtk_clist_append (GTK_CLIST (SMS.smsClist), row);
+      msgPtrs = (MessagePointers *) g_malloc (sizeof (MessagePointers));
       msgPtrs->count = msgPtrs->number = 1;
+      msgPtrs->validity = data->Validity;
+      msgPtrs->class = data->Class;
+      strcpy (msgPtrs->sender, data->Sender);
+      msgPtrs->destination[0]='\0';
       msgPtrs->msgPtr = (gint *) g_malloc (sizeof (gint));
       *(msgPtrs->msgPtr) = data->MessageNumber;
-
-      gtk_clist_append (GTK_CLIST (SMS.smsClist), row);
       gtk_clist_set_row_data_full (GTK_CLIST (SMS.smsClist), SMS.row_i++,
                                    msgPtrs, DestroyMsgPtrs);
-//    }
+      g_free (row[0]);
+      g_free (row[1]);
+    }
+  }
+}
+
+
+static inline void RefreshInbox (void)
+{
+  gtk_clist_freeze (GTK_CLIST (SMS.smsClist));
+  gtk_clist_clear (GTK_CLIST (SMS.smsClist));
+  gtk_clist_set_column_title(GTK_CLIST (SMS.smsClist), 2/*column*/, _("Sender"));
 
+  SMS.row_i = 0;
+  g_slist_foreach (phoneMonitor.sms.messages, InsertInboxElement, (gpointer) NULL);
+
+  gtk_clist_sort (GTK_CLIST (SMS.smsClist));
+  gtk_clist_thaw (GTK_CLIST (SMS.smsClist));
+}
+
+
+static void InsertOutboxElement (gpointer d, gpointer userData)
+{
+  GSM_SMSMessage *data = (GSM_SMSMessage *) d;
+  MessagePointers *msgPtrs;
+
+  if (data->Type == GST_MO)
+  {
+    gchar *row[4];
+
+    if (data->Status)
+      row[0] = g_strdup (_("sent"));
+    else
+      row[0] = g_strdup (_("unsent"));
+
+    row[1] = g_strdup ("");    /* time */
+
+    row[2] = GUI_GetName (data->Destination);
+    if (row[2] == NULL)
+      row[2] = data->Destination;
+
+    row[3] = data->MessageText;
+
+    gtk_clist_append( GTK_CLIST (SMS.smsClist), row);
+    msgPtrs = (MessagePointers *) g_malloc (sizeof (MessagePointers));
+    msgPtrs->count = msgPtrs->number = 1;
+    msgPtrs->validity = data->Validity;
+    msgPtrs->class = data->Class;
+    msgPtrs->sender[0]='\0';
+    strcpy (msgPtrs->destination, data->Destination);
+    msgPtrs->msgPtr = (gint *) g_malloc (sizeof (gint));
+    *(msgPtrs->msgPtr) = data->MessageNumber;
+    gtk_clist_set_row_data_full (GTK_CLIST (SMS.smsClist), SMS.row_i++,
+                                 msgPtrs, DestroyMsgPtrs);
     g_free (row[0]);
     g_free (row[1]);
   }
 }
 
-static inline void RefreshFolder (void)
+
+static inline void RefreshOutbox (void)
 {
   gtk_clist_freeze (GTK_CLIST (SMS.smsClist));
-
   gtk_clist_clear (GTK_CLIST (SMS.smsClist));
+  gtk_clist_set_column_title(GTK_CLIST (SMS.smsClist), 2/*column*/, _("Destination"));
 
   SMS.row_i = 0;
-  g_slist_foreach (phoneMonitor.sms.messages, InsertFolderElement, (gpointer) NULL);
+  g_slist_foreach (phoneMonitor.sms.messages, InsertOutboxElement, (gpointer) NULL);
 
   gtk_clist_sort (GTK_CLIST (SMS.smsClist));
   gtk_clist_thaw (GTK_CLIST (SMS.smsClist));
@@ -316,7 +353,10 @@ inline void GUI_RefreshMessageWindow (void)
   if (!GTK_WIDGET_VISIBLE (GUI_SMSWindow))
     return;
 
-  RefreshFolder();
+  if (SMS.currentBox)
+    RefreshOutbox ();
+  else
+    RefreshInbox ();
 }
 
 
@@ -342,7 +382,7 @@ static void ClickEntry (GtkWidget      *clist,
   gtk_text_forward_delete (GTK_TEXT (SMS.smsText), gtk_text_get_length (GTK_TEXT (SMS.smsText)));
 
   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.colour), NULL,
-                   _("From: "), -1);
+                   (SMS.currentBox ? _("To: ") : _("From: ")), -1);
   gtk_clist_get_text (GTK_CLIST (clist), row, 2, &buf);
   gtk_text_insert (GTK_TEXT (SMS.smsText), NULL, &(SMS.smsText->style->black), NULL,
                    buf, -1);
@@ -367,27 +407,6 @@ static void ClickEntry (GtkWidget      *clist,
 
 inline void GUI_ShowSMS (void)
 {
-  int i,j;
-  
-  GUI_InitSMSFoldersInf();
-  
-  for (i=1;i<folders.number+1;i++) {
-    if (i>prev_num_of_folders) {
-      treeFolderItem[i-1] = gtk_tree_item_new_with_label (_(folders.Folder[i-1].Name));
-      gtk_tree_append (GTK_TREE (subTree), treeFolderItem[i-1]);
-      gtk_signal_connect (GTK_OBJECT (treeFolderItem[i-1]), "select",
-                          GTK_SIGNAL_FUNC (SelectTreeItem), GINT_TO_POINTER (i-1));
-      gtk_widget_show (treeFolderItem[i-1]);
-    } else {
-      gtk_widget_set_name(treeFolderItem[i-1],_(folders.Folder[i-1].Name));
-    }
-  }
-  
-  for (j=i+1;j<prev_num_of_folders;j++)
-    gtk_widget_hide (treeFolderItem[j-1]);
-      
-  prev_num_of_folders=folders.number;
-  
   gtk_widget_show (GUI_SMSWindow);
   GUI_RefreshMessageWindow ();
 }
@@ -451,28 +470,6 @@ static void OkDeleteSMSDialog (GtkWidget *widget, gpointer data)
   gtk_clist_thaw (GTK_CLIST (SMS.smsClist));
 }
 
-static void ReadFromPhone (void)
-{
-  GSM_SMSStatus SMSStatus;
-
-  SMSStatus.UnRead = 0;
-  SMSStatus.Number = 0;
-  
-  if (GSM->GetSMSStatus (&SMSStatus) == GE_NONE) {
-    if (phoneMonitor.sms.unRead  != SMSStatus.UnRead ||
-        phoneMonitor.sms.number2 != SMSStatus.Number)
-    {
-      phoneMonitor.working = _("Refreshing SMSes...");
-#ifdef XDEBUG
-   printf("Refreshing %d SMSes...\n",SMSStatus.Number);
-#endif
-      RefreshSMS (SMSStatus.Number);
-      phoneMonitor.working = NULL;
-    }
-
-    phoneMonitor.sms.unRead = SMSStatus.UnRead;
-  }
-}
 
 static void DeleteSMS (void)
 {
@@ -911,6 +908,7 @@ static void ShowSelectContactsDialog (void)
                       GTK_SIGNAL_FUNC (CancelSelectContactDialog), (gpointer) r);
 }
 
+typedef gint (*SaveSendSMSCore_func)(GSM_SMSMessage *sms);
 
 static gint SendSMSCore (GSM_SMSMessage *sms)
 {
@@ -951,12 +949,53 @@ static gint SendSMSCore (GSM_SMSMessage *sms)
   return (error);
 }
 
+static gint SaveSMSCore (GSM_SMSMessage *sms)
+{
+  GSM_Error error;
+  PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
+  D_SMSMessage *m = (D_SMSMessage *) g_malloc (sizeof (D_SMSMessage));
+  
+  /* FIXME: Give user a choice of choosing target memory type, currently
+   * we implicitely always force SIM storage.
+   */
+  sms->MemoryType = GMT_SM;
+  
+  m->sms = sms;
+  e->event = Event_SaveSMSMessage;
+  e->data = m;
+  GUI_InsertEvent (e);
+  pthread_mutex_lock (&saveSMSMutex);
+  pthread_cond_wait (&saveSMSCond, &saveSMSMutex);
+  pthread_mutex_unlock (&saveSMSMutex);
 
-static void SendSMS (void)
+#ifdef XDEBUG
+  g_print ("Address: %s\nText: %s\nDelivery report: %d\nSMS Center: %d\n",
+           sms->Destination,
+           sms->MessageText,
+           GTK_TOGGLE_BUTTON (sendSMS.report)->active,
+           sendSMS.center);
+#endif
+
+  error = m->status;
+  g_free (m);
+
+  if (error != GE_NONE)
+  {
+    gchar *buf = g_strdup_printf (_("SMS save of message to %s failed\n(error=%d)"),
+                                  sms->Destination, error);
+    gtk_label_set_text (GTK_LABEL(errorDialog.text), buf);
+    gtk_widget_show (errorDialog.dialog);
+    g_free (buf);
+  }
+  else
+    g_print ("Message saved, destination to: %s\n", sms->Destination);
+
+  return (error);
+}
+
+static void SaveSendSMS (SaveSendSMSCore_func corefunc)
 {
-  GSM_UDH UDHType;
-  GSM_MultiSMSMessage Multisms;
-  int chars_read;
+  GSM_SMSMessage sms;
   AddressPar aps;
   GSList *r;
   gchar *text, *number;
@@ -964,7 +1003,8 @@ static void SendSMS (void)
   gchar *buf;
   gint l;
   gint longSMS;
-  register gint i = 0, j;
+  register gint i = 0;
+  GSM_Deconcatenate_state SMS_Deconcatenate_state;
 
   if (CheckAddressMain ())
   {
@@ -992,46 +1032,44 @@ static void SendSMS (void)
     else
       number = addresses[i];
 
-    chars_read=strlen(text);
-    UDHType = GSM_NoUDH;
-    if (l > GSM_MAX_SMS_LENGTH && longSMS) UDHType = GSM_ConcatenatedMessages;
-    if (UDHType == GSM_NoUDH && chars_read>160) chars_read=160;
+    sms.MessageCenter = xgnokiiConfig.smsSetting[sendSMS.center];
+    sms.MessageCenter.No = 0;
 
-    GSM_MakeMultiPartSMS2(&Multisms,text,chars_read,UDHType,GSM_Coding_Default);
-    
-    for (j=0;j<Multisms.number;j++) {
-      Multisms.SMS[j].MessageCenter = xgnokiiConfig.smsSetting[sendSMS.center];
-      Multisms.SMS[j].MessageCenter.No = 0;
+    if (GTK_TOGGLE_BUTTON (sendSMS.report)->active)
+      sms.Type = GST_DR;
+    else
+      sms.Type = GST_MO;
 
-      if (GTK_TOGGLE_BUTTON (sendSMS.report)->active) Multisms.SMS[j].Type = GST_DR;
+    sms.Class = -1;
+    sms.Compression = false;
+    sms.EightBit = false;
+    sms.Validity = sms.MessageCenter.Validity;
+    sms.UDHPresent = false;
 
-      if (GTK_TOGGLE_BUTTON (sendSMS.class)->active) Multisms.SMS[j].Class = 0;
+    strncpy (sms.Destination, number, GSM_MAX_DESTINATION_LENGTH + 1);
+    sms.Destination[GSM_MAX_DESTINATION_LENGTH] = '\0';
 
-      Multisms.SMS[j].Validity = Multisms.SMS[j].MessageCenter.Validity;
+    buf = g_strdup_printf ((corefunc==SendSMSCore ? _("Sending SMS to %s ...\n") : _("Saving SMS to %s ...\n")),
+           sms.Destination);
+    gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
+    gtk_widget_show_now (infoDialog.dialog);
+    g_free (buf);
+    GUI_Refresh ();
 
-      strncpy (Multisms.SMS[j].Destination, number, GSM_MAX_DESTINATION_LENGTH + 1);
-      Multisms.SMS[j].Destination[GSM_MAX_DESTINATION_LENGTH] = '\0';      
+    SMS_Deconcatenate_state.first=true;
+    while (SMS_Deconcatenate(&SMS_Deconcatenate_state,&sms,text,l,longSMS)) {
 
-      buf = g_strdup_printf (_("Sending SMS to %s (%d/%d) ...\n"),
-                                 Multisms.SMS[j].Destination, j + 1, Multisms.number);
-      gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
-      gtk_widget_show_now (infoDialog.dialog);
-      g_free (buf);
-      GUI_Refresh ();
+           (void) (*corefunc)(&sms);   /* errors ignored, ugh */
 
-      if (SendSMSCore (&Multisms.SMS[j]) != GE_SMSSENDOK)
-      {
-        gtk_widget_hide (infoDialog.dialog);
-        GUI_Refresh ();
-        break;
-      }
+           /* Here the sleep have no meaning.
+            * If it is required by some backend phone driver, it should be done THERE!
+            */
+           /* sleep(1); */
+    }
 
-      gtk_widget_hide (infoDialog.dialog);
-      GUI_Refresh ();
+    gtk_widget_hide (infoDialog.dialog);
+    GUI_Refresh ();
 
-      sleep (1);
-    }
-    
     i++;
   }
 
@@ -1040,11 +1078,20 @@ static void SendSMS (void)
   g_free (text);
 }
 
+static void SendSMS (void)
+{
+  SaveSendSMS(SendSMSCore);
+}
+
+static void SaveSMS (void)
+{
+  SaveSendSMS(SaveSMSCore);
+}
 
 static GtkItemFactoryEntry send_menu_items[] = {
   { NULL,              NULL,           NULL,           0, "<Branch>"},
   { NULL,              "<control>X",   SendSMS,        0, NULL},
-  { NULL,              "<control>S",   NULL,           0, NULL},
+  { NULL,              "<control>S",   SaveSMS,        0, NULL},
   { NULL,              NULL,           NULL,           0, "<Separator>"},
   { NULL,              "<control>N",   CheckAddress,   0, NULL},
   { NULL,              "<control>C",   ShowSelectContactsDialog, 0, NULL},
@@ -1092,6 +1139,7 @@ static void CreateSMSSendWindow (void)
 
   InitSendMenu ();
   sendSMS.SMSSendWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_wmclass (GTK_WINDOW(sendSMS.SMSSendWindow), "SMSSendWindow", "Xgnokii");
 
   //gtk_widget_set_usize (GTK_WIDGET (sendSMS.SMSSendWindow), 436, 220);
   gtk_signal_connect (GTK_OBJECT (sendSMS.SMSSendWindow), "delete_event",
@@ -1129,7 +1177,7 @@ static void CreateSMSSendWindow (void)
   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Save message to outbox"), NULL,
                            NewPixmap(Send_xpm, GUI_SMSWindow->window,
                            &GUI_SMSWindow->style->bg[GTK_STATE_NORMAL]),
-                           (GtkSignalFunc) NULL, NULL);
+                           (GtkSignalFunc) SaveSMS, NULL);
 
   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
 
@@ -1226,10 +1274,6 @@ static void CreateSMSSendWindow (void)
   gtk_box_pack_start (GTK_BOX (vbox), sendSMS.longSMS, FALSE, FALSE, 3);
   gtk_widget_show (sendSMS.longSMS);
 
-  sendSMS.class = gtk_check_button_new_with_label (_("Send as Flash SMS (Class 0)"));
-  gtk_box_pack_start (GTK_BOX (vbox), sendSMS.class, FALSE, FALSE, 3);
-  gtk_widget_show (sendSMS.class);
-
   label = gtk_label_new (_("SMS Center:"));
   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 1);
   gtk_widget_show (label);
@@ -1313,6 +1357,7 @@ static void ReplySMS (void)
   gchar *buf;
 //  GSList *r;
 //  GSM_SMSMessage msg;
+  MessagePointers *msgPtrs;
 
   if (GTK_CLIST (SMS.smsClist)->selection == NULL)
     return;
@@ -1340,9 +1385,15 @@ static void ReplySMS (void)
 
   //r = g_slist_find_custom (SMS.messages, &msg, CompareSMSMessageLocation);
   //if (r)
-  gtk_entry_set_text (GTK_ENTRY (sendSMS.addr),
-                      ((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
-                      GPOINTER_TO_INT (GTK_CLIST (SMS.smsClist)->selection->data)))->sender);
+  msgPtrs = ((MessagePointers *) gtk_clist_get_row_data(GTK_CLIST (SMS.smsClist),
+               GPOINTER_TO_INT (GTK_CLIST (SMS.smsClist)->selection->data)));
+
+  /* We don't have GSM_SMSMessageType stored in MessagePointers so we just
+   * look at both the "sender" and "destination", shouldn't matter.
+   * Anyway to "Reply" to Outbox message is a bit weird, the icon/menu should
+   * be automatically changed when switched to the Outbox mode. Not my business.
+   */
+  gtk_entry_set_text (GTK_ENTRY (sendSMS.addr), (msgPtrs->sender[0] ? msgPtrs->sender : msgPtrs->destination));
 
   CheckAddressMain ();
   RefreshSMSStatus ();
@@ -1427,8 +1478,6 @@ static void NewBC (void)
 
 static GtkItemFactoryEntry menu_items[] = {
   { NULL,              NULL,           NULL,           0, "<Branch>"},
-  { NULL,              NULL,           ReadFromPhone,  0, NULL},
-  { NULL,              NULL,           NULL,           0, "<Separator>"},
   { NULL,              "<control>S",   NULL,           0, NULL},
   { NULL,              "<control>M",   SaveToMailbox,  0, NULL},
   { NULL,              NULL,           NULL,           0, "<Separator>"},
@@ -1451,8 +1500,6 @@ static void InitMainMenu (void)
   register gint i = 0;
   
   menu_items[i++].path = g_strdup (_("/_File"));
-  menu_items[i++].path = g_strdup (_("/File/Read from phone"));
-  menu_items[i++].path = g_strdup (_("/File/Sep0"));
   menu_items[i++].path = g_strdup (_("/File/_Save"));
   menu_items[i++].path = g_strdup (_("/File/Save to mailbo_x"));
   menu_items[i++].path = g_strdup (_("/File/Sep1"));
@@ -1480,14 +1527,16 @@ void GUI_CreateSMSWindow (void)
   GtkWidget *toolbar;
   GtkWidget *scrolledWindow;
   GtkWidget *vpaned, *hpaned;
-  GtkWidget *tree, *treeSMSItem;
+  GtkWidget *tree, *treeSMSItem, *treeInboxItem, *treeOutboxItem, *subTree;
   SortColumn *sColumn;
   GdkColormap *cmap;
   register gint i;
   gchar *titles[4] = { _("Status"), _("Date / Time"), _("Sender"), _("Message")};
 
+
   InitMainMenu ();
   GUI_SMSWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_wmclass (GTK_WINDOW (GUI_SMSWindow), "SMSWindow", "Xgnokii");
   gtk_window_set_title (GTK_WINDOW (GUI_SMSWindow), _("Short Message Service"));
   //gtk_widget_set_usize (GTK_WIDGET (GUI_SMSWindow), 436, 220);
   gtk_signal_connect (GTK_OBJECT (GUI_SMSWindow), "delete_event",
@@ -1571,6 +1620,18 @@ void GUI_CreateSMSWindow (void)
   gtk_tree_set_view_mode (GTK_TREE (subTree), GTK_TREE_VIEW_ITEM);
   gtk_tree_item_set_subtree (GTK_TREE_ITEM (treeSMSItem), subTree);
 
+  treeInboxItem = gtk_tree_item_new_with_label (_("Inbox"));
+  gtk_tree_append (GTK_TREE (subTree), treeInboxItem);
+  gtk_signal_connect (GTK_OBJECT (treeInboxItem), "select",
+                      GTK_SIGNAL_FUNC (SelectTreeItem), GINT_TO_POINTER (0));
+  gtk_widget_show (treeInboxItem);
+
+  treeOutboxItem = gtk_tree_item_new_with_label (_("Outbox"));
+  gtk_tree_append (GTK_TREE (subTree), treeOutboxItem);
+  gtk_signal_connect (GTK_OBJECT (treeOutboxItem), "select",
+                      GTK_SIGNAL_FUNC (SelectTreeItem), GINT_TO_POINTER (1));
+  gtk_widget_show (treeOutboxItem);
+
   scrolledWindow = gtk_scrolled_window_new (NULL, NULL);
   gtk_widget_set_usize (scrolledWindow, 75, 80);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
@@ -1583,6 +1644,7 @@ void GUI_CreateSMSWindow (void)
                                          tree);
   gtk_widget_show (scrolledWindow);
 
+
   /* Message viewer */
   SMS.smsText = gtk_text_new (NULL, NULL);
   gtk_text_set_editable (GTK_TEXT (SMS.smsText), FALSE);