Commit 06ad78ab authored by Alexandre Savard's avatar Alexandre Savard
Browse files

#6109: Implement stop recording playback button

parent a6acc98e
......@@ -235,12 +235,12 @@ void create_new_call (callable_type_t type, call_state_t state, gchar* callID ,
obj->_peer_number = g_strdup (peer_number);
obj->_peer_info = g_strdup (get_peer_info (peer_name, peer_number));
obj->_recordfile = NULL;
obj->_record_is_playing = FALSE;
obj->_trsft_to = "";
set_timestamp (& (obj->_time_start));
set_timestamp (& (obj->_time_current));
set_timestamp (& (obj->_time_stop));
// g_snprintf(obj->_timestr, 20, "00:00");
if (g_strcasecmp (callID, "") == 0)
call_id = generate_call_id ();
......
......@@ -157,6 +157,12 @@ typedef struct {
*/
gchar *_recordfile;
/**
* This boolean value is used to determine if the audio file
* is currently played back.
*/
gboolean _record_is_playing;
/* Associated IM widget */
GtkWidget *_im_widget;
......
......@@ -68,6 +68,7 @@ typedef struct {
time_t _time_stop;
time_t _time_current;
gchar *_recordfile;
gboolean _record_is_playing;
} conference_obj_t;
void create_new_conference (conference_state_t, const gchar*, conference_obj_t **);
......
......@@ -349,6 +349,12 @@
<arg type="s" name="filepath"/>
</signal>
<signal name="recordPlaybackResult" tp:name-for-bindings="recordPlaybackResult">
<tp:docstring/>
<arg type="b" name="callID" />
</signal>
<method name="getCallDetails" tp:name-for-bindings="getCallDetails">
<tp:docstring>
Get all the details about a specific call.
......@@ -605,6 +611,7 @@
<tp:docstring>
</tp:docstring>
<arg type="s" name="filepath" direction="in"/>
<arg type="b" name="result" direction="out"/>
</method>
<method name="stopRecordedFilePlayback" tp:name-for-bindings="stopRecordedFilePlayback">
......
......@@ -86,13 +86,16 @@ static void
conference_changed_cb (DBusGProxy *, const gchar *, const gchar *, void *);
static void
conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo UNUSED);
conference_created_cb (DBusGProxy *, const gchar *, void *);
static void
conference_removed_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo UNUSED);
conference_removed_cb (DBusGProxy *, const gchar *, void *);
static void
record_playback_filepath_cb (DBusGProxy *proxy UNUSED, const gchar *id, const gchar *filepath);
record_playback_filepath_cb (DBusGProxy *, const gchar *, const gchar *);
static void
record_playback_result_cb (DBusGProxy *, const gchar *, const gboolean);
static void
accounts_changed_cb (DBusGProxy *, void *);
......@@ -492,11 +495,21 @@ record_playback_filepath_cb (DBusGProxy *proxy UNUSED, const gchar *id, const gc
callable_obj_t *call = NULL;
conference_obj_t *conf = NULL;
DEBUG("DBUS: Filepath for call %s: %s", id, filepath);
DEBUG("DBUS: Filepath for %s: %s", id, filepath);
call = calllist_get_call(current_calls, id);
conf = conferencelist_get(current_calls, id);
if(call && conf) {
ERROR("DBUS: Two object for this callid");
return;
}
if(!call && !conf) {
ERROR("DBUS: Could not get object");
return;
}
if(call) {
if(call->_recordfile == NULL)
call->_recordfile = g_strdup(filepath);
......@@ -508,6 +521,36 @@ record_playback_filepath_cb (DBusGProxy *proxy UNUSED, const gchar *id, const gc
}
static void
record_playback_result_cb (DBusGProxy *proxy UNUSED, const gchar *id, const gboolean result)
{
callable_obj_t *call = NULL;
conference_obj_t *conf = NULL;
DEBUG("DBUS: Result for %s: %s", id, result ? "ok" : "bad");
call = calllist_get_call(history, id);
conf = conferencelist_get(history, id);
if(call && conf) {
ERROR("DBUS: Two object for this ID");
return;
}
if(!call && !conf) {
ERROR("DBUS: Could not get object");
return;
}
if(call) {
call->_record_is_playing = result;
}
else if(conf) {
conf->_record_is_playing = result;
}
update_actions();
}
static void
accounts_changed_cb (DBusGProxy *proxy UNUSED, void * foo UNUSED)
......@@ -772,6 +815,10 @@ dbus_connect (GError **error)
G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (callManagerProxy, "recordPlaybackFilepath",
G_CALLBACK (record_playback_filepath_cb), NULL, NULL);
dbus_g_proxy_add_signal (callManagerProxy, "recordPlaybackResult", G_TYPE_BOOLEAN,
G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_add_signal(callManagerProxy, "recordPlaybackResult",
G_CALLBACK (record_playback_result_cb), NULL, NULL);
/* Security related callbacks */
......@@ -925,19 +972,23 @@ dbus_unhold_conference (const conference_obj_t * c)
}
}
void
gboolean
dbus_start_recorded_file_playback(const gchar *filepath)
{
DEBUG("DBUS: Start recorded file playback %s", filepath);
GError *error = NULL;
gboolean result;
org_sflphone_SFLphone_CallManager_start_recorded_file_playback(callManagerProxy,
filepath, &error);
filepath, &result, &error);
if(error) {
ERROR("Failed to call recorded file playback: %s", error->message);
g_error_free(error);
}
return result;
}
void
......
......@@ -638,7 +638,7 @@ void dbus_send_text_message (const gchar* callID, const gchar *message);
* Start playback of a recorded
* @param The recorded file to start playback with
*/
void dbus_start_recorded_file_playback(const gchar *);
gboolean dbus_start_recorded_file_playback(const gchar *);
/**
* Stop playback of a recorded filie
......
......@@ -54,7 +54,8 @@
<separator/>
<toolitem name="VoicemailToolbar" action="Voicemail"/>
<toolitem name="HistoryToolbar" action="History"/>
<toolitem name="PlayRecordToolbar" action="PlayRecord"/>
<toolitem name="StartPlaybackRecordToolbar" action="StartPlaybackRecord"/>
<toolitem name="StopPlaybackRecordToolbar" action="StopPlaybackRecord" />
</toolbar>
<popup name="PopupMenu">
......
......@@ -79,7 +79,9 @@ static GtkWidget * voicemailToolbar;
static GtkWidget * imToolbar;
static GtkAction * imAction;
static GtkWidget * playRecordWidget;
static GtkWidget * playRecordAction;
static GtkAction * playRecordAction;
static GtkWidget * stopRecordWidget;
static GtkAction * stopRecordAction;
static GtkWidget * editable_num;
static GtkDialog * edit_dialog;
......@@ -185,6 +187,8 @@ update_actions()
if(is_inserted(GTK_WIDGET (playRecordWidget), GTK_WIDGET(toolbar)))
gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(playRecordWidget));
if(is_inserted(GTK_WIDGET (stopRecordWidget), GTK_WIDGET(toolbar)))
gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(stopRecordWidget));
}
// If addressbook support has been enabled and all addressbooks are loaded, display the icon
......@@ -279,7 +283,10 @@ update_actions()
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1);
else if(active_calltree == history) {
if(selectedCall->_recordfile && (g_strcmp0(selectedCall->_recordfile, "") != 0)) {
gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(playRecordWidget), 3);
if(selectedCall->_record_is_playing)
gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(stopRecordWidget), 3);
else
gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(playRecordWidget), 3);
}
}
break;
......@@ -715,9 +722,11 @@ call_record (void)
}
static void
playback_record_cb(void)
start_playback_record_cb(void)
{
DEBUG("UIManager: Playback button pressed");
gboolean result;
DEBUG("UIManager: Start playback button pressed");
callable_obj_t *selectedCall = calltab_get_selected_call (history);
conference_obj_t *selectedConf = calltab_get_selected_conf (history);
......@@ -727,10 +736,46 @@ playback_record_cb(void)
return;
}
if(selectedCall)
dbus_start_recorded_file_playback(selectedCall->_recordfile);
else if(selectedConf)
dbus_start_recorded_file_playback(selectedConf->_recordfile);
if(selectedCall) {
result = dbus_start_recorded_file_playback(selectedCall->_recordfile);
selectedCall->_record_is_playing = result;
}
else if(selectedConf) {
result = dbus_start_recorded_file_playback(selectedConf->_recordfile);
selectedConf->_record_is_playing = result;
}
update_actions();
}
static void
stop_playback_record_cb(void)
{
DEBUG("UIManager: Stop playback button pressed");
callable_obj_t *selectedCall = calltab_get_selected_call (history);
conference_obj_t *selectedConf = calltab_get_selected_conf(history);
if(selectedCall && selectedConf) {
ERROR("UIManager: Error: Two selected object in history treeview");
return;
}
if((selectedCall == NULL) && (selectedConf == NULL)) {
ERROR("UIManager: Error: No selected object in history treeview");
return;
}
if(selectedCall) {
dbus_stop_recorded_file_playback(selectedCall->_recordfile);
selectedCall->_record_is_playing = FALSE;
}
else if(selectedConf) {
dbus_stop_recorded_file_playback(selectedConf->_recordfile);
selectedConf->_record_is_playing = FALSE;
}
update_actions();
}
static void
......@@ -1000,8 +1045,10 @@ static const GtkActionEntry menu_entries[] = {
N_ ("Minimize to system tray"), G_CALLBACK (call_minimize) },
{ "Quit", GTK_STOCK_CLOSE, N_ ("_Quit"), "<control>Q",
N_ ("Quit the program"), G_CALLBACK (call_quit) },
{ "PlayRecord", GTK_STOCK_MEDIA_PLAY, N_ ("_Playback record"), NULL,
N_ ("Playback recorded file"), G_CALLBACK (playback_record_cb) },
{ "StartPlaybackRecord", GTK_STOCK_MEDIA_PLAY, N_ ("_Playback record"), NULL,
N_ ("Playback recorded file"), G_CALLBACK (start_playback_record_cb) },
{ "StopPlaybackRecord", GTK_STOCK_MEDIA_PAUSE, N_ ("_Stop playback"), NULL,
N_ ("Stop recorded file playback"), G_CALLBACK (stop_playback_record_cb) },
// Edit Menu
{ "Edit", NULL, N_ ("_Edit"), NULL, NULL, NULL },
......@@ -1752,9 +1799,13 @@ create_toolbar_actions (GtkUIManager *ui_manager, GtkWidget **widget)
historyButton = gtk_ui_manager_get_widget (ui_manager,
"/ToolbarActions/HistoryToolbar");
playRecordWidget = gtk_ui_manager_get_widget(ui_manager,
"/ToolbarActions/PlayRecordToolbar");
"/ToolbarActions/StartPlaybackRecordToolbar");
playRecordAction = gtk_ui_manager_get_action(ui_manager,
"/ToolbarActions/PlayRecord");
"/ToolbarActions/StartPlaybackRecord");
stopRecordWidget = gtk_ui_manager_get_widget(ui_manager,
"/ToolbarActions/StopPlaybackRecordToolbar");
stopRecordAction = gtk_ui_manager_get_action(ui_manager,
"/ToolbarActions/StopPlaybackRecord");
if(abookfactory_is_addressbook_loaded()) {
contactButton = gtk_ui_manager_get_widget (ui_manager, "/ToolbarActions/AddressbookToolbar");
}
......
......@@ -349,6 +349,12 @@
<arg type="s" name="filepath"/>
</signal>
<signal name="recordPlaybackResult" tp:name-for-bindings="recordPlaybackResult">
<tp:docstring/>
<arg type="b" name="callID" />
</signal>
<method name="getCallDetails" tp:name-for-bindings="getCallDetails">
<tp:docstring>
Get all the details about a specific call.
......@@ -605,6 +611,7 @@
<tp:docstring>
</tp:docstring>
<arg type="s" name="filepath" direction="in"/>
<arg type="b" name="result" direction="out"/>
</method>
<method name="stopRecordedFilePlayback" tp:name-for-bindings="stopRecordedFilePlayback">
......
......@@ -283,10 +283,10 @@ CallManager::getParticipantList (const std::string& confID)
return Manager::instance().getParticipantList (confID);
}
void
bool
CallManager::startRecordedFilePlayback(const std::string& filepath)
{
Manager::instance().startRecordedFilePlayback(filepath);
return Manager::instance().startRecordedFilePlayback(filepath);
}
void
......
......@@ -101,7 +101,7 @@ class CallManager
std::map< std::string, std::string > getConferenceDetails (const std::string& callID);
/* File Playback methods */
void startRecordedFilePlayback(const std::string& filepath);
bool startRecordedFilePlayback(const std::string& filepath);
void stopRecordedFilePlayback(const std::string& filepath);
/* General audio methods */
......
......@@ -1863,13 +1863,13 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId)
}
if (!hasCurrentCall()) {
_debug ("Manager: Has no current call");
_debug ("Manager: Has no current call start ringing");
call->setConnectionState (Call::Ringing);
ringtone (accountId);
} else {
_debug ("Manager: has current call");
_debug ("Manager: has current call, beep in current audio stream");
}
addWaitingCall (call->getCallId());
......@@ -2359,7 +2359,7 @@ void ManagerImpl::ringtone (const AccountID& accountID)
{
std::string ringchoice;
sfl::AudioCodec *codecForTone;
int layer, samplerate;
int samplerate;
_debug ("Manager: Ringtone");
......@@ -2394,8 +2394,6 @@ void ManagerImpl::ringtone (const AccountID& accountID)
return;
}
layer = _audiodriver->getLayerType();
samplerate = _audiodriver->getSampleRate();
codecForTone = static_cast<sfl::AudioCodec *>(_audioCodecFactory.getFirstCodecAvailable());
......@@ -3012,14 +3010,65 @@ bool ManagerImpl::isRecording (const CallID& id)
return ret;
}
void ManagerImpl::startRecordedFilePlayback(const std::string& filepath)
bool ManagerImpl::startRecordedFilePlayback(const std::string& filepath)
{
int sampleRate;
_debug("Manager: Start recorded file playback %s", filepath.c_str());
audioLayerMutexLock();
if(!_audiodriver) {
_error("Manager: Error: No audio layer in start recorded file playback");
}
sampleRate = _audiodriver->getSampleRate();
audioLayerMutexUnlock();
_toneMutex.enterMutex();
if(_audiofile) {
delete _audiofile;
_audiofile = NULL;
}
try {
_audiofile = static_cast<AudioFile *>(new WaveFile());
_audiofile->loadFile(filepath, NULL, sampleRate);
}
catch(AudioFileException &e) {
_error("Manager: Exception: %s", e.what());
}
_audiofile->start();
_toneMutex.leaveMutex();
audioLayerMutexLock();
_audiodriver->startStream();
audioLayerMutexUnlock();
return true;
}
void ManagerImpl::stopRecordedFilePlayback(const std::string& filepath)
{
_debug("Manager: Stop recorded file playback %s", filepath.c_str());
audioLayerMutexLock();
_audiodriver->stopStream();
audioLayerMutexUnlock();
_toneMutex.enterMutex();
if(_audiofile != NULL) {
_audiofile->stop();
delete _audiofile;
_audiofile = NULL;
}
_toneMutex.leaveMutex();
}
void ManagerImpl::setHistoryLimit (const int& days)
......
......@@ -759,7 +759,7 @@ class ManagerImpl
* Start playback fo a recorded file if and only if audio layer is not already started.
* @param File path of the file to play
*/
void startRecordedFilePlayback(const std::string&);
bool startRecordedFilePlayback(const std::string&);
/**
* Stop playback of recorded file
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment