ekiga r6429 - in trunk: . lib lib/engine lib/engine/account lib/engine/account/skel lib/engine/components/avahi-publisher lib/engine/gui/gtk-frontend lib/engine/presence/avahi lib/engine/presence/local-roster lib/engine/presence/skel lib/engine/protocol/skel src src/endpoints src/gui



Author: dsandras
Date: Mon Jun 30 20:58:35 2008
New Revision: 6429
URL: http://svn.gnome.org/viewvc/ekiga?rev=6429&view=rev

Log:
Created an AccountCore to manage registrations. This AccountCore has
various signals to notify from registration changes. It uses Banks of
Accounts. It is also using AccountSubscribers which are doing the real
job of registering an Account.
We current support OPAL accounts registered with SIP and H323
AccountSubscribers.
More work to come. Initial commit.


Added:
   trunk/lib/engine/account/
   trunk/lib/engine/account/Makefile.am
   trunk/lib/engine/account/skel/
   trunk/lib/engine/account/skel/Makefile.am
   trunk/lib/engine/account/skel/account-core.cpp
   trunk/lib/engine/account/skel/account-core.h
   trunk/lib/engine/account/skel/account.h
   trunk/lib/engine/account/skel/bank-impl.h
   trunk/lib/engine/account/skel/bank.h
   trunk/src/endpoints/opal-account.cpp
   trunk/src/endpoints/opal-account.h
   trunk/src/endpoints/opal-bank.cpp
   trunk/src/endpoints/opal-bank.h
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/lib/engine/Makefile.am
   trunk/lib/engine/components/avahi-publisher/Makefile.am
   trunk/lib/engine/components/avahi-publisher/avahi-publisher.h
   trunk/lib/engine/engine.cpp
   trunk/lib/engine/gui/gtk-frontend/Makefile.am
   trunk/lib/engine/presence/avahi/Makefile.am
   trunk/lib/engine/presence/local-roster/Makefile.am
   trunk/lib/engine/presence/local-roster/local-cluster.cpp
   trunk/lib/engine/presence/local-roster/local-presentity.cpp
   trunk/lib/engine/presence/skel/Makefile.am
   trunk/lib/engine/presence/skel/presence-core.cpp
   trunk/lib/engine/presence/skel/presence-core.h
   trunk/lib/engine/protocol/skel/call-core.cpp
   trunk/lib/engine/protocol/skel/call-core.h
   trunk/lib/engine/protocol/skel/call-manager.h
   trunk/lib/gmmarshallers.c
   trunk/src/Makefile.am
   trunk/src/endpoints/accountshandler.cpp
   trunk/src/endpoints/ekiga.cpp
   trunk/src/endpoints/h323.cpp
   trunk/src/endpoints/h323.h
   trunk/src/endpoints/manager.cpp
   trunk/src/endpoints/manager.h
   trunk/src/endpoints/opal-main.cpp
   trunk/src/endpoints/sip.cpp
   trunk/src/endpoints/sip.h
   trunk/src/gui/accounts.cpp
   trunk/src/gui/accounts.h
   trunk/src/gui/assistant.cpp
   trunk/src/gui/conf.cpp
   trunk/src/gui/main.cpp
   trunk/src/gui/tools.cpp

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Mon Jun 30 20:58:35 2008
@@ -601,6 +601,8 @@
 sounds/Makefile
 help/Makefile
 lib/engine/Makefile
+lib/engine/account/Makefile
+lib/engine/account/skel/Makefile
 lib/engine/addressbook/Makefile
 lib/engine/addressbook/call-history/Makefile
 lib/engine/addressbook/evolution/Makefile

Modified: trunk/lib/engine/Makefile.am
==============================================================================
--- trunk/lib/engine/Makefile.am	(original)
+++ trunk/lib/engine/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -1,4 +1,4 @@
-SUBDIRS = framework addressbook presence chat gui protocol videooutput videoinput audioinput audiooutput hal components
+SUBDIRS = framework account addressbook presence chat gui protocol videooutput videoinput audioinput audiooutput hal components
 
 noinst_LTLIBRARIES = libekiga_engine.la
 
@@ -14,10 +14,11 @@
 	-I$(top_srcdir)/lib/engine/addressbook/call-history		\
 	-I$(top_srcdir)/lib/engine/addressbook/evolution		\
 	-I$(top_srcdir)/lib/engine/addressbook/ldap			\
+	-I$(top_srcdir)/lib/engine/account/skel				\
 	-I$(top_srcdir)/lib/engine/presence/skel			\
 	-I$(top_srcdir)/lib/engine/presence/avahi			\
 	-I$(top_srcdir)/lib/engine/presence/local-roster		\
-	-I$(top_srcdir)/lib/engine/videooutput/skel				\
+	-I$(top_srcdir)/lib/engine/videooutput/skel			\
 	-I$(top_srcdir)/lib/engine/videoinput/skel			\
 	-I$(top_srcdir)/lib/engine/audioinput/skel			\
 	-I$(top_srcdir)/lib/engine/audiooutput/skel			\
@@ -71,6 +72,7 @@
 	$(top_builddir)/lib/engine/framework/libgmframework.la 						\
 	$(top_builddir)/lib/engine/addressbook/skel/libgmaddressbook.la 				\
 	$(top_builddir)/lib/engine/addressbook/call-history/libcall-history.la 				\
+	$(top_builddir)/lib/engine/account/skel/libaccount.la 						\
 	$(top_builddir)/lib/engine/presence/skel/libgmpresence.la 					\
 	$(top_builddir)/lib/engine/presence/local-roster/liblocal-roster.la 				\
 	$(top_builddir)/lib/engine/videooutput/skel/libgmvideooutput.la					\

Added: trunk/lib/engine/account/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/account/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -0,0 +1 @@
+SUBDIRS = skel

Added: trunk/lib/engine/account/skel/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/lib/engine/account/skel/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,19 @@
+noinst_LTLIBRARIES = libaccount.la
+
+account_dir = $(top_srcdir)/lib/engine/account/skel
+
+AM_CPPFLAGS = $(SIGC_CFLAGS) $(GLIB_CFLAGS)
+
+INCLUDES = \
+	-I$(top_srcdir)/lib/gmconf	 		\
+	-I$(top_srcdir)/lib/engine/include 		\
+	-I$(top_srcdir)/lib/engine/framework
+
+libaccount_la_SOURCES = \
+	$(account_dir)/account.h			\
+	$(account_dir)/bank.h				\
+	$(account_dir)/bank-impl.h			\
+	$(account_dir)/account-core.h			\
+	$(account_dir)/account-core.cpp
+
+libaccount_la_LDFLAGS = -export-dynamic -no-undefined $(SIGC_LIBS) $(GLIB_LIBS)

Added: trunk/lib/engine/account/skel/account-core.cpp
==============================================================================
--- (empty file)
+++ trunk/lib/engine/account/skel/account-core.cpp	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,100 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         account-core.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : implementation of the main account managing object
+ *
+ */
+
+#include <iostream>
+
+#include "config.h"
+
+#include "account-core.h"
+#include "bank.h"
+
+Ekiga::AccountCore::AccountCore ()
+{
+}
+
+
+Ekiga::AccountCore::~AccountCore ()
+{
+}
+
+
+bool Ekiga::AccountCore::populate_menu (MenuBuilder & builder)
+{
+  bool populated = false;
+
+  for (bank_const_iterator iter = banks.begin ();
+       iter != banks.end ();
+       iter++) {
+
+    populated = (*iter)->populate_menu (builder);
+  }
+
+  return populated;
+}
+
+
+void Ekiga::AccountCore::add_bank (Bank &bank)
+{
+  banks.insert (&bank);
+
+  bank.account_added.connect (account_added.make_slot ());
+  bank.account_removed.connect (account_removed.make_slot ());
+  bank.account_updated.connect (account_updated.make_slot ());
+
+  bank_added.emit (bank);
+
+  bank.questions.add_handler (questions.make_slot ());
+}
+
+
+void Ekiga::AccountCore::visit_banks (sigc::slot<bool, Bank &> visitor)
+{
+  bool go_on = true;
+
+  for (bank_iterator iter = banks.begin ();
+       iter != banks.end () && go_on;
+       iter++)
+    go_on = visitor (*(*iter));
+}
+
+
+void Ekiga::AccountCore::add_account_subscriber (AccountSubscriber &subscriber)
+{
+  account_subscribers.insert (&subscriber);
+
+  subscriber.registration_event.connect (registration_event.make_slot ());
+}
+
+

Added: trunk/lib/engine/account/skel/account-core.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/account/skel/account-core.h	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,262 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         account-core.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : interface of the main account managing object
+ *
+ */
+
+#ifndef __ACCOUNT_CORE_H__
+#define __ACCOUNT_CORE_H__
+
+#include <set>
+#include <iostream>
+
+#include "menu-builder.h"
+#include "form-request.h"
+#include "chain-of-responsibility.h"
+#include "services.h"
+
+
+/* declaration of a few helper classes */
+namespace Ekiga
+{
+  class AccountSubscriber;
+  class Bank;
+  class Account;
+
+/**
+ * @defgroup accounts 
+ * @{
+ */
+
+  /** Core object for address account support.
+   *
+   * Notice that you give banks to this object as references, so they won't
+   * be freed here : it's up to you to free them somehow.
+   */
+  class AccountCore: public Service
+  {
+  public:
+
+    /** The constructor.
+     */
+    AccountCore ();
+
+    /** The destructor.
+     */
+    ~AccountCore ();
+
+
+    /*** Service Implementation ***/
+
+    /** Returns the name of the service.
+     * @return The service name.
+     */
+    const std::string get_name () const
+    { return "account-core"; }
+
+
+    /** Returns the description of the service.
+     * @return The service description.
+     */
+    const std::string get_description () const
+    { return "\tAccount managing object"; }
+
+
+    /*** Public API ***/
+
+    /** Adds a bank to the AccountCore service.
+     * @param The bank to be added.
+     */
+    void add_bank (Bank &bank);
+
+
+    /** Triggers a callback for all Ekiga::Bank banks of the
+     * AccountCore service.
+     * @param The callback (the return value means "go on" and allows
+     *  stopping the visit)
+     */
+    void visit_banks (sigc::slot<bool, Bank &> visitor);
+
+
+    /** This signal is emitted when a bank has been added to the core
+     */
+    sigc::signal<void, Bank &> bank_added;
+
+    /** This signal is emitted when a account has been added to one of
+     * the banks
+     */
+    sigc::signal<void, Account &> account_added;
+
+    /** This signal is emitted when a account has been removed from one of
+     * the banks
+     */
+    sigc::signal<void, Account &> account_removed;
+
+    /** This signal is emitted when a account has been updated in one of
+     * the banks
+     */
+    sigc::signal<void, Account &> account_updated;
+
+  private:
+
+    std::set<Bank *> banks;
+    typedef std::set<Bank *>::iterator bank_iterator;
+    typedef std::set<Bank *>::const_iterator bank_const_iterator;
+
+
+    /*** Account Subscriber API ***/
+  public:
+    void add_account_subscriber (AccountSubscriber &subscriber);
+
+    template<class T>
+    bool subscribe_account (const T &account);
+
+    template<class T>
+    bool unsubscribe_account (const T &account);
+
+  private:
+    std::set<AccountSubscriber *> account_subscribers;
+    typedef std::set<AccountSubscriber *>::iterator subscriber_iterator;
+    typedef std::set<AccountSubscriber *>::const_iterator subscriber_const_iterator;
+
+
+    /*** Misc ***/
+
+  public:
+    typedef enum { Processing, Registered, Unregistered, RegistrationFailed, UnregistrationFailed } RegistrationState;
+
+
+    /** Create the menu for the AccountCore and its actions.
+     * @param A MenuBuilder object to populate.
+     */
+    bool populate_menu (MenuBuilder &builder);
+
+    /** This signal is emitted when the AccountCore Service has been
+     * updated.
+     */
+    sigc::signal<void> updated;
+
+
+    /** This chain allows the AccountCore to present forms to the user
+     */
+    ChainOfResponsibility<FormRequest*> questions;
+
+
+    /** This signal is emitted when there is a new registration event
+     * @param: account is the account uri
+     *         state is the state
+     *         info contains information about the registration status
+     */
+    sigc::signal<void, std::string, Ekiga::AccountCore::RegistrationState, std::string> registration_event;
+  };
+
+
+  class AccountSubscriber 
+  {
+public:
+    virtual ~AccountSubscriber () {}
+
+    /* Implemented by the object implementing an AccountSubscriberImpl */
+    virtual bool subscribe (const Ekiga::Account & account) = 0;
+    virtual bool unsubscribe (const Ekiga::Account & account) = 0;
+
+    /** This signal is emitted when there is a new registration event
+     * @param: account is the account uri
+     *         state is the state
+     *         info contains information about the registration status
+     */
+    sigc::signal<void, std::string, Ekiga::AccountCore::RegistrationState, std::string> registration_event;
+  };
+
+
+  template<class T = Account>
+  class AccountSubscriberImpl : public AccountSubscriber
+  {
+public:
+    virtual ~AccountSubscriberImpl () {}
+
+    virtual bool subscribe (const T & /*account*/);
+    virtual bool unsubscribe (const T & /*account*/);
+  };
+
+/**
+ * @}
+ */
+};
+
+
+
+template<class T>
+bool Ekiga::AccountCore::subscribe_account (const T &account)
+{
+  if (!account.is_enabled ())
+    return false;
+
+  for (subscriber_iterator iter = account_subscribers.begin ();
+       iter != account_subscribers.end ();
+       iter++)
+    if ((*iter)->subscribe (account))
+      return true;
+
+  return false;
+}
+
+
+template<class T>
+bool Ekiga::AccountCore::unsubscribe_account (const T &account)
+{
+  if (account.is_enabled ())
+    return false;
+
+  for (subscriber_iterator iter = account_subscribers.begin ();
+       iter != account_subscribers.end ();
+       iter++)
+    if ((*iter)->unsubscribe (account))
+      return true;
+
+  return false;
+}
+
+
+template<class T>
+bool Ekiga::AccountSubscriberImpl<T>::subscribe (const T & /*account*/)
+{
+  return false;
+}
+
+
+template<class T>
+bool Ekiga::AccountSubscriberImpl<T>::unsubscribe (const T & /*account*/)
+{
+  return false;
+}
+#endif

Added: trunk/lib/engine/account/skel/account.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/account/skel/account.h	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,176 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         account.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : declaration of the interface of an AccountManager 
+ *                          Account
+ *
+ */
+
+#ifndef __ACCOUNT_H__
+#define __ACCOUNT_H__
+
+#include <set>
+#include <map>
+#include <string>
+
+#include "chain-of-responsibility.h"
+#include "form-request.h"
+#include "menu-builder.h"
+
+namespace Ekiga
+{
+
+/**
+ * @addtogroup accounts 
+ * @{
+ */
+
+  class Account
+  {
+  public:
+
+    /** The destructor.
+     */
+    virtual ~Account () { }
+
+
+    /** Returns the name of the Ekiga::Account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     * @return The name of the Ekiga::Contact.
+     */
+    virtual const std::string get_name () const = 0;
+
+
+    /** Returns the protocol name of the Ekiga::Account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     * @return The protocol name of the Ekiga::Contact.
+     */
+    virtual const std::string get_protocol_name () const = 0;
+
+
+    /** Returns the hostname for the Ekiga::Account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     * @return The host name of the Ekiga::Account.
+     */
+    virtual const std::string get_host () const = 0;
+
+
+    /** Returns the user name for the Ekiga::Account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     * @return The user name of the Ekiga::Account.
+     */
+    virtual const std::string get_username () const = 0;
+
+
+    /** Returns the authentication user name for the Ekiga::Account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     * @return The authentication user name of the Ekiga::Account.
+     */
+    virtual const std::string get_authentication_username () const = 0;
+
+
+    /** Returns the password for the Ekiga::Account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     * @return The password of the Ekiga::Account.
+     */
+    virtual const std::string get_password () const = 0;
+
+
+    /** Returns the registration timeout for the Ekiga::Account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     * @return The timeout of the Ekiga::Account.
+     */
+    virtual unsigned get_timeout () const = 0;
+
+
+    /** Subscribe the given account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     */
+    virtual void enable () = 0;
+
+
+    /** Unsubscribe the given account.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     */
+    virtual void disable () = 0;
+
+
+    /** Return true if the account is active.
+     * It does not mean that the account is successfully registered, it
+     * just means it is active.
+     * This function is purely virtual and should be implemented by the
+     * Ekiga::Account descendant.
+     */
+    virtual bool is_enabled () const = 0;
+    
+    
+    /** Create the menu for that account and its actions.
+     * This function is purely virtual and should be implemented by
+     * the descendant of the Ekiga::Contact.
+     * @param A MenuBuilder object to populate.
+     */
+    virtual bool populate_menu (MenuBuilder &) = 0;
+
+
+    /**
+     * Signals on that object
+     */
+
+    /** This signal is emitted when the Account has been updated.
+     */
+    sigc::signal<void> updated;
+
+
+    /** This signal is emitted when the Account has been removed.
+     */
+    sigc::signal<void> removed;
+
+
+    /** This chain allows the Account to present forms to the user
+     */
+    ChainOfResponsibility<FormRequest*> questions;
+  };
+
+/**
+ * @}
+ */
+
+};
+#endif

Added: trunk/lib/engine/account/skel/bank-impl.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/account/skel/bank-impl.h	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,268 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         bank.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : declaration of a partial implementation
+ *                          of a Bank
+ *
+ */
+
+#ifndef __BANK_IMPL_H__
+#define __BANK_IMPL_H__
+
+#include "lister.h"
+#include "account-core.h"
+#include "account.h"
+#include "bank.h"
+#include "gmconf.h"
+
+namespace Ekiga
+{
+  class AccountCore;
+
+/**
+ * @addtogroup accounts
+ * @{
+ */
+
+  /** Generic implementation for the Ekiga::BankImpl abstract class.
+   *
+   * This class is there to make it easy to implement a new type of account
+   * bank: it will take care of implementing the external api, you
+   * just have to decide when to add and remove accounts.
+   *
+   * You can remove a Account from an Ekiga::BankImpl in two ways:
+   *  - either by calling the remove_account method,
+   *  - or by emission of the account's removed signal.
+   *
+   * Notice that this class won't take care of removing the Account from a
+   * backend -- only from the Ekiga::BankImpl.
+   * If you want the Account <b>deleted</b> from the backend, then you
+   * probably should have an organization like:
+   *  - the account has a 'deleted' signal ;
+   *  - the bank listens to this signal ;
+   *  - when the signal is received, then do a remove_account followed by
+   *    calling the appropriate api function to delete the account in your
+   *    backend.
+   */
+  template<class T = Account>
+  class BankImpl:
+    public Bank,
+    public sigc::trackable,
+    protected Lister<T>
+  {
+
+  public:
+
+    typedef typename Lister<T>::iterator iterator;
+    typedef typename Lister<T>::const_iterator const_iterator;
+
+    /** The constructor
+     */
+    BankImpl (ServiceCore &core);
+
+    /** The destructor.
+     */
+    ~BankImpl ();
+
+    /** Visit all accounts of the bank and trigger the given callback.
+     * @param The callback (the return value means "go on" and allows
+     *  stopping the visit)
+     */
+    void visit_accounts (sigc::slot<bool, Account &> visitor);
+
+    /** This function be called when a new account has to be added to the Bank.
+     */
+    void new_account ();
+  
+  protected:
+
+    /** Returns an iterator to the first Account of the collection
+     */
+    iterator begin ();
+
+    /** Returns an iterator to the last Account of the collection
+     */
+    iterator end ();
+
+    /** Returns a const iterator to the first Account of the collection
+     */
+    const_iterator begin () const;
+
+    /** Returns a const iterator to the last Account of the collection
+     */
+    const_iterator end () const;
+
+    /** Adds a account to the Ekiga::BankImpl.
+     * @param: The account to be added.
+     * @return: The Ekiga::BankImpl 'account_added' signal is emitted when the account
+     * has been added. The Ekiga::BankImpl 'account_updated' signal will be emitted
+     * when the account has been updated and the Ekiga::BankImpl 'account_removed' signal
+     * will be emitted when the account has been removed from the Ekiga::BankImpl.
+     */
+    void add_account (T &account);
+
+    /** Removes a account from the Ekiga::BankImpl.
+     * @param: The account to be removed.
+     * @return: The Ekiga::BankImpl 'account_removed' signal is emitted when the account
+     * has been removed.
+     */
+    void remove_account (T &account);
+
+    /** Save the bank to the GmConf key.
+     */
+    void save () const;
+
+  protected:
+    ServiceCore & core;
+    AccountCore *account_core;
+  };
+
+/**
+ * @}
+ */
+
+};
+
+
+/* here begins the code from the template functions */
+
+template<typename T>
+Ekiga::BankImpl<T>::BankImpl (Ekiga::ServiceCore & _core) : core (_core)
+{
+  /* Account Core */
+  account_core = dynamic_cast<Ekiga::AccountCore*> (core.get ("account-core"));
+
+  /* this is signal forwarding */
+  Lister<T>::object_added.connect (account_added.make_slot ());
+  Lister<T>::object_removed.connect (account_removed.make_slot ());
+  Lister<T>::object_updated.connect (account_updated.make_slot ());
+
+  GSList *accounts = gm_conf_get_string_list ("/apps/ekiga/protocols/accounts_list");
+  GSList *accounts_iter = accounts;
+
+  while (accounts_iter) {
+
+    T *account = new T (core, (char *) accounts_iter->data);
+    add_account (*account);
+
+    accounts_iter = g_slist_next (accounts_iter);
+  }
+
+  g_slist_foreach (accounts, (GFunc) g_free, NULL);
+  g_slist_free (accounts);
+}
+
+
+template<typename T>
+Ekiga::BankImpl<T>::~BankImpl ()
+{
+}
+
+
+template<typename T>
+void
+Ekiga::BankImpl<T>::save () const
+{
+  GSList *accounts = NULL;
+
+  for (const_iterator it = begin ();
+       it != end ();
+       it++)
+    accounts = g_slist_append (accounts, g_strdup ((*it).as_string ().c_str ()));
+
+  gm_conf_set_string_list ("/apps/ekiga/protocols/accounts_list", accounts);
+
+  g_slist_foreach (accounts, (GFunc) g_free, NULL);
+  g_slist_free (accounts);
+}
+
+
+template<typename T>
+void
+Ekiga::BankImpl<T>::visit_accounts (sigc::slot<bool, Account &> visitor)
+{
+  Lister<T>::visit_objects (visitor);
+}
+
+
+template<typename T>
+typename Ekiga::BankImpl<T>::iterator
+Ekiga::BankImpl<T>::begin ()
+{
+  return Lister<T>::begin ();
+}
+
+
+template<typename T>
+typename Ekiga::BankImpl<T>::iterator
+Ekiga::BankImpl<T>::end ()
+{
+  return Lister<T>::end ();
+}
+
+
+template<typename T>
+typename Ekiga::BankImpl<T>::const_iterator
+Ekiga::BankImpl<T>::begin () const
+{
+  return Lister<T>::begin ();
+}
+
+
+template<typename T>
+typename Ekiga::BankImpl<T>::const_iterator
+Ekiga::BankImpl<T>::end () const
+{
+  return Lister<T>::end ();
+}
+
+
+template<typename T>
+void
+Ekiga::BankImpl<T>::add_account (T &account)
+{
+  add_object (account);
+
+  account_core->subscribe_account (account);
+
+  account.questions.add_handler (questions.make_slot ());
+  account.trigger_saving.connect (sigc::mem_fun (this, &Ekiga::BankImpl<T>::save));
+}
+
+
+template<typename T>
+void
+Ekiga::BankImpl<T>::remove_account (T &account)
+{
+  remove_object (account);
+}
+
+#endif

Added: trunk/lib/engine/account/skel/bank.h
==============================================================================
--- (empty file)
+++ trunk/lib/engine/account/skel/bank.h	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,95 @@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+
+ * This program is free software; you can  redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Ekiga is licensed under the GPL license and as a special exception, you
+ * have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination, without
+ * applying the requirements of the GNU GPL to the OPAL, OpenH323 and PWLIB
+ * programs, as long as you do follow the requirements of the GNU GPL for all
+ * the rest of the software thus combined.
+ */
+
+
+/*
+ *                         bank.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : declaration of a partial implementation
+ *                          of a Bank
+ *
+ */
+
+#ifndef __BANK_H__
+#define __BANK_H__
+
+#include "lister.h"
+#include "account-core.h"
+#include "account.h"
+#include "gmconf.h"
+
+namespace Ekiga
+{
+  class AccountCore;
+
+/**
+ * @addtogroup accounts
+ * @{
+ */
+
+  class Bank 
+  {
+  public:
+
+    /** Visit all accounts of the bank and trigger the given callback.
+     * @param The callback (the return value means "go on" and allows
+     *  stopping the visit)
+     */
+    virtual void visit_accounts (sigc::slot<bool, Account &> visitor) = 0;
+
+    /** Create the menu for that Bank and its actions.
+     * This function is purely virtual and should be implemented by
+     * the descendant of the Ekiga::Bank.
+     * @param A MenuBuilder object to populate.
+     */
+    virtual bool populate_menu (MenuBuilder &) = 0;
+      
+
+    /** This signal is emitted when a account has been added.
+     */
+    sigc::signal<void, Account &> account_added;
+
+    /** This signal is emitted when a account has been removed.
+     */
+    sigc::signal<void, Account &> account_removed;
+
+    /** This signal is emitted when a account has been updated.
+     */
+    sigc::signal<void, Account &> account_updated;
+
+
+    /** This chain allows the BankImpl to present forms to the user
+     */
+    ChainOfResponsibility<FormRequest*> questions;
+  };
+
+/**
+ * @}
+ */
+
+};
+#endif

Modified: trunk/lib/engine/components/avahi-publisher/Makefile.am
==============================================================================
--- trunk/lib/engine/components/avahi-publisher/Makefile.am	(original)
+++ trunk/lib/engine/components/avahi-publisher/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -8,8 +8,9 @@
 	-I$(top_srcdir)/lib/gmconf	 		\
 	-I$(top_srcdir)/lib/engine/include 		\
 	-I$(top_srcdir)/lib/engine/framework		\
+	-I$(top_srcdir)/lib/engine/protocol/skel 	\
 	-I$(top_srcdir)/lib/engine/presence/skel 	\
-	-I$(top_srcdir)/lib/engine/protocol/skel 
+	-I$(top_srcdir)/lib/engine/account/skel 
 
 libavahipublisher_la_SOURCES = 						\
 	$(avahi_publisher_dir)/avahi-publisher-main.cpp			\
@@ -18,7 +19,7 @@
 	$(avahi_publisher_dir)/avahi-publisher.h
 
 libavahipublisher_la_LIBADD = 						\
-	$(top_builddir)/lib/engine/protocol/skel/libgmprotocol.la	\
+	$(top_builddir)/lib/engine/account/skel/libaccount.la		\
 	$(top_builddir)/lib/engine/framework/libgmframework.la		\
 	$(top_builddir)/lib/engine/presence/skel/libgmpresence.la
 

Modified: trunk/lib/engine/components/avahi-publisher/avahi-publisher.h
==============================================================================
--- trunk/lib/engine/components/avahi-publisher/avahi-publisher.h	(original)
+++ trunk/lib/engine/components/avahi-publisher/avahi-publisher.h	Mon Jun 30 20:58:35 2008
@@ -52,7 +52,9 @@
 
 #include "call-manager.h"
 
-class Ekiga::PersonalDetails;
+namespace Ekiga {
+  class PersonalDetails;
+}
 
 namespace Avahi
 {

Modified: trunk/lib/engine/engine.cpp
==============================================================================
--- trunk/lib/engine/engine.cpp	(original)
+++ trunk/lib/engine/engine.cpp	Mon Jun 30 20:58:35 2008
@@ -42,6 +42,7 @@
 #include "services.h"
 
 #include "presence-core.h"
+#include "account-core.h"
 #include "contact-core.h"
 #include "call-core.h"
 #include "chat-core.h"
@@ -105,6 +106,7 @@
    * be constructed thereafter                                      */
 
   Ekiga::PresenceCore *presence_core = new Ekiga::PresenceCore;
+  Ekiga::AccountCore *account_core = new Ekiga::AccountCore;
   Ekiga::ContactCore *contact_core = new Ekiga::ContactCore;
   Ekiga::CallCore *call_core = new Ekiga::CallCore;
   Ekiga::ChatCore *chat_core = new Ekiga::ChatCore;
@@ -123,6 +125,7 @@
    *   (e.g. VideoOutputCore).                                          */
    
   core->add (*runtime);
+  core->add (*account_core);
   core->add (*contact_core);
   core->add (*presence_core);
   core->add (*call_core);

Modified: trunk/lib/engine/gui/gtk-frontend/Makefile.am
==============================================================================
--- trunk/lib/engine/gui/gtk-frontend/Makefile.am	(original)
+++ trunk/lib/engine/gui/gtk-frontend/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -11,6 +11,7 @@
 	-I$(top_srcdir)/lib/engine/chat/skel 			\
 	-I$(top_srcdir)/lib/engine/presence/skel 		\
 	-I$(top_srcdir)/lib/engine/protocol/skel 		\
+	-I$(top_srcdir)/lib/engine/account/skel 		\
 	-I$(top_srcdir)/lib/engine/addressbook/skel 		\
 	-I$(top_srcdir)/lib/engine/addressbook/call-history 	\
 	-I$(top_srcdir)/lib/engine/gui/gtk-core 

Modified: trunk/lib/engine/presence/avahi/Makefile.am
==============================================================================
--- trunk/lib/engine/presence/avahi/Makefile.am	(original)
+++ trunk/lib/engine/presence/avahi/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -6,7 +6,7 @@
 
 INCLUDES = \
 	-I$(top_srcdir)/lib/engine/framework \
-	-I$(top_srcdir)/lib/engine/protocol/skel \
+	-I$(top_srcdir)/lib/engine/account/skel \
 	-I$(top_srcdir)/lib/engine/presence/skel
 
 libgmavahi_la_SOURCES = \

Modified: trunk/lib/engine/presence/local-roster/Makefile.am
==============================================================================
--- trunk/lib/engine/presence/local-roster/Makefile.am	(original)
+++ trunk/lib/engine/presence/local-roster/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -8,7 +8,7 @@
 	-I$(top_srcdir)/lib/gmconf	 		\
 	-I$(top_srcdir)/lib/engine/framework 		\
 	-I$(top_srcdir)/lib/engine/addressbook/skel	\
-	-I$(top_srcdir)/lib/engine/protocol/skel	\
+	-I$(top_srcdir)/lib/engine/account/skel		\
 	-I$(top_srcdir)/lib/engine/presence/skel
 
 liblocal_roster_la_SOURCES = \

Modified: trunk/lib/engine/presence/local-roster/local-cluster.cpp
==============================================================================
--- trunk/lib/engine/presence/local-roster/local-cluster.cpp	(original)
+++ trunk/lib/engine/presence/local-roster/local-cluster.cpp	Mon Jun 30 20:58:35 2008
@@ -42,7 +42,7 @@
   presence_core
     = dynamic_cast<Ekiga::PresenceCore*>(core.get ("presence-core"));
 
-  heap = new Heap (core);
+  heap = new Local::Heap (core);
 
   presence_core->presence_received.connect (sigc::mem_fun (this, &Local::Cluster::on_presence_received));
   presence_core->status_received.connect (sigc::mem_fun (this, &Local::Cluster::on_status_received));

Modified: trunk/lib/engine/presence/local-roster/local-presentity.cpp
==============================================================================
--- trunk/lib/engine/presence/local-roster/local-presentity.cpp	(original)
+++ trunk/lib/engine/presence/local-roster/local-presentity.cpp	Mon Jun 30 20:58:35 2008
@@ -212,6 +212,7 @@
 {
   Cluster *cluster = dynamic_cast<Cluster*>(core.get ("local-cluster"));
   Ekiga::FormRequestSimple request;
+
   std::set<std::string> all_groups = cluster->existing_groups ();
 
   request.title (_("Edit roster element"));
@@ -269,8 +270,10 @@
 
 	xmlUnlinkNode (iter->second);
 	xmlFreeNode (iter->second);
-      } else
+      } 
+      else {
 	future_group_nodes[iter->first] = iter->second;
+      }
     }
 
     // the second loop looking for groups we weren't in but are now

Modified: trunk/lib/engine/presence/skel/Makefile.am
==============================================================================
--- trunk/lib/engine/presence/skel/Makefile.am	(original)
+++ trunk/lib/engine/presence/skel/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -8,7 +8,7 @@
 	-I$(top_srcdir)/lib/engine/include \
 	-I$(top_srcdir)/lib/engine/framework \
 	-I$(top_srcdir)/lib/engine/presence/skel \
-	-I$(top_srcdir)/lib/engine/protocol/skel
+	-I$(top_srcdir)/lib/engine/account/skel
 
 libgmpresence_la_SOURCES = \
 	$(presence_dir)/presentity.h		\

Modified: trunk/lib/engine/presence/skel/presence-core.cpp
==============================================================================
--- trunk/lib/engine/presence/skel/presence-core.cpp	(original)
+++ trunk/lib/engine/presence/skel/presence-core.cpp	Mon Jun 30 20:58:35 2008
@@ -37,21 +37,20 @@
 
 #include <iostream>
 
-#include "call-core.h"
+#include "account-core.h"
 #include "presence-core.h"
 #include "personal-details.h"
 
 
 Ekiga::PresencePublisher::PresencePublisher (Ekiga::ServiceCore & core)
 {
-  Ekiga::CallCore *call_core = dynamic_cast <Ekiga::CallCore *> (core.get ("call-core"));
+  Ekiga::AccountCore *account_core = dynamic_cast <Ekiga::AccountCore *> (core.get ("account-core"));
   Ekiga::PersonalDetails *details = dynamic_cast <Ekiga::PersonalDetails *> (core.get ("personal-details"));
 
   if (details)
     details->personal_details_updated.connect (sigc::mem_fun (this, &Ekiga::PresencePublisher::on_personal_details_updated));
-
-  if (call_core)
-    call_core->registration_event.connect (sigc::bind (sigc::mem_fun (this, &Ekiga::PresencePublisher::on_registration_event), details));
+  if (account_core)
+    account_core->registration_event.connect (sigc::bind (sigc::mem_fun (this, &Ekiga::PresencePublisher::on_registration_event), details));
 }
 
 
@@ -61,22 +60,21 @@
 }
 
 
