fix send via email
[maemo-recorder] / src / maemo-recorder-ui.c
index 58d22cd..ca76ddf 100644 (file)
@@ -1,4 +1,4 @@
-/* vim: set ts=4 sw=4 et: */
+/* vim: set sts=4 sw=4 et: */
 /*
  * maemo-recorder-ui.c
  *
  *
  */
 
-
 #include <gst/gst.h>
 #include <glib/gi18n-lib.h>
 #include <libgnomevfs/gnome-vfs.h>
 #include <locale.h>
-#include <hildon-widgets/hildon-program.h>
-#include <hildon-widgets/hildon-note.h>
-#include <hildon-widgets/hildon-banner.h>
-#include <hildon-widgets/hildon-defines.h>
-#include <hildon-widgets/hildon-file-system-model.h>
-#include <hildon-widgets/hildon-file-chooser-dialog.h>
+#include <hildon/hildon-program.h>
+#include <hildon/hildon-note.h>
+#include <hildon/hildon-banner.h>
+#include <hildon/hildon-defines.h>
+#include <hildon/hildon-file-system-model.h>
+#include <hildon/hildon-file-chooser-dialog.h>
 #include <string.h>
 #include <sys/time.h>
-
+#include <libmodest-dbus-client/libmodest-dbus-client.h>
+#include <glib/gstdio.h>
 #include "maemo-recorder.h"
 #include "maemo-recorder-ui.h"
 #include "maemo-recorder-file.h"
-
+#include "settings.h"
 
 #define DEFAULT_REC_BLOCKSIZE "160"
 
 #define STOP_DELAY 500
-#define REC_UPDATE_INTERVAL 750
+#define REC_UPDATE_INTERVAL 500
 #define PLAY_UPDATE_INTERVAL 200
 
 /* MACROs */
@@ -56,7 +56,7 @@
 #define GST_TIME_MSECS(t) \
         (guint) (((GstClockTime)(t)) % GST_SECOND)
 
-#define RECORDER_APP_TITLE "Maemo Recorder"
+#define RECORDER_APP_TITLE "Recorder"
 #define RECORDER_MSG_READY _("Ready")
 #define RECORDER_MSG_STOPPED _("Stopped")
 #define RECORDER_MSG_PAUSED _("Paused")
@@ -64,6 +64,8 @@
 #define RECORDER_MSG_RECORDING _("Recording")
 #define RECORDER_FILE_UNTITLED _("Untitled")
 
+#define RECORDER_FMT_STRING_NONE _("N/A")
+
 /* general enumerations */
     
 typedef enum
@@ -72,19 +74,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,18 +96,15 @@ 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);
-static void cbRec(GtkWidget* widget, AppData *data);
+static void cbStop(GtkWidget* widget, GdkEventButton *event, AppData *data);
+static void cbPlay(GtkWidget* widget, GdkEventButton *event, AppData *data);
+static void cbRec(GtkWidget* widget, GdkEventButton *event, AppData *data);
 static void cbNew(GtkWidget* widget, AppData *data);
 static void cbOpen(GtkWidget* widget, AppData *data);
 /*static void cbSave(GtkWidget* widget, AppData *data);*/
 static void cbSaveAs(GtkWidget* widget, AppData *data);
-static void cbItemClose(GtkWidget *widget, gpointer data);
-static void cbUserSeek(GtkAdjustment *adjustment, gpointer data);
-static gchar* cbFormatSeekbarValue(GtkScale *scale, gdouble value);
-static GtkWidget* createToolBar(AppData *data);
 static void createMenu( AppData *data );
 static gboolean createPipeline(AppData *app, PipeLineType type);
 static void openPlayPipeline( AppData *data );
@@ -129,60 +115,44 @@ 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);
+static gboolean evKeypress(GtkWidget *widget, GdkEventKey *ev, AppData *appdata);
+static gboolean cbScaleRelease(GtkWidget *widget, GdkEventButton *ev, gpointer data);
 
