-/* 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 <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"
#include "maemo-recorder-file.h"
-
+#include "settings.h"
#define DEFAULT_REC_BLOCKSIZE "160"
#define RECORDER_MSG_RECORDING _("Recording")
#define RECORDER_FILE_UNTITLED _("Untitled")
+#define RECORDER_FMT_STRING_NONE _("N/A")
+
/* general enumerations */
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,
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 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);
{
case PIPELINE_PLAY_MP3:
ULOG_INFO("mp3 playback - queue");
- src = gst_element_factory_make ("filesrc", "source");
+ src = gst_element_factory_make ("gnomevfssrc", "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,
+ "blocksize", 65536,
NULL);
break;
ULOG_ERR("gst_element_link failed for src, filter and sink!");
return FALSE;
}
- break;
+ break;
+
case FORMAT_WAV:
gst_bin_add_many(GST_BIN(pipeline), src, parse, sink, NULL);
if (!gst_element_link_many (src, parse, sink, NULL))
}
break;
+
case FORMAT_WAV:
gst_bin_add_many(GST_BIN(pipeline), src, parse, NULL);
if (!gst_element_link_many (src, parse, NULL))
app->playPipeline = pipeline;
g_signal_connect(parse, "pad_added",
G_CALLBACK(new_pad_cb), app);
-
break;
default:
data->recPipeline = NULL;
*/
break;
+
default:
pipeline = data->playPipeline;
/*
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),
+ /* 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;
+ break;
case GST_STATE_PAUSED:
{
g_free (debug);
break;
}
+
case GST_MESSAGE_ERROR:
{
GError *err;
/* break; */
/* flow through to eos */
}
+
case GST_MESSAGE_EOS:
{
ULOG_INFO("%s() - eos", G_STRFUNC);
}
break;
}
+
case GST_MESSAGE_STATE_CHANGED:
{
GstState old;
app = (AppData *) data;
+ ULOG_DEBUG("delete_event");
if (!closeFile(app))
return;
else
setLength(data, 0.0);
+ setFormatString(data, data->file_format);
data->saved = TRUE;
}
else
else
setLength(data, 0.0);
+ setFormatString(data, data->file_format);
data->saved = TRUE;
}
else
}
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)
{
}
#endif
+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;
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"));
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);
switch (data->filter)
{
case FORMAT_PCM:
- data->saveFileName = g_strdup(DEFAULT_TMP_FILE);
- data->openFileName = g_strdup(DEFAULT_TMP_FILE);
- break;
+ data->saveFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_FILE);
+ data->openFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_FILE);
+ break;
- case FORMAT_PCMA:
- data->saveFileName = g_strdup(DEFAULT_TMP_PCMA_FILE);
- data->openFileName = g_strdup(DEFAULT_TMP_PCMA_FILE);
- break;
-
- case FORMAT_PCMU:
- data->saveFileName = g_strdup(DEFAULT_TMP_PCMU_FILE);
- data->openFileName = g_strdup(DEFAULT_TMP_PCMU_FILE);
- break;
+ case FORMAT_PCMA:
+ data->saveFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_PCMA_FILE);
+ data->openFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_PCMA_FILE);
+ break;
+
+ case FORMAT_PCMU:
+ data->saveFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_PCMU_FILE);
+ data->openFileName = g_strdup_printf("%s/%s", get_default_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);
- break;
+ case FORMAT_WAV:
+ data->saveFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_WAV_FILE);
+ data->openFileName = g_strdup_printf("%s/%s", get_default_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);
+ case FORMAT_ILBC:
+ default:
+ data->saveFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_ILBC_FILE);
+ data->openFileName = g_strdup_printf("%s/%s", get_default_dir(), DEFAULT_TMP_ILBC_FILE);
break;
}
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
{
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);
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();
GtkWidget *item_pcmu;
GtkWidget *item_ilbc;
GtkWidget *item_pcm;
-
+ GtkWidget *item_settings;
+ GtkWidget *item_email;
/*
GtkWidget *item_radio_type1;
*/
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_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, "PCM A-law");
+ group, FORMAT_NAME_PCMA);
item_ilbc = gtk_radio_menu_item_new_with_label_from_widget(
- GTK_RADIO_MENU_ITEM(item_pcma), "iLBC");
+ GTK_RADIO_MENU_ITEM(item_pcma), FORMAT_NAME_ILBC);
item_pcmu = gtk_radio_menu_item_new_with_label_from_widget(
- GTK_RADIO_MENU_ITEM(item_pcma), "PCM u-law");
+ GTK_RADIO_MENU_ITEM(item_pcma), FORMAT_NAME_PCMU);
item_pcm = gtk_radio_menu_item_new_with_label_from_widget(
- GTK_RADIO_MENU_ITEM(item_pcma), "WAV");
+ GTK_RADIO_MENU_ITEM(item_pcma), FORMAT_NAME_WAV);
+
+ data->filter = get_default_filter();
+
+ if (data->filter == FORMAT_ILBC)
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_ilbc), TRUE);
+ else if (data->filter == FORMAT_WAV)
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_pcm), TRUE);
+ else if (data->filter == FORMAT_PCMA)
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_pcma), TRUE);
+ else
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_ilbc), TRUE);
+ data->filter = FORMAT_ILBC;
+ }
- /* default is iLBC */
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_ilbc), TRUE);
- data->filter = FORMAT_ILBC;
-
data->radio_pcma = item_pcma;
data->radio_ilbc = item_ilbc;
data->radio_pcm = item_pcm;
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_close );
+ gtk_menu_append(main_menu, item_settings );
+
+ gtk_menu_append(main_menu, item_close );
/* Add others submenu to the "Others" item */
gtk_menu_item_set_submenu(
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_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);
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;
GtkWidget *entry2 = NULL;
GtkWidget *entry3 = NULL;
GtkWidget *toolBar = NULL;
+ GtkWidget *infohbox = NULL;
GtkWidget *table = NULL;
GtkWidget *scale = NULL;
GtkObject *adjustment = NULL;
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);
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,
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;
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;
default:
return -1.0;
}
+
if (bitrate == 0.0)
return -1.0;
return FALSE;
}
+