-void Ekiga::PresencePublisher::on_registration_event (Ekiga::CallManager & /*manager*/,
-                                                      std::string /*aor*/,
-                                                      Ekiga::CallCore::RegistrationState state,
+void Ekiga::PresencePublisher::on_registration_event (std::string /*aor*/,
+                                                      Ekiga::AccountCore::RegistrationState state,
                                                       std::string /*info*/,
                                                       Ekiga::PersonalDetails *details)
 {
   switch (state) {
-  case Ekiga::CallCore::Registered:
+  case Ekiga::AccountCore::Registered:
     if (details)
       this->publish (*details);
     break;
 
-  case Ekiga::CallCore::Unregistered:
-  case Ekiga::CallCore::UnregistrationFailed:
-  case Ekiga::CallCore::RegistrationFailed:
-  case Ekiga::CallCore::Processing:
+  case Ekiga::AccountCore::Unregistered:
+  case Ekiga::AccountCore::UnregistrationFailed:
+  case Ekiga::AccountCore::RegistrationFailed:
+  case Ekiga::AccountCore::Processing:
   default:
     break;
   }

Modified: trunk/lib/engine/presence/skel/presence-core.h
==============================================================================
--- trunk/lib/engine/presence/skel/presence-core.h	(original)
+++ trunk/lib/engine/presence/skel/presence-core.h	Mon Jun 30 20:58:35 2008
@@ -40,7 +40,7 @@
 
 #include "services.h"
 #include "cluster.h"
-#include "call-core.h"
+#include "account-core.h"
 
 namespace Ekiga
 {
@@ -110,9 +110,8 @@
 
   private:
     void on_personal_details_updated (PersonalDetails & details);
-    void on_registration_event (Ekiga::CallManager & /*manager*/,
-                                std::string aor,
-                                Ekiga::CallCore::RegistrationState state,
+    void on_registration_event (std::string aor,
+                                Ekiga::AccountCore::RegistrationState state,
                                 std::string /*info*/,
                                 Ekiga::PersonalDetails *details);
   };

Modified: trunk/lib/engine/protocol/skel/call-core.cpp
==============================================================================
--- trunk/lib/engine/protocol/skel/call-core.cpp	(original)
+++ trunk/lib/engine/protocol/skel/call-core.cpp	Mon Jun 30 20:58:35 2008
@@ -52,7 +52,6 @@
   manager_added.emit (manager);
 
   manager.mwi_event.connect (sigc::bind (sigc::mem_fun (this, &CallCore::on_mwi_event), &manager));
-  manager.registration_event.connect (sigc::bind (sigc::mem_fun (this, &CallCore::on_registration_event), &manager));
 }
 
 
@@ -181,12 +180,6 @@
 }
 
 
-void CallCore::on_registration_event (std::string account, Ekiga::CallCore::RegistrationState state, std::string info, CallManager *manager)
-{
-  registration_event.emit (*manager, account, state, info);
-}
-
-
 void CallCore::on_manager_ready (std::string info, CallManager *manager)
 {
   manager_ready.emit (*manager, info);

Modified: trunk/lib/engine/protocol/skel/call-core.h
==============================================================================
--- trunk/lib/engine/protocol/skel/call-core.h	(original)
+++ trunk/lib/engine/protocol/skel/call-core.h	Mon Jun 30 20:58:35 2008
@@ -146,9 +146,6 @@
       // TODO Should move too
       sigc::signal<void, CallManager &, std::string, std::string> mwi_event;
 
-      typedef enum { Processing, Registered, Unregistered, RegistrationFailed, UnregistrationFailed } RegistrationState;
-      sigc::signal<void, CallManager &, std::string, Ekiga::CallCore::RegistrationState, std::string> registration_event;
-
       /*** Misc ***/
       sigc::signal<void, CallManager &, std::string> manager_ready;
 
@@ -172,7 +169,6 @@
       void on_new_chat (std::string, std::string, CallManager *manager);
 
       void on_mwi_event (std::string, std::string, CallManager *manager);
-      void on_registration_event (std::string, Ekiga::CallCore::RegistrationState, std::string, CallManager *manager);
 
       void on_manager_ready (std::string, CallManager *manager);
       

Modified: trunk/lib/engine/protocol/skel/call-manager.h
==============================================================================
--- trunk/lib/engine/protocol/skel/call-manager.h	(original)
+++ trunk/lib/engine/protocol/skel/call-manager.h	Mon Jun 30 20:58:35 2008
@@ -203,13 +203,7 @@
        *         mwi is the message waiting indication
        */
       sigc::signal<void, std::string, std::string> mwi_event;
-
-      /** This signal is emitted when there is a new registration event
-       * @param: account is the voicemail account
-       *         state is the state
-       *         info contains information about the registration status
-       */
-      sigc::signal<void, std::string, Ekiga::CallCore::RegistrationState, std::string> registration_event;
+      //FIXME
 
 
       /*

Modified: trunk/lib/gmmarshallers.c
==============================================================================
--- trunk/lib/gmmarshallers.c	(original)
+++ trunk/lib/gmmarshallers.c	Mon Jun 30 20:58:35 2008
@@ -50,10 +50,10 @@
 /* VOID:STRING,UINT (gmmarshallers.list:1) */
 void
 gm_marshal_VOID__STRING_UINT (GClosure     *closure,
-                              GValue       *return_value,
+                              GValue       *return_value G_GNUC_UNUSED,
                               guint         n_param_values,
                               const GValue *param_values,
-                              gpointer      invocation_hint,
+                              gpointer      invocation_hint G_GNUC_UNUSED,
                               gpointer      marshal_data)
 {
   typedef void (*GMarshalFunc_VOID__STRING_UINT) (gpointer     data1,
@@ -87,10 +87,10 @@
 /* VOID:STRING,STRING (gmmarshallers.list:2) */
 void
 gm_marshal_VOID__STRING_STRING (GClosure     *closure,
-                                GValue       *return_value,
+                                GValue       *return_value G_GNUC_UNUSED,
                                 guint         n_param_values,
                                 const GValue *param_values,
-                                gpointer      invocation_hint,
+                                gpointer      invocation_hint G_GNUC_UNUSED,
                                 gpointer      marshal_data)
 {
   typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer     data1,
@@ -124,10 +124,10 @@
 /* VOID:STRING,BOOLEAN (gmmarshallers.list:3) */
 void
 gm_marshal_VOID__STRING_BOOLEAN (GClosure     *closure,
-                                 GValue       *return_value,
+                                 GValue       *return_value G_GNUC_UNUSED,
                                  guint         n_param_values,
                                  const GValue *param_values,
-                                 gpointer      invocation_hint,
+                                 gpointer      invocation_hint G_GNUC_UNUSED,
                                  gpointer      marshal_data)
 {
   typedef void (*GMarshalFunc_VOID__STRING_BOOLEAN) (gpointer     data1,
@@ -161,10 +161,10 @@
 /* BOOLEAN:STRING (gmmarshallers.list:4) */
 void
 gm_marshal_BOOLEAN__STRING (GClosure     *closure,
-                            GValue       *return_value,
+                            GValue       *return_value G_GNUC_UNUSED,
                             guint         n_param_values,
                             const GValue *param_values,
-                            gpointer      invocation_hint,
+                            gpointer      invocation_hint G_GNUC_UNUSED,
                             gpointer      marshal_data)
 {
   typedef gboolean (*GMarshalFunc_BOOLEAN__STRING) (gpointer     data1,
@@ -200,10 +200,10 @@
 /* BOOLEAN:STRING,STRING (gmmarshallers.list:5) */
 void
 gm_marshal_BOOLEAN__STRING_STRING (GClosure     *closure,
-                                   GValue       *return_value,
+                                   GValue       *return_value G_GNUC_UNUSED,
                                    guint         n_param_values,
                                    const GValue *param_values,
-                                   gpointer      invocation_hint,
+                                   gpointer      invocation_hint G_GNUC_UNUSED,
                                    gpointer      marshal_data)
 {
   typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_STRING) (gpointer     data1,

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Mon Jun 30 20:58:35 2008
@@ -1,15 +1,10 @@
 INCLUDES = \
-	-I$(top_srcdir)/src				\
-	-I$(top_srcdir)/src/clients/			\
-	-I$(top_srcdir)/src/components/			\
-	-I$(top_srcdir)/src/devices/			\
-	-I$(top_srcdir)/src/endpoints/			\
-	-I$(top_srcdir)/src/gui/			\
 	-I$(top_srcdir)/lib				\
 	-I$(top_srcdir)/lib/gmconf			\
 	-I$(top_srcdir)/lib/gui				\
 	-I$(top_srcdir)/lib/engine/			\
 	-I$(top_srcdir)/lib/engine/gui/gtk-frontend	\
+	-I$(top_srcdir)/lib/engine/account/skel		\
 	-I$(top_srcdir)/lib/engine/addressbook/skel	\
 	-I$(top_srcdir)/lib/engine/chat/skel		\
 	-I$(top_srcdir)/lib/engine/presence/skel	\
@@ -19,8 +14,15 @@
 	-I$(top_srcdir)/lib/engine/videoinput/skel	\
 	-I$(top_srcdir)/lib/engine/audioinput/skel	\
 	-I$(top_srcdir)/lib/engine/audiooutput/skel	\
-	-I$(top_srcdir)/lib/engine/hal/skel	\
+	-I$(top_srcdir)/lib/engine/hal/skel		\
 	-I$(top_srcdir)/lib/engine/framework		\
+	-I$(top_srcdir)/lib/engine/gui/gtk-core		\
+	-I$(top_srcdir)/src				\
+	-I$(top_srcdir)/src/clients/			\
+	-I$(top_srcdir)/src/components/			\
+	-I$(top_srcdir)/src/devices/			\
+	-I$(top_srcdir)/src/endpoints/			\
+	-I$(top_srcdir)/src/gui/			\
 	-I$(top_builddir)				\
 	$(GNOME_INCLUDEDIR)				\
 	-DSCHEMA_AGE= SCHEMA_AGE@ 
@@ -87,26 +89,28 @@
 
 
 # Endpoints 
-ekiga_SOURCES +=			\
-	endpoints/accountshandler.h	\
-	endpoints/accountshandler.cpp	\
-	endpoints/ekiga.h		\
-	endpoints/ekiga.cpp		\
-	endpoints/manager.h		\
-	endpoints/manager.cpp		\
-	endpoints/h323.h		\
-	endpoints/h323.cpp		\
-	endpoints/pcss.h		\
-	endpoints/pcss.cpp		\
-	endpoints/sip.h			\
-	endpoints/sip.cpp		\
-	endpoints/opal-call.h		\
-	endpoints/opal-call.cpp		\
+ekiga_SOURCES +=				\
+	endpoints/ekiga.h			\
+	endpoints/ekiga.cpp			\
+	endpoints/manager.h			\
+	endpoints/manager.cpp			\
+	endpoints/h323.h			\
+	endpoints/h323.cpp			\
+	endpoints/pcss.h			\
+	endpoints/pcss.cpp			\
+	endpoints/sip.h				\
+	endpoints/sip.cpp			\
+	endpoints/opal-account.h		\
+	endpoints/opal-account.cpp		\
+	endpoints/opal-bank.h			\
+	endpoints/opal-bank.cpp			\
+	endpoints/opal-call.h			\
+	endpoints/opal-call.cpp			\
 	endpoints/opal-codec-description.h	\
 	endpoints/opal-codec-description.cpp	\
-	endpoints/opal-gmconf-bridge.h	\
-	endpoints/opal-gmconf-bridge.cpp\
-	endpoints/opal-main.h		\
+	endpoints/opal-gmconf-bridge.h		\
+	endpoints/opal-gmconf-bridge.cpp	\
+	endpoints/opal-main.h			\
 	endpoints/opal-main.cpp
 
 if HAVE_DBUS 

Modified: trunk/src/endpoints/accountshandler.cpp
==============================================================================
--- trunk/src/endpoints/accountshandler.cpp	(original)
+++ trunk/src/endpoints/accountshandler.cpp	Mon Jun 30 20:58:35 2008
@@ -152,18 +152,10 @@
 }
 
 
-void GMAccountsEndpoint::SIPRegister (GmAccount *a)
+void GMAccountsEndpoint::SIPRegister (GmAccount * /*a*/)
 {
-  std::string aor;
-  Opal::Sip::CallProtocolManager *sip_manager = dynamic_cast<Opal::Sip::CallProtocolManager *> (ep.get_protocol_manager ("sip"));
-
-  // TODO Move this to the engine and drop the dynamic cast
-  aor = a->username;
-  if (aor.find ("@") == string::npos)
-    aor = aor + "@" + a->host;
+  return;
 
-  if (sip_manager)
-    sip_manager->Register (aor.c_str (), a->auth_username, a->password, a->timeout, !a->enabled);
 }
 
 

Modified: trunk/src/endpoints/ekiga.cpp
==============================================================================
--- trunk/src/endpoints/ekiga.cpp	(original)
+++ trunk/src/endpoints/ekiga.cpp	Mon Jun 30 20:58:35 2008
@@ -45,6 +45,7 @@
 #include "assistant.h"
 #include "tools.h"
 #include "statusicon.h"
+#include "accounts.h"
 #include "main.h"
 #include "misc.h"
 

Modified: trunk/src/endpoints/h323.cpp
==============================================================================
--- trunk/src/endpoints/h323.cpp	(original)
+++ trunk/src/endpoints/h323.cpp	Mon Jun 30 20:58:35 2008
@@ -41,43 +41,80 @@
 #include "h323.h"
 
 #include "opal-call.h"
+#include "account-core.h"
 
 
-class dialer : public PThread
-{
-  PCLASSINFO(dialer, PThread);
-
-public:
+namespace Opal {
 
-  dialer (const std::string & uri, Opal::CallManager & ep) 
-    : PThread (1000, AutoDeleteThread), 
-    dial_uri (uri),
-    endpoint (ep) 
-  {
-    this->Resume ();
-  };
+  namespace H323 {
 
-  void Main () 
+    class dialer : public PThread
     {
-      PString token;
-      endpoint.SetUpCall ("pc:*", dial_uri, token);
+      PCLASSINFO(dialer, PThread);
+
+    public:
+
+      dialer (const std::string & uri, Opal::CallManager & ep) 
+        : PThread (1000, AutoDeleteThread), 
+        dial_uri (uri),
+        endpoint (ep) 
+      {
+        this->Resume ();
+      };
+
+      void Main () 
+        {
+          PString token;
+          endpoint.SetUpCall ("pc:*", dial_uri, token);
+        };
+
+    private:
+      const std::string dial_uri;
+      Opal::CallManager & endpoint;
     };
 
-private:
-  const std::string dial_uri;
-  Opal::CallManager & endpoint;
+    class subscriber : public PThread
+    {
+      PCLASSINFO(subscriber, PThread);
+
+    public:
+
+      subscriber (const Ekiga::Account & _account,
+                  Opal::H323::CallProtocolManager & ep) 
+        : PThread (1000, AutoDeleteThread),
+        account (_account),
+        endpoint (ep) 
+      {
+        this->Resume ();
+      };
+
+      void Main () 
+        {
+          endpoint.Register (account.get_host (), 
+                             account.get_authentication_username (), 
+                             account.get_password (), 
+                             PString (), 
+                             account.get_timeout (), 
+                             false);
+        };
+
+    private:
+      const Ekiga::Account & account;
+      Opal::H323::CallProtocolManager & endpoint;
+    };
+  };
 };
 
 
 using namespace Opal::H323;
 
-
 /* The class */
 CallProtocolManager::CallProtocolManager (Opal::CallManager & ep, Ekiga::ServiceCore & _core, unsigned _listen_port)
                     : H323EndPoint (ep), 
                       endpoint (ep),
                       core (_core),
-                      runtime (*(dynamic_cast<Ekiga::Runtime *> (core.get ("runtime"))))
+                      runtime (*(dynamic_cast<Ekiga::Runtime *> (core.get ("runtime")))),
+                      account_core (*(dynamic_cast<Ekiga::AccountCore *> (core.get ("account-core"))))
 {
   protocol_name = "h323";
   uri_prefix = "h323:";
@@ -239,7 +276,25 @@
 }
 
 
-void CallProtocolManager::Register (const PString & aor,
+bool CallProtocolManager::subscribe (const Ekiga::Account & account)
+{
+  if (account.get_protocol_name () != "H323")
+    return false;
+
+  /* Signal */
+  new subscriber (account, *this);
+
+  return true;
+}
+
+
+bool CallProtocolManager::unsubscribe (const Ekiga::Account & /*account*/)
+{
+  return true;
+}
+
+
+void CallProtocolManager::Register (const PString & host,
                                     const PString & authUserName,
                                     const PString & password,
                                     const PString & gatekeeperID,
@@ -247,25 +302,18 @@
                                     bool unregister)
 {
   PString info;
-  PString host;
-  PINDEX i = 0;
+  PString aor = authUserName + "@" + host;
 
   bool result = false;
 
-  i = aor.Find ("@");
-  if (i == P_MAX_INDEX)
-    return;
-
-  host = aor.Mid (i+1);
-
   if (!unregister && !IsRegisteredWithGatekeeper (host)) {
 
     H323EndPoint::RemoveGatekeeper (0);
 
     /* Signal */
-    runtime.run_in_main (sigc::bind (endpoint.registration_event.make_slot (), 
+    runtime.run_in_main (sigc::bind (account_core.registration_event.make_slot (), 
                                      aor,
-                                     Ekiga::CallCore::Processing,
+                                     Ekiga::AccountCore::Processing,
                                      std::string ()));
 
     if (!authUserName.IsEmpty ()) {
@@ -311,17 +359,17 @@
       else
         info = _("Failed");
 
-      runtime.run_in_main (sigc::bind (endpoint.registration_event.make_slot (), 
+      runtime.run_in_main (sigc::bind (account_core.registration_event.make_slot (), 
                                        aor, 
-                                       Ekiga::CallCore::RegistrationFailed,
+                                       Ekiga::AccountCore::RegistrationFailed,
                                        info));
     }
     else {
 
       /* Signal */
-      runtime.run_in_main (sigc::bind (endpoint.registration_event.make_slot (), 
+      runtime.run_in_main (sigc::bind (account_core.registration_event.make_slot (), 
                                        aor,
-                                       Ekiga::CallCore::Registered,
+                                       Ekiga::AccountCore::Registered,
                                        std::string ()));
     }
   }
@@ -331,9 +379,9 @@
     RemoveAliasName (authUserName);
 
     /* Signal */
-    runtime.run_in_main (sigc::bind (endpoint.registration_event.make_slot (), 
+    runtime.run_in_main (sigc::bind (account_core.registration_event.make_slot (), 
                                      aor,
-                                     Ekiga::CallCore::Unregistered,
+                                     Ekiga::AccountCore::Unregistered,
                                      std::string ()));
   }
 }

Modified: trunk/src/endpoints/h323.h
==============================================================================
--- trunk/src/endpoints/h323.h	(original)
+++ trunk/src/endpoints/h323.h	Mon Jun 30 20:58:35 2008
@@ -44,6 +44,8 @@
 #include "common.h"
 
 #include "manager.h"
+#include "opal-account.h"
+#include "account-core.h"
 
 
 namespace Opal {
@@ -53,6 +55,7 @@
     class CallProtocolManager : public H323EndPoint,
                                 public Ekiga::CallProtocolManager,
                                 public Ekiga::PresentityDecorator,
+                                public Ekiga::AccountSubscriberImpl<Opal::Account>,
                                 public Ekiga::ContactDecorator
     {
       PCLASSINFO(CallProtocolManager, H323EndPoint);
@@ -90,6 +93,10 @@
       const std::string & get_forward_uri () const;
 
 
+      /* AccountSubscriber */
+      bool subscribe (const Ekiga::Account & account);
+      bool unsubscribe (const Ekiga::Account & account);
+
       /* OPAL methods */
       void Register (const PString & aor,
                      const PString & authUserName,
@@ -118,6 +125,7 @@
       CallManager & endpoint;
       Ekiga::ServiceCore & core;
       Ekiga::Runtime & runtime;
+      Ekiga::AccountCore & account_core;
 
       PMutex gk_name_mutex;
       PString gk_name;

Modified: trunk/src/endpoints/manager.cpp
==============================================================================
--- trunk/src/endpoints/manager.cpp	(original)
+++ trunk/src/endpoints/manager.cpp	Mon Jun 30 20:58:35 2008
@@ -111,8 +111,6 @@
   SetTCPPorts (30000, 30100);
   SetRtpIpPorts (5000, 5100);
   
-  manager = NULL;
-
   pcssEP = NULL;
 
   forward_on_no_answer = false;
@@ -149,7 +147,6 @@
 CallManager::~CallManager ()
 {
   ClearAllCalls (OpalConnection::EndedByLocalUser, false);
-  RemoveAccountsEndpoint ();
 }
 
 
@@ -177,7 +174,7 @@
 void CallManager::set_echo_cancellation (bool enabled)
 {
   OpalEchoCanceler::Params ec;
-  
+
   // General settings
   ec = GetEchoCancelParams ();
   if (enabled)
@@ -185,7 +182,7 @@
   else
     ec.m_mode = OpalEchoCanceler::NoCancelation;
   SetEchoCancelParams (ec);
-  
+
   // Adjust setting for all connections of all calls
   for (PSafePtr<OpalCall> call = activeCalls;
        call != NULL;
@@ -198,10 +195,10 @@
       PSafePtr<OpalConnection> connection = call->GetConnection (i);
       if (connection) {
 
-	OpalEchoCanceler *echo_canceler = connection->GetEchoCanceler ();
+        OpalEchoCanceler *echo_canceler = connection->GetEchoCanceler ();
 
-	if (echo_canceler)
-	  echo_canceler->SetParameters (ec);
+        if (echo_canceler)
+          echo_canceler->SetParameters (ec);
       }
     }
   }
@@ -220,7 +217,7 @@
 {
   // Adjust general settings
   SetAudioJitterDelay (20, PMIN (max_val, 1000));
-  
+
   // Adjust setting for all sessions of all connections of all calls
   for (PSafePtr<OpalCall> call = activeCalls;
        call != NULL;
@@ -256,7 +253,7 @@
 void CallManager::set_silence_detection (bool enabled)
 {
   OpalSilenceDetector::Params sd;
-  
+
   // General settings
   sd = GetSilenceDetectParams ();
   if (enabled)
@@ -264,7 +261,7 @@
   else
     sd.m_mode = OpalSilenceDetector::NoSilenceDetection;
   SetSilenceDetectParams (sd);
-  
+
   // Adjust setting for all connections of all calls
   for (PSafePtr<OpalCall> call = activeCalls;
        call != NULL;
@@ -277,10 +274,10 @@
       PSafePtr<OpalConnection> connection = call->GetConnection (i);
       if (connection) {
 
-	OpalSilenceDetector *silence_detector = connection->GetSilenceDetector ();
+        OpalSilenceDetector *silence_detector = connection->GetSilenceDetector ();
 
-	if (silence_detector)
-	  silence_detector->SetParameters (sd);
+        if (silence_detector)
+          silence_detector->SetParameters (sd);
       }
     }
   }
@@ -438,7 +435,7 @@
 }
 
 void CallManager::set_udp_ports (unsigned min_port, 
-                               unsigned max_port)
+                                 unsigned max_port)
 {
   if (min_port < max_port) {
 
@@ -449,14 +446,14 @@
 
 
 void CallManager::get_udp_ports (unsigned & min_port, 
-                               unsigned & max_port) const
+                                 unsigned & max_port) const
 {
   min_port = GetUDPPortBase ();
   max_port = GetUDPPortMax ();
 }
 
 void CallManager::set_tcp_ports (unsigned min_port, 
-                               unsigned max_port)
+                                 unsigned max_port)
 {
   if (min_port < max_port) 
     SetTCPPorts (min_port, max_port);
@@ -464,7 +461,7 @@
 
 
 void CallManager::get_tcp_ports (unsigned & min_port, 
-                               unsigned & max_port) const
+                                 unsigned & max_port) const
 {
   min_port = GetTCPPortBase ();
   max_port = GetTCPPortMax ();
@@ -527,11 +524,11 @@
            media_format.GetName() != "RGB24") {
 
         media_format.SetOptionBoolean (OpalVideoFormat::RateControlEnableOption(),
-                                      true);
+                                       true);
         media_format.SetOptionInteger (OpalVideoFormat::RateControlWindowSizeOption(),
-                                      500);
+                                       500);
         media_format.SetOptionInteger (OpalVideoFormat::RateControlMaxFramesSkipOption(),
-                                      1);
+                                       1);
       }
 
       OpalMediaFormat::SetRegisteredMediaFormat(media_format);
@@ -603,30 +600,6 @@
 }
 
 
-void
-CallManager::Register (GmAccount *account)
-{
-  PWaitAndSignal m(manager_access_mutex);
-
-  if (manager == NULL)
-    manager = new GMAccountsEndpoint (*this);
-
-  if (account != NULL)
-    manager->RegisterAccount (account);
-}
-
-
-void
-CallManager::RemoveAccountsEndpoint ()
-{
-  PWaitAndSignal m(manager_access_mutex);
-
-  if (manager)
-    delete manager;
-  manager = NULL;
-}
-
-
 OpalCall *CallManager::CreateCall ()
 {
   Ekiga::Call *call = NULL;

Modified: trunk/src/endpoints/manager.h
==============================================================================
--- trunk/src/endpoints/manager.h	(original)
+++ trunk/src/endpoints/manager.h	Mon Jun 30 20:58:35 2008
@@ -43,10 +43,6 @@
 
 #include "common.h"
 
-#include "accounts.h"
-
-#include "accountshandler.h"
-
 #include "gmconf-bridge.h"
 #include "runtime.h"
 #include "contact-core.h"
@@ -70,8 +66,6 @@
   {
     PCLASSINFO(CallManager, OpalManager);
 
-    friend class GMAccountsEndpoint;
-
 public:
 
     CallManager (Ekiga::ServiceCore & _core);
@@ -152,15 +146,9 @@
     void set_video_options (const VideoOptions & options);
     void get_video_options (VideoOptions & options) const;
 
-
-    /**/ 
-    void Register (GmAccount * = NULL);
-
 private:
     OpalCall *CreateCall ();
 
-    void RemoveAccountsEndpoint ();
-
     bool OnOpenMediaStream (OpalConnection &,
                             OpalMediaStream &);
 
@@ -175,9 +163,6 @@
     /* The various related endpoints */
     GMPCSSEndpoint *pcssEP;
 
-    /* The various components of the endpoint */
-    GMAccountsEndpoint *manager;
-
     /* Various mutexes to ensure thread safeness around internal
        variables */
     PMutex manager_access_mutex;

Added: trunk/src/endpoints/opal-account.cpp
==============================================================================
--- (empty file)
+++ trunk/src/endpoints/opal-account.cpp	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,343 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         opal-account.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : implementation of an opal account
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+#include <sstream>
+
+#include "config.h"
+
+#include "common.h"
+
+#include "opal-account.h"
+#include "form-request-simple.h"
+
+
+Opal::Account::Account (Ekiga::ServiceCore & core,
+                        const std::string & account)
+{
+  int i = 0;
+  char *pch = strtok ((char *) account.c_str (), "|");
+  while (pch != NULL) {
+
+    switch (i) {
+
+    case 0:
+      enabled = atoi (pch);
+      break;
+
+    case 2:
+      aid = pch;
+      break;
+
+    case 3:
+      name = pch;
+      break;
+
+    case 4:
+      protocol_name = pch;
+      break;
+
+    case 5:
+      host = pch;
+      break;
+
+    case 7:
+      username = pch;
+      break;
+
+    case 8:
+      auth_username = pch;
+      break;
+
+    case 9:
+      password = pch;
+      break;
+
+    case 10:
+      timeout = atoi (pch);
+      break;
+
+    case 1:
+    case 6:
+    case 11:
+    default:
+      break;
+    }
+    pch = strtok (NULL, "|");
+    i++;
+  }
+
+  account_core = dynamic_cast<Ekiga::AccountCore*>(core.get ("account-core"));
+
+  if (enabled)
+    enable ();
+}
+
+
+Opal::Account::Account (Ekiga::ServiceCore & core,
+                        std::string _name, 
+                        std::string _host,
+                        std::string _username,
+                        std::string _auth_username,
+                        std::string _password,
+                        bool _enabled,
+                        unsigned _timeout)
+{
+  enabled = _enabled;
+  aid = (const char *) PGloballyUniqueID ().AsString ();
+  name = _name;
+  protocol_name = "SIP";
+  host = _host;
+  username = _username;
+  auth_username = _auth_username;
+  password = _password;
+  timeout = _timeout;
+
+  account_core = dynamic_cast<Ekiga::AccountCore*>(core.get ("account-core"));
+
+  if (enabled)
+    enable ();
+}
+
+
+Opal::Account::~Account ()
+{
+}
+
+
+const std::string Opal::Account::as_string () const
+{
+  std::stringstream str;
+
+  str << enabled << "|1|" 
+      << aid << "|" 
+      << name << "|" 
+      << protocol_name << "|" 
+      << host << "|" 
+      << host << "|" 
+      << username << "|" 
+      << auth_username << "|" 
+      << password << "|" 
+      << timeout; 
+
+  return str.str ();
+}
+
+const std::string Opal::Account::get_name () const
+{
+  return name;
+}
+
+
+const std::string Opal::Account::get_protocol_name () const
+{
+  return protocol_name;
+}
+
+
+const std::string Opal::Account::get_host () const
+{
+  return host;
+}
+
+
+const std::string Opal::Account::get_username () const
+{
+  return username;
+}
+
+
+const std::string Opal::Account::get_authentication_username () const
+{
+  return auth_username;
+}
+
+
+const std::string Opal::Account::get_password () const
+{
+  return password;
+}
+
+
+unsigned Opal::Account::get_timeout () const
+{
+  return timeout;
+}
+
+
+void Opal::Account::enable ()
+{
+  enabled = true;
+
+  account_core->subscribe_account (*this);
+
+  updated.emit ();
+  trigger_saving.emit ();
+}
+
+
+void Opal::Account::disable ()
+{
+  enabled = false;
+
+  account_core->unsubscribe_account (*this);
+
+  updated.emit ();
+  trigger_saving.emit ();
+}
+
+
+bool Opal::Account::is_enabled () const
+{
+  return enabled;
+}
+
+    
+void Opal::Account::remove ()
+{
+}
+
+bool Opal::Account::populate_menu (Ekiga::MenuBuilder &builder)
+{
+  if (enabled)
+    builder.add_action ("disable", _("_Disable"),
+                        sigc::mem_fun (this, &Opal::Account::disable));
+  else
+    builder.add_action ("enable", _("_Enable"),
+                        sigc::mem_fun (this, &Opal::Account::enable));
+
+  builder.add_separator ();
+
+  builder.add_action ("edit", _("_Edit"),
+		      sigc::mem_fun (this, &Opal::Account::edit));
+  builder.add_action ("remove", _("_Remove"),
+		      sigc::mem_fun (this, &Opal::Account::remove));
+
+  return true;
+}
+
+
+void Opal::Account::edit ()
+{
+  Ekiga::FormRequestSimple request;
+  std::stringstream str;
+
+  str << get_timeout ();
+  
+  request.title (_("Edit account"));
+
+  request.instructions (_("Please update the following fields:"));
+
+  request.text ("name", _("Name:"), get_name ());
+  request.text ("host", _("Host"), get_host ());
+  request.text ("user", _("User:"), get_username ());
+  request.text ("authentication_user", _("Authentication User:"), get_authentication_username ());
+  request.private_text ("password", _("Password:"), get_password ());
+  request.text ("timeout", _("Timeout:"), str.str ());
+  request.boolean ("enabled", _("Enable Account"), enabled);
+
+  request.submitted.connect (sigc::mem_fun (this, &Opal::Account::on_edit_form_submitted));
+
+  if (!questions.handle_request (&request)) {
+
+    // FIXME: better error reporting
+#ifdef __GNUC__
+    std::cout << "Unhandled form request in "
+	      << __PRETTY_FUNCTION__ << std::endl;
+#endif
+  }
+}
+
+
+void Opal::Account::on_edit_form_submitted (Ekiga::Form &result)
+{
+  try {
+
+    Ekiga::FormRequestSimple request;
+
+    std::string error;
+    std::string new_name = result.text ("name");
+    std::string new_host = result.text ("host");
+    std::string new_user = result.text ("user");
+    std::string new_authentication_user = result.text ("authentication_user");
+    std::string new_password = result.private_text ("password");
+    bool new_enabled = result.boolean ("enabled");
+    unsigned new_timeout = atoi (result.text ("timeout").c_str ());
+
+    result.visit (request);
+
+    if (new_name.empty ()) 
+      error = _("You did not supply a name for that account.");
+    else if (new_host.empty ()) 
+      error = _("You did not supply a host to register to.");
+    else if (new_user.empty ())
+      error = _("You did not supply a user name for that account.");
+
+    if (!error.empty ()) {
+      request.error (error);
+      request.submitted.connect (sigc::mem_fun (this, &Opal::Account::on_edit_form_submitted));
+
+      if (!questions.handle_request (&request)) {
+#ifdef __GNUC__
+        std::cout << "Unhandled form request in "
+          << __PRETTY_FUNCTION__ << std::endl;
+#endif
+      }
+    }
+    else {
+
+      disable ();
+      name = new_name;
+      host = new_host;
+      username = new_user;
+      auth_username = new_authentication_user;
+      password = new_password;
+      timeout = new_timeout;
+      enabled = new_enabled;
+      enable ();
+
+      updated.emit ();
+      trigger_saving.emit ();
+    }
+
+  } catch (Ekiga::Form::not_found) {
+
+    std::cerr << "Invalid result form" << std::endl; // FIXME: do better
+  }
+}

Added: trunk/src/endpoints/opal-account.h
==============================================================================
--- (empty file)
+++ trunk/src/endpoints/opal-account.h	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,123 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         opal-account.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : declaration of an OPAL account
+ *
+ */
+
+#ifndef __OPAL_ACCOUNT_H__
+#define __OPAL_ACCOUNT_H__
+
+#include "services.h"
+#include "account-core.h"
+#include "account.h"
+#include "form.h"
+#include "bank-impl.h"
+
+namespace Opal
+{
+  /**
+   * @addtogroup accounts
+   * @internal
+   * @{
+   */
+  class Account: public Ekiga::Account
+  {
+public:
+
+    Account (Ekiga::ServiceCore & core, 
+             const std::string & account);
+
+    Account (Ekiga::ServiceCore & core,
+             std::string name, 
+             std::string host,
+             std::string user,
+             std::string auth_user,
+             std::string password,
+             bool enabled,
+             unsigned timeout);
+
+    ~Account ();
+
+    const std::string get_name () const;
+
+    const std::string get_protocol_name () const;
+
+    const std::string get_host () const;
+
+    const std::string get_username () const;
+
+    const std::string get_authentication_username () const;
+
+    const std::string get_password () const;
+
+    unsigned get_timeout () const;
+
+    void enable ();
+
+    void disable ();
+
+    bool is_enabled () const;
+
+    void remove ();
+
+    void edit ();
+
+    bool populate_menu (Ekiga::MenuBuilder &builder);
+
+    const std::string as_string () const;
+
+    sigc::signal<void> trigger_saving;
+    
+private:
+    void on_edit_form_submitted (Ekiga::Form &result);
+
+    bool enabled;
+    unsigned timeout;
+    std::string aid;
+    std::string name;
+    std::string protocol_name;
+    std::string host;
+    std::string username;
+    std::string auth_username;
+    std::string password;
+
+    Ekiga::AccountCore *account_core;
+  };
+
+  /**
+   * @}
+   */
+};
+
+#endif

Added: trunk/src/endpoints/opal-bank.cpp
==============================================================================
--- (empty file)
+++ trunk/src/endpoints/opal-bank.cpp	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,150 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         opal-account.cpp  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : implementation of an opal account
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+#include <sstream>
+
+#include "config.h"
+
+#include "common.h"
+
+#include "menu-builder.h"
+
+#include "opal-bank.h"
+#include "form-request-simple.h"
+
+
+bool Opal::Bank::populate_menu (Ekiga::MenuBuilder & builder)
+{
+  builder.add_action ("new", _("_New"),
+		      sigc::mem_fun (this, &Opal::Bank::new_account));
+
+  return true;
+}
+
+
+void Opal::Bank::new_account ()
+{
+  Ekiga::FormRequestSimple request;
+
+  request.title (_("Edit account"));
+
+  request.instructions (_("Please update the following fields:"));
+
+  request.text ("name", _("Name:"), std::string ());
+  request.text ("host", _("Host"), std::string ());
+  request.text ("user", _("User:"), std::string ());
+  request.text ("authentication_user", _("Authentication User:"), std::string ());
+  request.private_text ("password", _("Password:"), std::string ());
+  request.text ("timeout", _("Timeout:"), std::string ());
+  request.boolean ("enabled", _("Enable Account"), true);
+
+  request.submitted.connect (sigc::mem_fun (this, &Opal::Bank::on_new_account_form_submitted));
+
+  if (!questions.handle_request (&request)) {
+
+    // FIXME: better error reporting
+#ifdef __GNUC__
+    std::cout << "Unhandled form request in "
+	      << __PRETTY_FUNCTION__ << std::endl;
+#endif
+  }
+}
+
+
+void Opal::Bank::on_new_account_form_submitted (Ekiga::Form &result)
+{
+  try {
+
+    Ekiga::FormRequestSimple request;
+
+    std::string error;
+    std::string new_name = result.text ("name");
+    std::string new_host = result.text ("host");
+    std::string new_user = result.text ("user");
+    std::string new_authentication_user = result.text ("authentication_user");
+    std::string new_password = result.private_text ("password");
+    bool new_enabled = result.boolean ("enabled");
+    unsigned new_timeout = atoi (result.text ("timeout").c_str ());
+
+    result.visit (request);
+
+    if (new_name.empty ()) 
+      error = _("You did not supply a name for that account.");
+    else if (new_host.empty ()) 
+      error = _("You did not supply a host to register to.");
+    else if (new_user.empty ())
+      error = _("You did not supply a user name for that account.");
+
+    if (!error.empty ()) {
+      request.error (error);
+      request.submitted.connect (sigc::mem_fun (this, &Opal::Bank::on_new_account_form_submitted));
+
+      if (!questions.handle_request (&request)) {
+#ifdef __GNUC__
+        std::cout << "Unhandled form request in "
+          << __PRETTY_FUNCTION__ << std::endl;
+#endif
+      }
+    }
+    else {
+
+      add (new_name, new_host, new_user, new_authentication_user, new_password, new_enabled, new_timeout);
+      save ();
+    }
+
+  } catch (Ekiga::Form::not_found) {
+
+    std::cerr << "Invalid result form" << std::endl; // FIXME: do better
+  }
+}
+
+
+void Opal::Bank::add (std::string name, 
+                      std::string host,
+                      std::string user,
+                      std::string auth_user,
+                      std::string password,
+                      bool enabled,
+                      unsigned timeout)
+{
+  Opal::Account *account = new Opal::Account (core, name, host, user, auth_user, password, enabled, timeout);
+
+  add_account (*account);
+}

Added: trunk/src/endpoints/opal-bank.h
==============================================================================
--- (empty file)
+++ trunk/src/endpoints/opal-bank.h	Mon Jun 30 20:58:35 2008
@@ -0,0 +1,77 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2007 Damien Sandras
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ *                         opal-bank.h  -  description
+ *                         ------------------------------------------
+ *   begin                : written in 2008 by Damien Sandras
+ *   copyright            : (c) 2008 by Damien Sandras
+ *   description          : declaration of an OPAL bank 
+ *
+ */
+
+#ifndef __OPAL_BANK_H__
+#define __OPAL_BANK_H__
+
+#include "bank-impl.h"
+#include "opal-account.h"
+
+namespace Opal
+{
+  /**
+   * @addtogroup accounts
+   * @internal
+   * @{
+   */
+  class Bank: public Ekiga::BankImpl<Account> 
+  {
+public:
+    Bank (Ekiga::ServiceCore &_core) : Ekiga::BankImpl<Opal::Account> (_core) {}
+
+    bool populate_menu (Ekiga::MenuBuilder & builder);
+
+    void new_account ();
+
+private:
+    void on_new_account_form_submitted (Ekiga::Form & form);
+
+    void add (std::string name, 
+              std::string host,
+              std::string user,
+              std::string auth_user,
+              std::string password,
+              bool enabled,
+              unsigned timeout);
+  };
+
+  /**
+   * @}
+   */
+};
+
+#endif

Modified: trunk/src/endpoints/opal-main.cpp
==============================================================================
--- trunk/src/endpoints/opal-main.cpp	(original)
+++ trunk/src/endpoints/opal-main.cpp	Mon Jun 30 20:58:35 2008
@@ -36,11 +36,14 @@
  */
 
 #include "opal-main.h"
+#include "bank.h"
 #include "contact-core.h"
 #include "presence-core.h"
 #include "call-core.h"
 #include "chat-core.h"
 #include "opal-gmconf-bridge.h"
+#include "opal-account.h"
+#include "opal-bank.h"
 
 #include "manager.h"
 #include "ekiga.h"
@@ -57,6 +60,16 @@
 
 using namespace Opal;
 
+void 
+on_call_manager_ready_cb (Ekiga::ServiceCore *core)
+{
+  Ekiga::AccountCore *account_core = dynamic_cast<Ekiga::AccountCore *> (core->get ("account-core"));
+
+  Opal::Bank *bank = new Bank (*core);
+  account_core->add_bank (*bank);
+  // FIXME Service ?
+}
+
 bool
 opal_init (Ekiga::ServiceCore &core,
            int * /*argc*/,
@@ -66,6 +79,7 @@
   Ekiga::PresenceCore *presence_core = NULL;
   Ekiga::CallCore *call_core = NULL;
   Ekiga::ChatCore *chat_core = NULL;
+  Ekiga::AccountCore *account_core = NULL;
 
   bool result = true;
   unsigned sip_port = gm_conf_get_int (SIP_KEY "listen_port");
@@ -75,6 +89,7 @@
   presence_core = dynamic_cast<Ekiga::PresenceCore *> (core.get ("presence-core"));
   call_core = dynamic_cast<Ekiga::CallCore *> (core.get ("call-core"));
   chat_core = dynamic_cast<Ekiga::ChatCore *> (core.get ("chat-core"));
+  account_core = dynamic_cast<Ekiga::AccountCore *> (core.get ("account-core"));
 
   CallManager *call_manager = new CallManager (core);
   Sip::CallProtocolManager *sip_manager = new Sip::CallProtocolManager (*call_manager, core, sip_port);
@@ -86,11 +101,15 @@
   call_core->add_manager (*call_manager);
   core.add (*call_manager); // FIXME temporary
   chat_core->add_manager (*sip_manager);
+  account_core->add_account_subscriber (*sip_manager);
 
-  new Opal::ConfBridge (*call_manager);
+  new ConfBridge (*call_manager);
   call_manager->start ();
   // FIXME Service ?
 
+  // Add the bank of accounts when the CallManager is ready
+  call_manager->ready.connect (sigc::bind (sigc::ptr_fun (on_call_manager_ready_cb), &core));
+
   if (contact_core != NULL) 
     contact_core->add_contact_decorator (*sip_manager);
   else
@@ -104,8 +123,10 @@
     presence_core->add_presence_fetcher (*sip_manager);
     presence_core->add_presence_publisher (*sip_manager);
   }
-  else 
+  else {
+
     return false;
+  }
 
   return result;
 }

Modified: trunk/src/endpoints/sip.cpp
==============================================================================
--- trunk/src/endpoints/sip.cpp	(original)
+++ trunk/src/endpoints/sip.cpp	Mon Jun 30 20:58:35 2008
@@ -46,33 +46,67 @@
 #include "opal-call.h"
 
 #include "presence-core.h"
+#include "account-core.h"
 #include "personal-details.h"
+#include "opal-account.h"
 
-class dialer : public PThread
-{
-  PCLASSINFO(dialer, PThread);
-
-public:
+namespace Opal {
 
-  dialer (const std::string & uri, Opal::CallManager & ep) 
-    : PThread (1000, AutoDeleteThread), 
-    dial_uri (uri),
-    endpoint (ep) 
-  {
-    this->Resume ();
-  };
+  namespace Sip {
 
-  void Main () 
+    class dialer : public PThread
     {
-      PString token;
-      endpoint.SetUpCall ("pc:*", dial_uri, token);
+      PCLASSINFO(dialer, PThread);
+
+    public:
+
+      dialer (const std::string & uri, Opal::CallManager & ep) 
+        : PThread (1000, AutoDeleteThread), 
+        dial_uri (uri),
+        endpoint (ep) 
+      {
+        this->Resume ();
+      };
+
+      void Main () 
+        {
+          PString token;
+          endpoint.SetUpCall ("pc:*", dial_uri, token);
+        };
+
+    private:
+      const std::string dial_uri;
+      Opal::CallManager & endpoint;
     };
 
-private:
-  const std::string dial_uri;
-  Opal::CallManager & endpoint;
+
+    class subscriber : public PThread
+    {
+      PCLASSINFO(subscriber, PThread);
+
+    public:
+      subscriber (const Ekiga::Account & _account,
+                  Opal::Sip::CallProtocolManager & ep) 
+        : PThread (1000, AutoDeleteThread),
+        account (_account),
+        endpoint (ep) 
+      {
+        this->Resume ();
+      };
+
+      void Main () 
+        {
+          endpoint.Register (account);
+        };
+
+    private:
+      const Ekiga::Account & account;
+      Opal::Sip::CallProtocolManager & endpoint;
+    };
+  };
 };
 
+
 using namespace Opal::Sip;
 
 
@@ -85,7 +119,8 @@
                       endpoint (ep), 
                       core (_core),
                       presence_core (*(dynamic_cast<Ekiga::PresenceCore *> (core.get ("presence-core")))),
-                      runtime (*(dynamic_cast<Ekiga::Runtime *> (core.get ("runtime"))))
+                      runtime (*(dynamic_cast<Ekiga::Runtime *> (core.get ("runtime")))),
+                      account_core (*(dynamic_cast<Ekiga::AccountCore *> (core.get ("account-core"))))
 {
   protocol_name = "sip";
   uri_prefix = "sip:";
@@ -415,40 +450,39 @@
 }
 
 
-void  CallProtocolManager::Register (const PString & _aor,
-                                     const PString & authUserName,
-                                     const PString & password,
-                                     unsigned int expires,
-                                     bool unregister)
+// FIXME : check code Ekiga::Account or Opal::Account, how can we be sure the correct one is called ?
+bool CallProtocolManager::subscribe (const Ekiga::Account & account)
 {
-  std::string aor = (const char *) _aor;
-  std::stringstream strm;
-  bool result = false;
+  if (account.get_protocol_name () != "SIP")
+    return false;
 
-  /* Account is enabled, and we are not registered */
-  if (!unregister && !IsRegistered (aor)) {
+  new subscriber (account, *this);
+  return true;
+}
 
-    if (aor.find (uri_prefix) == std::string::npos) 
-      strm << uri_prefix << aor;
-    else
-      strm << aor;
 
-    /* Signal */
-    runtime.run_in_main (sigc::bind (endpoint.registration_event.make_slot (), 
-                                     aor,
-                                     Ekiga::CallCore::Processing,
-                                     std::string ()));
+bool CallProtocolManager::unsubscribe (const Ekiga::Account & account)
+{
+  if (account.get_protocol_name () != "SIP")
+    return false;
 
-    /* Trigger registering */
-    result = SIPEndPoint::Register (PString::Empty (), aor, authUserName, password, PString::Empty (), expires);
+  new subscriber (account, *this);
+  return true;
+}
 
-    if (!result) 
-      OnRegistrationFailed (_aor, SIP_PDU::MaxStatusCode, true);
-  }
-  else if (unregister && IsRegistered (aor)) {
 
-    SIPEndPoint::Unregister (aor);
-  }
+void CallProtocolManager::Register (const Ekiga::Account & account)
+{
+  std::stringstream aor;
+  
+  aor << account.get_username () << "@" << account.get_host ();
+  if (!SIPEndPoint::Register (account.get_host (),
+                              account.get_username (),
+                              account.get_authentication_username (),
+                              account.get_password (),
+                              PString::Empty (), 
+                              (account.is_enabled () ? account.get_timeout () : 0)))
+    OnRegistrationFailed (aor.str (), SIP_PDU::MaxStatusCode, account.is_enabled ());
 }
 
 
@@ -516,9 +550,9 @@
   }
 
   /* Signal */
-  runtime.run_in_main (sigc::bind (endpoint.registration_event.make_slot (), 
+  runtime.run_in_main (sigc::bind (account_core.registration_event.make_slot (), 
                                    strm.str (),
-                                   was_registering ? Ekiga::CallCore::Registered : Ekiga::CallCore::Unregistered,
+                                   was_registering ? Ekiga::AccountCore::Registered : Ekiga::AccountCore::Unregistered,
                                    std::string ()));
 }
 
@@ -742,9 +776,9 @@
   SIPEndPoint::OnRegistrationFailed (strm.str ().c_str (), r, wasRegistering);
 
   /* Signal */
-  runtime.run_in_main (sigc::bind (endpoint.registration_event.make_slot (), 
+  runtime.run_in_main (sigc::bind (account_core.registration_event.make_slot (), 
                                    aor, 
-                                   wasRegistering ? Ekiga::CallCore::RegistrationFailed : Ekiga::CallCore::UnregistrationFailed,
+                                   wasRegistering ? Ekiga::AccountCore::RegistrationFailed : Ekiga::AccountCore::UnregistrationFailed,
                                    info));
 }
 
@@ -828,7 +862,8 @@
 
 SIPURL CallProtocolManager::GetRegisteredPartyName (const SIPURL & host)
 {
-  GmAccount *account = NULL;
+  //FIXME
+  //GmAccount *account = NULL;
 
   PString local_address;
   PIPSocket::Address address;
@@ -852,6 +887,7 @@
      */
     if (host.GetHostAddress ().GetIpAndPort (address, port) && !manager.IsLocalAddress (address)) {
 
+      /*
       account = gnomemeeting_get_default_account ("SIP");
       if (account && account->enabled) {
 
@@ -862,6 +898,7 @@
 
         return SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + url + ">");
       }
+          */
     }
   }
 

Modified: trunk/src/endpoints/sip.h
==============================================================================
--- trunk/src/endpoints/sip.h	(original)
+++ trunk/src/endpoints/sip.h	Mon Jun 30 20:58:35 2008
@@ -49,11 +49,12 @@
 #include "chat-manager.h"
 #include "call-manager.h"
 #include "call-protocol-manager.h"
+#include "account-core.h"
+#include "opal-account.h"
 
 
 PDICTIONARY (msgDict, PString, PString);
 
-class Ekiga::PersonalDetails;
 
 namespace Opal {
 
@@ -65,6 +66,7 @@
                                 public Ekiga::PresenceFetcher,
                                 public Ekiga::PresencePublisher,
                                 public Ekiga::PresentityDecorator,
+                                public Ekiga::AccountSubscriberImpl<Opal::Account>,
                                 public Ekiga::ContactDecorator
     {
       PCLASSINFO(CallProtocolManager, SIPEndPoint);
@@ -122,13 +124,14 @@
       void set_forward_uri (const std::string & uri);
       const std::string & get_forward_uri () const;
 
+      
+      /* AccountSubscriber */
+      bool subscribe (const Ekiga::Account & account);
+      bool unsubscribe (const Ekiga::Account & account);
+
 
       /* OPAL Methods */
-      void Register (const PString & aor,
-                     const PString & authUserName,
-                     const PString & password,
-                     unsigned int expires,
-                     bool unregister);
+      void Register (const Ekiga::Account & account);
 
       void OnRegistered (const PString & aor,
                          bool wasRegistering);
@@ -173,6 +176,7 @@
       Ekiga::ServiceCore & core;
       Ekiga::PresenceCore & presence_core;
       Ekiga::Runtime & runtime;
+      Ekiga::AccountCore & account_core;
 
       Ekiga::CallProtocolManager::Interface interface;
 

Modified: trunk/src/gui/accounts.cpp
==============================================================================
--- trunk/src/gui/accounts.cpp	(original)
+++ trunk/src/gui/accounts.cpp	Mon Jun 30 20:58:35 2008
@@ -30,15 +30,19 @@
  *                         accounts.cpp  -  description
  *                         ----------------------------
  *   begin                : Sun Feb 13 2005
- *   copyright            : (C) 2000-2006 by Damien Sandras
+ *   copyright            : (C) 2000-2008 by Damien Sandras
  *   description          : This file contains all the functions needed to
- *   			    manipulate H323/SIP/... provider accounts.
+ *   			    manipulate accounts.
  */
 
 #include "config.h"
 
 #include "accounts.h"
 
+#include "account.h"
+#include "bank.h"
+#include "account-core.h"
+
 #include "callbacks.h"
 #include "misc.h"
 #include "main.h"
@@ -53,35 +57,16 @@
 #include "gmdialog.h"
 
 #include "services.h"
-
-
-typedef struct GmAccountsEditWindow_ {
-
-  GtkWidget *account_entry;
-  GtkWidget *protocol_option_menu;
-  GtkWidget *host_label;
-  GtkWidget *host_entry;
-  GtkWidget *username_entry;
-  GtkWidget *auth_username_label;
-  GtkWidget *auth_username_entry;
-  GtkWidget *password_entry;
-  GtkWidget *domain_label;
-  GtkWidget *domain_entry;
-  GtkWidget *timeout_entry;
-
-
-} GmAccountsEditWindow;
-
-#define GM_ACCOUNTS_EDIT_WINDOW(x) (GmAccountsEditWindow *) (x)
+#include "menu-builder-gtk.h"
+#include "form-dialog-gtk.h"
 
 typedef struct GmAccountsWindow_ {
 
   GmAccountsWindow_ (Ekiga::ServiceCore & _core) : core (_core) {};
 
   GtkWidget *accounts_list;
-  GtkWidget *delete_button;
-  GtkWidget *edit_button;
-  GtkWidget *default_button;
+  GtkWidget *menu_item_core;
+  GtkAccelGroup *accel;
 
   Ekiga::ServiceCore &core;
 
@@ -90,22 +75,6 @@
 #define GM_ACCOUNTS_WINDOW(x) (GmAccountsWindow *) (x)
 
 
-/* Functions */
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Returns a GmAccount from its string representation.
- * PRE          : /
- */
-static GmAccount *gm_aw_from_string_to_account (gchar *str);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Returns a string representing a GmAccount.
- * PRE          : /
- */
-static gchar *gm_aw_from_account_to_string (GmAccount *account);
-
-
 /* GUI Functions */
 
 /* DESCRIPTION  : /
@@ -124,40 +93,6 @@
 static GmAccountsWindow *gm_aw_get_aw (GtkWidget *account_window);
 
 
-/* DESCRIPTION  : /
- * BEHAVIOR     : Creates and run a dialog where the user can edit a new
- * 		  or an already selected account. It also checks if all
- * 		  required parameters are present, and once a valid choice
- * 		  has been entered and validated, it is added/modified in
- * 		  the accounts database.
- * PRE          : The GmAccount is a valid pointer to a valid GmAccount
- * 		  that we are editing. If it is NULL, it means we
- * 		  are creating a new account.
- */
-static void gm_aw_edit_account_dialog_run (GtkWidget *accounts_window,
-					   GmAccount *account,
-					   GtkWidget *parent_window);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Creates and run a dialog asking to the user if he wants
- * 		  to delete the given account.
- * PRE          : The GmAccount is a valid pointer to a valid GmAccount
- * 		  that we are editing. If can not be NULL.
- */
-static void gm_aw_delete_account_dialog_run (GtkWidget *accounts_window,
-					     GmAccount *account,
-					     GtkWidget *parent_window);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Returns the currently selected account in the main window.
- * 		  (if any).
- * PRE          : /
- */
-static GmAccount *gm_aw_get_selected_account (GtkWidget *accounts_window);
-
-
 /* GTK+ Callbacks */
 
 /* DESCRIPTION  :  This callback is called when the user clicks
@@ -183,69 +118,10 @@
 				gpointer data);
 
 
-/* DESCRIPTION  :  This callback is called when the user chooses to add
- * 		   an account.
- * BEHAVIOR     :  It runs the edit account dialog until the user validates
- * 		   it with correct data.
- * PRE          :  /
- */
-static void add_account_cb (GtkWidget *button,
-			    gpointer data);
-
-
-/* DESCRIPTION  :  This callback is called when the user chooses to edit
- * 		   an account using the properties button.
- * BEHAVIOR     :  It runs the edit account dialog until the user validates
- * 		   it with correct data.
- * PRE          :  The accounts window GMObject.
- */
-static void edit_account1_cb (GtkWidget *button,
-			      gpointer data);
-
-
-/* DESCRIPTION  :  This callback is called when the user chooses to edit
- * 		   an account by double-clicking on it.
- * BEHAVIOR     :  It calls edit_account1_cb.
- * PRE          :  The accounts window GMObject.
- */
-static void edit_account2_cb (GtkTreeView *tree_view,
-			      GtkTreePath *arg1,
-			      GtkTreeViewColumn *arg2,
-			      gpointer data);
-
-
-/* DESCRIPTION  :  This callback is called when the user chooses to set
- * 		   an account as default.
- * BEHAVIOR     :  It sets it as default, only one default at a time.
- *                 It also updates the various endpoints with the new default.
- * PRE          :  /
- */
-static void set_account_as_default_cb (GtkWidget *button,
-				       gpointer data);
-
-
-/* DESCRIPTION  :  This callback is called when the user chooses to delete
- * 		   an account.
- * BEHAVIOR     :  It runs the delete account dialog until the user validates
- * 		   it.
- * PRE          :  /
- */
-static void delete_account_cb (GtkWidget *button,
-			       gpointer data);
-
-
-/* DESCRIPTION  :  This callback is called when the user changes the protocol
- * 		   in the account dialog.
- * BEHAVIOR     :  Updates the content and labels.
- * PRE          :  data is a valid pointer to a valid GmAccountWindow.
- */
-static void account_dialog_protocol_changed_cb (GtkWidget *menu,
-						gpointer data);
-
-
 /* Columns for the VoIP accounts */
 enum {
 
+  COLUMN_ACCOUNT,
   COLUMN_ACCOUNT_WEIGHT,
   COLUMN_ACCOUNT_ENABLED,
   COLUMN_ACCOUNT_DEFAULT,
@@ -267,85 +143,6 @@
 };
 
 
-/* Functions */
-static GmAccount *
-gm_aw_from_string_to_account (gchar *str)
-{
-  GmAccount *account = NULL;
-
-  gchar **couple = NULL;
-
-  int size = 0;
-  
-  g_return_val_if_fail (str != NULL, NULL);
-  
-  couple = g_strsplit (str, "|", 0);
-
-  if (couple) {
-
-    while (couple [size])
-      size++;
-    size = size + 1;
-
-    account = gm_account_new ();
-
-    if (size >= 1 && couple [0])
-      account->enabled = atoi (couple [0]);
-    if (size >= 2 && couple [1])
-      account->default_account = atoi (couple [1]);
-    if (size >= 3 && couple [2]) {
-
-      if (account->aid)
-	g_free (account->aid);
-      account->aid = g_strdup (couple [2]);
-    }
-    if (size >= 4 && couple [3])
-      account->account_name = g_strdup (couple [3]);
-    if (size >= 5 && couple [4])
-      account->protocol_name = g_strdup (couple [4]);
-    if (size >= 6 && couple [5])
-      account->host = g_strdup (couple [5]);
-    if (size >= 7 && couple [6])
-      account->domain = g_strdup (couple [6]);
-    if (size >= 8 && couple [7])
-      account->username = g_strdup (couple [7]);
-    if (size >= 9 && couple [8])
-      account->auth_username = g_strdup (couple [8]);
-    if (size >= 10 && couple [9])
-      account->password = g_strdup (couple [9]);
-    if (size >= 11 && couple [10])
-      account->timeout = atoi (couple [10]);
-    if (size >= 12 && couple [11])
-      account->method = atoi (couple [11]);
-
-    g_strfreev (couple);
-  }
-
-  return account;
-}
-
-
-static gchar *
-gm_aw_from_account_to_string (GmAccount *account)
-{
-  g_return_val_if_fail (account != NULL, NULL);
-  
-  return g_strdup_printf ("%d|%d|%s|%s|%s|%s|%s|%s|%s|%s|%d|%d", 
-			  account->enabled,
-			  account->default_account,
-			  account->aid, 
-			  account->account_name, 
-			  account->protocol_name,
-			  account->host,
-			  account->domain,
-			  account->username,
-			  account->auth_username,
-			  account->password,
-			  account->timeout,
-			  account->method);
-}
-
-
 /* GUI Functions */
 static void
 gm_aw_destroy (gpointer aw)
@@ -365,463 +162,37 @@
 }
 
 
-static void
-gm_aw_edit_account_dialog_run (G_GNUC_UNUSED GtkWidget *accounts_window,
-			       GmAccount *account,
-			       GtkWidget *parent_window)
-{
-  GtkWidget *dialog = NULL;
-
-  GtkWidget *expander = NULL;
-
-  GtkSizeGroup *size_group_label = NULL;
-  GtkSizeGroup *size_group_entry = NULL;
-  
-  GtkWidget *table = NULL;
-  GtkWidget *label = NULL;
-
-  PString username;
-  PString auth_username;
-  PString host;
-  PString domain;
-  PString password;
-  PString account_name;
-  PString timeout;
-
-  gchar *timeout_string = NULL;
-
-  gint protocol = 0;
-
-  gboolean valid = FALSE;
-  gboolean is_editing = FALSE;
-
-  GmAccountsEditWindow *aew = NULL;
-
-  is_editing = (account != NULL);
-
-  PRegularExpression regex_digits = ("^[0-9]*$");
-
-  /* Create the windows and the table */
-  aew = new GmAccountsEditWindow ();
-  dialog =
-    gtk_dialog_new_with_buttons (_("Edit the Account Information"), 
-				 GTK_WINDOW (NULL),
-				 GTK_DIALOG_MODAL,
-				 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-				 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-				 NULL);
-  gtk_dialog_set_default_response (GTK_DIALOG (dialog),
-				   GTK_RESPONSE_ACCEPT);
-  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), 
-				GTK_WINDOW (parent_window));
-
-  size_group_entry = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
-  size_group_label = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
-  
-  table = gtk_table_new (7, 2, FALSE);
-  gtk_table_set_row_spacings (GTK_TABLE (table), 3);
-  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
-  gtk_container_set_border_width (GTK_CONTAINER (table), 12);
-  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), table);
-  gtk_widget_show (table);
-
-
-  /* Account Name */
-  label = gtk_label_new (_("Account Name:"));
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  aew->account_entry = gtk_entry_new ();
-  gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1); 
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->account_entry, 1, 2, 0, 1); 
-  gtk_entry_set_activates_default (GTK_ENTRY (aew->account_entry), TRUE);
-  if (account && account->account_name)
-    gtk_entry_set_text (GTK_ENTRY (aew->account_entry), account->account_name);
-  gtk_widget_show (label);
-  gtk_widget_show (aew->account_entry);
-
-  /* Protocol */
-  if (!is_editing) {
-
-    label = gtk_label_new (_("Protocol:"));
-    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), aew->protocol_option_menu);
-    
-    aew->protocol_option_menu = gtk_combo_box_new_text ();
-    gtk_combo_box_append_text (GTK_COMBO_BOX (aew->protocol_option_menu), "SIP");
-    gtk_combo_box_append_text (GTK_COMBO_BOX (aew->protocol_option_menu), "H323");
-    gtk_combo_box_set_active (GTK_COMBO_BOX (aew->protocol_option_menu), 0);
-
-    gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2); 
-    gtk_table_attach_defaults (GTK_TABLE (table), aew->protocol_option_menu, 
-			       1, 2, 1, 2); 
-
-    gtk_widget_show (label);
-    gtk_widget_show (aew->protocol_option_menu);
-
-    g_signal_connect (GTK_COMBO_BOX (aew->protocol_option_menu),
-		      "changed",
-		      G_CALLBACK (account_dialog_protocol_changed_cb),
-		      (gpointer) aew);
-  }
-
-  /* Host */
-  if (!account || !strcmp (account->protocol_name, "SIP"))
-    aew->host_label = gtk_label_new (_("Registrar:"));
-  else
-    aew->host_label = gtk_label_new (_("Gatekeeper:"));
-  gtk_misc_set_alignment (GTK_MISC (aew->host_label), 0.0, 0.5);
-  aew->host_entry = gtk_entry_new ();
-  gtk_size_group_add_widget (size_group_label, aew->host_label);
-  gtk_size_group_add_widget (size_group_entry, aew->host_entry);
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->host_label, 0, 1, 2, 3); 
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->host_entry, 1, 2, 2, 3); 
-  gtk_entry_set_activates_default (GTK_ENTRY (aew->host_entry), TRUE);
-  if (account && account->host)
-    gtk_entry_set_text (GTK_ENTRY (aew->host_entry), account->host);
-  gtk_widget_show (aew->host_label);
-  gtk_widget_show (aew->host_entry);
-
-  /* User */
-  label = gtk_label_new (_("User:"));
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  aew->username_entry = gtk_entry_new ();
-  gtk_size_group_add_widget (size_group_label, label);
-  gtk_size_group_add_widget (size_group_entry, aew->username_entry);
-  gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 4, 5); 
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->username_entry, 
-			     1, 2, 4, 5); 
-  gtk_entry_set_activates_default (GTK_ENTRY (aew->username_entry), TRUE);
-  if (account && account->username)
-    gtk_entry_set_text (GTK_ENTRY (aew->username_entry), account->username);
-  gtk_widget_show (label);
-  gtk_widget_show (aew->username_entry);
-
-  /* Password */
-  label = gtk_label_new (_("Password:"));
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  aew->password_entry = gtk_entry_new ();
-  gtk_size_group_add_widget (size_group_label, label);
-  gtk_size_group_add_widget (size_group_entry, aew->password_entry);
-  gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6); 
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->password_entry, 
-			     1, 2, 5, 6); 
-  gtk_entry_set_activates_default (GTK_ENTRY (aew->password_entry), TRUE);
-  gtk_entry_set_visibility (GTK_ENTRY (aew->password_entry), FALSE);
-  if (account && account->password)
-    gtk_entry_set_text (GTK_ENTRY (aew->password_entry), account->password);
-  gtk_widget_show (label);
-  gtk_widget_show (aew->password_entry);
-  
-
-  /* Advanced Options */
-  expander = gtk_expander_new_with_mnemonic (_("More _Options"));
-  gtk_table_attach_defaults (GTK_TABLE (table), expander, 0, 2, 6, 7); 
-  
-  table = gtk_table_new (3, 2, FALSE);
-  gtk_table_set_row_spacings (GTK_TABLE (table), 3);
-  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
-  gtk_container_set_border_width (GTK_CONTAINER (table), 0);
-  gtk_container_add (GTK_CONTAINER (expander), table);
-  gtk_widget_show_all (table);
-  gtk_widget_show (expander);
-  
-  /* Auth User Name */
-  if (!account || !strcmp (account->protocol_name, "SIP")) {
-
-    aew->auth_username_label = gtk_label_new (_("Authentication Login:"));
-    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-    aew->auth_username_entry = gtk_entry_new ();
-    gtk_size_group_add_widget (size_group_label, aew->auth_username_label);
-    gtk_size_group_add_widget (size_group_entry, aew->auth_username_entry);
-    gtk_table_attach_defaults (GTK_TABLE (table), aew->auth_username_label, 
-			       0, 1, 0, 1); 
-    gtk_table_attach_defaults (GTK_TABLE (table), aew->auth_username_entry, 
-			       1, 2, 0, 1); 
-    gtk_entry_set_activates_default (GTK_ENTRY (aew->auth_username_entry), 
-				     TRUE);
-    if (account && account->auth_username)
-      gtk_entry_set_text (GTK_ENTRY (aew->auth_username_entry), 
-			  account->auth_username);
-    gtk_widget_show (aew->auth_username_label);
-    gtk_widget_show (aew->auth_username_entry);
-  }
-
-  /* Realm/Domain */
-  if (!account || !strcmp (account->protocol_name, "SIP"))
-    aew->domain_label = gtk_label_new (NULL);
-  else
-    aew->domain_label = gtk_label_new (_("Gatekeeper ID:"));
-
-  gtk_misc_set_alignment (GTK_MISC (aew->domain_label), 0.0, 0.5);
-  aew->domain_entry = gtk_entry_new ();
-  gtk_size_group_add_widget (size_group_label, aew->domain_label);
-  gtk_size_group_add_widget (size_group_entry, aew->domain_entry);
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->domain_label, 0, 1, 1, 2); 
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->domain_entry, 1, 2, 1, 2); 
-  gtk_entry_set_activates_default (GTK_ENTRY (aew->domain_entry), TRUE);
-  if (account && account->domain)
-    gtk_entry_set_text (GTK_ENTRY (aew->domain_entry), account->domain);
-  
-  if (!account || !strcmp (account->protocol_name, "SIP")) {
-  
-    gtk_widget_hide (aew->domain_label);
-    gtk_widget_hide (aew->domain_entry);
-  }
-  else {
-
-    gtk_widget_show (aew->domain_label);
-    gtk_widget_show (aew->domain_entry);
-  }
-
-  /* Timeout */
-  label = gtk_label_new (_("Registration Timeout:"));
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  aew->timeout_entry = gtk_entry_new ();
-  gtk_size_group_add_widget (size_group_label, label);
-  gtk_size_group_add_widget (size_group_entry, aew->timeout_entry);
-  gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3); 
-  gtk_table_attach_defaults (GTK_TABLE (table), aew->timeout_entry, 
-			     1, 2, 2, 3); 
-  gtk_entry_set_activates_default (GTK_ENTRY (aew->timeout_entry), TRUE);
-  if (account) 
-    timeout_string = g_strdup_printf ("%d", account->timeout);
-  else
-    timeout_string = g_strdup ("3600");
-  gtk_entry_set_text (GTK_ENTRY (aew->timeout_entry), timeout_string);
-  g_free (timeout_string);
-  gtk_widget_show (label);
-  gtk_widget_show (aew->timeout_entry);
-
-
-  gtk_widget_show (dialog);
-  while (!valid) {
-
-    switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
-
-    case GTK_RESPONSE_ACCEPT:
-
-      username = gtk_entry_get_text (GTK_ENTRY (aew->username_entry));
-      if (aew->auth_username_entry)
-	auth_username = gtk_entry_get_text (GTK_ENTRY (aew->auth_username_entry));
-      account_name = gtk_entry_get_text (GTK_ENTRY (aew->account_entry));
-      host = gtk_entry_get_text (GTK_ENTRY (aew->host_entry));
-      password = gtk_entry_get_text (GTK_ENTRY (aew->password_entry));
-      domain = gtk_entry_get_text (GTK_ENTRY (aew->domain_entry));
-      timeout = gtk_entry_get_text (GTK_ENTRY (aew->timeout_entry));
-
-      if (!is_editing)
-	protocol = // take it from the menu
-	  gtk_combo_box_get_active (GTK_COMBO_BOX (aew->protocol_option_menu));
-      else // take it from the existing account field
-	protocol = (account->protocol_name 
-		    && !strcmp (account->protocol_name, "SIP") ? 0 : 1);
-
-      /* string sanity check */
-      valid = (!username.IsEmpty () &&
-	       !account_name.IsEmpty ()
-	       && username.Find ("|") == P_MAX_INDEX
-	       && auth_username.Find ("|") == P_MAX_INDEX
-	       && account_name.Find ("|") == P_MAX_INDEX
-	       && host.Find ("|") == P_MAX_INDEX
-	       && password.Find ("|") == P_MAX_INDEX
-	       && domain.Find ("|") == P_MAX_INDEX
-	       && !(timeout.FindRegEx (regex_digits) == P_MAX_INDEX));
-
-      if (valid) {
-
-	if (!is_editing)
-	  account = gm_account_new ();
-
-	g_free (account->username);
-	g_free (account->auth_username);
-	g_free (account->account_name);
-	g_free (account->host);
-	g_free (account->password);
-	g_free (account->domain);
-	if (!is_editing)
-	  g_free (account->protocol_name);
-
-	account->account_name = g_strdup (account_name);
-	account->host = g_strdup (host);
-	account->username = g_strdup (username);
-	
-	if (!strcmp (domain, ""))
-	  if (protocol == 0) { // SIP
-	    if (PString(username).Find("@") != P_MAX_INDEX)
-	      account->domain = g_strdup (SIPURL(username).GetHostName());
-	    else
-	      account->domain = g_strdup (host);
-	  }
-	  else
-	    account->domain = g_strdup ("");
-	else
-	  account->domain = g_strdup (domain);
-
-	if (!strcmp (auth_username, "")) {
-	  if (PString(username).Find("@") != P_MAX_INDEX)
-	    account->auth_username = g_strdup (SIPURL(username).GetUserName());
-	  else
-	    account->auth_username = g_strdup (account->username);
-	}
-	else
-	  account->auth_username = g_strdup (auth_username);
-
-	account->password = g_strdup (password);
-	if (atoi (timeout) == 0)
-	  account->timeout = 3600;
-	else 
-	  account->timeout = PMAX (atoi (timeout), 25);
-
-	if (!is_editing)
-	  account->protocol_name = g_strdup ((protocol == 0) ? "SIP" : "H323");
-
-	/* The GUI will be updated through the GmConf notifiers */
-	if (is_editing) 
-	  gnomemeeting_account_modify (account);
-	else 
-	  gnomemeeting_account_add (account);
-      }
-      else /* !valid */
-	gnomemeeting_error_dialog (GTK_WINDOW (dialog), _("Missing or wrong information"),
-				   _("Please make sure to provide at least an <b>account name</b>, a <b>username</b> and a valid <b>timeout in seconds</b>."));
-      break; /* GTK_RESPONSE_ACCEPT */
-
-    case GTK_RESPONSE_DELETE_EVENT:
-    case GTK_RESPONSE_CANCEL:
-    default:
-      valid = TRUE;
-      break;
-    }
-  }
-
-  delete ((GmAccountsEditWindow *) aew);
-  gtk_widget_destroy (dialog);
-}
-
-
-static void 
-gm_aw_delete_account_dialog_run (GtkWidget *accounts_window,
-				 GmAccount *account,
-				 G_GNUC_UNUSED GtkWidget *parent_window)
-{
-  GtkWidget *dialog = NULL;
-
-  gchar *confirm_msg = NULL;
-
-  g_return_if_fail (accounts_window != NULL);
-  g_return_if_fail (account != NULL);
-
-  /* Create the dialog to delete the account */
-  confirm_msg = 
-    g_strdup_printf (_("Are you sure you want to delete account %s?"), 
-		     account->account_name);
-  dialog =
-    gtk_message_dialog_new (GTK_WINDOW (accounts_window),
-			    GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
-			    GTK_BUTTONS_YES_NO, "%s", confirm_msg);
-  g_free (confirm_msg);
-
-  gtk_dialog_set_default_response (GTK_DIALOG (dialog),
-				   GTK_RESPONSE_YES);
-
-  gtk_widget_show_all (dialog);
-
-
-  /* Now run the dialg */
-  switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
-
-  case GTK_RESPONSE_YES:
-
-    /* The GUI will be updated throught the GmConf notifiers */
-    gnomemeeting_account_delete (account);
-    break;
-  default:
-    break;
-  }
-
-  gtk_widget_destroy (dialog);
-}
-
-
-GmAccount *
-gm_aw_get_selected_account (GtkWidget *accounts_window)
-{
-  GmAccountsWindow *aw = NULL;
-
-  GtkTreeModel *model = NULL;
-  GtkTreeSelection *selection = NULL;
-  GtkTreeIter iter;
-
-  GmAccount *account = NULL;
-
-  g_return_val_if_fail (accounts_window != NULL, NULL);
-
-  /* Get the required data */
-  aw = gm_aw_get_aw (accounts_window);
-
-  g_return_val_if_fail (aw != NULL, NULL);
-
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (aw->accounts_list));
-  model = gtk_tree_view_get_model (GTK_TREE_VIEW (aw->accounts_list));
-
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-
-    account = gm_account_new ();
-
-    gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 
-			COLUMN_ACCOUNT_ENABLED, &account->enabled,
-			COLUMN_ACCOUNT_DEFAULT, &account->default_account,
-			COLUMN_ACCOUNT_AID, &account->aid,
-			COLUMN_ACCOUNT_ACCOUNT_NAME, &account->account_name,
-			COLUMN_ACCOUNT_PROTOCOL_NAME, &account->protocol_name,
-			COLUMN_ACCOUNT_HOST, &account->host,
-			COLUMN_ACCOUNT_DOMAIN, &account->domain,
-			COLUMN_ACCOUNT_USERNAME, &account->username,
-			COLUMN_ACCOUNT_AUTH_USERNAME, &account->auth_username,
-			COLUMN_ACCOUNT_PASSWORD, &account->password,
-			COLUMN_ACCOUNT_TIMEOUT, &account->timeout,
-			COLUMN_ACCOUNT_METHOD, &account->method,
-			-1); 
-
-    if (account->timeout == 0)
-      account->timeout = 3600;
-  }
-
-  return account;
-}
-
 /* Engine callbacks */