-static void new_pad_cb (GstElement *wavparse, GstPad *new_pad, gpointer data)
-{
-    GstElement *sink;
-    AppData* app = (AppData*) data; 
-
-    ULOG_INFO("new pad");
-    sink = gst_element_factory_make ("dsppcmsink", "sink");
-    gst_bin_add (GST_BIN (app->playPipeline), sink);
-    if (!gst_element_link (wavparse, sink))
-      g_error ("link(wavparse, sink) failed!");
-    gst_element_sync_state_with_parent(sink); 
-}
+static gboolean lengthSet = FALSE;
 
 static gboolean createPipeline(AppData *app, PipeLineType type)
 {
     GstElement *src = NULL;
     GstElement *sink = NULL;
     GstElement *filter = NULL;
-    GstElement *queue = NULL;
     GstElement *pipeline = NULL;
     GstElement *parse = NULL;
+    GstElement *bin = NULL;
     GstCaps *caps = NULL;
 
     g_assert(NULL != app);
 
-    pipeline = gst_pipeline_new("pipeline");
-
-    gst_bus_add_watch(gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
-                   cbBus, app);
-
     /* create elements */
     switch (type)
     {
         case PIPELINE_PLAY_MP3:
             ULOG_INFO("mp3 playback - queue");
-            src = gst_element_factory_make ("filesrc", "source");
-            queue = gst_element_factory_make ("queue", "queue");
-            sink = gst_element_factory_make ("dspmp3sink", "sink");
-
-            g_object_set(G_OBJECT (queue), 
-                "max-size-buffers", 8192,
-                "min-threshold-bytes", 131072,
-                "min-threshold-buffers", 2048,
-                NULL );
-            g_object_set(G_OBJECT(src), 
-                    "location", app->openFileName, 
-                    NULL);
+            bin = gst_element_factory_make ("playbin2", "bin");
+            gchar* uri = g_strdup_printf("file://%s", app->openFileName);
+            g_object_set(G_OBJECT(bin), 
+                "uri", uri, 
+                NULL);
+            g_free(uri);
+            gst_bus_add_watch(gst_pipeline_get_bus (GST_PIPELINE (bin)),
+                   cbBus, app);
+
+            app->playPipeline = bin;
+            app->playPipelineType = type;
+                     
+            return TRUE;
             break;
 
         case PIPELINE_PLAY:
@@ -200,12 +170,25 @@ static gboolean createPipeline(AppData *app, PipeLineType type)
                 case FORMAT_PCMU:
                 case FORMAT_PCM:
                     ULOG_INFO("using pcm sink");
-                    sink = gst_element_factory_make ("dsppcmsink", "sink");
+                    sink = gst_element_factory_make ("pulsesink", "sink");
                     break;
 
                 case FORMAT_WAV:
                     ULOG_INFO("using wavparse & pcm sink");
-                    parse = gst_element_factory_make ("wavparse", "parse");
+                    bin = gst_element_factory_make ("playbin2", "bin");
+                    gchar* uri = g_strdup_printf("file://%s", app->openFileName);
+                    g_object_set(G_OBJECT(bin),
+                        "uri", uri,
+                        NULL);
+                    g_free(uri);
+                    
+                    gst_bus_add_watch(gst_pipeline_get_bus (GST_PIPELINE (bin)),
+                        cbBus, app);
+
+                    app->playPipeline = bin;
+                    app->playPipelineType = type;
+                              
+                    return TRUE;
                     break;
                     
                 default:
@@ -230,6 +213,7 @@ static gboolean createPipeline(AppData *app, PipeLineType type)
                     src = gst_element_factory_make("dspilbcsrc", "source");
                     g_object_set(G_OBJECT(src),
                         "dtx", DTX_OFF,
+                        "mode", 1,
                         NULL);
                     break;
         
@@ -237,20 +221,16 @@ static gboolean createPipeline(AppData *app, PipeLineType type)
                 case FORMAT_PCMU:
                 case FORMAT_PCM:
                     ULOG_INFO("using pcm source");
-                    src = gst_element_factory_make("dsppcmsrc", "source");
-                    g_object_set(G_OBJECT (src), 
+                    src = gst_element_factory_make("pulsesrc", "source");
+                    /*g_object_set(G_OBJECT (src), 
                           "blocksize", DEFAULT_REC_BLOCKSIZE, 
                           "dtx", DTX_OFF,
-                        NULL);
+                        NULL);*/
                     break;
             
                 case FORMAT_WAV:
                     ULOG_INFO("using pcm source & wavenc");
-                    src = gst_element_factory_make("dsppcmsrc", "source");
-                    g_object_set(G_OBJECT (src),
-                            "blocksize", DEFAULT_REC_BLOCKSIZE,
-                            "dtx", DTX_OFF,
-                            NULL);
+                    src = gst_element_factory_make("pulsesrc", "source");
                     parse = gst_element_factory_make("wavenc", "enc");
                     break;   
             
@@ -274,17 +254,21 @@ static gboolean createPipeline(AppData *app, PipeLineType type)
 
         default:
             ULOG_ERR("Invalid pipeline type!");
-            gst_object_unref(pipeline);
             return FALSE;
     }
 
+    pipeline = gst_pipeline_new("pipeline");
+
+    gst_bus_add_watch(gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
+                   cbBus, app);
+    
     if (!src || !pipeline)
     {
         ULOG_ERR("Could not create GstElement!");
         return FALSE;
     }
 
-    if (!sink && app->filter != FORMAT_WAV)
+    if (!sink && app->filter != FORMAT_WAV )
     {
         ULOG_ERR("Could not create GstElement!");
         return FALSE;        
@@ -296,82 +280,70 @@ static gboolean createPipeline(AppData *app, PipeLineType type)
     switch (type)
     {
         case PIPELINE_REC:
-          switch (app->filter)
-           {
-            case FORMAT_ILBC:
-            case FORMAT_PCM:
-            case FORMAT_PCMA:
-                if (!filter)
-                {
-                   ULOG_ERR("Could not create filter GstElement!");
-                   return FALSE;
-                }
-                gst_bin_add_many(GST_BIN(pipeline), src, filter, sink, NULL);
-
-                if (!gst_element_link_many (src, filter, sink, NULL))
-                {
-                    ULOG_ERR("gst_element_link failed for src, filter and sink!");
-                    return FALSE;
-                }
-                break;   
-            case FORMAT_WAV:
-                gst_bin_add_many(GST_BIN(pipeline), src, parse, sink, NULL);
-                if (!gst_element_link_many (src, parse, sink, NULL))
-                {
-                    ULOG_ERR("gst_element_link failed for src, parse and sink!");
-                }
-                break;
-     
-            default:
-                break;
+            switch (app->filter)
+            {
+                case FORMAT_ILBC:
+                case FORMAT_PCM:
+                case FORMAT_PCMA:
+                    if (!filter)
+                    {
+                       ULOG_ERR("Could not create filter GstElement!");
+                       return FALSE;
+                    }
+                    gst_bin_add_many(GST_BIN(pipeline), src, filter, sink, NULL);
+
+                    if (!gst_element_link_many (src, filter, sink, NULL))
+                    {
+                        ULOG_ERR("gst_element_link failed for src, filter and sink!");
+                        return FALSE;
+                    }
+                    break;
+
+                case FORMAT_WAV:
+                    gst_bin_add_many(GST_BIN(pipeline), src, filter, parse, sink, NULL);
+                    if (!gst_element_link_many (src, filter, parse, sink, NULL))
+                    {
+                        ULOG_ERR("gst_element_link failed for src, parse and sink!");
+                    }
+                    break;
+
+                default:
+                    break;
           
-         }
-         break; 
-        
+            }
+            break; 
+           
         case PIPELINE_PLAY:
-          switch (app->filter)
-           {
-            case FORMAT_ILBC:
-            case FORMAT_PCM:
-            case FORMAT_PCMA:
-                if (!filter)
-                {
-                   ULOG_ERR("Could not create filter GstElement!");
-                   return FALSE;
-                }
-                gst_bin_add_many(GST_BIN(pipeline), src, filter, sink, NULL);
-
-                if (!gst_element_link_many (src, filter, sink, NULL))
-                {
-                    ULOG_ERR("gst_element_link failed for src, filter and sink!");
-                    return FALSE;
-                }
-
-                break;
-            case FORMAT_WAV:
-                gst_bin_add_many(GST_BIN(pipeline), src, parse, NULL);
-                if (!gst_element_link_many (src, parse, NULL))
-                {
-                    ULOG_ERR("gst_element_link failed for src, parse and sink!");
-                    return FALSE;
-                }
-                app->playPipeline = pipeline;
-                g_signal_connect(parse, "pad_added",
-                             G_CALLBACK(new_pad_cb), app);
-         
-                break;
-
-            default:
-                break;
-           }
-
-           break;
+            switch (app->filter)
+            {
+                case FORMAT_ILBC:
+                case FORMAT_PCM:
+                case FORMAT_PCMA:
+                    if (!filter)
+                    {
+                       ULOG_ERR("Could not create filter GstElement!");
+                       return FALSE;
+                    }
+                    gst_bin_add_many(GST_BIN(pipeline), src, filter, sink, NULL);
+
+                    if (!gst_element_link_many (src, filter, sink, NULL))
+                    {
+                        ULOG_ERR("gst_element_link failed for src, filter and sink!");
+                        return FALSE;
+                    }
+
+                    break;
+
+                default:
+                    break;
+            }
+
+            break;
      
-        case PIPELINE_PLAY_MP3:
         default:
-            gst_bin_add_many(GST_BIN(pipeline), src, queue, sink, NULL);
+            gst_bin_add_many(GST_BIN(pipeline), src, sink, NULL);
  
-            if(!gst_element_link_many(src, queue, sink, NULL))
+            if(!gst_element_link_many(src, sink, NULL))
             {
                  ULOG_ERR("gst_element_link failed for src and sink!");
                  return FALSE;
@@ -412,48 +384,53 @@ static gboolean destroyPipelines(AppData *data)
 
 static gboolean destroyPipeline(AppData *data, PipeLineType type)
 {
-     GstState state;
-     GstState pending;
-     GstElement *pipeline = NULL;
+    GstState state;
+    GstState pending;
+    GstElement *pipeline = NULL;
 
-     ULOG_INFO("%s() - Stopping playback/recording", G_STRFUNC);
+    ULOG_INFO("%s() - Stopping playback/recording", G_STRFUNC);
 
-     switch (type)
-     {
+    //hildon_banner_show_information(GTK_WIDGET(data->mainView), NULL, RECORDER_MSG_STOPPED);         
+    gtk_label_set_text(GTK_LABEL(data->mainViewData.stateEntry), "");
+    gtk_widget_set_sensitive(data->buttonRec, TRUE);
+
+    switch (type)
+    {
         case PIPELINE_REC:
             pipeline = data->recPipeline;
             /*
             data->recPipeline = NULL;
             */
             break;
+
         default:
             pipeline = data->playPipeline;
             /*
             data->playPipeline = NULL;
             */
             break;
-     }
+    }
     
-     if (!GST_IS_ELEMENT(pipeline))
-         return TRUE;
-
-     /* this unallocates everything */
-     gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
-
-     /* for some reason the state does not update manually */
-     gst_element_get_state(pipeline, &state, 
-                &pending, GST_CLOCK_TIME_NONE);
-     pipelineStateChanged(pipeline,
-               state,
-               state,
-               pending,
-               data);
-
-     /*
-     gst_object_unref(pipeline);
-     */
-
-     return TRUE;
+    if (!GST_IS_ELEMENT(pipeline))
+        return TRUE;
+
+    /* this unallocates everything */
+    gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
+
+    /* for some reason the state does not update manually */
+    gst_element_get_state(pipeline, &state, 
+            &pending, GST_CLOCK_TIME_NONE);
+    pipelineStateChanged(pipeline,
+           state,
+           state,
+           pending,
+           data);
+
+    /*
+    gst_object_unref(pipeline);
+    */
+
+    return TRUE;
 }
 
 
@@ -477,12 +454,12 @@ static void pipelineStateChanged (GstElement *element,
                g_free(tmp);
                tmp = NULL;
                ULOG_INFO("%s() - Recording", G_STRFUNC);
-               gtk_entry_set_text(GTK_ENTRY(data->mainViewData.stateEntry), 
+               gtk_label_set_text(GTK_LABEL(data->mainViewData.stateEntry), 
                       RECORDER_MSG_RECORDING);
 
                gtk_widget_set_state(data->buttonRec, GTK_STATE_ACTIVE);
 
-               if (data->recUpdateId == 0 && gettimeofday(&data->recStartTv, NULL) == 0)
+               if (data->recUpdateId == 0)
                {
                    data->recUpdateId = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, REC_UPDATE_INTERVAL, (GSourceFunc) cbUpdateRecLength, data, NULL);
                }
@@ -494,22 +471,18 @@ static void pipelineStateChanged (GstElement *element,
                g_free(tmp);
                tmp = NULL;
                ULOG_INFO("%s() - Playing", G_STRFUNC);
-               gtk_entry_set_text(GTK_ENTRY(data->mainViewData.stateEntry), 
+               gtk_label_set_text(GTK_LABEL(data->mainViewData.stateEntry), 
                       RECORDER_MSG_PLAYING);  
                gtk_widget_set_state(data->buttonPlay, GTK_STATE_ACTIVE);
-               /*
-               gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(data->buttonPlay), GTK_STOCK_MEDIA_PAUSE);
-               */
           }
 
           break;
 
         case GST_STATE_READY:
-          //hildon_banner_show_information(GTK_WIDGET(data->mainView), NULL, "Ready...");
-          ULOG_INFO("%s() - Ready", G_STRFUNC);
-          gtk_entry_set_text(GTK_ENTRY(data->mainViewData.stateEntry), 
-                     RECORDER_MSG_READY);  
-          break;
+            /* hildon_banner_show_information(GTK_WIDGET(data->mainView), NULL, "Ready..."); */
+            ULOG_INFO("%s() - Ready", G_STRFUNC);
+            gtk_label_set_text(GTK_LABEL(data->mainViewData.stateEntry), ""); 
+            break;
 
         case GST_STATE_PAUSED:
           {
@@ -521,20 +494,8 @@ static void pipelineStateChanged (GstElement *element,
               if (GST_IS_ELEMENT(data->playPipeline) && gst_element_query_position(data->playPipeline, &fmt, &pos) && pos != 0)
               {
                   hildon_banner_show_information(GTK_WIDGET(data->mainView), NULL, RECORDER_MSG_PAUSED);       
-                  gtk_entry_set_text(GTK_ENTRY(data->mainViewData.stateEntry), 
+                  gtk_label_set_text(GTK_LABEL(data->mainViewData.stateEntry), 
                          RECORDER_MSG_PAUSED);
-                  /*
-                  gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(data->buttonPlay), GTK_STOCK_MEDIA_PLAY);
-                  gtk_widget_set_state(data->buttonPlay, GTK_STATE_NORMAL);
-                  */
-              }
-              else
-              {
-                  hildon_banner_show_information(GTK_WIDGET(data->mainView), NULL, RECORDER_MSG_STOPPED);       
-                  gtk_entry_set_text(GTK_ENTRY(data->mainViewData.stateEntry), 
-                         RECORDER_MSG_STOPPED);  
-                  gtk_widget_set_state(data->buttonPlay, GTK_STATE_NORMAL);
-                  gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(data->buttonPlay), GTK_STOCK_MEDIA_PLAY);
               }
               gtk_widget_set_state(data->buttonRec, GTK_STATE_NORMAL);
           }
@@ -542,11 +503,7 @@ static void pipelineStateChanged (GstElement *element,
           
         case GST_STATE_NULL:
           ULOG_INFO("%s() - Null", G_STRFUNC);
-          hildon_banner_show_information(GTK_WIDGET(data->mainView), NULL, RECORDER_MSG_STOPPED);
-          gtk_entry_set_text(GTK_ENTRY(data->mainViewData.stateEntry), 
-                     RECORDER_MSG_READY);  
           gtk_widget_set_state(data->buttonPlay, GTK_STATE_NORMAL);
-          gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(data->buttonPlay), GTK_STOCK_MEDIA_PLAY);
           gtk_widget_set_state(data->buttonRec, GTK_STATE_NORMAL);
           
           break;
@@ -562,77 +519,90 @@ static gboolean cbBus(GstBus *bus,
                GstMessage *message,
                gpointer   data)
 {
-     AppData *app = (AppData*)data;
-
-     switch (GST_MESSAGE_TYPE(message)) 
-     {
-     case GST_MESSAGE_WARNING:
-     {
-      GError *err;
-      gchar *debug;
-      
-      gst_message_parse_error (message, &err, &debug);
-      ULOG_WARN("%s() - Warning: %s", G_STRFUNC, err->message);
-      g_error_free (err);
-      g_free (debug);
-      break;
-     }
-     case GST_MESSAGE_ERROR: 
-     {
-      GError *err;
-      gchar *debug;
-      
-      gst_message_parse_error (message, &err, &debug);
-      ULOG_ERR("%s() - Error: %s", G_STRFUNC, err->message);
-      g_error_free (err);
-      g_free (debug);
-      /* break; */
-      /* flow through to eos */
-     }
-     case GST_MESSAGE_EOS:
-     {
-        ULOG_INFO("%s() - eos", G_STRFUNC);
-     
-         switch(getAppState(app))
-         {
-         case APPSTATE_PLAYING:
-              /* stop playback after a short break*/
-              g_timeout_add(STOP_DELAY, (GSourceFunc)cbStopPlayback, data);
-              break;
-
-         case APPSTATE_RECORDING:
-          gst_element_set_state(GST_ELEMENT(app->recPipeline), 
-               GST_STATE_PAUSED);
-          destroyPipeline(app, PIPELINE_REC);
-          app->saved = FALSE;
-          break;
-         case APPSTATE_READY:
-         default:
-             /* destroyPipelines(app); */
-          break;
-         }
-         break;
-     }
-     case GST_MESSAGE_STATE_CHANGED: 
-     {
-      GstState old;
-      GstState new;
-      GstState pending;
-      
-      gst_message_parse_state_changed(message, &old, &new, &pending);
-    
-      pipelineStateChanged(NULL, old, new, pending, app);
-  
-      break;
-     }
-     default:
-      /* unhandled message */
-      ULOG_WARN("%s() - Unhandled message, type = %d", G_STRFUNC, message->type);
-      break;
-     }
-     
-     /* remove message from the queue */
-     return TRUE;
+    AppData *app = (AppData*)data;
+
+    switch (GST_MESSAGE_TYPE(message)) 
+    {
+        case GST_MESSAGE_WARNING:
+        {
+            GError *err = NULL;
+            gchar *debug = NULL;
+
+            gst_message_parse_warning (message, &err, &debug);
+            ULOG_WARN("%s() - Warning: %s", G_STRFUNC, err->message);
+            if (err)
+                g_error_free (err);
+            g_free (debug);
+            break;
+        }
+
+        case GST_MESSAGE_ERROR: 
+        {
+            GError *err = NULL;
+            gchar *debug = NULL;
+
+            gst_message_parse_error (message, &err, &debug);
+            ULOG_ERR("%s() - Error: %s", G_STRFUNC, err->message);
+            if (err)
+                g_error_free (err);
+            g_free (debug);
+            /* break; */
+            /* flow through to eos */
+        }
+
+        case GST_MESSAGE_EOS:
+        {
+            ULOG_INFO("%s() - eos", G_STRFUNC);
+
+             switch(getAppState(app))
+             {
+                 case APPSTATE_PLAYING:
+                    /* stop playback after a short break*/
+                    g_timeout_add(STOP_DELAY, (GSourceFunc)cbStopPlayback, data);
+                    //hildon_banner_show_information(GTK_WIDGET(app->mainView), NULL, RECORDER_MSG_STOPPED);       
+                    gtk_label_set_text(GTK_LABEL(app->mainViewData.stateEntry), 
+                         "");  
+
+                    break;
+
+                 case APPSTATE_RECORDING:
+                     gst_element_set_state(GST_ELEMENT(app->recPipeline), 
+                           GST_STATE_PAUSED);
+                     destroyPipeline(app, PIPELINE_REC);
+                     app->saved = FALSE;
+                     setAppState(data, APPSTATE_READY);
+                     break;
+
+                 case APPSTATE_READY:
+                 default:
+                    /* destroyPipelines(app); */
+                     break;
+             }
+             break;
+        }
+
+        case GST_MESSAGE_ASYNC_DONE:
+        case GST_MESSAGE_STATE_CHANGED: 
+        {
+            GstState old;
+            GstState new;
+            GstState pending;
+
+            gst_message_parse_state_changed(message, &old, &new, &pending);
+
+            pipelineStateChanged(NULL, old, new, pending, app);
+
+            break;
+        }
+
+        default:
+            /* unhandled message */
+            ULOG_WARN("%s() - Unhandled message, type = %d", G_STRFUNC, message->type);
+            break;
+    }
+
+    /* remove message from the queue */
+    return TRUE;
 }
 
 static void cbDestroy(GtkWidget* widget, GdkEvent *event, gpointer data)
@@ -643,8 +613,8 @@ static void cbDestroy(GtkWidget* widget, GdkEvent *event, gpointer data)
 
     app = (AppData *) data;
 
-    if (!closeFile(app))
-        return;
+    ULOG_DEBUG("delete_event");
+    closeFile(app);
 
     destroyPipelines(app);
     if (app->playPipeline)
@@ -658,29 +628,30 @@ static void cbDestroy(GtkWidget* widget, GdkEvent *event, gpointer data)
 
 static gboolean cbCheckPosition (AppData *data)
 {
-     GstFormat fmt = GST_FORMAT_TIME;
-     gint64 pos = 0, len = 0;
-     static gboolean lengthSet = FALSE;
-
-     g_assert(NULL != data);
-
-     /* get length */
-     if(!lengthSet && gst_element_query_duration(data->playPipeline, &fmt, &len))
-     {
-       if (len > 0)
-       {
-          gdouble size = 0;
-          size = GST_TIME_TO_SECS(len);
-          setLength(data, size); /* sets lengthEntry and adjustment */
-          lengthSet = TRUE;
-       }
-     }
-
-     /* calculate position */
+    GstFormat fmt = GST_FORMAT_TIME;
+    gint64 pos = 0, len = 0;
+
+    g_assert(NULL != data);
+
+    /* get length */
+    if(!lengthSet && gst_element_query_duration(data->playPipeline, &fmt, &len))
+    {
+        if (len > 0)
+        {
+            gdouble size = 0;
+            size = GST_TIME_TO_SECS(len);
+            setLength(data, size); /* sets lengthEntry and adjustment */
+            lengthSet = TRUE;
+        }
+    }
+
+    /* calculate position */
     if (gst_element_query_position(data->playPipeline, &fmt, &pos))
     {
         gdouble time = GST_TIME_TO_SECS(pos);
-      
+        guint mins = 0;
+        gchar* tmp;
+
         ULOG_DEBUG("pos = %lld, time = %f", 
              pos,
            time 
@@ -690,6 +661,18 @@ static gboolean cbCheckPosition (AppData *data)
            GTK_ADJUSTMENT(data->mainViewData.adjustment),
            time);
         gtk_adjustment_value_changed(GTK_ADJUSTMENT(data->mainViewData.adjustment));
+        if (time >= 60.0)
+        {
+            mins = time / 60;
+            time -= mins * 60.0;
+        }
+
+        tmp = g_strdup_printf("%02u:%02d", mins, (int)time);
+
+        gtk_label_set_text(GTK_LABEL(data->mainViewData.ctime),
+                 tmp);
+        g_free(tmp);
+
     }
 
     if (APPSTATE_PLAYING == getAppState(data))
@@ -708,7 +691,12 @@ static void cbNew(GtkWidget* widget, AppData *data)
         return;
 
     /* remove pipelines if existing */
-    destroyPipelines(data);
+    if (APPSTATE_PLAYING == getAppState(data) || APPSTATE_RECORDING == getAppState(data)) {
+        cbStop(widget, NULL, data);
+        destroyPipelines(data);
+    }
+
+    setAppState(data, APPSTATE_READY);
     ULOG_DEBUG_F("cbNew");
     /* destroy tmp file */
 
@@ -721,18 +709,16 @@ static void cbNew(GtkWidget* widget, AppData *data)
     data->file_format = FORMAT_NONE;
 
     /* update display */
-    gtk_entry_set_text(GTK_ENTRY(data->mainViewData.fileNameEntry), 
+    gtk_label_set_text(GTK_LABEL(data->mainViewData.fileNameEntry), 
         RECORDER_FILE_UNTITLED);
     setLength(data, 0.0);
     /* update the display + scale */
     gtk_adjustment_set_value(GTK_ADJUSTMENT(data->mainViewData.adjustment),
               0);
-    gtk_widget_set_sensitive(data->buttonSave, FALSE);
+    gtk_label_set_text(GTK_LABEL(data->mainViewData.ctime), "00:00");
     gtk_widget_set_sensitive(data->buttonSaveAs, FALSE);
     data->saved = TRUE;
 
-    gtk_window_set_title(GTK_WINDOW(data->mainView), RECORDER_FILE_UNTITLED);
-
     ULOG_DEBUG_F("cbNew end");
 }
 
@@ -753,6 +739,10 @@ static void cbOpen(GtkWidget* widget, AppData *data)
 
     if (!closeFile(data))
         return;
+    if (APPSTATE_PLAYING == getAppState(data) || APPSTATE_RECORDING == getAppState(data)) {
+        cbStop(widget, NULL, data);
+        destroyPipelines(data);
+    }
 
 #if 0
     /* create filter */
@@ -788,8 +778,15 @@ static void cbOpen(GtkWidget* widget, AppData *data)
         */
     }
 
-    if (NULL == selected) /* no file selected */
+    if (NULL == selected) 
+    { 
+        /* no file selected */
+        if (!g_file_test(getFileName(data), G_FILE_TEST_EXISTS))
+        {
+                cbNew(widget, data);
+        }
         return;
+    }
 
     ULOG_INFO("%s() - selected filename = '%s'", G_STRFUNC, selected);
 
@@ -802,14 +799,13 @@ static void cbOpen(GtkWidget* widget, AppData *data)
         /* update filenames */
         basename = g_path_get_basename(selected);
 
-        gtk_entry_set_text(GTK_ENTRY(data->mainViewData.fileNameEntry), selected);
-        gtk_window_set_title(GTK_WINDOW(data->mainView), basename);
+        gtk_label_set_text(GTK_LABEL(data->mainViewData.fileNameEntry), basename);
         g_free(basename);
 
         g_free(data->openFileName);
         data->openFileName = tmpfile;
         data->file_format = format;
-        data->filter = format;
+        //data->filter = format;
         g_free(data->saveFileName);
         data->saveFileName = NULL;
         gtk_widget_set_sensitive(data->buttonSaveAs, TRUE);
@@ -820,6 +816,7 @@ static void cbOpen(GtkWidget* widget, AppData *data)
         else
             setLength(data, 0.0);
 
+        setFormatString(data, data->file_format);
         data->saved = TRUE;
     }
     else
@@ -875,14 +872,13 @@ openURI(gpointer user_data)
         /* update filenames */
         basename = g_path_get_basename(selected);
         
-        gtk_entry_set_text(GTK_ENTRY(data->mainViewData.fileNameEntry), selected);
-        gtk_window_set_title(GTK_WINDOW(data->mainView), basename);
+        gtk_label_set_text(GTK_LABEL(data->mainViewData.fileNameEntry), basename);
         g_free(basename);
 
         g_free(data->openFileName);
         data->openFileName = tmpfile;
         data->file_format = format;
-        data->filter = format;
+        //data->filter = format;
         g_free(data->saveFileName);
         data->saveFileName = NULL;
         gtk_widget_set_sensitive(data->buttonSaveAs, TRUE);
@@ -893,6 +889,7 @@ openURI(gpointer user_data)
         else
             setLength(data, 0.0);
 
+        setFormatString(data, data->file_format);
         data->saved = TRUE;
     }
     else
@@ -910,40 +907,42 @@ static void openPlayPipeline( AppData *data )
 {
 
     GstFormat fmt = GST_FORMAT_TIME;
-      gint64 len;
-      gdouble size = 0;
-      /* create pipelines */
-      /* check file type */
-      switch (data->file_format)
-      {
-          case FORMAT_PCMA:
-          case FORMAT_PCMU:
-          case FORMAT_PCM:
-          case FORMAT_ILBC:
-          case FORMAT_WAV:
-              destroyPipelines(data);
-              data->filter = data->file_format;
-              createPipeline(data, PIPELINE_PLAY);
-              break;
-          case FORMAT_MP3:
-              destroyPipelines(data);
-              data->filter = data->file_format;
-              createPipeline(data, PIPELINE_PLAY_MP3);
-              break;
-          case FORMAT_NONE:
-          default:
-              ULOG_WARN("%s() - unknown file_format", G_STRFUNC);
-              hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Unknown filetype!"));
-              return;
-
-              break;
-      }
-      
-      if (!GST_IS_ELEMENT(data->playPipeline))
-      {
-          hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Could not create pipeline!"));
-          return;
-      }
+    gint64 len;
+    gdouble size = 0;
+    lengthSet = FALSE;
+    /* create pipelines */
+    /* check file type */
+    switch (data->file_format)
+    {
+        case FORMAT_PCMA:
+        case FORMAT_PCMU:
+        case FORMAT_PCM:
+        case FORMAT_ILBC:
+        case FORMAT_WAV:
+            //destroyPipelines(data);
+            //data->filter = data->file_format;
+            createPipeline(data, PIPELINE_PLAY);
+            break;
+
+        case FORMAT_MP3:
+            destroyPipelines(data);
+            //data->filter = data->file_format;
+            createPipeline(data, PIPELINE_PLAY_MP3);
+            break;
+
+        case FORMAT_NONE:
+        default:
+            ULOG_WARN("%s() - unknown file_format", G_STRFUNC);
+            hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Unknown filetype!"));
+            return;
+            break;
+    }
+
+    if (!GST_IS_ELEMENT(data->playPipeline))
+    {
+        hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Could not create pipeline!"));
+        return;
+    }
 
     gst_element_set_state(GST_ELEMENT(data->playPipeline), GST_STATE_READY);
     gst_element_get_state(GST_ELEMENT(data->playPipeline), NULL, NULL, GST_CLOCK_TIME_NONE /* or ns */);
@@ -958,13 +957,11 @@ static void openPlayPipeline( AppData *data )
             setLength(data, size);
         }
     }
-    /*
     else 
     {
-        ULOG_INFO("playSize else");
         setLength(data, 0.0);
     }
-    */
+    
 }
 
 /* returns whether the action can proceed or should be aborted */
@@ -980,7 +977,6 @@ closeFile(AppData *data)
     note = hildon_note_new_confirmation_add_buttons(GTK_WINDOW(data->mainView), _("Save recording?"),
             _("Yes"), GTK_RESPONSE_YES,
             _("No"), GTK_RESPONSE_NO,
-            _("Cancel"), GTK_RESPONSE_CANCEL,
             NULL);
 
     i = gtk_dialog_run(GTK_DIALOG(note));
@@ -992,6 +988,9 @@ closeFile(AppData *data)
             return FALSE;
 
         case GTK_RESPONSE_NO:
+            if (data->saveFileName)
+                g_unlink(data->saveFileName);
+            data->saved = TRUE;
             return TRUE;
 
         case GTK_RESPONSE_YES:
@@ -1004,78 +1003,48 @@ closeFile(AppData *data)
     }
     return FALSE;
 }
-     
-#if 0
-static void cbSave(GtkWidget* widget, AppData *data) 
+
+static const gchar *
+getFileName(AppData *data)
 {
-     GtkWidget* dialog = NULL;
-     const gchar *current;
-     gchar *selected = NULL;
-
-     g_assert(data);
-
-     ULOG_DEBUG("%s() - begin", G_STRFUNC);
-
-     current = gtk_entry_get_text(GTK_ENTRY(data->mainViewData.fileNameEntry));
-     if (NULL == current || strcmp(current, RECORDER_FILE_UNTITLED) == 0) 
-     {
-       hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Nothing to save"));
-       return;
-     }
-
-     /* if saveFileName does not exist run saveas */
-     if (NULL == data->saveFileName)
-     {
-      /* create dialog */
-      dialog = GTK_WIDGET(hildon_file_chooser_dialog_new(
-                   GTK_WINDOW(data->mainView), 
-                   GTK_FILE_CHOOSER_ACTION_SAVE));
-      
-      /* show it */
-      gtk_widget_show_all(dialog);
-      
-      if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) 
-      {
-           selected = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
-      }
-     
-      ULOG_DEBUG("%s() - dialog finished", G_STRFUNC);
-      
-      gtk_widget_destroy(dialog);
-      
-      if (NULL != selected)
-      {
-           ULOG_INFO("%s() - selected filename = '%s'", G_STRFUNC,
-            selected);
-           g_free(data->saveFileName);
-           data->saveFileName = g_strdup_printf("%s%s", selected, getExtension(data->file_format));
-           g_free(selected);
-           selected = NULL;
-      }
-      else
-      {
-           return;
-      }
-     }
-
-     /* save the file */
-     if (doSave(gtk_entry_get_text(GTK_ENTRY(data->mainViewData.fileNameEntry)), data->saveFileName, data->file_format))
-     {
-      gchar *basename = g_path_get_basename(data->saveFileName);
-      ULOG_INFO("%s() - file succesfully saved!", G_STRFUNC);
-      g_free(data->openFileName);
-      data->openFileName = g_strdup(data->saveFileName);
-            
-      gtk_entry_set_text(GTK_ENTRY(data->mainViewData.fileNameEntry), 
-                 data->saveFileName);
-      gtk_widget_set_sensitive(data->buttonSave, FALSE);
-      gtk_window_set_title(GTK_WINDOW(data->mainView), basename);
-      g_free(basename);
-     }
-     
-     ULOG_DEBUG("%s() - end", G_STRFUNC);
+    g_assert(data);
+    return gtk_label_get_text(GTK_LABEL(data->mainViewData.fileNameEntry));
+
+}
+
+static void cbSettings(GtkWidget* widget, AppData *data)
+{
+    settings_edit( widget, data );
+}
+
+static void cbEmailing(GtkWidget* widget, AppData *data)
+{
+
+    gboolean result;
+    GSList *list = NULL;    
+    gchar *file = NULL;
+
+    g_assert(NULL != data);
+    
+    if (g_file_test(data->openFileName, G_FILE_TEST_EXISTS))
+    {
+        file = file2uri(data->openFileName);
+        ULOG_INFO("Emailing: %s", file);
+        list = g_slist_append(list, file);
+        result = libmodest_dbus_client_compose_mail(data->osso,
+                NULL, /*to*/
+                NULL, /*cc*/
+                NULL, /*bcc*/
+                NULL, /*body*/
+                NULL, /*subj*/
+                list);
+        if (!result)
+            hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Emailing failed"));
+
+        g_slist_free(list);
+        g_free(file);
+    }
 }
-#endif
 
 static void cbSaveAs(GtkWidget* widget, AppData *data) 
 {
@@ -1087,7 +1056,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"));
@@ -1099,6 +1068,9 @@ static void cbSaveAs(GtkWidget* widget, AppData *data)
               GTK_WINDOW(data->mainView), 
               GTK_FILE_CHOOSER_ACTION_SAVE));
 
