update
[maemo-recorder] / src / maemo-recorder-ui.c
index 0bfc029..7e5b8c1 100644 (file)
@@ -20,7 +20,6 @@
  *
  */
 
-
 #include <gst/gst.h>
 #include <glib/gi18n-lib.h>
 #include <libgnomevfs/gnome-vfs.h>
@@ -33,6 +32,8 @@
 #include <hildon-widgets/hildon-file-chooser-dialog.h>
 #include <string.h>
 #include <sys/time.h>
+#include <osso-helplib.h>
+#include <ossoemailinterface.h>
 
 #include "maemo-recorder.h"
 #include "maemo-recorder-ui.h"
@@ -64,6 +65,8 @@
 #define RECORDER_MSG_RECORDING _("Recording")
 #define RECORDER_FILE_UNTITLED _("Untitled")
 
+#define RECORDER_FMT_STRING_NONE _("N/A")
+
 /* general enumerations */
     
 typedef enum
@@ -72,19 +75,6 @@ typedef enum
     DTX_ON = 1
 } DTX;
 
-/* menu codes */
-typedef enum 
-{
-    MENU_FILE_NEW = 1,
-    MENU_FILE_OPEN,
-    MENU_FILE_SAVE,
-    MENU_FILE_SAVE_AS,
-    MENU_FILE_REC,
-    MENU_FILE_PLAY,
-    MENU_FILE_STOP,
-    MENU_FILE_QUIT
-} MenuActionCode;
-
 typedef enum 
 {
     PIPELINE_PLAY = 1,
@@ -107,6 +97,7 @@ static void pipelineStateChanged (GstElement *element,
 static void seekToTime(GstElement *pipeline, gdouble secs);
 static gboolean seekToZero(AppData *data, GstElement *pipeline);
 static void setLength(AppData *data, gdouble secs);
+static void setFormatString(AppData *data, AudioFormat afmt);
 static gboolean cbStopPlayback(AppData *data);
 static void cbStop(GtkWidget* widget, AppData *data);
 static void cbPlay(GtkWidget* widget, AppData *data);
@@ -129,6 +120,7 @@ static gboolean cbUpdateRecLength(AppData *data);
 static void cbDestroy(GtkWidget* widget, GdkEvent *event, gpointer data);
 static gboolean openURI(gpointer user_data);
 static gboolean closeFile(AppData *data);
+static const gchar *getFileName(AppData *data);
 static gdouble guessMediaLength(AppData *data);
 static GstCaps *createCapsFilter(AudioFormat format);
 
@@ -649,6 +641,7 @@ static void cbDestroy(GtkWidget* widget, GdkEvent *event, gpointer data)
 
     app = (AppData *) data;
 
+    ULOG_DEBUG("delete_event");
     if (!closeFile(app))
         return;
 
@@ -826,6 +819,7 @@ static void cbOpen(GtkWidget* widget, AppData *data)
         else
             setLength(data, 0.0);
 
+        setFormatString(data, data->file_format);
         data->saved = TRUE;
     }
     else
@@ -899,6 +893,7 @@ openURI(gpointer user_data)
         else
             setLength(data, 0.0);
 
+        setFormatString(data, data->file_format);
         data->saved = TRUE;
     }
     else
@@ -1011,7 +1006,15 @@ closeFile(AppData *data)
     }
     return FALSE;
 }
-     
+
+static const gchar *
+getFileName(AppData *data)
+{
+    g_assert(data);
+    return gtk_entry_get_text(GTK_ENTRY(data->mainViewData.fileNameEntry));
+
+}
+
 #if 0
 static void cbSave(GtkWidget* widget, AppData *data) 
 {
@@ -1089,6 +1092,26 @@ static void cbSettings(GtkWidget* widget, AppData *data)
     settings_edit( widget, data );
 }
 