-static void on_registration_event_cb (Ekiga::CallManager & /*manager*/,
-                                      std::string aor,
-                                      Ekiga::CallCore::RegistrationState state,
-                                      std::string info,
-                                      gpointer window)
+static void on_registration_event (std::string aor,
+                                   Ekiga::AccountCore::RegistrationState state,
+                                   std::string info,
+                                   gpointer window)
 {
   bool is_processing = false;
   std::string status;
 
   switch (state) {
-  case Ekiga::CallCore::Registered:
+  case Ekiga::AccountCore::Registered:
     status = _("Registered");
     break;
 
-  case Ekiga::CallCore::Unregistered:
+  case Ekiga::AccountCore::Unregistered:
     status = _("Unregistered");
     break;
 
-  case Ekiga::CallCore::UnregistrationFailed:
+  case Ekiga::AccountCore::UnregistrationFailed:
     status = _("Could not unregister");
     if (!info.empty ())
       status = status + "(" + info + ")";
     break;
 
-  case Ekiga::CallCore::RegistrationFailed:
+  case Ekiga::AccountCore::RegistrationFailed:
     status = _("Could not register");
     if (!info.empty ())
       status = status + "(" + info + ")";
     break;
 
-  case Ekiga::CallCore::Processing:
+  case Ekiga::AccountCore::Processing:
     status = _("Processing...");
     is_processing = true;
   default:
@@ -833,664 +204,272 @@
 }
 
 
-/* GTK+ Callbacks */
-static gint
-account_clicked_cb (G_GNUC_UNUSED GtkWidget *w,
-		    G_GNUC_UNUSED GdkEventButton *e,
-		    gpointer data)
+static void
+populate_menu (GtkWidget *window)
 {
-  GmAccount *account = NULL;
   GmAccountsWindow *aw = NULL;
 
-  g_return_val_if_fail (data != NULL, FALSE);
+  MenuBuilderGtk builder;
 
-  aw = gm_aw_get_aw (GTK_WIDGET (data));
-  g_return_val_if_fail (aw != NULL, FALSE);
-  
-  account = gm_aw_get_selected_account (GTK_WIDGET (data));
+  GtkWidget *item = NULL;
+  GtkTreeSelection *selection = NULL;
+  GtkTreeModel *model = NULL;
+  GtkTreeIter iter;
+
+  Ekiga::Account *account = NULL;
 
-  if (account) {
+  aw = gm_aw_get_aw (GTK_WIDGET (window));
 
-    gtk_widget_set_sensitive (aw->delete_button, TRUE);
-    gtk_widget_set_sensitive (aw->edit_button, TRUE);
-    if (!account->default_account)
-      gtk_widget_set_sensitive (aw->default_button, TRUE);
-    else
-      gtk_widget_set_sensitive (aw->default_button, FALSE);
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (aw->accounts_list));
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (aw->accounts_list));
 
-    gm_account_delete (account);
+  Ekiga::AccountCore *account_core = dynamic_cast<Ekiga::AccountCore *> (aw->core.get ("account-core"));
+
+  if (account_core->populate_menu (builder)) {
+    item = gtk_separator_menu_item_new ();
+    gtk_menu_shell_append (GTK_MENU_SHELL (builder.menu), item);
   }
-  else {
 
-    gtk_widget_set_sensitive (aw->delete_button, FALSE);
-    gtk_widget_set_sensitive (aw->edit_button, FALSE);
-    gtk_widget_set_sensitive (aw->default_button, FALSE);
+  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+
+    gtk_tree_model_get (model, &iter,
+                        COLUMN_ACCOUNT, &account,
+                        -1);
+
+    if (account->populate_menu (builder)) {
+      item = gtk_separator_menu_item_new ();
+      gtk_menu_shell_append (GTK_MENU_SHELL (builder.menu), item);
+    }
   }
+  item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLOSE, aw->accel);
+  gtk_menu_shell_append (GTK_MENU_SHELL (builder.menu), item);
+  g_signal_connect_swapped (G_OBJECT (item), "activate",
+                            GTK_SIGNAL_FUNC (gtk_widget_hide),
+                            (gpointer) window);
 