+    gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), 
+            get_default_dir() );
+
     /* show it */
     gtk_widget_show_all(dialog);
 
@@ -1129,8 +1101,6 @@ static void cbSaveAs(GtkWidget* widget, AppData *data)
         basename = g_path_get_basename(data->saveFileName);
         ULOG_DEBUG("%s() - file '%s' succesfully saved!", G_STRFUNC, data->saveFileName);
 
-        gtk_window_set_title(GTK_WINDOW(data->mainView), basename);
-
         /* Houston, we have a kludge:
          * for AU files we need to keep the old tmpfile for playback
          * for RAW/iLBC files, we can remove the tmpfile and point openFileName to the saved file
@@ -1142,8 +1112,8 @@ static void cbSaveAs(GtkWidget* widget, AppData *data)
             data->openFileName = g_strdup(data->saveFileName);
         }
 
-        gtk_entry_set_text(GTK_ENTRY(data->mainViewData.fileNameEntry), 
-                 data->saveFileName);
+        gtk_label_set_text(GTK_LABEL(data->mainViewData.fileNameEntry), 
+                 basename);
         
         g_free(basename);
         data->saved = TRUE;
@@ -1159,87 +1129,121 @@ static void cbSaveAs(GtkWidget* widget, AppData *data)
     ULOG_DEBUG("%s() - end", G_STRFUNC);
 }
 
-static void cbRec(GtkWidget* widget, AppData *data) 
+static void cbRec(GtkWidget* widget, GdkEventButton *event, AppData *data) 
 {
-     g_assert(NULL != data);
-
-     ULOG_DEBUG("%s() - begin", G_STRFUNC);     
+    g_assert(NULL != data);
 
-     if (APPSTATE_READY != getAppState(data))
-     {
-      ULOG_WARN("%s() - state different than READY -> return", G_STRFUNC);
-      return;
-     }
+    ULOG_DEBUG("%s() - begin", G_STRFUNC);     
 
-     if (!closeFile(data))
+    if (APPSTATE_RECORDING == getAppState(data))
+    {
+         if (GST_IS_ELEMENT(data->recPipeline))
+         {
+             gst_element_set_state(GST_ELEMENT(data->recPipeline), GST_STATE_PAUSED);
+             gtk_label_set_text(GTK_LABEL(data->mainViewData.stateEntry),
+                                              RECORDER_MSG_PAUSED);
+             hildon_banner_show_information(GTK_WIDGET(data->mainView), NULL, RECORDER_MSG_PAUSED);
+             setAppState(data, APPSTATE_PAUSED);
+         }
          return;
+    }
+
+    if (APPSTATE_PAUSED == getAppState(data)) 
+    {
+         if (GST_IS_ELEMENT(data->recPipeline))
+         {
+             gst_element_set_state(GST_ELEMENT(data->recPipeline),
+                           GST_STATE_PLAYING);
+             setAppState(data, APPSTATE_RECORDING);
+             return;
+         }
+    }
+
+    if (APPSTATE_READY != getAppState(data))
+    {
+        ULOG_WARN("%s() - state different than READY -> return", G_STRFUNC);
+        if (APPSTATE_RECORDING == getAppState(data))
+            cbStop(widget, NULL,data);
+        return;
+    }
 
-     /* clear filenames, use tmp file */
-     g_free(data->openFileName);
-     data->openFileName = NULL;
+    if (!closeFile(data))
+     return;
 
