[ekiga/ds-gtk-application] Engine+OPAL: Added new global actions.



commit f36a3fa357fd16336ab149f9222389915d163efc
Author: Damien Sandras <dsandras beip be>
Date:   Sun Mar 16 15:24:51 2014 +0100

    Engine+OPAL: Added new global actions.
    
    Global actions were added to implement the minimum functions we would
    expect from a softphone:
    - Call (coming from the CallCore)
    - Transfer (coming from the CallCore)
    - IM (coming from the CallCore, but should probably be moved in the
      ChatCore)
    
    The corresponding methods were added to the Core and to the respective
    CallManager/CallProtocolManager classes because they are the minimal
    subset of operations we want endpoints to implement. More specific
    actions will be exposed to the Actor mechanism too, but will not be part
    of the Core API.
    
    The old populate_menu stuff has been (partially) removed.

 lib/engine/components/opal/h323-endpoint.cpp     |   71 ++++++-----
 lib/engine/components/opal/h323-endpoint.h       |   17 +--
 lib/engine/components/opal/opal-account.cpp      |   53 --------
 lib/engine/components/opal/opal-account.h        |    5 -
 lib/engine/components/opal/opal-bank.cpp         |   23 +---
 lib/engine/components/opal/opal-bank.h           |    5 -
 lib/engine/components/opal/opal-call-manager.cpp |   63 ++++++----
 lib/engine/components/opal/opal-call-manager.h   |   10 +-
 lib/engine/components/opal/opal-main.cpp         |    1 -
 lib/engine/components/opal/sip-endpoint.cpp      |  151 ++++++++--------------
 lib/engine/components/opal/sip-endpoint.h        |   33 +----
 lib/engine/protocol/call-core.cpp                |  111 ++++++++++++++--
 lib/engine/protocol/call-core.h                  |   49 ++++++-
 lib/engine/protocol/call-manager.h               |   30 ++++-
 lib/engine/protocol/call-protocol-manager.h      |   38 +++++-
 15 files changed, 354 insertions(+), 306 deletions(-)
---
diff --git a/lib/engine/components/opal/h323-endpoint.cpp b/lib/engine/components/opal/h323-endpoint.cpp
index 64ca338..fa7fa9e 100644
--- a/lib/engine/components/opal/h323-endpoint.cpp
+++ b/lib/engine/components/opal/h323-endpoint.cpp
@@ -112,36 +112,62 @@ Opal::H323::EndPoint::~EndPoint ()
 {
 }
 
+
 bool
-Opal::H323::EndPoint::populate_menu (const std::string& /*fullname*/,
-                                     const std::string& uri,
-                                     Ekiga::MenuBuilder& builder)
+Opal::H323::EndPoint::dial (const std::string&  uri)
 {
-  if (0 == GetConnectionCount ())
-    builder.add_action ("phone-pick-up", _("Call"),
-                        boost::bind (&Opal::H323::EndPoint::on_dial, this, uri));
-  else
-    builder.add_action ("mail-forward", _("Transfer"),
-                        boost::bind (&Opal::H323::EndPoint::on_transfer, this, uri));
+  if (!is_supported_uri (uri))
+    return false;
+
+  PString token;
+  manager.SetUpCall("pc:*", uri, token, (void*) uri.c_str());
+
   return true;
 }
 
 
 bool