-  return TRUE;
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (aw->menu_item_core),
+                             builder.menu);
+
+  gtk_widget_show_all (builder.menu);
 }
 
 
-static void
-account_toggled_cb (G_GNUC_UNUSED GtkCellRendererToggle *cell,
-		    gchar *path_str,
+/* GTK+ Callbacks */
+static gint
+account_clicked_cb (G_GNUC_UNUSED GtkWidget *w,
+		    GdkEventButton *event,
 		    gpointer data)
 {
   GmAccountsWindow *aw = NULL;
-  GmAccount *account = NULL;
 
   GtkTreePath *path = NULL;
-  GtkTreeSelection *selection = NULL;
+  GtkTreeView *tree_view = NULL;
+  GtkTreeModel *model = NULL;
+  GtkTreeIter iter;
 
-  aw = gm_aw_get_aw (GTK_WIDGET (data));
+  Ekiga::Account *account = NULL;
 
-  /* Make sure the toggled row is selected */
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (aw->accounts_list));
-  path = gtk_tree_path_new_from_string (path_str);
-  gtk_tree_selection_select_path (selection, path);
-  gtk_tree_path_free (path);
+  aw = gm_aw_get_aw (GTK_WIDGET (data));
 
-  /* Update the config */
-  account = gm_aw_get_selected_account (GTK_WIDGET (data));
-  gnomemeeting_account_toggle_active (account);
-
-  /* Update the account */
-  //gdk_threads_leave ();
-  dynamic_cast<Opal::CallManager *>(aw->core.get ("opal-component"))->Register (account);
-  //gdk_threads_enter ();
+  tree_view = GTK_TREE_VIEW (aw->accounts_list);
+  model = gtk_tree_view_get_model (tree_view);
 
-  gm_account_delete (account);
-}
+  if (event->type == GDK_BUTTON_PRESS || event->type == GDK_KEY_PRESS) {
 
+    populate_menu (GTK_WIDGET (data));
 
-static void
-add_account_cb (G_GNUC_UNUSED GtkWidget *button, 
-		G_GNUC_UNUSED gpointer data)
-{
-  GtkWidget *accounts_window = NULL;
+    if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree_view),
+                                       (gint) event->x, (gint) event->y,
+                                       &path, NULL, NULL, NULL)) {
 
-  accounts_window = GnomeMeeting::Process ()->GetAccountsWindow (); 
+      if (gtk_tree_model_get_iter (model, &iter, path)) {
 
-  gm_aw_edit_account_dialog_run (GTK_WIDGET (accounts_window), 
-				 NULL, 
-				 GTK_WIDGET (accounts_window));
-}
+        gtk_tree_model_get (model, &iter,
+                            COLUMN_ACCOUNT, &account,
+                            -1);
 
+        if (event->button == 3) {
 
-static void
-edit_account1_cb (G_GNUC_UNUSED GtkWidget *button, 
-		  gpointer data)
-{
-  GmAccount *account = NULL;
-  GtkWidget *accounts_window = NULL;
+          MenuBuilderGtk builder;
+          account->populate_menu (builder);
+          if (!builder.empty ()) {
 
-  g_return_if_fail (data != NULL);
+            gtk_widget_show_all (builder.menu);
+            gtk_menu_popup (GTK_MENU (builder.menu), NULL, NULL,
+                            NULL, NULL, event->button, event->time);
+            g_signal_connect (G_OBJECT (builder.menu), "hide",
+                              GTK_SIGNAL_FUNC (g_object_unref),
+                              (gpointer) builder.menu);
+          }
+        }
+      }
 
-  accounts_window = GTK_WIDGET (data);
+      gtk_tree_path_free (path);
+    }
+  }
 