-     g_free(data->saveFileName);
-     data->saveFileName = NULL;     
-    
-     switch (data->filter)
-     {
-         case FORMAT_PCM:
-             data->saveFileName = g_strdup(DEFAULT_TMP_FILE);
-             data->openFileName = g_strdup(DEFAULT_TMP_FILE);
+    /* clear filenames, use tmp file */
+    g_free(data->openFileName);
+    data->openFileName = NULL;
+
+    g_free(data->saveFileName);
+    data->saveFileName = NULL;     
+
+    switch (data->filter)
+    {
+        case FORMAT_PCM:
+             data->saveFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_FILE);
+             data->openFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_FILE);
              break;
 
          case FORMAT_PCMA:
-             data->saveFileName = g_strdup(DEFAULT_TMP_PCMA_FILE);
-             data->openFileName = g_strdup(DEFAULT_TMP_PCMA_FILE);
+             data->saveFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_PCMA_FILE);
+             data->openFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_PCMA_FILE);
              break;
              
          case FORMAT_PCMU:
-             data->saveFileName = g_strdup(DEFAULT_TMP_PCMU_FILE);
-             data->openFileName = g_strdup(DEFAULT_TMP_PCMU_FILE);
+             data->saveFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_PCMU_FILE);
+             data->openFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_PCMU_FILE);
              break;
 
          case FORMAT_WAV:
