Implemented connection type "tcp" (GCT_TCP), use <hostname>:<port> as "port"
[gnokii.git] / xgnokii / xgnokii_sms.c
index 39c2e40..185cc3b 100644 (file)
@@ -47,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 {
@@ -268,6 +269,7 @@ static void InsertInboxElement (gpointer d, gpointer userData)
       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_set_row_data_full (GTK_CLIST (SMS.smsClist), SMS.row_i++,
@@ -282,8 +284,8 @@ static void InsertInboxElement (gpointer d, gpointer userData)
 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);
@@ -307,7 +309,12 @@ static void InsertOutboxElement (gpointer d, gpointer userData)
     else
       row[0] = g_strdup (_("unsent"));
 
-    row[1] = row[2] = g_strdup ("");
+    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);
@@ -315,7 +322,8 @@ static void InsertOutboxElement (gpointer d, gpointer userData)
     msgPtrs->count = msgPtrs->number = 1;
     msgPtrs->validity = data->Validity;
     msgPtrs->class = data->Class;
-    strcpy (msgPtrs->sender, data->Sender);
+    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++,
@@ -330,6 +338,7 @@ 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, InsertOutboxElement, (gpointer) NULL);
@@ -373,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);
@@ -899,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)
 {
@@ -939,19 +949,62 @@ 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_SMSMessage sms;
   AddressPar aps;
-  char udh[GSM_MAX_USER_DATA_HEADER_LENGTH];
   GSList *r;
   gchar *text, *number;
   gchar **addresses;
   gchar *buf;
-  gint offset, nr_msg, l;
+  gint l;
   gint longSMS;
-  register gint i = 0, j;
+  register gint i = 0;
+  GSM_Deconcatenate_state SMS_Deconcatenate_state;
 
   if (CheckAddressMain ())
   {
@@ -991,106 +1044,31 @@ static void SendSMS (void)
     sms.Compression = false;
     sms.EightBit = false;
     sms.Validity = sms.MessageCenter.Validity;
+    sms.UDHPresent = false;
 
     strncpy (sms.Destination, number, GSM_MAX_DESTINATION_LENGTH + 1);
     sms.Destination[GSM_MAX_DESTINATION_LENGTH] = '\0';
 
-    if (l > GSM_MAX_SMS_LENGTH)
-    {
-      if (longSMS)
-      {
-        sms.UDHType = GSM_ConcatenatedMessages;
-        nr_msg = ((l - 1) / 153) + 1;
-        udh[0] = 0x05; // UDH length
-        udh[1] = 0x00; // concatenated messages (IEI)
-        udh[2] = 0x03; // IEI data length
-        udh[3] = 0x01; // reference number
-        udh[4] = nr_msg;       // number of messages
-        udh[5] = 0x00; // message reference number
-        offset = 6;
-
-        for (j = 0; j < nr_msg; j++)
-        {
-          udh[5] = j + 1;
-
-          memcpy(sms.UDH,udh,offset);
-          strncpy (sms.MessageText, text + (j * 153), 153);
-          sms.MessageText[153] = '\0';
-
-          buf = g_strdup_printf (_("Sending SMS to %s (%d/%d) ...\n"),
-                                 sms.Destination, j + 1, nr_msg);
-          gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
-          gtk_widget_show_now (infoDialog.dialog);
-          g_free (buf);
-          GUI_Refresh ();
-
-          if (SendSMSCore (&sms) != GE_SMSSENDOK)
-          {
-            gtk_widget_hide (infoDialog.dialog);
-            GUI_Refresh ();
-            break;
-          }
-
-          gtk_widget_hide (infoDialog.dialog);
-          GUI_Refresh ();
-
-          sleep (1);
-        }
-      }
-      else
-      {
-        sms.UDHType = GSM_NoUDH;
-        nr_msg = ((l - 1) / 153) + 1;
-        if (nr_msg > 99) // We have place only for 99 messages in header.
-          nr_msg = 99;
-        for (j = 0; j < nr_msg; j++)
-        {
-          gchar header[8];
-
-          g_snprintf (header, 8, "%2d/%-2d: ", j + 1, nr_msg);
-          header[7] = '\0';
-
-          strcpy (sms.MessageText, header);
-          strncat (sms.MessageText, text + (j * 153), 153);
-          sms.MessageText[160] = '\0';
-
-          buf = g_strdup_printf (_("Sending SMS to %s (%d/%d) ...\n"),
-                                 sms.Destination, j + 1, nr_msg);
-          gtk_label_set_text (GTK_LABEL (infoDialog.text), buf);
-          gtk_widget_show_now (infoDialog.dialog);
-          g_free (buf);
-          GUI_Refresh ();
+    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 ();
 
-          if (SendSMSCore (&sms) != GE_SMSSENDOK)
-          {
-            gtk_widget_hide (infoDialog.dialog);
-            GUI_Refresh ();
-            break;
-          }
+    SMS_Deconcatenate_state.first=true;
+    while (SMS_Deconcatenate(&SMS_Deconcatenate_state,&sms,text,l,longSMS)) {
 
-          gtk_widget_hide (infoDialog.dialog);
-          GUI_Refresh ();
+           (void) (*corefunc)(&sms);   /* errors ignored, ugh */
 
-          sleep (1);
-        }
-      }
+           /* Here the sleep have no meaning.
+            * If it is required by some backend phone driver, it should be done THERE!
+            */
+           /* sleep(1); */
     }
-    else
-    {
-      sms.UDHType = GSM_NoUDH;
-      strncpy (sms.MessageText, text, GSM_MAX_SMS_LENGTH + 1);
-      sms.MessageText[GSM_MAX_SMS_LENGTH] = '\0';
 
-      buf = g_strdup_printf (_("Sending 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 ();
-
-      (void) SendSMSCore (&sms);
-      gtk_widget_hide (infoDialog.dialog);
-      GUI_Refresh ();
-    }
+    gtk_widget_hide (infoDialog.dialog);
+    GUI_Refresh ();
 
     i++;
   }
@@ -1100,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},
@@ -1190,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));
 
@@ -1370,6 +1357,7 @@ static void ReplySMS (void)
   gchar *buf;
 //  GSList *r;
 //  GSM_SMSMessage msg;
+  MessagePointers *msgPtrs;
 
   if (GTK_CLIST (SMS.smsClist)->selection == NULL)
     return;
@@ -1397,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 ();