From acec60a9036e8a80f638ef17ae25b27c8b7e4eec Mon Sep 17 00:00:00 2001
From: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
Date: Mon, 9 May 2011 18:43:43 -0400
Subject: [PATCH] #5747: Handle offhold action for recording conference

---
 sflphone-client-gnome/src/conference_obj.c    |  2 +
 sflphone-client-gnome/src/conference_obj.h    |  3 +-
 sflphone-client-gnome/src/contacts/calltree.c |  2 +
 sflphone-client-gnome/src/dbus/dbus.c         |  4 +-
 sflphone-client-gnome/src/uimanager.c         | 39 ++++++++-----
 sflphone-client-gnome/src/widget/imwidget.c   |  1 +
 sflphone-common/src/conference.cpp            |  5 +-
 sflphone-common/src/conference.h              | 54 +++++++++++++++++-
 sflphone-common/src/managerimpl.cpp           | 55 ++++++++++++++-----
 9 files changed, 133 insertions(+), 32 deletions(-)

diff --git a/sflphone-client-gnome/src/conference_obj.c b/sflphone-client-gnome/src/conference_obj.c
index 61fab647f7..ba451a562f 100644
--- a/sflphone-client-gnome/src/conference_obj.c
+++ b/sflphone-client-gnome/src/conference_obj.c
@@ -103,6 +103,8 @@ void create_new_conference_from_details (const gchar *conf_id, GHashTable *detai
         new_conf->_state = CONFERENCE_STATE_ACTIVE_DETACHED_RECORD;
     } else if (g_strcasecmp (state_str, "HOLD") == 0) {
         new_conf->_state = CONFERENCE_STATE_HOLD;
+    } else if (g_strcasecmp (state_str, "HOLD_REC") == 0) {
+        new_conf->_state = CONFERENCE_STATE_HOLD_RECORD;
     }
 
     *conf = new_conf;
diff --git a/sflphone-client-gnome/src/conference_obj.h b/sflphone-client-gnome/src/conference_obj.h
index 74c789c433..04b15ac34a 100644
--- a/sflphone-client-gnome/src/conference_obj.h
+++ b/sflphone-client-gnome/src/conference_obj.h
@@ -46,7 +46,8 @@ typedef enum {
     CONFERENCE_STATE_ACTIVE_DETACHED,
     CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD,
     CONFERENCE_STATE_ACTIVE_DETACHED_RECORD,
-    CONFERENCE_STATE_HOLD
+    CONFERENCE_STATE_HOLD,
+    CONFERENCE_STATE_HOLD_RECORD
 } conference_state_t;
 
 
diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c
index f493f5e649..a276734e42 100644
--- a/sflphone-client-gnome/src/contacts/calltree.c
+++ b/sflphone-client-gnome/src/contacts/calltree.c
@@ -261,6 +261,7 @@ row_activated (GtkTreeView       *tree_view UNUSED,
                         sflphone_add_main_participant (selectedConf);
                         break;
                     case CONFERENCE_STATE_HOLD:
+                    case CONFERENCE_STATE_HOLD_RECORD:
                         sflphone_conference_off_hold (selectedConf);
                         break;
                     case CONFERENCE_STATE_ACTIVE_ATACHED:
@@ -1139,6 +1140,7 @@ void calltree_add_conference (calltab_t* tab, conference_obj_t* conf)
                 break;
             case CONFERENCE_STATE_ACTIVE_DETACHED:
             case CONFERENCE_STATE_HOLD:
+            case CONFERENCE_STATE_HOLD_RECORD:
                 pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/usersDetached.svg", NULL);
                 break;
             case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c
index 546e5ee84f..f13a8c4cf8 100644
--- a/sflphone-client-gnome/src/dbus/dbus.c
+++ b/sflphone-client-gnome/src/dbus/dbus.c
@@ -246,7 +246,7 @@ conference_changed_cb (DBusGProxy *proxy UNUSED, const gchar* confID,
     conference_obj_t* changed_conf = conferencelist_get (confID);
     GSList * part;
 
-    DEBUG ("conference new state %s\n", state);
+    DEBUG ("DBUS: Conference state changed: %s\n", state);
 
     if (changed_conf) {
         // remove old conference from calltree
@@ -263,6 +263,8 @@ conference_changed_cb (DBusGProxy *proxy UNUSED, const gchar* confID,
              changed_conf->_state = CONFERENCE_STATE_ACTIVE_DETACHED_RECORD;
         } else if (strcmp (state, "HOLD") == 0) {
             changed_conf->_state = CONFERENCE_STATE_HOLD;
+        } else if (strcmp(state, "HOLD_REC") == 0) {
+            changed_conf->_state = CONFERENCE_STATE_HOLD_RECORD;
         } else {
             DEBUG ("Error: conference state not recognized");
         }
diff --git a/sflphone-client-gnome/src/uimanager.c b/sflphone-client-gnome/src/uimanager.c
index 187cf175f7..24fe3b3aca 100644
--- a/sflphone-client-gnome/src/uimanager.c
+++ b/sflphone-client-gnome/src/uimanager.c
@@ -375,6 +375,7 @@ update_actions()
                 break;
 
             case CONFERENCE_STATE_HOLD:
+            case CONFERENCE_STATE_HOLD_RECORD:
                 gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE);
                 gtk_widget_set_sensitive (GTK_WIDGET (offHoldToolbar), TRUE);
                 gtk_action_set_sensitive (GTK_ACTION (recordAction), TRUE);
@@ -552,19 +553,25 @@ call_hold (void* foo UNUSED)
 
         switch (selectedConf->_state) {
 
-            case CONFERENCE_STATE_HOLD: {
+            case CONFERENCE_STATE_HOLD:
                 selectedConf->_state = CONFERENCE_STATE_ACTIVE_ATACHED;
                 sflphone_conference_off_hold (selectedConf);
-            }
-            break;
+                break;
+            case CONFERENCE_STATE_HOLD_RECORD:
+                selectedConf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD;
+                sflphone_conference_off_hold (selectedConf);
+                break;
 
             case CONFERENCE_STATE_ACTIVE_ATACHED:
             case CONFERENCE_STATE_ACTIVE_DETACHED:
-            case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
-            case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
                 selectedConf->_state = CONFERENCE_STATE_HOLD;
                 sflphone_conference_on_hold (selectedConf);
-            break;
+                break;
+            case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
+            case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
+              selectedConf->_state = CONFERENCE_STATE_HOLD_RECORD;
+              sflphone_conference_on_hold (selectedConf);
+              break;
             default:
                 break;
         }
@@ -602,18 +609,23 @@ conference_hold (void* foo UNUSED)
     DEBUG ("UIManager: Hold button pressed (conference)");
 
     switch (selectedConf->_state) {
-        case CONFERENCE_STATE_HOLD: {
+        case CONFERENCE_STATE_HOLD:
             selectedConf->_state = CONFERENCE_STATE_ACTIVE_ATACHED;
             sflphone_conference_off_hold (selectedConf);
-        }
-        break;
-
+            break;
+        case CONFERENCE_STATE_HOLD_RECORD:
+            selectedConf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD;
+            sflphone_conference_off_hold (selectedConf);
+            break;
         case CONFERENCE_STATE_ACTIVE_ATACHED:
-        case CONFERENCE_STATE_ACTIVE_DETACHED: {
+        case CONFERENCE_STATE_ACTIVE_DETACHED:
             selectedConf->_state = CONFERENCE_STATE_HOLD;
             sflphone_conference_on_hold (selectedConf);
-        }
-        break;
+            break;
+        case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
+        case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
+            selectedConf->_state = CONFERENCE_STATE_HOLD_RECORD;
+            sflphone_conference_on_hold(selectedConf);
         default:
             break;
     }
@@ -1181,6 +1193,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
                 case CONFERENCE_STATE_ACTIVE_DETACHED:
                     break;
                 case CONFERENCE_STATE_HOLD:
+                case CONFERENCE_STATE_HOLD_RECORD:
                     hangup_conf = TRUE;
                     hold_conf = TRUE;
                     break;
diff --git a/sflphone-client-gnome/src/widget/imwidget.c b/sflphone-client-gnome/src/widget/imwidget.c
index 14f1f9fbcc..d1021e5dbd 100644
--- a/sflphone-client-gnome/src/widget/imwidget.c
+++ b/sflphone-client-gnome/src/widget/imwidget.c
@@ -462,6 +462,7 @@ conf_state_image_widget (conference_state_t state)
         case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
         case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
         case CONFERENCE_STATE_HOLD:
+        case CONFERENCE_STATE_HOLD_RECORD:
             image = gtk_image_new_from_stock (GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
             break;
         default:
diff --git a/sflphone-common/src/conference.cpp b/sflphone-common/src/conference.cpp
index 21aa633223..ba09240623 100644
--- a/sflphone-common/src/conference.cpp
+++ b/sflphone-common/src/conference.cpp
@@ -145,9 +145,12 @@ std::string Conference::getStateStr()
         case ACTIVE_DETACHED_REC:
         	state_str = "ACTIVE_DETACHED_REC";
         	break;
-        case Hold:
+        case HOLD:
             state_str = "HOLD";
             break;
+        case HOLD_REC:
+        	state_str = "HOLD_REC";
+        	break;
         default:
             break;
     }
diff --git a/sflphone-common/src/conference.h b/sflphone-common/src/conference.h
index 1ba432e16e..8da27fbbc7 100644
--- a/sflphone-common/src/conference.h
+++ b/sflphone-common/src/conference.h
@@ -48,51 +48,101 @@ class Conference: public Recordable
 
     public:
 
-        enum ConferenceState {ACTIVE_ATTACHED, ACTIVE_DETACHED, ACTIVE_ATTACHED_REC, ACTIVE_DETACHED_REC, Hold};
+        enum ConferenceState {ACTIVE_ATTACHED, ACTIVE_DETACHED, ACTIVE_ATTACHED_REC, ACTIVE_DETACHED_REC, HOLD, HOLD_REC};
 
         static int count;
 
+        /**
+         * Constructor for this class, increment static counter
+         */
         Conference();
 
+        /**
+         * Destructor
+         */
         ~Conference();
 
+        /**
+         * Return the conference id
+         */
         std::string getConfID() {
             return _id;
         }
 
+        /**
+         * Return the current conference state
+         */
         int getState();
 
+        /**
+         * Set conference state
+         */
         void setState (ConferenceState state);
 
+        /**
+         * Return a string description of the conference state
+         */
         std::string getStateStr();
 
+        /**
+         * Return the number of participant for this conference
+         */
         int getNbParticipants() {
             return _nbParticipant;
         }
 
+        /**
+         * Add a new participant to the conference
+         */
         void add (CallID participant_id);
 
+        /**
+         * Remove a participant from the conference
+         */
         void remove (CallID participant_id);
 
+        /**
+         * Bind a participant to the conference
+         */
         void bindParticipant (CallID participant_id);
 
+        /**
+         * Get the participant list for this conference
+         */
         ParticipantSet getParticipantList();
 
+        /**
+         * Get recording file ID
+         */
         std::string getRecFileId() {
             return getConfID();
         }
 
+        /**
+         * Start/stop recording toggle
+         */
         virtual bool setRecording();
 
     private:
 
-        /** Unique ID of the conference */
+        /**
+         * Unique ID of the conference
+         */
         CallID _id;
 
+        /**
+         * Conference state
+         */
         ConferenceState _confState;
 
+        /**
+         * List of participant ids
+         */
         ParticipantSet _participants;
 
+        /**
+         * Number of participant
+         */
         int _nbParticipant;
 
 };
diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp
index 2c19955c50..df9d513a2a 100644
--- a/sflphone-common/src/managerimpl.cpp
+++ b/sflphone-common/src/managerimpl.cpp
@@ -619,14 +619,14 @@ bool ManagerImpl::offHoldCall (const CallID& call_id)
 
     if (hasCurrentCall()) {
 
-        _debug ("Manager: Has current call, put on hold");
+        _debug ("Manager: Has current call %s, put on hold", current_call_id.c_str());
 
-        // if this is not a conferenceand this and is not a conference participant
-        if (!isConference (current_call_id) && !participToConference (
-                    current_call_id)) {
+        // if this is not a conference and this and is not a conference participant
+        if (!isConference (current_call_id) && !participToConference (current_call_id)) {
+        	_debug("------------------------------------------------ is not a conference and does not participate to conference");
             onHoldCall (current_call_id);
-        } else if (isConference (current_call_id) && !participToConference (
-                       call_id)) {
+        } else if (isConference (current_call_id) && !participToConference (call_id)) {
+        	_debug("------------------------------------------------ detach participant");
             detachParticipant (default_id, current_call_id);
         }
     }
@@ -907,6 +907,7 @@ void ManagerImpl::holdConference (const CallID& id)
 
     Conference *conf;
     ConferenceMap::iterator iter_conf = _conferencemap.find (id);
+    bool isRec = false;
 
     AccountID currentAccountId;
 
@@ -915,6 +916,14 @@ void ManagerImpl::holdConference (const CallID& id)
     if (iter_conf != _conferencemap.end()) {
         conf = iter_conf->second;
 
+        if(conf->getState() == Conference::ACTIVE_ATTACHED_REC) {
+        	isRec = true;
+        } else if (conf->getState() == Conference::ACTIVE_DETACHED_REC) {
+        	isRec = true;
+        } else if (conf->getState() == Conference::HOLD_REC) {
+        	isRec = true;
+        }
+
         ParticipantSet participants = conf->getParticipantList();
         ParticipantSet::iterator iter_participant = participants.begin();
 
@@ -930,7 +939,12 @@ void ManagerImpl::holdConference (const CallID& id)
 
         }
 
-        conf->setState (Conference::Hold);
+        if(isRec) {
+        	conf->setState(Conference::HOLD_REC);
+        }
+        else {
+            conf->setState (Conference::HOLD);
+        }
 
         if (_dbus)
             _dbus->getCallManager()->conferenceChanged (conf->getConfID(), conf->getStateStr());
@@ -958,6 +972,12 @@ void ManagerImpl::unHoldConference (const CallID& id)
         ParticipantSet participants = conf->getParticipantList();
         ParticipantSet::iterator iter_participant = participants.begin();
 
+        if((conf->getState() == Conference::ACTIVE_ATTACHED_REC) ||
+           (conf->getState() == Conference::ACTIVE_DETACHED_REC) ||
+           (conf->getState() == Conference::HOLD_REC)) {
+        	isRec = true;
+        }
+
         while (iter_participant != participants.end()) {
             _debug ("    unholdConference: participant %s", (*iter_participant).c_str());
             currentAccountId = getAccountFromCall (*iter_participant);
@@ -975,14 +995,17 @@ void ManagerImpl::unHoldConference (const CallID& id)
         }
 
         if(isRec) {
+        	_debug("----------------------------------------------------------- active attached rec");
             conf->setState (Conference::ACTIVE_ATTACHED_REC);
         }
         else {
         	conf->setState (Conference::ACTIVE_ATTACHED);
         }
-        if (_dbus)
-            _dbus->getCallManager()->conferenceChanged (conf->getConfID(), conf->getStateStr());
 
+        if (_dbus) {
+        	_debug("------------------------------------------------------------ dbus %s", conf->getStateStr().c_str());
+            _dbus->getCallManager()->conferenceChanged (conf->getConfID(), conf->getStateStr());
+        }
     }
 
 }
@@ -2826,21 +2849,25 @@ bool ManagerImpl::getMd5CredentialHashing (void)
 void ManagerImpl::setRecordingCall (const CallID& id)
 {
 
+	Call *call = NULL;
+	Conference *conf = NULL;
     Recordable* rec = NULL;
 
     if (!isConference (id)) {
         _debug ("Manager: Set recording for call %s", id.c_str());
         AccountID accountid = getAccountFromCall (id);
-        rec = (Recordable *) getAccountLink (accountid)->getCall (id);
+        call = getAccountLink (accountid)->getCall (id);
+        rec = static_cast<Recordable *>(call);
     } else {
-        _debug ("Manager: Ser recording for conference %s", id.c_str());
+        _debug ("Manager: Set recording for conference %s", id.c_str());
         ConferenceMap::iterator it = _conferencemap.find (id);
-        rec = (Recordable *) it->second;
+        conf = it->second;
+        rec = static_cast<Recordable *>(conf);
     }
 
-    if (rec)
+    if (rec != NULL) {
         rec->setRecording();
-
+    }
 }
 
 bool ManagerImpl::isRecording (const CallID& id)
-- 
GitLab