-             data->saveFileName = g_strdup(DEFAULT_TMP_WAV_FILE);
-             data->openFileName = g_strdup(DEFAULT_TMP_WAV_FILE);
+             data->saveFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_WAV_FILE);
+             data->openFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_WAV_FILE);
              break;
 
          case FORMAT_ILBC:
          default:
-             data->saveFileName = g_strdup(DEFAULT_TMP_ILBC_FILE);
-             data->openFileName = g_strdup(DEFAULT_TMP_ILBC_FILE);
-             break;
-     }
-     
-     ULOG_INFO("%s() - creating pipelines", G_STRFUNC);
-     /* start recording */
-     /* create related pipelines */
-     if (createPipeline(data, PIPELINE_REC))
-     {
-         ULOG_INFO("%s() - starting recording", G_STRFUNC);
-         /* start recording */
-         gst_element_set_state(GST_ELEMENT(data->recPipeline), 
-                               GST_STATE_PLAYING);
-
-         /* update display */
-         gtk_entry_set_text(GTK_ENTRY(data->mainViewData.fileNameEntry), 
-                data->saveFileName);
-
-         setAppState(data, APPSTATE_RECORDING);
-         gtk_widget_set_sensitive(data->buttonSaveAs, TRUE);
-         gtk_window_set_title(GTK_WINDOW(data->mainView), RECORDER_FILE_UNTITLED);
-         data->file_format = data->filter;
-     }
-     else
-     {
-       ULOG_ERR("Could not create rec pipeline!");
-       hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Could not create pipeline"));
-       setAppState(data, APPSTATE_READY);
-     }
-     
-     ULOG_DEBUG("%s() - end", G_STRFUNC);     
+             data->saveFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_ILBC_FILE);
+             data->openFileName = g_strdup_printf("%s/%s", DEFAULT_TMP_DIR, DEFAULT_TMP_ILBC_FILE);
+            break;
+    }
+
+    g_mkdir(DEFAULT_TMP_DIR, 755);
+    
+    ULOG_INFO("%s() - creating pipelines", G_STRFUNC);
+    /* start recording */
+    /* create related pipelines */
+    if (createPipeline(data, PIPELINE_REC))
+    {
+        ULOG_INFO("%s() - starting recording", G_STRFUNC);
+        gchar *basename;
+        /* start recording */
+        data->rectime = 0;
+        gst_element_set_state(GST_ELEMENT(data->recPipeline), 
+                           GST_STATE_PLAYING);
+
+        /* update display */
+        basename = g_path_get_basename(data->saveFileName);
+        gtk_label_set_text(GTK_LABEL(data->mainViewData.fileNameEntry), 
+            basename);
+        g_free(basename);
+
+        setAppState(data, APPSTATE_RECORDING);
+        gtk_widget_set_sensitive(data->buttonSaveAs, TRUE);
+        data->file_format = data->filter;
+        setFormatString(data, data->file_format);
+    }
+    else
+    {
+        ULOG_ERR("Could not create rec pipeline!");
+        hildon_banner_show_information(GTK_WIDGET(data->mainView), GTK_STOCK_DIALOG_ERROR, _("Could not create pipeline"));
+        setAppState(data, APPSTATE_READY);
+    }
+
+    gtk_widget_set_sensitive(data->buttonPlay, FALSE);
+
+    ULOG_DEBUG("%s() - end", G_STRFUNC);     
 }
 
-static void cbPlay(GtkWidget* widget, AppData *data) 
+static void cbPlay(GtkWidget* widget, GdkEventButton *event, AppData *data) 
 {
     const gchar * file = NULL;
      
@@ -1247,26 +1251,29 @@ 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);
         return;
     }
 