-  account = gm_aw_get_selected_account (accounts_window);
-  gm_aw_edit_account_dialog_run (GTK_WIDGET (accounts_window), 
-				 account, 
-				 GTK_WIDGET (accounts_window));
-  gm_account_delete (account);
+  return TRUE;
 }
 
 
 static void
-edit_account2_cb (G_GNUC_UNUSED GtkTreeView *tree_view,
-		  G_GNUC_UNUSED GtkTreePath *arg1,
-		  G_GNUC_UNUSED GtkTreeViewColumn *arg2,
-		  gpointer data)
+account_toggled_cb (G_GNUC_UNUSED GtkCellRendererToggle *cell,
+		    gchar *path_str,
+		    gpointer data)
 {
-  g_return_if_fail (data != NULL);
-
-  edit_account1_cb (NULL, data);
-}
-
+  GmAccountsWindow *aw = NULL;
 
+  GtkTreeModel *model = NULL;
+  GtkTreePath *path = NULL;
+  GtkTreeSelection *selection = NULL;
+  GtkTreeIter iter;
 
-static void
-set_account_as_default_cb (G_GNUC_UNUSED GtkWidget *button, 
-			   gpointer data)
-{
-  GmAccount *account = NULL;
-  GmAccountsWindow *aw = NULL;
+  Ekiga::Account *account = NULL;
 
   aw = gm_aw_get_aw (GTK_WIDGET (data));
 
-  account = gm_aw_get_selected_account (GTK_WIDGET (data));
-  gnomemeeting_account_set_default (account, TRUE);
-  gm_account_delete (account);
-}
-
+  /* Make sure the toggled row is selected */
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (aw->accounts_list));
+  path = gtk_tree_path_new_from_string (path_str);
+  gtk_tree_selection_select_path (selection, path);
+  gtk_tree_path_free (path);
 
-static void
-delete_account_cb (G_GNUC_UNUSED GtkWidget *button, 
-		   G_GNUC_UNUSED gpointer data)
-{
-  GmAccount *account = NULL;
-  GtkWidget *accounts_window = NULL;
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (aw->accounts_list));
+  if (gtk_tree_model_get_iter (model, &iter, path)) {
 
-  accounts_window = GnomeMeeting::Process ()->GetAccountsWindow (); 
+    gtk_tree_model_get (model, &iter,
+                        COLUMN_ACCOUNT, &account,
+                        -1);
+    std::cout << "FIXME" << std::endl << std::flush;
+  }
 
-  account = gm_aw_get_selected_account (accounts_window);
-  if (account)
-    gm_aw_delete_account_dialog_run (GTK_WIDGET (accounts_window), 
-				     account, 
-				     GTK_WIDGET (accounts_window));
-  gm_account_delete (account);
+  gtk_tree_path_free (path);
 }
 
 
-static void
-account_dialog_protocol_changed_cb (G_GNUC_UNUSED GtkWidget *menu,
-				    gpointer data)
+static void 
+gm_accounts_window_add_account (GtkWidget *window,
+                                Ekiga::Account & account)
 {
-  GmAccountsEditWindow *aew = NULL;
-
-  g_return_if_fail (data != NULL);
-
-  aew = GM_ACCOUNTS_EDIT_WINDOW (data);
-
-  switch (gtk_combo_box_get_active (GTK_COMBO_BOX (aew->protocol_option_menu)))
-    {
-    case 0:
-      gtk_label_set_text (GTK_LABEL (aew->host_label), _("Registrar:"));
-      gtk_label_set_text (GTK_LABEL (aew->domain_label), _("Realm/Domain:"));
-      gtk_widget_show (aew->auth_username_label);
-      gtk_widget_show (aew->auth_username_entry);
-      gtk_widget_hide (aew->domain_entry);
-      gtk_widget_hide (aew->domain_label);
-      break;
-
-    case 1:
-      gtk_label_set_text (GTK_LABEL (aew->host_label), _("Gatekeeper:"));
-      gtk_label_set_text (GTK_LABEL (aew->domain_label), _("Gatekeeper ID:"));
-      gtk_widget_hide (aew->auth_username_label);
-      gtk_widget_hide (aew->auth_username_entry);
-      gtk_widget_show (aew->domain_entry);
-      gtk_widget_show (aew->domain_label);
-      break;
-    default:
-      break;
-    };
-}
+  GmAccountsWindow *aw = NULL;
+  GtkTreeModel *model = NULL;
 
+  GtkTreeIter iter;
 
-/* Implementation of public functions */
-GmAccount *
-gm_account_new ()
-{
-  GmAccount *account = NULL;
+  g_return_if_fail (window != NULL);
 
-  account = g_new (GmAccount, 1);
+  aw = gm_aw_get_aw (window);
 
-  account->aid = g_strdup ((const char *) OpalGloballyUniqueID ().AsString ());
-  account->account_name = NULL;
-  account->protocol_name = NULL;
-  account->host = NULL;
-  account->domain = NULL;
-  account->username = NULL;
-  account->auth_username = NULL;
-  account->password = NULL;
-  account->enabled = FALSE;
-  account->default_account = FALSE;
-  account->timeout = 3600;
-  account->method = 0;
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (aw->accounts_list));
 