+static void cbEmailing(GtkWidget* widget, AppData *data)
+{
+    gchar *file = NULL;
+    GSList *list = NULL;
+
+    g_assert(NULL != data);
+    
+    if (g_file_test(getFileName(data), G_FILE_TEST_EXISTS))
+    {
+        file = file2uri(getFileName(data));
+        ULOG_INFO("Emailing: %s", file);
+        list = g_slist_append(list, file);
+        if (osso_email_files_email(data->osso, list) != OSSO_OK)
+            hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Emailing failed"));
+
+        g_slist_free(list);
+        g_free(file);
+    }
+}
+
 static void cbSaveAs(GtkWidget* widget, AppData *data) 
 {
     GtkWidget* dialog = NULL;
@@ -1099,7 +1122,7 @@ static void cbSaveAs(GtkWidget* widget, AppData *data)
 
     ULOG_DEBUG("%s() - begin", G_STRFUNC);
 
-    current = gtk_entry_get_text(GTK_ENTRY(data->mainViewData.fileNameEntry));
+    current = getFileName(data);
     if (NULL == current || strcmp(current, RECORDER_FILE_UNTITLED) == 0) 
     {
         hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Nothing to save"));
@@ -1243,6 +1266,7 @@ static void cbRec(GtkWidget* widget, AppData *data)
         gtk_widget_set_sensitive(data->buttonSaveAs, TRUE);
         gtk_window_set_title(GTK_WINDOW(data->mainView), RECORDER_FILE_UNTITLED);
         data->file_format = data->filter;
+        setFormatString(data, data->file_format);
     }
     else
     {
@@ -1262,7 +1286,7 @@ static void cbPlay(GtkWidget* widget, AppData *data)
 
     ULOG_DEBUG("%s() - begin", G_STRFUNC);
 
-    file = gtk_entry_get_text(GTK_ENTRY(data->mainViewData.fileNameEntry));
+    file = getFileName(data);
     if (NULL == data->openFileName || NULL == file || strcmp(file, RECORDER_FILE_UNTITLED) == 0) 
     {
         ULOG_WARN("%s() - nothing to play", G_STRFUNC);
@@ -1417,12 +1441,20 @@ static GtkWidget* createToolBar(AppData *data)
      gtk_widget_set_sensitive(data->buttonSaveAs, FALSE);
      data->saved = TRUE;
 
+     gtk_tool_item_set_expand( GTK_TOOL_ITEM(new), TRUE );
+     gtk_tool_item_set_expand( GTK_TOOL_ITEM(open), TRUE );
+     gtk_tool_item_set_expand( GTK_TOOL_ITEM(saveas), TRUE );
+
      rec = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_RECORD); 
      data->buttonRec = GTK_WIDGET(rec);
      play = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY); 
      data->buttonPlay = GTK_WIDGET(play);
      stop = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP);
      
+     gtk_tool_item_set_expand( GTK_TOOL_ITEM(rec), TRUE );
+     gtk_tool_item_set_expand( GTK_TOOL_ITEM(play), TRUE );
+     gtk_tool_item_set_expand( GTK_TOOL_ITEM(stop), TRUE );
+
      /* create separator */
      sep  = gtk_separator_tool_item_new();
 
@@ -1525,6 +1557,7 @@ static void createMenu( AppData *data )
     GtkWidget *item_ilbc;
     GtkWidget *item_pcm;
     GtkWidget *item_settings;
+    GtkWidget *item_email;
     /*
     GtkWidget *item_radio_type1;
     */
@@ -1545,6 +1578,7 @@ static void createMenu( AppData *data )
     item_file_save_as = gtk_menu_item_new_with_label(_("Save as..."));
     item_others = gtk_menu_item_new_with_label (_("Recording format"));
     item_settings = gtk_menu_item_new_with_label (_("Settings"));
+    item_email = gtk_menu_item_new_with_label(_("Send via e-mail..."));
     
     item_pcma = gtk_radio_menu_item_new_with_label(
         group, FORMAT_NAME_PCMA);
@@ -1579,17 +1613,18 @@ static void createMenu( AppData *data )
     item_separator = gtk_separator_menu_item_new();
     
     /* Add menu items to right menus */
-    gtk_menu_append( main_menu, item_file );
-    gtk_menu_append( menu_file, item_file_open );
-    gtk_menu_append( menu_file, item_file_save_as );
-    gtk_menu_append( main_menu, item_others );
-    gtk_menu_append( menu_others, item_pcm );
-    gtk_menu_append( menu_others, item_pcma );
-    gtk_menu_append( menu_others, item_ilbc);
+    gtk_menu_append(main_menu, item_file );
+    gtk_menu_append(menu_file, item_file_open );
+    gtk_menu_append(menu_file, item_file_save_as );
+    gtk_menu_append(menu_file, item_email );
+    gtk_menu_append(main_menu, item_others );
+    gtk_menu_append(menu_others, item_pcm );
+    gtk_menu_append(menu_others, item_pcma );
+    gtk_menu_append(menu_others, item_ilbc);
     
-    gtk_menu_append( main_menu, item_settings );
+    gtk_menu_append(main_menu, item_settings );
     
-    gtk_menu_append( main_menu, item_close );
+    gtk_menu_append(main_menu, item_close );
 
     /* Add others submenu to the "Others" item */
     gtk_menu_item_set_submenu(
@@ -1604,7 +1639,8 @@ static void createMenu( AppData *data )
         GTK_SIGNAL_FUNC (cbSaveAs), data);
     g_signal_connect( G_OBJECT( item_settings ), "activate",
         GTK_SIGNAL_FUNC (cbSettings), data);