-    openPlayPipeline(data);
-     
     if (APPSTATE_PLAYING == getAppState(data))
     {
          if (GST_IS_ELEMENT(data->playPipeline)) 
          {
              gst_element_set_state(GST_ELEMENT(data->playPipeline), GST_STATE_PAUSED);
-             setAppState(data, APPSTATE_READY);
+             setAppState(data, APPSTATE_PAUSED);
          }
          return;
     }
 
-    if (APPSTATE_READY != getAppState(data))
+    if (APPSTATE_PAUSED != getAppState(data)) {
+        openPlayPipeline(data);
+        setAppState(data, APPSTATE_READY);
+    }
+    
+    if (APPSTATE_READY != getAppState(data) && APPSTATE_PAUSED != getAppState(data))
     {
         ULOG_WARN("%s() - state different than PLAYING or READY -> return", G_STRFUNC);
         return;
@@ -1274,18 +1281,6 @@ static void cbPlay(GtkWidget* widget, AppData *data)
 
     ULOG_INFO("filename %s", file);
      
-    /*openPlayPipeline( data );*/
-     
-    /*if ( ! GST_IS_ELEMENT(data->playPipeline) ) 
-    {
-        if (g_strrstr(data->openFileName, EXTENSION_RAW))
-        {
-             ULOG_INFO("cbOpen() - file was raw, assuming audio/x-raw-int, 8kHz, 1 ch, 16-bit");
-             destroyPipelines(data);
-             createPipeline(data, PIPELINE_PLAY);      
-        }
-    }*/
-     
     if (! GST_IS_ELEMENT(data->playPipeline))
     {
         ULOG_WARN("%s() - playPipeline does not exist", G_STRFUNC);
@@ -1299,10 +1294,12 @@ static void cbPlay(GtkWidget* widget, AppData *data)
 
     g_timeout_add(PLAY_UPDATE_INTERVAL, (GSourceFunc)cbCheckPosition, data);
 
+    gtk_widget_set_sensitive(data->buttonRec, FALSE);
+
     ULOG_DEBUG("%s() - end", G_STRFUNC);
 }
 
-static void cbStop(GtkWidget* widget, AppData *data) 
+static void cbStop(GtkWidget* widget, GdkEventButton *event, AppData *data) 
 {
     g_assert(NULL != data);
 
@@ -1310,20 +1307,11 @@ static void cbStop(GtkWidget* widget, AppData *data)
 
     /* check if we are playing/recording */
 
-    /*
-    if (APPSTATE_PLAYING != getAppState(data) &&
-    APPSTATE_RECORDING != getAppState(data))
-    {
-      ULOG_WARN("cbStop() - state different than PLAYING or RECORDING "
-          "-> return");
-      return;
-    } 
-    */
-
     /* stop playing or recording */
-    gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(data->buttonPlay), GTK_STOCK_MEDIA_PLAY);
     gtk_widget_set_state(data->buttonPlay, GTK_STATE_NORMAL);
     gtk_widget_set_state(data->buttonRec, GTK_STATE_NORMAL);
+    gtk_widget_set_sensitive(data->buttonPlay, TRUE);
+    gtk_widget_set_sensitive(data->buttonRec, TRUE);
 
     /* destroy related pipeline */
     switch(getAppState(data))
@@ -1334,7 +1322,9 @@ static void cbStop(GtkWidget* widget, AppData *data)
             ULOG_INFO("%s() - Setting playPipeline state to PAUSED", G_STRFUNC);
             gst_element_set_state(GST_ELEMENT(data->playPipeline), 
                      GST_STATE_PAUSED);
+            setAppState(data, APPSTATE_READY);
             /* flow through */
+        case APPSTATE_PAUSED:
         case APPSTATE_READY:
             /* seek to zero, but not for PCM pipeline */
             /* if (data->playPipelineType == PIPELINE_PLAY || seekToZero(data, GST_ELEMENT(data->playPipeline))) */
@@ -1343,16 +1333,17 @@ static void cbStop(GtkWidget* widget, AppData *data)
               gtk_adjustment_set_value( 
                    GTK_ADJUSTMENT(data->mainViewData.adjustment), 0);
               gtk_adjustment_value_changed(GTK_ADJUSTMENT(data->mainViewData.adjustment));
-              gtk_entry_set_text(GTK_ENTRY(data->mainViewData.stateEntry), 
-                         RECORDER_MSG_STOPPED);  
+              gtk_label_set_text(GTK_LABEL(data->mainViewData.ctime), "00:00");
+              gtk_label_set_text(GTK_LABEL(data->mainViewData.stateEntry), 
+                         "");  
             }
             break;
+
         case APPSTATE_RECORDING:
         {
             gdouble len = -1.0;
-            gst_element_set_state(GST_ELEMENT(data->recPipeline), 
-                 GST_STATE_PAUSED);
-            destroyPipeline(data, PIPELINE_REC);
+            gst_element_send_event(GST_ELEMENT(data->recPipeline),
+                 gst_event_new_eos());
             gtk_widget_set_sensitive(data->buttonSaveAs, TRUE);
             data->saved = FALSE;
 
@@ -1369,91 +1360,12 @@ static void cbStop(GtkWidget* widget, AppData *data)
             break;
     }
 
-    setAppState(data, APPSTATE_READY);
-
     ULOG_DEBUG("%s() - end", G_STRFUNC); 
 }
 
 
 /* ui construction functions */
 
-static GtkWidget* createToolBar(AppData *data)
-{
-     GtkToolbar* toolBar = NULL;
-     
-     GtkToolItem* new = NULL;
-     GtkToolItem* open = NULL;
-     GtkToolItem* save = NULL;
-     GtkToolItem* saveas = NULL;
-     GtkToolItem* sep = NULL;
-     GtkToolItem* play = NULL;
-     GtkToolItem* rec = NULL;
-     GtkToolItem* stop = NULL;
-     
-     /* create buttons */
-     new = gtk_tool_button_new_from_stock(GTK_STOCK_NEW); 
-     open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN); 
-     save = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
-     data->buttonSave = GTK_WIDGET(save);
-     saveas = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE_AS);
-     data->buttonSaveAs = GTK_WIDGET(saveas);
-     gtk_widget_set_sensitive(data->buttonSave, FALSE);
-     gtk_widget_set_sensitive(data->buttonSaveAs, FALSE);
-     data->saved = 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);
-     
-     /* create separator */
-     sep  = gtk_separator_tool_item_new();
-
-     /* create the toolbar itself */
-     toolBar = GTK_TOOLBAR(gtk_toolbar_new());
-
-     /* add items to toolbar */
-     gtk_toolbar_insert(toolBar, new, -1);
-     gtk_toolbar_insert(toolBar, open, -1);
-     /*
-     gtk_toolbar_insert(toolBar, save, -1);
-     */
-     gtk_toolbar_insert(toolBar, saveas, -1);
-     gtk_toolbar_insert(toolBar, sep,  -1);
-     gtk_toolbar_insert(toolBar, rec, -1);
-     gtk_toolbar_insert(toolBar, play, -1);
-     gtk_toolbar_insert(toolBar, stop, -1);
-
-     /* connect signals */
-     g_signal_connect(G_OBJECT(new), "clicked",
-              G_CALLBACK(cbNew), 
-              data);
-     g_signal_connect(G_OBJECT(open), "clicked",
-              G_CALLBACK(cbOpen), 
-              data);
-     /*
-     g_signal_connect(G_OBJECT(save), "clicked",
-              G_CALLBACK(cbSave), 
-              data);
-     */
-     g_signal_connect(G_OBJECT(saveas), "clicked",
-              G_CALLBACK(cbSaveAs), 
-              data);
-     g_signal_connect(G_OBJECT(rec), "clicked",
-              G_CALLBACK(cbRec), 
-              data);
-     g_signal_connect(G_OBJECT(play), "clicked",
-              G_CALLBACK(cbPlay), 
-              data);
-     g_signal_connect(G_OBJECT(stop), "clicked",
-              G_CALLBACK(cbStop), 
-              data);
-
-     return GTK_WIDGET(toolBar);
-
-}
-
 static void cbItemGroupChanged( gpointer data )
 {
     AppData* app = (AppData* ) data;
@@ -1482,123 +1394,111 @@ static void cbItemGroupChanged( gpointer data )
     ULOG_INFO("filter type=%d", app->filter);
 }
 
-static void cbItemClose(GtkWidget *widget, gpointer data)
+/* Create the menu items needed for the main view */
+static void createMenu( AppData *data )
 {
-    g_assert(data);
+    HildonAppMenu *menu;
+    GtkWidget *button_new;
+    GtkWidget *button_open;
+    GtkWidget *button_save;
+    GtkWidget *button_email;
+
+    menu = HILDON_APP_MENU( hildon_app_menu_new() );
+    button_new = hildon_gtk_button_new(HILDON_SIZE_AUTO);
+    gtk_button_set_label( GTK_BUTTON(button_new), "New");
+    button_open = hildon_gtk_button_new(HILDON_SIZE_AUTO);
+    gtk_button_set_label( GTK_BUTTON(button_open), "Open");
+    button_save = hildon_gtk_button_new(HILDON_SIZE_AUTO);
+    data->buttonSaveAs = button_save;
+    gtk_widget_set_sensitive(data->buttonSaveAs, FALSE);
+    gtk_button_set_label( GTK_BUTTON(button_save), "Save");
+    button_email = hildon_gtk_button_new(HILDON_SIZE_AUTO);
+    gtk_button_set_label( GTK_BUTTON(button_email), "Send via email");
+
+    hildon_app_menu_append( menu, GTK_BUTTON(button_new));
+    hildon_app_menu_append( menu, GTK_BUTTON(button_open));
+    hildon_app_menu_append( menu, GTK_BUTTON(button_save));
+    hildon_app_menu_append( menu, GTK_BUTTON(button_email));
+    g_signal_connect(G_OBJECT(button_new), "clicked",
+              G_CALLBACK(cbNew),
+              data);
+    g_signal_connect(G_OBJECT(button_open), "clicked",
+              G_CALLBACK(cbOpen),
+              data);
+    g_signal_connect(G_OBJECT(button_save), "clicked",
+              G_CALLBACK(cbSaveAs),
+              data); 
+    g_signal_connect( G_OBJECT( button_email ), "clicked",
+        GTK_SIGNAL_FUNC (cbEmailing), data);
+    
+    gtk_widget_show_all( GTK_WIDGET(menu));
 
-    if (!closeFile(data))
-        return;
+    hildon_window_set_app_menu(HILDON_WINDOW(data->mainView), menu);
+
+    data->filter = get_default_filter();
+
+    setFormatString(data, data->filter);
 
-    gtk_main_quit();
 }
 