-  return account;
+  gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+  gtk_list_store_set (GTK_LIST_STORE (model), &iter, 
+                      COLUMN_ACCOUNT, &account,
+                      COLUMN_ACCOUNT_WEIGHT, PANGO_WEIGHT_NORMAL,
+                      COLUMN_ACCOUNT_ENABLED, account.is_enabled (),
+                      COLUMN_ACCOUNT_DEFAULT, false,
+                      COLUMN_ACCOUNT_ACCOUNT_NAME, account.get_name ().c_str (),
+                      COLUMN_ACCOUNT_PROTOCOL_NAME, account.get_protocol_name ().c_str (),
+                      COLUMN_ACCOUNT_HOST, account.get_host ().c_str (),
+                      COLUMN_ACCOUNT_DOMAIN, account.get_host ().c_str (),
+                      COLUMN_ACCOUNT_USERNAME, account.get_username ().c_str (),
+                      COLUMN_ACCOUNT_AUTH_USERNAME, account.get_authentication_username ().c_str (),
+                      COLUMN_ACCOUNT_PASSWORD, account.get_password ().c_str (),
+                      -1); 
 }
 
 
 void
-gm_account_delete (GmAccount *account)
-{
-  if (!account)
-    return;
-
-  g_free (account->aid);
-  g_free (account->account_name);
-  g_free (account->protocol_name);
-  g_free (account->domain);
-  g_free (account->auth_username);
-  g_free (account->username);
-  g_free (account->password);
-  g_free (account->host);
-
-  g_free (account);
-}
-
-
-GmAccount *
-gm_account_copy (GmAccount *a)
+gm_accounts_window_update_account (GtkWidget *accounts_window,
+                                   Ekiga::Account & account)
 {
-  GmAccount *account = NULL;
-
-  if (!a)
-    return account;
+  Ekiga::Account *caccount = NULL;
 
-  account = g_new (GmAccount, 1);
-
-  account->aid = g_strdup (a->aid);
-  account->account_name = g_strdup (a->account_name);
-  account->protocol_name = g_strdup (a->protocol_name);
-  account->host = g_strdup (a->host);
-  account->domain = g_strdup (a->domain);
-  account->username = g_strdup (a->username);
-  account->auth_username = g_strdup (a->auth_username);
-  account->password = g_strdup (a->password);
-  account->enabled = a->enabled;
-  account->default_account = a->default_account;
-  account->timeout = a->timeout;
-  account->method = a->method;
-
-  return account;
-}
+  GtkTreeModel *model = NULL;
 
+  GtkTreeIter iter;
 
-gboolean 
-gnomemeeting_account_add (GmAccount *account)
-{
-  GSList *accounts = NULL;
-  GSList *accounts_iter = NULL;
-  
-  GmAccount *current_account = NULL;
+  GmAccountsWindow *aw = NULL;
 
-  gchar *entry = NULL;
+  g_return_if_fail (accounts_window != NULL);
 
-  if (account == NULL)
-    return FALSE;
-  
-  accounts = gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
+  aw = gm_aw_get_aw (accounts_window);
 
-  if (accounts == NULL)
-    account->default_account = TRUE;
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (aw->accounts_list));
 
-  if (account->default_account) {
+  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)){
 
-    accounts_iter = accounts;
-    while (accounts_iter) {
+    do {
 
-      current_account = 
-        gm_aw_from_string_to_account ((gchar *) accounts_iter->data);
-      current_account->default_account = FALSE;
+      gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+			  COLUMN_ACCOUNT, &caccount, -1);
       
-      entry = gm_aw_from_account_to_string (current_account);
-      g_free (accounts_iter->data);
-      accounts_iter->data = entry;
-
-      gm_account_delete (current_account);
-
-      accounts_iter = g_slist_next (accounts_iter);
-    }
-  }
-
-  entry = gm_aw_from_account_to_string (account);
-  accounts = g_slist_append (accounts, (gpointer) entry);
-  gm_conf_set_string_list (PROTOCOLS_KEY "accounts_list", 
-			   accounts);
-
-  g_slist_foreach (accounts, (GFunc) g_free, NULL);
-  g_slist_free (accounts);
+      if (caccount == &account) {
 
-  return TRUE;
-}
-
-
-gboolean 
-gnomemeeting_account_delete (GmAccount *account)
-{
-  GSList *list = NULL;
-  GSList *l = NULL;
-  GSList *l_default_delete = NULL;
-  GSList *l_delete = NULL;
-
-  GmAccount *current_account = NULL;
-  
-  gchar *entry = NULL;
-
-  gboolean found = FALSE;
-  gboolean new_default = FALSE;
-
-  if (account == NULL)
-    return FALSE;
-
-  list = 
-    gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
-
-  l = list;
-  while (l && (!found || !new_default)) {
-
-    if (l->data) {
-
-      current_account = gm_aw_from_string_to_account ((char *) l->data);
-      if (current_account->aid && account->aid 
-	  && !strcmp (current_account->aid, account->aid)) {
-	
-	found = TRUE;
-	l_delete = l;
-      }
-      else if (account->default_account) { /* It was the default account */
-
-	if (current_account->protocol_name && account->protocol_name
-	    && !strcmp (current_account->protocol_name, 
-			account->protocol_name)) {
-
-	  l_default_delete = l;
-	  current_account->default_account = TRUE;
-	  entry = gm_aw_from_account_to_string (current_account);
-	  new_default = TRUE;
-	}
+        gtk_list_store_set (GTK_LIST_STORE (model), &iter, 
+                            COLUMN_ACCOUNT, &account,
+                            COLUMN_ACCOUNT_WEIGHT, PANGO_WEIGHT_NORMAL,
+                            COLUMN_ACCOUNT_ENABLED, account.is_enabled (),
+                            COLUMN_ACCOUNT_DEFAULT, false,
+                            COLUMN_ACCOUNT_ACCOUNT_NAME, account.get_name ().c_str (),
+                            COLUMN_ACCOUNT_PROTOCOL_NAME, account.get_protocol_name ().c_str (),
+                            COLUMN_ACCOUNT_HOST, account.get_host ().c_str (),
+                            COLUMN_ACCOUNT_DOMAIN, account.get_host ().c_str (),
+                            COLUMN_ACCOUNT_USERNAME, account.get_username ().c_str (),
+                            COLUMN_ACCOUNT_AUTH_USERNAME, account.get_authentication_username ().c_str (),
+                            COLUMN_ACCOUNT_PASSWORD, account.get_password ().c_str (),
+                            -1); 
+        break;
       }
-
-      gm_account_delete (current_account);
-    }
-
-    l = g_slist_next (l);
-  }
-
-  if (found) {
-
-    list = g_slist_remove_link (list, l_delete);
-
-    g_free (l_delete->data);
-    g_slist_free_1 (l_delete);
-  }
-
-  if (new_default) {
-
-    list = g_slist_insert_before (list, l_default_delete, (gpointer) entry);
-    list = g_slist_remove_link (list, l_default_delete);
-
-    g_free (l_default_delete->data);
-    g_slist_free_1 (l_default_delete);
-  }
-
-  gm_conf_set_string_list (PROTOCOLS_KEY "accounts_list", 
-			   list);
-
-  g_slist_foreach (list, (GFunc) g_free, NULL);
-  g_slist_free (list);
-
-  return found;
-}
-
-
-gboolean 
-gnomemeeting_account_modify (GmAccount *account)
-{
-  GSList *list = NULL;
-  GSList *l = NULL;
-
-  gchar *entry = NULL;
-  gchar **couple = NULL;
-
-  gboolean found = FALSE;
-
-  if (account == NULL)
-    return FALSE;
-
-  list = 
-    gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
-
-  entry = gm_aw_from_account_to_string (account);
-
-  l = list;
-  while (l && !found) {
-
-    if (l->data) {
-
-      couple = g_strsplit ((const char *) l->data, "|", 0);
-      if (couple && couple [2] && !strcmp (couple [2], account->aid)) {
-
-	found = TRUE;
-	break;
-      }
-    }
-
-    l = g_slist_next (l);
-  }
-
-  if (found) {
-
-    list = g_slist_insert_before (list, l, (gpointer) entry);
-    list = g_slist_remove_link (list, l);
-
-    g_free (l->data);
-    g_slist_free_1 (l);
-
-    gm_conf_set_string_list (PROTOCOLS_KEY "accounts_list", 
-			     list);
+    } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
   }
-
-  g_slist_foreach (list, (GFunc) g_free, NULL);
-  g_slist_free (list);
-
-  return found;
 }
 
 
-GSList *
-gnomemeeting_get_accounts_list ()
+static bool 
+visit_accounts (Ekiga::Account & account,
+                gpointer data)
 {
-  GSList *result = NULL;
-
-  GSList *accounts_data_iter = NULL;
-  GSList *accounts_data = NULL;
-
-  GmAccount *account = NULL;
+  gm_accounts_window_add_account (GTK_WIDGET (data), account);
 
-  accounts_data = 
-    gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
-
-  accounts_data_iter = accounts_data;
-  while (accounts_data_iter) {
-
-    account = gm_aw_from_string_to_account ((gchar *) accounts_data_iter->data);
-
-    if (account != NULL)
-      result = g_slist_append (result, (void *) account);
-
-    accounts_data_iter = g_slist_next (accounts_data_iter);
-  }
-
-  g_slist_foreach (accounts_data, (GFunc) g_free, NULL);
-  g_slist_free (accounts_data);
-
-  return result;
+  return true;
 }
 
 
-GmAccount *
-gnomemeeting_get_account (const char *domain)
+static void
+on_account_added (Ekiga::Account & account,
+                  gpointer data)
 {
-  GmAccount *current_account = NULL;
-
-  GSList *list = NULL;
-  GSList *l = NULL;
-
-  gboolean found = FALSE;
-  
-  g_return_val_if_fail (domain != NULL, NULL);
-  
-  list = 
-    gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
-
-  l = list;
-  while (l && !found) {
-
-    if (l->data) {
-
-      current_account = gm_aw_from_string_to_account ((gchar *) l->data);
-      if ((current_account->domain
-	  && !g_ascii_strcasecmp (current_account->domain, domain))
-	  || (current_account->host
-	      && !g_ascii_strcasecmp (current_account->host, domain))) {
-	
-	found = TRUE;
-	break;
-      }
-
-      gm_account_delete (current_account);
-      current_account = NULL;
-    }
-
-    l = g_slist_next (l);
-  }
-
-  g_slist_foreach (list, (GFunc) g_free, NULL);
-  g_slist_free (list);
-
-  return current_account;
+  gm_accounts_window_add_account (GTK_WIDGET (data), account);
 }
 
 
-GmAccount *
-gnomemeeting_get_default_account (const gchar *protocol)
+static void 
+on_account_updated (Ekiga::Account & account,
+                    gpointer data)
 {
-  GmAccount *current_account = NULL;
-
-  GSList *list = NULL;
-  GSList *l = NULL;
-
-  gboolean found = FALSE;
-  
-  g_return_val_if_fail (protocol != NULL, NULL);
-  
-  list = 
-    gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
-
-  l = list;
-  while (l && !found) {
-
-    if (l->data) {
-
-      current_account = gm_aw_from_string_to_account ((gchar *) l->data);
-      if (current_account->protocol_name
-	  && current_account->default_account
-	  && !g_ascii_strcasecmp (current_account->protocol_name, protocol)) {
-	
-	found = TRUE;
-	break;
-      }
-
-      gm_account_delete (current_account);
-      current_account = NULL;
-    }
-
-    l = g_slist_next (l);
-  }
-
-  g_slist_foreach (list, (GFunc) g_free, NULL);
-  g_slist_free (list);
-
-  return current_account;
+  gm_accounts_window_update_account (GTK_WIDGET (data), account);
 }
 
 
-gboolean 
-gnomemeeting_account_toggle_active (GmAccount *account)
+static void 
+on_bank_added (Ekiga::Bank & bank,
+               gpointer data)
 {
-  GmAccount *current_account = NULL;
-  
-  GSList *accounts = NULL;
-  GSList *accounts_iter = NULL;
-  
-  gchar *entry = NULL;
-
-  if (!account)
-    return FALSE;
-
-  accounts = gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
-
-  accounts_iter = accounts;
-  while (accounts_iter) {
-
-    current_account = 
-      gm_aw_from_string_to_account ((gchar *) accounts_iter->data);
-
-    if (!strcmp (account->protocol_name, "H323")
-	&& !strcmp (current_account->protocol_name, "H323")
-	&& !account->enabled) 
-      current_account->enabled = FALSE;
-    
-    if (!strcmp (current_account->aid, account->aid)) {
-      
-      current_account->enabled = !account->enabled;
-      account->enabled = current_account->enabled;
-    }
-    
-    entry = gm_aw_from_account_to_string (current_account);
-    g_free (accounts_iter->data);
-    accounts_iter->data = entry;
-
-    accounts_iter = g_slist_next (accounts_iter);
-  }
-
-  gm_conf_set_string_list (PROTOCOLS_KEY "accounts_list", accounts);
-  
-  g_slist_foreach (accounts, (GFunc) g_free, NULL);
-  g_slist_free (accounts);
-
-  return TRUE;
+  bank.visit_accounts (sigc::bind (sigc::ptr_fun (visit_accounts), data));
+  populate_menu (GTK_WIDGET (data));
 }
 
 
-gboolean 
-gnomemeeting_account_set_default (GmAccount *account,
-				  gboolean default_account)
+static bool
+on_handle_questions (Ekiga::FormRequest *request,
+                     gpointer data)
 {
-  GmAccount *current_account = NULL;
+  FormDialog dialog (*request, GTK_WIDGET (data));
 
-  GSList *accounts = NULL;
-  GSList *accounts_iter = NULL;
+  dialog.run ();
 
-  gchar *entry = NULL;
-  
-  gboolean found = FALSE;
-  
-  if (!account || !account->protocol_name)
-    return FALSE;
-
-  accounts = gm_conf_get_string_list (PROTOCOLS_KEY "accounts_list");
-  if (!accounts)
-    return FALSE;
-
-  /* Only one account for each protocol as default at a time */
-  accounts_iter = accounts;
-  while (accounts_iter) {
-
-    current_account = 
-      gm_aw_from_string_to_account ((gchar *) accounts_iter->data);
-    if (!strcmp (current_account->protocol_name, account->protocol_name)) {
-      
-      /* Same protocol, other account */
-      if (strcmp (current_account->aid, account->aid)) {
-
-	current_account->default_account = !default_account;
-      }
-      /* Same protocol, same account */
-      else {
-
-	current_account->default_account = default_account;
-	account->default_account = default_account;
-	found = TRUE;
-      }
-
-      entry = gm_aw_from_account_to_string (current_account);
-      g_free (accounts_iter->data);
-      accounts_iter->data = entry;
-    }
-
-    accounts_iter = g_slist_next (accounts_iter);
-  }
-  
-  gm_conf_set_string_list (PROTOCOLS_KEY "accounts_list", accounts);
-  
-  g_slist_foreach (accounts, (GFunc) g_free, NULL);
-  g_slist_free (accounts);
-  
-  return found;
+  return true;
 }
 
 
@@ -1501,16 +480,13 @@
 
   GtkWidget *window = NULL;
 
+  GtkWidget *menu_bar = NULL;
   GtkWidget *event_box = NULL;
   GtkWidget *scroll_window = NULL;
 
   GtkWidget *frame = NULL;
   GtkWidget *hbox = NULL;
 
-  GtkWidget *button = NULL;
-  GtkWidget *buttons_vbox = NULL;
-  GtkWidget *alignment = NULL;
-
   GtkCellRenderer *renderer = NULL;
   GtkListStore *list_store = NULL;
   GtkTreeViewColumn *column = NULL;
@@ -1552,8 +528,23 @@
   g_object_set_data_full (G_OBJECT (window), "GMObject", 
 			  aw, gm_aw_destroy);
 
+  /* The menu */
+  menu_bar = gtk_menu_bar_new ();
+
+  aw->accel = gtk_accel_group_new ();
+  gtk_window_add_accel_group (GTK_WINDOW (window), aw->accel);
+  g_object_unref (aw->accel);
+
+  aw->menu_item_core = 
+    gtk_menu_item_new_with_mnemonic (_("Account"));
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar),
+                         aw->menu_item_core);
+  g_object_ref (aw->menu_item_core);
+
+
   /* The accounts list store */
   list_store = gtk_list_store_new (COLUMN_ACCOUNT_NUMBER,
+                                   G_TYPE_POINTER,
 				   G_TYPE_INT,
 				   G_TYPE_BOOLEAN, /* Enabled? */
 				   G_TYPE_BOOLEAN, /* Default? */
@@ -1577,8 +568,6 @@
   g_object_unref (list_store);
   gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (aw->accounts_list), TRUE);
   gtk_tree_view_set_reorderable (GTK_TREE_VIEW (aw->accounts_list), TRUE);
-  g_signal_connect (G_OBJECT (aw->accounts_list), "row-activated",
-		    G_CALLBACK (edit_account2_cb), window);
 
   aobj = gtk_widget_get_accessible (GTK_WIDGET (aw->accounts_list));
   atk_object_set_name (aobj, _("Accounts"));
@@ -1656,43 +645,9 @@
   gtk_container_set_border_width (GTK_CONTAINER (aw->accounts_list), 0);
   gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
 
-
-  /* The buttons */
-  alignment = gtk_alignment_new (1, 0.5, 0, 0);
-  buttons_vbox = gtk_vbutton_box_new ();
-
-  gtk_box_set_spacing (GTK_BOX (buttons_vbox), 2 * GNOMEMEETING_PAD_SMALL);
-
-  gtk_container_add (GTK_CONTAINER (alignment), buttons_vbox);
-  gtk_box_pack_start (GTK_BOX (hbox), alignment, 
-		      FALSE, FALSE, 2 * GNOMEMEETING_PAD_SMALL);
-
-  button = gtk_button_new_from_stock (GTK_STOCK_ADD);
-  gtk_box_pack_start (GTK_BOX (buttons_vbox), button, TRUE, TRUE, 0);
-  g_signal_connect (G_OBJECT (button), "clicked", 
-  		    GTK_SIGNAL_FUNC (add_account_cb), NULL); 
-
-  aw->delete_button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
-  gtk_widget_set_sensitive (aw->delete_button, FALSE);
-  gtk_box_pack_start (GTK_BOX (buttons_vbox), aw->delete_button, TRUE, TRUE, 0);
-  g_signal_connect (G_OBJECT (aw->delete_button), "clicked", 
-  		    GTK_SIGNAL_FUNC (delete_account_cb), NULL); 
-
-  aw->edit_button = gtk_button_new_from_stock (GTK_STOCK_PROPERTIES);
-  gtk_widget_set_sensitive (aw->edit_button, FALSE);
-  gtk_box_pack_start (GTK_BOX (buttons_vbox), aw->edit_button, TRUE, TRUE, 0);
-  g_signal_connect (G_OBJECT (aw->edit_button), "clicked", 
-  		    GTK_SIGNAL_FUNC (edit_account1_cb), window); 
-  
-  aw->default_button = gtk_button_new_with_mnemonic (_("_Default"));
-  gtk_widget_set_sensitive (aw->default_button, FALSE);
-  gtk_box_pack_start (GTK_BOX (buttons_vbox), 
-		      aw->default_button, TRUE, TRUE, 0);
-  g_signal_connect (G_OBJECT (aw->default_button), "clicked", 
-  		    GTK_SIGNAL_FUNC (set_account_as_default_cb), window); 
-
-  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
-		      event_box, TRUE, TRUE, 0);
+  populate_menu (window); // This will add static and dynamic actions
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), menu_bar, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), event_box, TRUE, TRUE, 0);
 
 
   /* Generic signals */
@@ -1707,14 +662,15 @@
   gtk_widget_show_all (GTK_WIDGET (GTK_DIALOG (window)->vbox));
 
   
-  /* We update it the accounts list to make sure the cursor is updated */
-  gm_accounts_window_update_accounts_list (window);
-
   /* Engine Signals callbacks */
   // FIXME sigc::connection conn;
-  Ekiga::CallCore *call_core = dynamic_cast<Ekiga::CallCore *> (core.get ("call-core"));
-  if (call_core) 
-    call_core->registration_event.connect (sigc::bind (sigc::ptr_fun (on_registration_event_cb), (gpointer) window));
+
+  Ekiga::AccountCore *account_core = dynamic_cast<Ekiga::AccountCore *> (core.get ("account-core"));
+  account_core->bank_added.connect (sigc::bind (sigc::ptr_fun (on_bank_added), window));
+  account_core->account_added.connect (sigc::bind (sigc::ptr_fun (on_account_added), window));
+  account_core->account_updated.connect (sigc::bind (sigc::ptr_fun (on_account_updated), window));
+  account_core->questions.add_handler (sigc::bind (sigc::ptr_fun (on_handle_questions), (gpointer) window));
+  account_core->registration_event.connect (sigc::bind (sigc::ptr_fun (on_registration_event), (gpointer) window));
   
   return window;
 }
@@ -1785,173 +741,5 @@
 
     } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
   }