-    
+    g_signal_connect( G_OBJECT( item_email ), "activate",
+        GTK_SIGNAL_FUNC (cbEmailing), data);
     g_signal_connect( G_OBJECT( item_close ), "activate",
         GTK_SIGNAL_FUNC (cbItemClose), data);
 
@@ -1616,6 +1652,29 @@ static void createMenu( AppData *data )
     gtk_widget_show_all( GTK_WIDGET( main_menu ) );
 }
 
+gboolean
+evKeypress(GtkWidget *widget, GdkEventKey *ev, AppData *appdata)
+{
+
+  switch (ev->keyval)
+  {
+    case GDK_Return:
+      cbRec(widget, appdata);
+      return TRUE;
+    case GDK_Right:
+      cbPlay(widget, appdata);
+      return TRUE;
+    case GDK_Escape:
+      cbStop(widget, appdata);
+      return TRUE;
+    default:
+      break;
+  }
+
+  return FALSE;
+}
+
+
 gboolean maemo_recorder_ui_new(AppData *data)
 {
     HildonProgram *app = NULL;
@@ -1627,6 +1686,7 @@ gboolean maemo_recorder_ui_new(AppData *data)
     GtkWidget *entry2 = NULL;
     GtkWidget *entry3 = NULL;
     GtkWidget *toolBar = NULL;
+    GtkWidget *infohbox = NULL;
     GtkWidget *table = NULL;
     GtkWidget *scale = NULL;
     GtkObject *adjustment = NULL;
@@ -1653,30 +1713,27 @@ gboolean maemo_recorder_ui_new(AppData *data)
     toolBar = createToolBar(data);
 
     /* create table for labels */
-    table = gtk_table_new (4, 3, FALSE);
+    table = gtk_table_new (4, 2, FALSE);
     gtk_table_set_homogeneous(GTK_TABLE(table), FALSE);
 
     gtk_table_set_row_spacings (GTK_TABLE (table), 4);
-    gtk_table_set_col_spacings (GTK_TABLE (table), 0);
+    gtk_table_set_col_spacings (GTK_TABLE (table), HILDON_MARGIN_TRIPLE);
 
     label = gtk_label_new_with_mnemonic(_("Filename:"));
-    /*
     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
-    */
     gtk_table_attach_defaults (GTK_TABLE (table),
             label,
             0, 1, 0, 1);
 
-    entry1 = gtk_entry_new ();
+    entry1 = gtk_entry_new();
     gtk_entry_set_has_frame(GTK_ENTRY(entry1), FALSE);
-    gtk_entry_set_text (GTK_ENTRY (entry1), _(RECORDER_FILE_UNTITLED));
-    gtk_table_attach_defaults (GTK_TABLE (table), entry1, 1, 3, 0, 1);
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry1);
+    gtk_entry_set_text(GTK_ENTRY (entry1), _(RECORDER_FILE_UNTITLED));
+    gtk_entry_set_editable(GTK_ENTRY(entry1), FALSE);
+    gtk_table_attach_defaults(GTK_TABLE (table), entry1, 1, 2, 0, 1);
+    gtk_label_set_mnemonic_widget(GTK_LABEL (label), entry1);
 
     label = gtk_label_new_with_mnemonic (_("Length:"));
-    /*
     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
-    */
     gtk_table_attach_defaults (GTK_TABLE (table),
             label,
             0, 1, 1, 2);
@@ -1684,22 +1741,39 @@ gboolean maemo_recorder_ui_new(AppData *data)
     entry2 = gtk_entry_new ();
     gtk_entry_set_has_frame(GTK_ENTRY(entry2), FALSE);
     gtk_entry_set_text (GTK_ENTRY (entry2), "0:00.00");
-    gtk_table_attach_defaults (GTK_TABLE (table), entry2, 1, 3, 1, 2);
+    gtk_entry_set_editable(GTK_ENTRY(entry2), FALSE);
+    gtk_table_attach_defaults (GTK_TABLE (table), entry2, 1, 2, 1, 2);
     gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry2);
 
-    label = gtk_label_new_with_mnemonic (_("State:"));
-    /*
+    /* audio format field */
+    label = gtk_label_new_with_mnemonic(_("Format:"));
     gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
-    */
     gtk_table_attach_defaults (GTK_TABLE (table),
             label,
             0, 1, 2, 3);
 