-/* Create the menu items needed for the main view */
-static void createMenu( AppData *data )
+static gboolean
+cbScaleRelease(GtkWidget *widget, GdkEventButton *ev, gpointer data)
 {
-    /* Create needed variables */
-    GSList *group = NULL;
-    GtkMenu *main_menu;
-    GtkWidget *menu_file;
-    GtkWidget *menu_others;
-    GtkWidget *item_file;
-    GtkWidget *item_file_open;
-    GtkWidget *item_file_save_as;
-    GtkWidget *item_others;
-    GtkWidget *item_pcma;
-    GtkWidget *item_pcmu;
-    GtkWidget *item_ilbc;
-    GtkWidget *item_pcm;
-   
-    /*
-    GtkWidget *item_radio_type1;
-    */
-    GtkWidget *item_close;
-    GtkWidget *item_separator;
+    AppData* app = (AppData* ) data;
+  
+    if (getAppState(app) == APPSTATE_RECORDING || NULL == app->playPipeline)
+        return FALSE;
 
-    /* Get the menu from view */
-    main_menu = GTK_MENU(gtk_menu_new());
-    hildon_window_set_menu(data->mainView, main_menu);
-    
-    /* Create new submenu for "Others" */
-    menu_file = gtk_menu_new ();
-    menu_others = gtk_menu_new ();
-
-    /* Create menu items */
-    item_file = gtk_menu_item_new_with_label (_("File"));
-    item_file_open = gtk_menu_item_new_with_label(_("Open..."));
-    item_file_save_as = gtk_menu_item_new_with_label(_("Save as..."));
-    item_others = gtk_menu_item_new_with_label (_("Recording format"));
-    
-    item_pcma = gtk_radio_menu_item_new_with_label(
-        group, "PCM A-law");
-    item_ilbc = gtk_radio_menu_item_new_with_label_from_widget(
-        GTK_RADIO_MENU_ITEM(item_pcma), "iLBC");
-    item_pcmu = gtk_radio_menu_item_new_with_label_from_widget(
-        GTK_RADIO_MENU_ITEM(item_pcma), "PCM u-law");
-    item_pcm = gtk_radio_menu_item_new_with_label_from_widget(
-        GTK_RADIO_MENU_ITEM(item_pcma), "WAV");
-    
-    /* default is iLBC */
-    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_ilbc), TRUE); 
-    data->filter = FORMAT_ILBC;
+    seekToTime(app->playPipeline, gtk_adjustment_get_value(GTK_ADJUSTMENT(app->mainViewData.adjustment)));
+  
+    return FALSE;
 
-    data->radio_pcma = item_pcma;
-    data->radio_ilbc = item_ilbc;
-    data->radio_pcm = item_pcm;        
-    /*
-    data->radiotype = item_radio_type1;
-    */
-    item_close = gtk_menu_item_new_with_label(_("Close"));
-    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_close );
-
-    /* Add others submenu to the "Others" item */
-    gtk_menu_item_set_submenu(
-        GTK_MENU_ITEM(item_file), menu_file );
-    gtk_menu_item_set_submenu(
-        GTK_MENU_ITEM(item_others), menu_others );
-
-    /* Attach the callback functions to the activate signal */
-    g_signal_connect( G_OBJECT( item_file_open), "activate",
-        GTK_SIGNAL_FUNC (cbOpen), data);
-    g_signal_connect( G_OBJECT( item_file_save_as), "activate",
-        GTK_SIGNAL_FUNC (cbSaveAs), data);
-    g_signal_connect( G_OBJECT( item_close ), "activate",
-        GTK_SIGNAL_FUNC (cbItemClose), data);
-
-    g_signal_connect_swapped(G_OBJECT(item_pcma), "activate", G_CALLBACK(cbItemGroupChanged), data);
-    g_signal_connect_swapped(G_OBJECT(item_pcm), "activate", G_CALLBACK(cbItemGroupChanged), data);
-    
-    /* Make all menu widgets visible */
+}
 
-    gtk_widget_show_all( GTK_WIDGET( main_menu ) );
+static gboolean
+evKeypress(GtkWidget *widget, GdkEventKey *ev, AppData *appdata)
+{
+
+  switch (ev->keyval)
+  {
+    case GDK_Return:
+      cbRec(widget, NULL, appdata);
+      return TRUE;
+    case GDK_Right:
+      cbPlay(widget, NULL, appdata);
+      return TRUE;
+    case GDK_Escape:
+      cbStop(widget, NULL, appdata);
+      return TRUE;
+    default:
+      break;
+  }
+
+  return FALSE;
 }
 
+
 gboolean maemo_recorder_ui_new(AppData *data)
 {
     HildonProgram *app = NULL;
     HildonWindow *window = NULL;
     GtkWidget *hbox = NULL;
-    GtkWidget *vbox = NULL;
-    GtkWidget *label = NULL;
-    GtkWidget *entry1 = NULL;
-    GtkWidget *entry2 = NULL;
-    GtkWidget *entry3 = NULL;
-    GtkWidget *toolBar = NULL;
+    GtkWidget *ctime = NULL;
+    GtkWidget *etime = NULL;
+    GtkWidget *filename = NULL;
+    GtkWidget *format = NULL;
+    GtkWidget *state = NULL;
     GtkWidget *table = NULL;
     GtkWidget *scale = NULL;
     GtkObject *adjustment = NULL;
 
+    GtkWidget *rec = NULL;
+    GtkWidget *play = NULL;
+    GtkWidget *stop = NULL;
+    GtkWidget *recimage = NULL;
+    GtkWidget *playimage = NULL;
+    GtkWidget *stopimage = NULL;
+
     g_assert(NULL != data);
 
     app = HILDON_PROGRAM(hildon_program_get_instance());
@@ -1611,55 +1511,21 @@ gboolean maemo_recorder_ui_new(AppData *data)
 
     /* content for main view */
 
-    /* create vbox, divides control area and view area */
-    vbox = gtk_vbox_new(FALSE, 0);
-
     /* create hbox to divide control area */
     hbox = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
 
     /* create toolbar */
-    toolBar = createToolBar(data);
 
     /* create table for labels */
-    table = gtk_table_new (4, 3, FALSE);
-    gtk_table_set_homogeneous(GTK_TABLE(table), FALSE);
+    table = gtk_table_new (6, 6, TRUE);
+    gtk_table_set_homogeneous(GTK_TABLE(table), TRUE);
 
     gtk_table_set_row_spacings (GTK_TABLE (table), 4);
-    gtk_table_set_col_spacings (GTK_TABLE (table), 0);
-
-    label = gtk_label_new_with_mnemonic(_("Filename:"));
-    gtk_table_attach_defaults (GTK_TABLE (table),
-            label,
-            0, 1, 0, 1);
-
-    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);
-
-    label = gtk_label_new_with_mnemonic (_("Length:"));
-    gtk_table_attach_defaults (GTK_TABLE (table),
-            label,
-            0, 1, 1, 2);
-
-    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_label_set_mnemonic_widget (GTK_LABEL (label), entry2);
-
-    label = gtk_label_new_with_mnemonic (_("State:"));
-    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_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_table_set_col_spacings (GTK_TABLE (table), HILDON_MARGIN_TRIPLE);
 
+    filename = gtk_label_new(_(RECORDER_FILE_UNTITLED));
+    format = gtk_label_new(RECORDER_FMT_STRING_NONE);
+    state = gtk_label_new("");
     adjustment = gtk_adjustment_new (0.00,
                   0.00,
                   100.00,
@@ -1667,37 +1533,73 @@ gboolean maemo_recorder_ui_new(AppData *data)
                   0.01,
                   0);
 
+    ctime = gtk_label_new("00:00");
+    etime = gtk_label_new("00:00");
     scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
+    gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
+    gtk_box_pack_start(GTK_BOX(hbox), ctime, FALSE, FALSE, HILDON_MARGIN_DOUBLE);
+    gtk_box_pack_end(GTK_BOX(hbox), etime, FALSE, FALSE, HILDON_MARGIN_DOUBLE);
+    gtk_box_pack_end(GTK_BOX(hbox), scale, TRUE, TRUE, HILDON_MARGIN_DOUBLE);
+    gtk_box_set_homogeneous(GTK_BOX(hbox), FALSE);
       