-
-
-  /* We update it the accounts list to make sure the cursor is updated */
-  gm_accounts_window_update_accounts_list (accounts_window);
-}
-
-
-void
-gm_accounts_window_update_accounts_list (GtkWidget *accounts_window)
-{
-  GmAccountsWindow *aw = NULL;
-
-  GdkCursor *cursor = NULL;
-
-  GtkTreeSelection *selection = NULL;
-  GtkTreeModel *model = NULL;
-  GtkTreeIter iter;
-
-  gchar *selected_aid = NULL;
-  gchar *aid = NULL;
-
-  GmAccount *account = NULL;
-
-  GSList *accounts_data = NULL;
-  GSList *accounts_data_iter = NULL;
-
-  gboolean found = FALSE;
-  gboolean enabled = FALSE;
-  gboolean refreshing = FALSE;
-  gboolean busy = FALSE;
-  gboolean valid_iter = TRUE;
-
-  g_return_if_fail (accounts_window != NULL);
-
-  aw = gm_aw_get_aw (accounts_window);
-
-
-  /* Get the data and the selected codec */
-  model = gtk_tree_view_get_model (GTK_TREE_VIEW (aw->accounts_list));
-  selection = 
-    gtk_tree_view_get_selection (GTK_TREE_VIEW (aw->accounts_list));
-
-  if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-
-    gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
-			COLUMN_ACCOUNT_AID, &selected_aid, -1);
-  }
-
-
-  /* Loop through all accounts in the configuration.
-   * Then find that account in the GUI and updates it. 
-   * If we do not find the account in the GUI, append the new account
-   * at the end.
-   */
-  accounts_data = gnomemeeting_get_accounts_list (); 
-  accounts_data_iter = accounts_data;
-  while (accounts_data_iter && accounts_data_iter->data) {
-
-    account = GM_ACCOUNT (accounts_data_iter->data);
-
-    found = FALSE;
-    if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) {
-
-      do {
-
-	gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
-			    COLUMN_ACCOUNT_ENABLED, &enabled,
-			    COLUMN_ACCOUNT_STATE, &refreshing,
-			    COLUMN_ACCOUNT_AID, &aid, -1);
-	if (aid && account->aid && !strcmp (account->aid, aid)) {
-
-	  busy = busy || refreshing;
-	  found = TRUE;
-	}
-	g_free (aid);
-
-      } while (!found && 
-	       gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter)); 
-    }
-    if (!found) /* No existing entry for that account */ 
-      gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-
-    gtk_list_store_set (GTK_LIST_STORE (model), &iter, 
-			COLUMN_ACCOUNT_WEIGHT, 
-			account->default_account?
-			PANGO_WEIGHT_BOLD:PANGO_WEIGHT_NORMAL,
-			COLUMN_ACCOUNT_ENABLED, account->enabled,
-			COLUMN_ACCOUNT_DEFAULT, account->default_account,
-			COLUMN_ACCOUNT_AID, account->aid,
-			COLUMN_ACCOUNT_ACCOUNT_NAME, account->account_name,
-			COLUMN_ACCOUNT_PROTOCOL_NAME, account->protocol_name,
-			COLUMN_ACCOUNT_HOST, account->host,
-			COLUMN_ACCOUNT_DOMAIN, account->domain,
-			COLUMN_ACCOUNT_USERNAME, account->username,
-			COLUMN_ACCOUNT_AUTH_USERNAME, account->auth_username,
-			COLUMN_ACCOUNT_PASSWORD, account->password,
-			COLUMN_ACCOUNT_TIMEOUT, account->timeout,
-			COLUMN_ACCOUNT_METHOD, account->method,
-			-1); 
-
-    if (selected_aid && account->aid 
-	&& !strcmp (selected_aid, account->aid))
-      gtk_tree_selection_select_iter (selection, &iter);
-
-    accounts_data_iter = g_slist_next (accounts_data_iter);
-  }
-
-
-  /* Loop through the accounts in the window, and check
-   * if they are in the configuration. If not, remove them from the GUI.
-   */
-  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) {
-
-    do {
-
-      found = FALSE;
-      valid_iter = TRUE;
-
-      gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
-			  COLUMN_ACCOUNT_AID, &aid, -1);
-
-      accounts_data_iter = accounts_data;
-      while (accounts_data_iter && accounts_data_iter->data && !found) {
-
-	account = GM_ACCOUNT (accounts_data_iter->data);
-
-	if (account->aid && aid && !strcmp (account->aid, aid))
-	  found = TRUE;
-
-	accounts_data_iter = g_slist_next (accounts_data_iter);
-      }
-
-      if (!found)
-	valid_iter = gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-
-      g_free (aid);
-
-    } while (valid_iter &&
-	     gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter)); 
-  }
-
-
-  /* Free things */
-  g_slist_foreach (accounts_data, (GFunc) gm_account_delete, NULL);
-  g_slist_free (accounts_data);
-
-
-  /* Update the cursor and the activatable state of all accounts
-   * following we are refreshing or not */
-  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) {
-
-    do {
-
-      gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-			  COLUMN_ACCOUNT_ACTIVATABLE, !busy, -1);
-    } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
-  }
-
-  gtk_widget_realize (GTK_WIDGET (accounts_window));
-
-  if (busy) {
-
-    cursor = gdk_cursor_new (GDK_WATCH);
-    gdk_window_set_cursor (GTK_WIDGET (accounts_window)->window, cursor);
-    gdk_cursor_unref (cursor);
-  }
-  else
-    gdk_window_set_cursor (GTK_WIDGET (accounts_window)->window, NULL);
 }
 

Modified: trunk/src/gui/accounts.h
==============================================================================
--- trunk/src/gui/accounts.h	(original)
+++ trunk/src/gui/accounts.h	Mon Jun 30 20:58:35 2008
@@ -32,7 +32,7 @@
  *   begin                : Sun Feb 13 2005
  *   copyright            : (C) 2000-2006 by Damien Sandras
  *   description          : This file contains all the functions needed to
- *   			    manipulate H.323/SIP/... provider accounts.
+ *   			    manipulate accounts.
  */
 
 
@@ -42,127 +42,8 @@
 #include "common.h"
 #include "services.h"
 
-namespace Opal {
-  class CallManager;
-}
-
-
-/* An account is uniquely identified by its Account ID */
-struct GmAccount_ {
-
-  gchar *aid;			/* Account ID */
-  gchar *account_name;		/* Account Name */
-  gchar *protocol_name;		/* Protocol for the account */
-  gchar *host;			/* Host to register to */
-  gchar *domain;		/* Registration domain/realm */
-  gchar *username;		/* Username */
-  gchar *auth_username;		/* Authentication username */
-  gchar *password;		/* Password */
-  gboolean enabled;		/* Account active or not */
-  gboolean default_account;	/* Default account or not */
-  int timeout;			/* Registration timeout */
-  int method;			/* Registration method */
-}; 
-
-typedef GmAccount_ GmAccount;
-
-
-#define GM_ACCOUNT(x)     (GmAccount *) (x)
-
-
 /* The API */
 
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Returns an empty GmAccount. Only the UID field has a unique
- *                value.
- * PRE          : /
- */
-GmAccount *gm_account_new ();
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Deletes the given account and frees the associated memory.
- * PRE          : /
- */
-void gm_account_delete (GmAccount *account);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Makes a copy of the given account, keeps the same ID.
- * PRE          : /
- */
-GmAccount *gm_account_copy (GmAccount *account);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Adds the given account to the accounts list. The given 
- * 		  account and its ID must not exist yet in the list.
- * 		  Returns TRUE on success, FALSE on failure.
- * 		  If there is no default account for that protocol yet,
- * 		  then the added account becomes the new default.
- * PRE          : /
- */
-gboolean gnomemeeting_account_add (GmAccount *account);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Deletes the given account from the accounts list. 
- * 		  Returns TRUE on success, FALSE on failure.
- * 		  If that account was the default account for that protocol,
- * 		  then the first account of the same protocol will become
- * 		  the new default account.
- * PRE          : /
- */
-gboolean gnomemeeting_account_delete (GmAccount *account);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Modifies the given account in the accounts list. 
- * 		  Returns TRUE on success, FALSE on failure.
- * PRE          : /
- */
-gboolean gnomemeeting_account_modify (GmAccount *account);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Returns the list of configured GmAccounts.
- * PRE          : /
- */
-GSList *gnomemeeting_get_accounts_list ();
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Returns the account for the given domain or host.
- * PRE          : /
- */
-GmAccount *gnomemeeting_get_account (const char *);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Returns the default account for the given protocol (if any).
- * PRE          : /
- */
-GmAccount *gnomemeeting_get_default_account (const gchar *protocol);
-
-	
-/* DESCRIPTION  : /
- * BEHAVIOR     : Toggles the active state of the given account.
- * 		  Returns TRUE on success, FALSE on failure.
- * PRE          : /
- */
-gboolean gnomemeeting_account_toggle_active (GmAccount *account);
-
-
-/* DESCRIPTION  : /
- * BEHAVIOR     : Sets the account as default or not.
- * 		  Returns TRUE on success, FALSE on failure.
- * PRE          : /
- */
-gboolean gnomemeeting_account_set_default (GmAccount *account,
-					   gboolean default_account);
-
-
 /* DESCRIPTION  : /
  * BEHAVIOR     : Builds the GMAccounts window GMObject.
  * PRE          : /
@@ -185,15 +66,4 @@
 					      const gchar *voicemails);
 
 
-/* DESCRIPTION  :  /
- * BEHAVIOR     :  Refreshes the accounts list in the GUI to update them from
- *                 the accounts list in the GmConf user configuration.
- *                 If one of the account is in "refreshing state", then all
- *                 other accounts are unsensitive and the busy cursor is 
- *                 displayed for the accounts list box.
- * PRE          :  /
- */
-void gm_accounts_window_update_accounts_list (GtkWidget *accounts_window);
-
-
 #endif

Modified: trunk/src/gui/assistant.cpp
==============================================================================
--- trunk/src/gui/assistant.cpp	(original)
+++ trunk/src/gui/assistant.cpp	Mon Jun 30 20:58:35 2008
@@ -447,6 +447,7 @@
 static void
 prepare_ekiga_net_page (EkigaAssistant *assistant)
 {
+/*
   GmAccount *account = gnomemeeting_get_account ("ekiga.net");
 
   if (account && account->username)
@@ -459,11 +460,14 @@
 
   set_current_page_complete (GTK_ASSISTANT (assistant),
                              account && account->username && account->password);
+                             */
+  std::cout << "FIXME" << std::endl << std::flush;
 }
 
 static void
 apply_ekiga_net_page (EkigaAssistant *assistant)
 {
+/*
   GmAccount *account = gnomemeeting_get_account ("ekiga.net");
   Opal::CallManager *manager;
   gboolean new_account = FALSE;
@@ -495,18 +499,14 @@
   account->enabled =
     !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (assistant->priv->skip_ekiga_net));
 
-  /* If creating a new account, add it only if the user wants to use GM.NET,
-   * and make it the default account */
   if (new_account) {
     if (account->enabled)
       gnomemeeting_account_add (account);
   }
   else {
-    /* Modify the account, do not set it as default */
     gnomemeeting_account_modify (account);
   }
 
-  /* Register the current Endpoint to GnomeMeeting.NET */
   //gdk_threads_leave ();
   if (account->enabled) {
     manager = dynamic_cast<Opal::CallManager *> (assistant->priv->core->get ("opal-component"));
@@ -515,6 +515,7 @@
   //gdk_threads_enter ();
 
   gm_account_delete (account);
+  */
 }
 
 /************************

Modified: trunk/src/gui/conf.cpp
==============================================================================
--- trunk/src/gui/conf.cpp	(original)
+++ trunk/src/gui/conf.cpp	Mon Jun 30 20:58:35 2008
@@ -65,11 +65,6 @@
 
 
 /* Declarations */
-
-static void accounts_list_changed_nt (gpointer id,
-				      GmConfEntry *entry,
-				      gpointer data);
-
 static void manager_changed_nt (gpointer id,
 				GmConfEntry *entry,
 				gpointer data);
@@ -88,30 +83,6 @@
 
 
 /* DESCRIPTION  :  This notifier is called when the config database data
- *                 associated with an account changes.
- * BEHAVIOR     :  Updates the GUI and the registrations.
- * PRE          :  /
- */
-static void 
-accounts_list_changed_nt (G_GNUC_UNUSED gpointer id,
-			  GmConfEntry *entry, 
-			  G_GNUC_UNUSED gpointer data)
-{
-  GtkWidget *accounts_window = NULL;
-
-  accounts_window = GnomeMeeting::Process ()->GetAccountsWindow ();
-
-  if (gm_conf_entry_get_type (entry) == GM_CONF_LIST) {
-
-    //gdk_threads_enter ();
-    gm_accounts_window_update_accounts_list (accounts_window);
-    //gdk_threads_leave ();
-  }
-
-}
-
-
-/* DESCRIPTION  :  This notifier is called when the config database data
  *                 associated with the audio or video manager changes.
  * BEHAVIOR     :  Updates the devices list for the new manager.
  * PRE          :  /
@@ -234,11 +205,6 @@
    * several actions.
    */
 
-  /* Notifiers for the PROTOCOLS_KEY */
-  gm_conf_notifier_add (PROTOCOLS_KEY "accounts_list",
-			accounts_list_changed_nt, NULL);
-
-
   /* Notifiers to AUDIO_DEVICES_KEY */
   gm_conf_notifier_add (AUDIO_DEVICES_KEY "plugin", 
 			manager_changed_nt, NULL);

Modified: trunk/src/gui/main.cpp
==============================================================================
--- trunk/src/gui/main.cpp	(original)
+++ trunk/src/gui/main.cpp	Mon Jun 30 20:58:35 2008
@@ -581,34 +581,33 @@
 }
 
 
-static void on_registration_event_cb (Ekiga::CallManager & /*manager*/,
-                                      std::string aor,
-                                      Ekiga::CallCore::RegistrationState state,
-                                      G_GNUC_UNUSED std::string info,
-                                      gpointer window)
+static void on_registration_event (std::string aor,
+                                   Ekiga::AccountCore::RegistrationState state,
+                                   G_GNUC_UNUSED std::string info,
+                                   gpointer window)
 {
   gchar *msg = NULL;
 
   switch (state) {
-  case Ekiga::CallCore::Registered:
+  case Ekiga::AccountCore::Registered:
     /* Translators: Is displayed once an account "%s" is registered. */
     msg = g_strdup_printf (_("Registered %s"), aor.c_str ()); 
     break;
 
-  case Ekiga::CallCore::Unregistered:
+  case Ekiga::AccountCore::Unregistered:
     /* Translators: Is displayed once an account "%s" is unregistered. */
     msg = g_strdup_printf (_("Unregistered %s"), aor.c_str ());
     break;
 
-  case Ekiga::CallCore::UnregistrationFailed:
+  case Ekiga::AccountCore::UnregistrationFailed:
     msg = g_strdup_printf (_("Could not unregister %s"), aor.c_str ());
     break;
 
-  case Ekiga::CallCore::RegistrationFailed:
+  case Ekiga::AccountCore::RegistrationFailed:
     msg = g_strdup_printf (_("Could not register %s"), aor.c_str ());
     break;
 
-  case Ekiga::CallCore::Processing:
+  case Ekiga::AccountCore::Processing:
   default:
     break;
   }
@@ -3864,12 +3863,13 @@
     
   /* New Call Engine signals */
   Ekiga::CallCore *call_core = dynamic_cast<Ekiga::CallCore *> (mw->core.get ("call-core"));
+  Ekiga::AccountCore *account_core = dynamic_cast<Ekiga::AccountCore *> (mw->core.get ("account-core"));
 
   /* Engine Signals callbacks */
-  conn = call_core->mwi_event.connect (sigc::bind (sigc::ptr_fun (on_mwi_event_cb), (gpointer) window));
+  conn = account_core->registration_event.connect (sigc::bind (sigc::ptr_fun (on_registration_event), (gpointer) window));
   mw->connections.push_back (conn);
 
-  conn = call_core->registration_event.connect (sigc::bind (sigc::ptr_fun (on_registration_event_cb), (gpointer) window));
+  conn = call_core->mwi_event.connect (sigc::bind (sigc::ptr_fun (on_mwi_event_cb), (gpointer) window));
   mw->connections.push_back (conn);
 
   conn = call_core->setup_call.connect (sigc::bind (sigc::ptr_fun (on_setup_call_cb), (gpointer) window));
@@ -4373,10 +4373,6 @@
         g_timeout_add (15000, (GtkFunction) gnomemeeting_tray_hack_cb, NULL);
     }
 
-    Opal::CallManager *manager = dynamic_cast<Opal::CallManager *> (mw->core.get ("opal-component")); // FIXME
-    manager->Register ();
-
-
     /* Call the given host if needed */
     if (url) 
       call_core->dial (url);

Modified: trunk/src/gui/tools.cpp
==============================================================================
--- trunk/src/gui/tools.cpp	(original)
+++ trunk/src/gui/tools.cpp	Mon Jun 30 20:58:35 2008
@@ -147,8 +147,9 @@
 			     gint response,
 			     gpointer data)
 {
-  Opal::CallManager *ep = NULL;
+  //Opal::CallManager *ep = NULL;
   
+  /*
   GmAccount *account = NULL;
   GmPC2PhoneWindow *pcw = NULL;
 
@@ -166,13 +167,11 @@
   
   ep = dynamic_cast<Opal::CallManager *> (pcw->core.get ("opal-component"));
   
-  /* Get the data from the widgets */
   username = gtk_entry_get_text (GTK_ENTRY (pcw->username_entry));
   password = gtk_entry_get_text (GTK_ENTRY (pcw->password_entry));
   use_service = 
     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pcw->use_service_toggle));
 
-  /* If validate or apply, check all settings are present */
   if (response != GTK_RESPONSE_CANCEL && use_service 
       && (!strcmp (username, "") || !strcmp (password, ""))) {
     
@@ -180,7 +179,6 @@
     return;
   }
   
-  /* Let's go */
   account = gnomemeeting_get_account ("sip.diamondcard.us");
   if (account == NULL) {
 
@@ -214,17 +212,17 @@
     account->enabled =
       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pcw->use_service_toggle));
 
-    /* Update the account or create it */
     if (new_account)
       gnomemeeting_account_add (account);
     else
       gnomemeeting_account_modify (account);
     
-    /* Register the current Endpoint to the Gatekeeper */
     ep->Register (account);
   }
 
   gm_account_delete (account);
+  */
+    //FIXME
 }
 
 
@@ -281,7 +279,7 @@
 GtkWidget *
 gm_pc2phone_window_new (Ekiga::ServiceCore & core)
 {
-  GmAccount *account = NULL;
+  //GmAccount *account = NULL;
 
   GmPC2PhoneWindow *pcw = NULL;
   
@@ -295,7 +293,7 @@
   
 
   /* Get the PC-To-Phone account, if any */
-  account = gnomemeeting_get_account ("sip.diamondcard.us");
+  //account = gnomemeeting_get_account ("sip.diamondcard.us");
 
   
   /* Build the window */
@@ -337,8 +335,8 @@
 		    0, 0);
 
   pcw->username_entry = gtk_entry_new ();
-  if (account && account->username)
-    gtk_entry_set_text (GTK_ENTRY (pcw->username_entry), account->username);
+  //if (account && account->username)
+    //gtk_entry_set_text (GTK_ENTRY (pcw->username_entry), account->username);
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), pcw->username_entry);
   gtk_table_attach (GTK_TABLE (subsection), pcw->username_entry, 1, 2, 0, 1,
 		    (GtkAttachOptions) (GTK_FILL),
@@ -355,8 +353,8 @@
   
   pcw->password_entry = gtk_entry_new ();
   gtk_entry_set_visibility (GTK_ENTRY (pcw->password_entry), FALSE);
-  if (account && account->password)
-    gtk_entry_set_text (GTK_ENTRY (pcw->password_entry), account->password);
+  //if (account && account->password)
+    //gtk_entry_set_text (GTK_ENTRY (pcw->password_entry), account->password);
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), pcw->password_entry);
   gtk_table_attach (GTK_TABLE (subsection), pcw->password_entry, 1, 2, 1, 2,
 		    (GtkAttachOptions) (GTK_FILL),
@@ -365,9 +363,9 @@
 
   pcw->use_service_toggle =
     gtk_check_button_new_with_label (_("Use PC-To-Phone service"));
-  if (account && account->enabled)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pcw->use_service_toggle), 
-				  TRUE);
+  //if (account && account->enabled)
+    //gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pcw->use_service_toggle), 
+//				  TRUE);
   gtk_table_attach (GTK_TABLE (subsection), 
 		    pcw->use_service_toggle, 0, 2, 2, 3,
 		    (GtkAttachOptions) (GTK_FILL),
@@ -446,8 +444,9 @@
   
   gtk_widget_show_all (GTK_WIDGET (GTK_DIALOG (window)->vbox));
 
-  if (account)
-    gm_account_delete (account);
+  //if (account)
+    //gm_account_delete (account);
   
+  //FIXME
   return window;
 }



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