-Opal::H323::EndPoint::dial (const std::string&  uri)
+Opal::H323::EndPoint::transfer (const std::string & uri,
+                                bool attended)
 {
-  if (uri.find ("h323:") == 0) {
+  /* This is not handled yet */
+  if (attended)
+    return false;
 
-    PString token;
-    manager.SetUpCall("pc:*", uri, token, (void*) uri.c_str());
+  if (GetConnectionCount () == 0 || !is_supported_uri (uri))
+      return false; /* No active SIP connection to transfer, or
+                     * transfer request to unsupported uri
+                     */
 
-    return true;
+  /* We don't handle several calls here */
+  for (PSafePtr<OpalConnection> connection(connectionsActive, PSafeReference);
+       connection != NULL;
+       ++connection) {
+    if (!PIsDescendant(&(*connection), OpalPCSSConnection)) {
+      connection->TransferConnection (uri);
+      return true; /* We could handle the transfer */
+    }
   }
 
   return false;
 }
 
 
+bool
+Opal::H323::EndPoint::message (const Ekiga::ContactPtr & contact,
+                               const std::string & uri)
+{
+  return false; /* Not reimplemented yet */
+}
+
+
+bool
+Opal::H323::EndPoint::is_supported_uri (const std::string & uri)
+{
+  return (!uri.empty () && uri.find ("h323:") == 0);
+}
+
+
 const std::string&
 Opal::H323::EndPoint::get_protocol_name () const
 {
@@ -429,22 +455,6 @@ Opal::H323::EndPoint::OnIncomingConnection (OpalConnection & connection,
 
 
 void
-Opal::H323::EndPoint::on_dial (std::string uri)
-{
-  manager.dial (uri);
-}
-
-
-void
-Opal::H323::EndPoint::on_transfer (std::string uri)
-{
-  /* FIXME : we don't handle several calls here */
-  for (PSafePtr<OpalConnection> connection(connectionsActive, PSafeReference); connection != NULL; 
++connection)
-    if (!PIsDescendant(&(*connection), OpalPCSSConnection))
-      connection->TransferConnection (uri);
-}
-
-void
 Opal::H323::EndPoint::registration_event_in_main (const Opal::Account& account,
                                                  Opal::Account::RegistrationState state,
                                                  const std::string msg)
@@ -452,6 +462,7 @@ Opal::H323::EndPoint::registration_event_in_main (const Opal::Account& account,
   account.handle_registration_event (state, msg);
 }
 
+
 void
 Opal::H323::EndPoint::setup (const std::string setting)
 {
diff --git a/lib/engine/components/opal/h323-endpoint.h b/lib/engine/components/opal/h323-endpoint.h
index 5f5777d..80d26e0 100644
--- a/lib/engine/components/opal/h323-endpoint.h
+++ b/lib/engine/components/opal/h323-endpoint.h
@@ -66,14 +66,15 @@ namespace Opal {
 
       ~EndPoint ();
 
-      // helper for Opal::Bank's contact/presentity decorator code
-      bool populate_menu (const std::string& fullname,
-                         const std::string& uri,
-                         Ekiga::MenuBuilder& builder);
-
 
       /* CallProtocolManager */
-      bool dial (const std::string & uri); 
+      bool dial (const std::string & uri);
+      bool transfer (const std::string & uri,
+                     bool attended);
+      bool message (const Ekiga::ContactPtr & contact,
+                    const std::string & uri);
+      bool is_supported_uri (const std::string & uri);
+
 
       const std::string & get_protocol_name () const;
 
@@ -112,10 +113,6 @@ namespace Opal {
                                  unsigned options,
                                  OpalConnection::StringOptions *str_options);
 
-      void on_dial (std::string uri);
-
-      void on_transfer (std::string uri);
-
       void registration_event_in_main (const Opal::Account& account,
                                       Account::RegistrationState state,
                                       const std::string msg);
diff --git a/lib/engine/components/opal/opal-account.cpp b/lib/engine/components/opal/opal-account.cpp
index 7772d23..a419cb7 100644
--- a/lib/engine/components/opal/opal-account.cpp
+++ b/lib/engine/components/opal/opal-account.cpp
@@ -575,59 +575,6 @@ Opal::Account::populate_menu (Ekiga::MenuBuilder &builder)
   return true;
 }
 
-bool
-Opal::Account::populate_menu (const std::string fullname,
-                             const std::string uri,
-                             Ekiga::MenuBuilder& builder)
-{
-  bool result = false;
-  Ekiga::TemporaryMenuBuilder tmp_builder;
-  std::string protocol;
-  std::string complete_uri;
-
-  if (!is_enabled ())
-    return false;
-
-  // if there is no protocol, add what we are
-  if (uri.find (":") == string::npos) {
-
-    if (type == H323)
-      protocol = "h323:";
-    else
-      protocol = "sip:";
-    complete_uri = protocol + uri;
-  } else
-    complete_uri = uri;
-
-  // whatever the protocol was previously, check if it fits
-  if (not(
-      (type == H323 && complete_uri.find ("h323:" != 0))
-      ||
-      (type != H323 && complete_uri.find ("sip:" != 0))
-         ))
-    return false;
-
-  // from now on, we're sure we have an uri corresponding to the account
-
-  // but does it have a domain?
-  //
-  // (it is supposed not to, but let's still test so the function
-  // can be called from several places without problem)
-  if (complete_uri.find ("@") == string::npos && type != H323)
-    complete_uri = complete_uri + "@" + get_host ();
-
-  call_manager->populate_menu (fullname, complete_uri, tmp_builder);
-
-  if ( !tmp_builder.empty ()) {
-
-    builder.add_ghost ("", get_name ());
-    tmp_builder.populate_menu (builder);
-    result = true;
-  }
-
-  return result;
-
-}
 
 void
 Opal::Account::edit ()
diff --git a/lib/engine/components/opal/opal-account.h b/lib/engine/components/opal/opal-account.h
index c06ca12..b4c325a 100644
--- a/lib/engine/components/opal/opal-account.h
+++ b/lib/engine/components/opal/opal-account.h
@@ -160,11 +160,6 @@ public:
 
     bool populate_menu (Ekiga::MenuBuilder &builder);
 
-    // used by the bank to add actions on contacts/presentities
-    bool populate_menu (const std::string fullname,
-                       const std::string uri,
-                       Ekiga::MenuBuilder& builder);
-
     boost::signals2::signal<void(void)> trigger_saving;
 
     /*
diff --git a/lib/engine/components/opal/opal-bank.cpp b/lib/engine/components/opal/opal-bank.cpp
index 5f7f4d1..11aa7c9 100644
--- a/lib/engine/components/opal/opal-bank.cpp
+++ b/lib/engine/components/opal/opal-bank.cpp
@@ -135,15 +135,6 @@ Opal::Bank::populate_menu (Ekiga::MenuBuilder & builder)
 
 
 bool
-Opal::Bank::populate_menu (Ekiga::ContactPtr contact,
-                          const std::string uri,
-                          Ekiga::MenuBuilder& builder)
-{
-  return populate_menu_helper (contact->get_name (), uri, builder);
-}
-
-
-bool
 Opal::Bank::populate_menu (Ekiga::PresentityPtr presentity,
                           const std::string uri,
                           Ekiga::MenuBuilder& builder)
@@ -159,19 +150,7 @@ Opal::Bank::populate_menu_helper (const std::string fullname,
 {
   bool result = false;
 
-  if (uri.find ("@") == string::npos) {
-
-    // no domain: try to save the situation by trying all accounts
-
-    for (iterator iter = begin ();
-        iter != end ();
-        ++iter)
-      result = (*iter)->populate_menu (fullname, uri, builder) || result;
-  } else {
-
-    // there is a domain: just add the actions
-    result = opal_component->populate_menu (fullname, uri, builder);
-  }
+  std::cout << "should be fixed" << std::endl << std::flush;
 
   return result;
 }
diff --git a/lib/engine/components/opal/opal-bank.h b/lib/engine/components/opal/opal-bank.h
index 0269d8c..ff13131 100644
--- a/lib/engine/components/opal/opal-bank.h
+++ b/lib/engine/components/opal/opal-bank.h
@@ -57,7 +57,6 @@ namespace Opal
       public Ekiga::Cluster,
       public Ekiga::PresencePublisher,
       public Ekiga::PresenceFetcher,
-      public Ekiga::ContactDecorator,
       public Ekiga::PresentityDecorator,
       public Ekiga::Service
   {
@@ -95,10 +94,6 @@ public:
     /*
      * this object is an Ekiga::ContactDecorator and an Ekiga::PresentityDecorator
      */
-    bool populate_menu (Ekiga::ContactPtr contact,
-                       const std::string uri,
-                       Ekiga::MenuBuilder& builder);
-
     bool populate_menu (Ekiga::PresentityPtr presentity,
                        const std::string uri,
                        Ekiga::MenuBuilder& builder);
diff --git a/lib/engine/components/opal/opal-call-manager.cpp 
b/lib/engine/components/opal/opal-call-manager.cpp
index 70c4074..a7eaf51 100644
--- a/lib/engine/components/opal/opal-call-manager.cpp
+++ b/lib/engine/components/opal/opal-call-manager.cpp
@@ -224,31 +224,6 @@ CallManager::~CallManager ()
 }
 
 
-bool
-CallManager::populate_menu (const std::string fullname,
-                           const std::string uri,
-                           Ekiga::MenuBuilder& builder)
-{
-  std::string complete_uri;
-  bool result = false;
-
-  // by default, prefer SIP
-  if (uri.find (":") == std::string::npos)
-    complete_uri = "sip:" + uri;
-  else
-    complete_uri = uri;
-
-  if (uri.find ("sip:") == 0)
-    result = sip_endpoint->populate_menu (fullname, complete_uri, builder);
-
-#ifdef HAVE_H323
-  if (uri.find ("h323:") == 0)
-    result = h323_endpoint->populate_menu (fullname, complete_uri, builder);
-#endif
-
-  return result;
-}
-
 void CallManager::set_display_name (const std::string & name)
 {
   display_name = name;
@@ -654,6 +629,44 @@ void CallManager::hang_up ()
 }
 
 
+bool CallManager::transfer (const std::string & uri,
+                            bool attended)
+{
+  for (CallManager::iterator iter = begin ();
+       iter != end ();
+       iter++)
+    if ((*iter)->transfer (uri, attended))
+      return true;
+
+  return false;
+}
+
+
+bool CallManager::message (const Ekiga::ContactPtr & contact,
+                           const std::string & uri)
+{
+  for (CallManager::iterator iter = begin ();
+       iter != end ();
+       iter++)
+    if ((*iter)->message (contact, uri))
+      return true;
+
+  return false;
+}
+
+
+bool CallManager::is_supported_uri (const std::string & uri)
+{
+  for (CallManager::iterator iter = begin ();
+       iter != end ();
+       iter++)
+    if ((*iter)->is_supported_uri (uri))
+      return true;
+
+  return false;
+}
+
+
 void CallManager::set_video_options (const CallManager::VideoOptions & options)
 {
   OpalMediaFormatList media_formats_list;
diff --git a/lib/engine/components/opal/opal-call-manager.h b/lib/engine/components/opal/opal-call-manager.h
index a1c0527..67e2509 100644
--- a/lib/engine/components/opal/opal-call-manager.h
+++ b/lib/engine/components/opal/opal-call-manager.h
@@ -87,17 +87,19 @@ public:
     const std::string get_description () const
       { return "\tObject bringing in Opal support (calls, text messaging, sip, h323, ...)"; }
 
-    /* helper function for the Opal::Bank contact/presentity decorator work */
-    bool populate_menu (const std::string fullname,
-                       const std::string uri,
-                       Ekiga::MenuBuilder& builder);
 
     /* Set up endpoint: all options or a specific setting */
     void setup (const std::string & setting = "");
 
+
     /** Call Manager **/
     bool dial (const std::string & uri);
     void hang_up ();
+    bool transfer (const std::string & uri,
+                   bool attended);
+    bool message (const Ekiga::ContactPtr & contact,
+                  const std::string & uri);
+    bool is_supported_uri (const std::string & uri);
 
     void set_display_name (const std::string & name);
     const std::string & get_display_name () const;
diff --git a/lib/engine/components/opal/opal-main.cpp b/lib/engine/components/opal/opal-main.cpp
index d460228..3b89079 100644
--- a/lib/engine/components/opal/opal-main.cpp
+++ b/lib/engine/components/opal/opal-main.cpp
@@ -122,7 +122,6 @@ struct OPALSpark: public Ekiga::Spark
       account_core->add_bank (bank);
       presence_core->add_cluster (bank);
       core.add (bank);
-      contact_core->add_contact_decorator (bank);
       presence_core->add_presentity_decorator (bank);
       call_manager->ready.connect (boost::bind (&Opal::Bank::call_manager_ready, &*bank));
       call_manager->setup ();
diff --git a/lib/engine/components/opal/sip-endpoint.cpp b/lib/engine/components/opal/sip-endpoint.cpp
index a58a833..9d0aaef 100644
--- a/lib/engine/components/opal/sip-endpoint.cpp
+++ b/lib/engine/components/opal/sip-endpoint.cpp
@@ -38,7 +38,6 @@
 
 #include <glib/gi18n.h>
 #include "config.h"
-#include "contact-action.h"
 #include "sip-endpoint.h"
 #include "chat-core.h"
 
@@ -119,7 +118,6 @@ Opal::Sip::EndPoint::EndPoint (Opal::CallManager & _manager,
   manager (_manager)
 {
   boost::shared_ptr<Ekiga::ChatCore> chat_core = core.get<Ekiga::ChatCore> ("chat-core");
-  boost::shared_ptr<Ekiga::ContactCore> contact_core = core.get<Ekiga::ContactCore> ("contact-core");
 
   protocol_name = "sip";
   uri_prefix = "sip:";
@@ -147,9 +145,6 @@ Opal::Sip::EndPoint::EndPoint (Opal::CallManager & _manager,
 
   settings = boost::shared_ptr<Ekiga::Settings> (new Ekiga::Settings (SIP_SCHEMA));
   settings->changed.connect (boost::bind (&EndPoint::setup, this, _1));
-
-  /* Ready to take actions */
-  register_actions (contact_core);
 }
 
 
@@ -179,53 +174,11 @@ Opal::Sip::EndPoint::setup (std::string setting)
 
 
 bool
-Opal::Sip::EndPoint::populate_menu (const std::string& fullname,
-                                   const std::string& uri,
-                                   Ekiga::MenuBuilder& builder)
-{
-  /*
-  if (0 == GetConnectionCount ())
-    builder.add_action ("phone-pick-up", _("Call"),
-                        boost::bind (&Opal::Sip::EndPoint::on_dial, this, uri));
-  else
-    builder.add_action ("mail-forward", _("Transfer"),
-                        boost::bind (&Opal::Sip::EndPoint::on_transfer, this, uri));
-  builder.add_action ("im-message-new", _("Message"),
-                      boost::bind (&Opal::Sip::EndPoint::on_message, this, uri, fullname));
-*/
-  return true;
-}
-
-
-void
-Opal::Sip::EndPoint::register_actions (boost::shared_ptr<Ekiga::ContactCore> ccore)
-{
-  ccore->add_action (Ekiga::ActionPtr (
-    new Ekiga::ContactAction ("sip-call", _("Call"),
-                              boost::bind (&Opal::Sip::EndPoint::on_dial,
-                                           this, _1, _2),
-                              boost::bind (&Opal::Sip::EndPoint::is_valid_uri,
-                                           this, _2))));
-  ccore->add_action (Ekiga::ActionPtr (
-    new Ekiga::ContactAction ("sip-transfer", _("Transfer"),
-                              boost::bind (&Opal::Sip::EndPoint::on_transfer,
-                                           this, _1, _2),
-                              boost::bind (&Opal::Sip::EndPoint::can_transfer,
-                                           this, _2))));
-  ccore->add_action (Ekiga::ActionPtr (
-    new Ekiga::ContactAction ("sip-message", _("Message"),
-                              boost::bind (&Opal::Sip::EndPoint::on_message,
-                                           this, _1, _2),
-                              boost::bind (&Opal::Sip::EndPoint::is_valid_uri,
-                                           this, _2))));
-}
-
-
-bool
 Opal::Sip::EndPoint::send_message (const std::string & _uri,
                                   const std::string & _message)
 {
-  if (!_uri.empty () && (_uri.find ("sip:") == 0 || _uri.find (':') == string::npos) && !_message.empty ()) {
+  if (is_supported_uri (_uri) && !_message.empty ()) {
+
     OpalIM im;
     im.m_to = PURL (_uri);
     im.m_mimeType = "text/plain;charset=UTF-8";
@@ -243,23 +196,67 @@ Opal::Sip::EndPoint::dial (const std::string & uri)
 {
   std::stringstream ustr;
 
-  if (uri.find ("sip:") == 0 || uri.find (":") == string::npos) {
+  if (!is_supported_uri (uri))
+    return false;
 
-    if (uri.find (":") == string::npos)
-      ustr << "sip:" << uri;
-    else
-      ustr << uri;
+  if (uri.find (":") == string::npos)
+    ustr << "sip:" << uri;
+  else
+    ustr << uri;
 
-    PString token;
-    manager.SetUpCall("pc:*", ustr.str(), token, (void*) ustr.str().c_str());
+  PString token;
+  manager.SetUpCall("pc:*", ustr.str(), token, (void*) ustr.str().c_str());
 
-    return true;
+  return true;
+}
+
+
+bool
+Opal::Sip::EndPoint::transfer (const std::string & uri,
+                               bool attended)
+{
+  /* This is not handled yet */
+  if (attended)
+    return false;
+
+  if (GetConnectionCount () == 0 || !is_supported_uri (uri))
+      return false; /* No active SIP connection to transfer, or
+                     * transfer request to unsupported uri
+                     */
+
+  /* We don't handle several calls here */
+  for (PSafePtr<OpalConnection> connection(connectionsActive, PSafeReference);
+       connection != NULL;
+       ++connection) {
+    if (!PIsDescendant(&(*connection), OpalPCSSConnection)) {
+      connection->TransferConnection (uri);
+      return true; /* We could handle the transfer */
+    }
   }
 
   return false;
 }
 
 
+bool
+Opal::Sip::EndPoint::message (const Ekiga::ContactPtr & contact,
+                              const std::string & uri)
+{
+  if (!is_supported_uri (uri))
+    return false;
+
+  dialect->start_chat_with (uri, contact->get_name ());
+  return true;
+}
+
+
+bool
+Opal::Sip::EndPoint::is_supported_uri (const std::string & uri)
+{
+  return (!uri.empty () && (uri.find ("sip:") == 0 || uri.find (':') == string::npos));
+}
+
+
 const std::string&
 Opal::Sip::EndPoint::get_protocol_name () const
 {
@@ -926,32 +923,6 @@ Opal::Sip::EndPoint::OnDialogInfoReceived (const SIPDialogNotification & info)
 }
 
 
-void Opal::Sip::EndPoint::on_dial (Ekiga::ContactPtr contact,
-                                   const std::string & uri)
-{
-  // FIXME: I really think Ekiga::Contacts are TelephonyContacts and, as such,
-  // should have an uri. All methods should act on Contacts, the Ekiga central
-  // point of things.
-  manager.dial (uri);
-}
-
-
-void Opal::Sip::EndPoint::on_message (Ekiga::ContactPtr contact,
-                                      const std::string & uri)
-{
-  dialect->start_chat_with (uri, contact->get_name ());
-}
-
-
-void Opal::Sip::EndPoint::on_transfer (Ekiga::ContactPtr contact,
-                                       const std::string & uri)
-{
-  /* FIXME : we don't handle several calls here */
-  for (PSafePtr<OpalConnection> connection(connectionsActive, PSafeReference); connection != NULL; 
++connection)
-    if (!PIsDescendant(&(*connection), OpalPCSSConnection))
-      connection->TransferConnection (uri);
-}
-
 void
 Opal::Sip::EndPoint::push_message_in_main (const std::string uri,
                                           const std::string name,
@@ -974,17 +945,3 @@ Opal::Sip::EndPoint::update_aor_map (std::map<std::string, std::string> _account
   PWaitAndSignal m(aorMutex);
   accounts = _accounts;
 }
-
-
-bool
-Opal::Sip::EndPoint::is_valid_uri (const std::string & uri)
-{
-  return (!uri.empty () && (uri.find ("sip:") == 0 || uri.find (':') == string::npos));
-}
-
-
-bool
-Opal::Sip::EndPoint::can_transfer (const std::string & uri)
-{
-  return (GetConnectionCount () > 0 && is_valid_uri (uri));
-}
diff --git a/lib/engine/components/opal/sip-endpoint.h b/lib/engine/components/opal/sip-endpoint.h
index ba3ce0f..36a8b46 100644
--- a/lib/engine/components/opal/sip-endpoint.h
+++ b/lib/engine/components/opal/sip-endpoint.h
@@ -47,7 +47,6 @@
 #include "opal-bank.h"
 #include "sip-dialect.h"
 #include "call-core.h"
-#include "contact-core.h"
 #include "services.h"
 
 #include "opal-call-manager.h"
@@ -84,15 +83,6 @@ namespace Opal {
       const std::string get_description () const
       { return "\tObject managing SIP objects with the Opal library"; }
 
-      // helper for Opal::Bank's contact/presentity decorator code
-      bool populate_menu (const std::string& fullname,
-                         const std::string& uri,
-                         Ekiga::MenuBuilder& builder);
-
-
-      /* Register actions on the ContactCore */
-      void register_actions (boost::shared_ptr<Ekiga::ContactCore> contact_core);
-
 
       /* Chat subsystem */
       bool send_message (const std::string & uri,
@@ -101,6 +91,12 @@ namespace Opal {
 
       /* CallProtocolManager */
       bool dial (const std::string & uri);
+      bool transfer (const std::string & uri,
+                     bool attended);
+      bool message (const Ekiga::ContactPtr & contact,
+                    const std::string & uri);
+      bool is_supported_uri (const std::string & uri);
+
 
       const std::string & get_protocol_name () const;
 
@@ -170,26 +166,9 @@ namespace Opal {
       SIPURL GetRegisteredPartyName (const SIPURL & host,
                                     const OpalTransport & transport);
 
-      /* Return true if URI can be handled by the endpoint,
-       * false otherwise.
-       */
-      bool is_valid_uri (const std::string & uri);
-
-      /* Return true if the endpoint is currently handling one or more calls,
-       * and there is an active call to transfer, false otherwise.
-       */
-      bool can_transfer (const std::string & uri);
-
 
       /* Callbacks */
     private:
-      void on_dial (Ekiga::ContactPtr contact,
-                    const std::string & uri);
-      void on_message (Ekiga::ContactPtr contact,
-                       const std::string & uri);
-      void on_transfer (Ekiga::ContactPtr contact,
-                        const std::string & uri);
-
       void push_message_in_main (const std::string uri,
                                 const std::string name,
                                 const std::string msg);
diff --git a/lib/engine/protocol/call-core.cpp b/lib/engine/protocol/call-core.cpp
index 8ed0027..30947dd 100644
--- a/lib/engine/protocol/call-core.cpp
+++ b/lib/engine/protocol/call-core.cpp
@@ -34,12 +34,25 @@
  *
  */
 
+#include "config.h"
+
+#include <glib/gi18n.h>
+
 #include "call-core.h"
+
+
 #include "call-manager.h"
+#include "contact-action.h"
 
 
 using namespace Ekiga;
 
+CallCore::CallCore ()
+{
+  nr_ready = 0;
+}
+
+
 void CallCore::add_manager (boost::shared_ptr<CallManager> manager)
 {
   managers.insert (manager);
@@ -63,17 +76,17 @@ CallCore::const_iterator CallCore::begin () const
 
 CallCore::iterator CallCore::end ()
 {
-  return managers.end (); 
+  return managers.end ();
 }
 
 
 CallCore::const_iterator CallCore::end () const
 {
-  return managers.end (); 
+  return managers.end ();
 }
 
 
-bool CallCore::dial (const std::string uri)
+bool CallCore::dial (const std::string & uri)
 {
   for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
        iter != managers.end ();
@@ -95,21 +108,91 @@ void CallCore::hang_up ()
 }
 
 
+bool CallCore::transfer (const std::string & uri,
+                         bool attended)
+{
+  for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+    if ((*iter)->transfer (uri, attended))
+      return true;
+  }
+
+  return false;
+}
+
+
+bool CallCore::message (const ContactPtr & contact,
+                        const std::string & uri)
+{
+  for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+    if ((*iter)->message (contact, uri))
+      return true;
+  }
+
+  return false;
+}
+
+
+bool CallCore::is_supported_uri (const std::string & uri)
+{
+  for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
+       iter != managers.end ();
+       iter++) {
+    if ((*iter)->is_supported_uri (uri))
+      return true;
+  }
+
+  return false;
+}
+
+
+void CallCore::register_actions (boost::shared_ptr<ContactCore> ccore)
+{
+  ccore->add_action (ActionPtr (
+                       new ContactAction ("call", _("Call"),
+                                          boost::bind (&CallCore::dial,
+                                                       this, _2),
+                                          boost::bind (&CallCore::is_supported_uri,
+                                                       this, _2))));
+
+  ccore->add_action (ActionPtr (
+                       new ContactAction ("message", _("Message"),
+                                          boost::bind (&CallCore::message,
+                                                       this, _1, _2),
+                                          boost::bind (&CallCore::is_supported_uri,
+                                                       this, _2))));
+}
+
+
 void CallCore::add_call (boost::shared_ptr<Call> call, boost::shared_ptr<CallManager> manager)
 {
   boost::shared_ptr<Ekiga::scoped_connections> conns(new Ekiga::scoped_connections);
 
-  conns->add (call->ringing.connect (boost::bind (&CallCore::on_ringing_call, this, call, manager)));
-  conns->add (call->setup.connect (boost::bind (&CallCore::on_setup_call, this, call, manager)));
-  conns->add (call->missed.connect (boost::bind (&CallCore::on_missed_call, this, call, manager)));
-  conns->add (call->cleared.connect (boost::bind (&CallCore::on_cleared_call, this, _1, call, manager)));
-  conns->add (call->established.connect (boost::bind (&CallCore::on_established_call, this, call, manager)));
-  conns->add (call->held.connect (boost::bind (&CallCore::on_held_call, this, call, manager)));
-  conns->add (call->retrieved.connect (boost::bind (&CallCore::on_retrieved_call, this, call, manager)));
-  conns->add (call->stream_opened.connect (boost::bind (&CallCore::on_stream_opened, this, _1, _2, _3, call, 
manager)));
-  conns->add (call->stream_closed.connect (boost::bind (&CallCore::on_stream_closed, this, _1, _2, _3, call, 
manager)));
-  conns->add (call->stream_paused.connect (boost::bind (&CallCore::on_stream_paused, this, _1, _2, call, 
manager)));
-  conns->add (call->stream_resumed.connect (boost::bind (&CallCore::on_stream_resumed, this, _1, _2, call, 
manager)));
+  conns->add (call->ringing.connect (boost::bind (&CallCore::on_ringing_call, this,
+                                                  call, manager)));
+  conns->add (call->setup.connect (boost::bind (&CallCore::on_setup_call, this,
+                                                call, manager)));
+  conns->add (call->missed.connect (boost::bind (&CallCore::on_missed_call, this,
+                                                 call, manager)));
+  conns->add (call->cleared.connect (boost::bind (&CallCore::on_cleared_call, this,
+                                                  _1, call, manager)));
+  conns->add (call->established.connect (boost::bind (&CallCore::on_established_call, this,
+                                                      call, manager)));
+  conns->add (call->held.connect (boost::bind (&CallCore::on_held_call, this,
+                                               call, manager)));
+  conns->add (call->retrieved.connect (boost::bind (&CallCore::on_retrieved_call, this,
+                                                    call, manager)));
+  conns->add (call->stream_opened.connect (boost::bind (&CallCore::on_stream_opened, this,
+                                                        _1, _2, _3, call, manager)));
+  conns->add (call->stream_closed.connect (boost::bind (&CallCore::on_stream_closed, this,
+                                                        _1, _2, _3, call, manager)));
+  conns->add (call->stream_paused.connect (boost::bind (&CallCore::on_stream_paused, this,
+                                                        _1, _2, call, manager)));
+  conns->add (call->stream_resumed.connect (boost::bind (&CallCore::on_stream_resumed, this,
+                                                         _1, _2, call, manager)));
   conns->add (call->removed.connect (boost::bind (&CallCore::on_call_removed, this, call)));
 
   call_connections [call->get_id ()] = conns;
diff --git a/lib/engine/protocol/call-core.h b/lib/engine/protocol/call-core.h
index 945acbe..1816dd0 100644
--- a/lib/engine/protocol/call-core.h
+++ b/lib/engine/protocol/call-core.h
@@ -44,6 +44,7 @@
 #include "call.h"
 #include "call-manager.h"
 #include "call-protocol-manager.h"
+#include "contact-core.h"
 
 #include <boost/smart_ptr.hpp>
 #include <boost/signals2.hpp>
@@ -73,7 +74,7 @@ namespace Ekiga
 
       /** The constructor
        */
-      CallCore () { nr_ready = 0; }
+      CallCore ();
 
 
       /*** Service Implementation ***/
@@ -115,7 +116,7 @@ namespace Ekiga
       const_iterator begin () const;
 
       /** Return iterator to end
-       * @return iterator to end 
+       * @return iterator to end
        */
       iterator end ();
       const_iterator end () const;
@@ -126,21 +127,53 @@ namespace Ekiga
       boost::signals2::signal<void(boost::shared_ptr<CallManager>)> manager_added;
 
 
-      /*** Call Management ***/                 
+      /*** Call Management ***/
 
       /** Create a call based on the remote uri given as parameter
-       * @param: an uri to call
-       * @return: true if a Ekiga::Call could be created
+       * @param an uri to call
+       * @return true if a Ekiga::Call could be created
        */
-      bool dial (const std::string uri); 
+      bool dial (const std::string & uri);
+
+      /** Transfer the call to the specified uri
+       * @param the destination uri
+       * @param true if we should do an attended transfer, false if
+       *        a blind transfer is required.
+       * @return true if the Ekiga::Call transfer could be attempted,
+       *         false otherwise. Returning true does not mean the
+       *         transfer succeeded, it simply means it could be handled.
+       */
+      bool transfer (const std::string & uri,
+                     bool attended);
+
+      /** Sends an instant message to the given contact
+       * @param the destination contact
+       * @param the destination uri
+       * @return true if the message transmission could be attempted,
+       *         false otherwise. Returning true does not mean the
+       *         message was sent, it simply means it could be handled.
+       */
+      bool message (const ContactPtr & contact,
+                    const std::string & uri);
 
       /** Hang up all active calls (if any).
        */
       void hang_up ();
 
+      /* Return true if URI can be handled by the CallCore,
+       * false otherwise.
+       * @param the URI to test
+       * @return true of the URI can be handled, false otherwise
+       */
+      bool is_supported_uri (const std::string & uri);
+
+
+      /*** Actor stuff ***/
+      void register_actions (boost::shared_ptr<ContactCore> contact_core);
+
 
       /*** Call Related Signals ***/
-      
+
       /** See call.h for the API
        */
       boost::signals2::signal<void(boost::shared_ptr<CallManager>, boost::shared_ptr<Call>)> ringing_call;
@@ -186,7 +219,7 @@ namespace Ekiga
 
       void on_call_removed (boost::shared_ptr<Call> call);
 
-      
+
       std::set<boost::shared_ptr<CallManager> > managers;
       std::map<std::string, boost::shared_ptr<Ekiga::scoped_connections> > call_connections;
       unsigned nr_ready;
diff --git a/lib/engine/protocol/call-manager.h b/lib/engine/protocol/call-manager.h
index b3934bf..66d039a 100644
--- a/lib/engine/protocol/call-manager.h
+++ b/lib/engine/protocol/call-manager.h
@@ -56,7 +56,7 @@ namespace Ekiga
  * @{
  */
 
-  class CallManager 
+  class CallManager
   {
 
     public:
@@ -116,6 +116,34 @@ namespace Ekiga
      */
     virtual void hang_up () = 0;
 
+    /** Transfer the call to the specified uri
+     * @param the destination uri
+     * @param true if we should do an attended transfer, false if
+     *        a blind transfer is required.
+     * @return true if the Ekiga::Call transfer could be attempted,
+     *         false otherwise. Returning true does not mean the
+     *         transfer succeeded, it simply means it could be handled.
+     */
+    virtual bool transfer (const std::string & uri,
+                           bool attended) = 0;
+
+    /** Sends an instant message to the given contact
+     * @param the destination contact
+     * @param the destination uri
+     * @return true if the message transmission could be attempted,
+     *         false otherwise. Returning true does not mean the
+     *         message was sent, it simply means it could be handled.
+     */
+    virtual bool message (const ContactPtr & contact,
+                          const std::string & uri) = 0;
+
+    /* Return true if URI can be handled by the CallCore,
+     * false otherwise.
+     * @param the URI to test
+     * @return true of the URI can be handled, false otherwise
+     */
+    virtual bool is_supported_uri (const std::string & uri) = 0;
+
 
     /*
      * PROTOCOL INFORMATION
diff --git a/lib/engine/protocol/call-protocol-manager.h b/lib/engine/protocol/call-protocol-manager.h
index 93271fa..c5b3738 100644
--- a/lib/engine/protocol/call-protocol-manager.h
+++ b/lib/engine/protocol/call-protocol-manager.h
@@ -43,6 +43,8 @@
 
 #include <boost/smart_ptr.hpp>
 
+#include "contact.h"
+
 namespace Ekiga
 {
 
@@ -75,15 +77,43 @@ namespace Ekiga
     virtual ~CallProtocolManager () {};
 
 
-    /*                 
-     * CALL MANAGEMENT 
-     */               
+    /*
+     * CALL MANAGEMENT
+     */
 
     /** Create a call based on the remote uri given as parameter
      * @param: An uri
      * @return: true if a Ekiga::Call could be created
      */
-    virtual bool dial (const std::string & uri) = 0; 
+    virtual bool dial (const std::string & uri) = 0;
+
+    /** Transfer the call to the specified uri
+     * @param the destination uri
+     * @param true if we should do an attended transfer, false if
+     *        a blind transfer is required.
+     * @return true if the Ekiga::Call transfer could be attempted,
+     *         false otherwise. Returning true does not mean the
+     *         transfer succeeded, it simply means it could be handled.
+     */
+    virtual bool transfer (const std::string & uri,
+                           bool attended) = 0;
+
+    /** Sends an instant message to the given contact
+     * @param the destination contact
+     * @param the destination uri
+     * @return true if the message transmission could be attempted,
+     *         false otherwise. Returning true does not mean the
+     *         message was sent, it simply means it could be handled.
+     */
+    virtual bool message (const ContactPtr & contact,
+                          const std::string & uri) = 0;
+
+    /* Return true if URI can be handled by the CallCore,
+     * false otherwise.
+     * @param the URI to test
+     * @return true of the URI can be handled, false otherwise
+     */
+    virtual bool is_supported_uri (const std::string & uri) = 0;
 
 
     /*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]