-/*     gtk_table_attach_defaults (GTK_TABLE (table),
-                label,
-                0, 3, 2, 3);
-*/
+    gtk_table_attach_defaults(GTK_TABLE(table), filename,
+                    1, 4, 1, 2);
+    gtk_table_attach_defaults(GTK_TABLE(table), format,
+                    1, 4, 2, 3);
+    gtk_table_attach_defaults(GTK_TABLE(table), state,
+                    1, 4, 3, 4);
+    gtk_table_attach_defaults(GTK_TABLE(table), hbox,
+                    0, 5, 5, 6);
+
+
+    recimage = gtk_image_new_from_file(REC_ICON);
+    rec = gtk_event_box_new();
+    data->buttonRec = GTK_WIDGET(rec);
+    gtk_container_add(GTK_CONTAINER(rec), recimage);
+    playimage = gtk_image_new_from_file(PLAY_ICON);
+    play = gtk_event_box_new();
+    data->buttonPlay = GTK_WIDGET(play);
+    gtk_container_add(GTK_CONTAINER(play), playimage);
+    stopimage = gtk_image_new_from_file(STOP_ICON);
+    stop = gtk_event_box_new();
+    gtk_container_add(GTK_CONTAINER(stop), stopimage);
+
+    gtk_table_attach_defaults(GTK_TABLE(table), rec,
+                    5, 6, 4, 6);
+    gtk_table_attach_defaults(GTK_TABLE(table), play,
+                    5, 6, 2, 4);
+    gtk_table_attach_defaults(GTK_TABLE(table), stop,
+                    5, 6, 0, 2);
+
+
     /* connect signals */
-    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(scale), "button-release-event", G_CALLBACK(cbScaleRelease), 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);
-    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)); 
+     g_signal_connect(G_OBJECT(rec), "button-release-event",
+              G_CALLBACK(cbRec),
+              data);
+     g_signal_connect(G_OBJECT(play), "button-release-event",
+              G_CALLBACK(cbPlay),
+              data);
+     g_signal_connect(G_OBJECT(stop), "button-release-event",
+              G_CALLBACK(cbStop),
+              data);
 
-    /* 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);
 
+    /* packing the view */
+    gtk_container_add(GTK_CONTAINER(window), table);
+    
     /* store needed widgets */
     data->app = app;
     data->mainView = window;
-    data->mainViewData.toolBar = GTK_WIDGET(toolBar);
-    data->mainViewData.fileNameEntry = GTK_WIDGET(entry1);
-    data->mainViewData.lengthEntry = GTK_WIDGET(entry2);
-    data->mainViewData.stateEntry = GTK_WIDGET(entry3);
+    data->mainViewData.fileNameEntry = GTK_WIDGET(filename);
+    data->mainViewData.formatEntry = GTK_WIDGET(format);
+    data->mainViewData.lengthEntry = GTK_WIDGET(etime);
+    data->mainViewData.ctime = GTK_WIDGET(ctime);
+    data->mainViewData.stateEntry = GTK_WIDGET(state);
     data->mainViewData.adjustment = GTK_OBJECT(adjustment);
 
     /* show the app */
@@ -1749,6 +1651,7 @@ static void seekToTime(GstElement *pipeline, gdouble secs)
 
 static gboolean seekToZero(AppData *data, GstElement *pipeline)
 {
+    gint plType;
     g_assert(NULL != pipeline);
     ULOG_DEBUG("Seeking to zero");
 
@@ -1758,7 +1661,7 @@ static gboolean seekToZero(AppData *data, GstElement *pipeline)
             GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
     {
         ULOG_ERR("seekToZero failed! Trying to destroy and re-create pipeline");
-        gint plType = data->playPipelineType;
+        plType = data->playPipelineType;
 
         /* gst_element_set_state(pipeline, GST_STATE_READY); */
         destroyPipeline(data, plType);
@@ -1769,6 +1672,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_LABEL(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_label_set_text(GTK_LABEL(data->mainViewData.formatEntry), RECORDER_FMT_STRING_NONE);
+            return;
+    }
+
+    str = g_strdup_printf("%s, %d %s, %d kHz, %d %s", format, channels, _("ch"), rate/1000, bits, _("bits"));
+    gtk_label_set_text(GTK_LABEL(data->mainViewData.formatEntry), str);
+    g_free(str);
+}
+
 static void setLength(AppData *data, gdouble secs)
 {
     guint mins = 0;
@@ -1779,10 +1728,10 @@ static void setLength(AppData *data, gdouble secs)
 
     if (secs > 0)
     {
-      g_object_set (G_OBJECT (data->mainViewData.adjustment), 
+        g_object_set(G_OBJECT(data->mainViewData.adjustment), 
             "upper", secs, 
             NULL);    
-      gtk_adjustment_changed(GTK_ADJUSTMENT(data->mainViewData.adjustment));
+        gtk_adjustment_changed(GTK_ADJUSTMENT(data->mainViewData.adjustment));
     }
 
     if (secs >= 60.0)
@@ -1791,12 +1740,12 @@ static void setLength(AppData *data, gdouble secs)
         secs -= mins * 60.0;
     }
 
-    tmp = g_strdup_printf("%u:%05.2f", mins, secs);
+    tmp = g_strdup_printf("%02u:%02d", mins, (int)secs);
 
     /*
     ULOG_INFO("Setting length to %s", tmp);
     */
-    gtk_entry_set_text(GTK_ENTRY(data->mainViewData.lengthEntry), 
+    gtk_label_set_text(GTK_LABEL(data->mainViewData.lengthEntry), 
                  tmp);
     g_free(tmp);
 }
@@ -1820,7 +1769,7 @@ static gdouble guessMediaLength(AppData *data)
     switch (data->file_format)
     {
         case FORMAT_ILBC:
-            bitrate = ILBC_BITRATE_20;
+            bitrate = ILBC_BITRATE_30;
             break; 
             
         case FORMAT_PCMA:
@@ -1831,6 +1780,7 @@ static gdouble guessMediaLength(AppData *data)
         default:
             return -1.0;
     }
+
     if (bitrate == 0.0)
         return -1.0;
 
@@ -1849,7 +1799,7 @@ static GstCaps *createCapsFilter(AudioFormat format)
                 GST_TYPE_ILBC,
                 "rate", G_TYPE_INT, ILBC_RATE,
                 "channels", G_TYPE_INT, DEFAULT_CHANNELS,
-                "mode", G_TYPE_INT, 20, /* 20 ms frames */
+                "mode", G_TYPE_INT, 30, /* 30 ms frames */
                 NULL);
         case FORMAT_PCMA:
             return gst_caps_new_simple(
@@ -1882,79 +1832,29 @@ static GstCaps *createCapsFilter(AudioFormat format)
 
 static gboolean cbStopPlayback(AppData *data)
 {
-    gint ret;
     ULOG_INFO("Stopping playback");
    
     g_assert(data != NULL);
-
-    ret = gst_element_set_state(GST_ELEMENT(data->playPipeline), 
-                        GST_STATE_PAUSED);
-    if (seekToZero(data, GST_ELEMENT(data->playPipeline)))
-    {
-      gtk_adjustment_set_value( 
-           GTK_ADJUSTMENT(data->mainViewData.adjustment), 0);
-      gtk_adjustment_value_changed(GTK_ADJUSTMENT(data->mainViewData.adjustment));
-    }
+    destroyPipelines(data);
     setAppState(data, APPSTATE_READY);
-    gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(data->buttonPlay), GTK_STOCK_MEDIA_PLAY);
     gtk_widget_set_state(data->buttonPlay, GTK_STATE_NORMAL);
 
     return FALSE;
 }
 
-static void cbUserSeek(GtkAdjustment *adjustment, gpointer data)
-{   
-    /*ULOG_INFO("cbUserSeek");*/
-    AppData *app;
-
-    g_return_if_fail(data != NULL);
-    app = (AppData *) data;
-
-    if (getAppState(app) != APPSTATE_READY || NULL == app->playPipeline)
-        return;
-
-    seekToTime(app->playPipeline, gtk_adjustment_get_value(adjustment));
-}
-
-static gchar *cbFormatSeekbarValue(GtkScale *scale, gdouble value)
-{
-/*    ULOG_INFO("cbFormatSeekbarValue");*/
-    gint mins = 0;
-    gint digits = gtk_scale_get_digits(scale);
-
-    if (value >= 60.0)
-    {
-        mins = value / 60;
-        value -= mins * 60.0;
-        return g_strdup_printf("%d:%0*.*f", mins, digits + 3, digits, value);
-    }
-    /* mins:sec.frac */
-    return g_strdup_printf("%0.*f", digits, value);
-}
-
 static gboolean cbUpdateRecLength(AppData *data)
 {
-    struct timeval tv;
     guint mins = 0;
     gdouble secs;
     gchar *tmp;
 
-    if (gettimeofday(&tv, NULL) != 0)
-        return FALSE;
+    data->rectime += REC_UPDATE_INTERVAL/1000.0;
 
-    secs = tv.tv_sec - data->recStartTv.tv_sec;
-    secs += ((tv.tv_usec - data->recStartTv.tv_usec) / 1000000.0);
+    mins = data->rectime / 60;
+    secs = data->rectime - (mins * 60.0);
+    tmp = g_strdup_printf("%02u:%02d", mins, (int)secs);
 
-    if (secs >= 60.0)
-    {
-        mins = secs / 60;
-        secs -= mins * 60.0;
-        tmp = g_strdup_printf("%u:%05.2f", mins, secs);
-    }
-    else
-        tmp = g_strdup_printf("%0.2f", secs);
-
-    gtk_entry_set_text(GTK_ENTRY(data->mainViewData.lengthEntry), 
+    gtk_label_set_text(GTK_LABEL(data->mainViewData.lengthEntry), 
                  tmp);
     g_free(tmp);
 
@@ -1965,3 +1865,4 @@ static gboolean cbUpdateRecLength(AppData *data)
     return FALSE;
 }
 
+