+    entry3 = gtk_entry_new();
+    gtk_entry_set_has_frame(GTK_ENTRY(entry3), FALSE);
+    gtk_entry_set_width_chars(GTK_ENTRY(entry3), 40);
+    gtk_entry_set_text (GTK_ENTRY (entry3), RECORDER_FMT_STRING_NONE);
+    gtk_entry_set_editable(GTK_ENTRY(entry3), FALSE);
+    data->mainViewData.formatEntry = GTK_WIDGET(entry3);
+    
+    gtk_table_attach_defaults (GTK_TABLE (table), entry3, 1, 2, 2, 3);
+    gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry3);
+
+    label = gtk_label_new_with_mnemonic(_("State:"));
+    gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
+    gtk_table_attach_defaults (GTK_TABLE (table),
+            label,
+            0, 1, 3, 4);
+
     entry3 = gtk_entry_new ();
     gtk_entry_set_has_frame(GTK_ENTRY(entry3), FALSE);
     gtk_entry_set_text (GTK_ENTRY (entry3), RECORDER_MSG_READY);
-    gtk_table_attach_defaults (GTK_TABLE (table), entry3, 1, 3, 2, 3);
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry3);
+    gtk_entry_set_editable(GTK_ENTRY(entry3), FALSE);
+    gtk_table_attach_defaults (GTK_TABLE (table), entry3, 1, 2, 3, 4);
+    gtk_label_set_mnemonic_widget(GTK_LABEL (label), entry3);
 
     adjustment = gtk_adjustment_new (0.00,
                   0.00,
@@ -1718,20 +1792,19 @@ gboolean maemo_recorder_ui_new(AppData *data)
     g_signal_connect(G_OBJECT(adjustment), "value-changed", G_CALLBACK(cbUserSeek), data);
     g_signal_connect(G_OBJECT(scale), "format-value", G_CALLBACK(cbFormatSeekbarValue), data);
     g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(cbDestroy), data);
+    g_signal_connect(G_OBJECT(window), "key-press-event",
+            G_CALLBACK(evKeypress), data);
 
     /* packing the view */
     gtk_container_add (GTK_CONTAINER(window), vbox);
-    gtk_box_pack_start (GTK_BOX(vbox), table, FALSE, TRUE, 0);
+    infohbox = gtk_hbox_new(FALSE, 0);
+    gtk_box_pack_start (GTK_BOX(infohbox), table, FALSE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX(vbox), infohbox, FALSE, TRUE, 0);
     gtk_box_pack_start (GTK_BOX(vbox), scale, FALSE, FALSE, 0);
 /*    gtk_box_pack_start (GTK_BOX(vbox), hbox, TRUE, TRUE, 0); */
     
     hildon_window_add_toolbar(window, GTK_TOOLBAR(toolBar)); 
 
-    /* initialise the ui */
-    gtk_entry_set_editable(GTK_ENTRY(entry1), FALSE);
-    gtk_entry_set_editable(GTK_ENTRY(entry2), FALSE);
-    gtk_entry_set_editable(GTK_ENTRY(entry3), FALSE);
-
     /* store needed widgets */
     data->app = app;
     data->mainView = window;
@@ -1811,6 +1884,52 @@ static gboolean seekToZero(AppData *data, GstElement *pipeline)
     return TRUE;
 }
 
+static void
+setFormatString(AppData *data, AudioFormat afmt)
+{
+    gchar *str;
+    gchar *format;
+
+    /* these are pretty much always the same */
+    gint channels = 1; 
+    gint rate = DEFAULT_RATE; /* 8000 */
+    gint bits = 8;
+
+    g_assert(data);
+    g_assert(GTK_IS_ENTRY(data->mainViewData.formatEntry));
+
+    switch (afmt)
+    {
+        case FORMAT_PCMA:
+            format = FORMAT_NAME_PCMA;
+            break;
+        case FORMAT_PCMU:
+            format = FORMAT_NAME_PCMU;
+            break;
+        case FORMAT_ILBC:
+            format = FORMAT_NAME_ILBC;
+            rate = ILBC_RATE;
+            break;
+        /* TODO: we can play wavs with many sampling rates, 2 channels */
+        /* we really should migrate to the better format spec */
+        case FORMAT_WAV:
+            format = FORMAT_NAME_WAV;
+            bits = PCM_WIDTH;
+            break;
+        case FORMAT_PCM:
+            format = FORMAT_NAME_PCM;
+            bits = PCM_WIDTH;
+            break;
+        default:
+            gtk_entry_set_text(GTK_ENTRY(data->mainViewData.formatEntry), RECORDER_FMT_STRING_NONE);
+            return;
+    }
+
+    str = g_strdup_printf("%s, %d %s, %d Hz, %d %s", format, channels, _("ch"), rate, bits, _("bits"));
+    gtk_entry_set_text(GTK_ENTRY(data->mainViewData.formatEntry), str);
+    g_free(str);
+}
+
 static void setLength(AppData *data, gdouble secs)
 {
     guint mins = 0;
@@ -2008,3 +2127,4 @@ static gboolean cbUpdateRecLength(AppData *data)
     return FALSE;
 }
 
+