[ekiga: 281/281] Merge remote-tracking branch 'origin/ds-gtk-application'
- From: Damien Sandras <dsandras src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ekiga: 281/281] Merge remote-tracking branch 'origin/ds-gtk-application'
- Date: Thu, 25 Dec 2014 17:25:17 +0000 (UTC)
commit 1bdd5d610f4ae6cb14b771eb146d64bafeb378bf
Merge: 05a3ad8 96d93cd
Author: Damien Sandras <dsandras seconix com>
Date: Thu Dec 25 18:22:23 2014 +0100
Merge remote-tracking branch 'origin/ds-gtk-application'
Conflicts:
configure.ac
lib/Makefile.am
lib/engine/components/local-roster/local-cluster.cpp
lib/engine/components/local-roster/local-cluster.h
lib/engine/components/opal/opal-account.cpp
lib/engine/components/opal/opal-bank.cpp
lib/engine/components/opal/sip-chat-simple.cpp
lib/engine/components/opal/sip-endpoint.cpp
lib/engine/components/opal/sip-heap.cpp
lib/engine/components/opal/sip-heap.h
lib/engine/gui/gtk-frontend/assistant-window.cpp
lib/engine/gui/gtk-frontend/call-window.cpp
lib/engine/gui/gtk-frontend/chat-area.cpp
lib/engine/gui/gtk-frontend/chat-window.cpp
lib/engine/gui/gtk-frontend/gtk-frontend.cpp
lib/engine/gui/gtk-frontend/heap-view.cpp
lib/engine/gui/gtk-frontend/main_window.cpp
lib/engine/gui/gtk-frontend/roster-view-gtk.cpp
lib/engine/protocol/call-core.cpp
lib/engine/protocol/call-core.h
pixmaps/Makefile.am
plugins/avahi/Makefile.am
src/Makefile.am
src/main.cpp
.gitignore | 3 +-
Makefile.am | 17 +-
TODO | 28 +-
configure.ac | 17 +-
lib/Makefile.am | 74 +-
lib/engine/account/account-core.cpp | 16 -
lib/engine/account/account-core.h | 6 -
lib/engine/account/account.h | 16 +
lib/engine/account/bank.h | 10 +-
.../action-provider.cpp} | 43 +-
lib/engine/action/action-provider.h | 87 +
src/ekiga.cpp => lib/engine/action/action.cpp | 76 +-
lib/engine/action/action.h | 187 ++
lib/engine/action/actor.cpp | 153 ++
lib/engine/action/actor.h | 169 ++
lib/engine/addressbook/book.h | 2 +
lib/engine/addressbook/contact-core.cpp | 44 -
lib/engine/addressbook/contact-core.h | 36 +-
lib/engine/addressbook/contact.h | 4 +-
lib/engine/addressbook/source.h | 2 +
lib/engine/chat/chat-core.cpp | 13 -
.../components/call-history/history-book.cpp | 18 +-
lib/engine/components/call-history/history-book.h | 7 +-
.../components/call-history/history-contact.cpp | 32 +-
.../components/call-history/history-contact.h | 4 +-
.../components/call-history/history-source.cpp | 11 +-
.../components/call-history/history-source.h | 4 +-
lib/engine/components/foe-list/foe-list.h | 1 -
.../components/local-roster/local-cluster.cpp | 111 -
lib/engine/components/local-roster/local-cluster.h | 104 -
lib/engine/components/local-roster/local-heap.cpp | 499 -----
lib/engine/components/local-roster/local-heap.h | 224 --
.../components/local-roster/local-presentity.cpp | 485 -----
.../components/local-roster/local-presentity.h | 210 --
.../local-roster/local-roster-bridge.cpp | 145 --
.../components/local-roster/local-roster-main.cpp | 85 -
.../components/local-roster/local-roster-main.h | 54 -
.../mlogo-videoinput/videoinput-manager-mlogo.cpp | 58 +-
.../mlogo-videoinput/videoinput-manager-mlogo.h | 4 +-
lib/engine/components/opal/h323-endpoint.cpp | 71 +-
lib/engine/components/opal/h323-endpoint.h | 17 +-
lib/engine/components/opal/opal-account.cpp | 397 ++--
lib/engine/components/opal/opal-account.h | 52 +-
lib/engine/components/opal/opal-bank.cpp | 233 +--
lib/engine/components/opal/opal-bank.h | 29 +-
lib/engine/components/opal/opal-call-manager.cpp | 119 +-
lib/engine/components/opal/opal-call-manager.h | 26 +-
lib/engine/components/opal/opal-call.cpp | 82 +-
lib/engine/components/opal/opal-call.h | 13 +-
lib/engine/components/opal/opal-main.cpp | 13 +-
lib/engine/components/opal/opal-main.h | 3 +
lib/engine/components/opal/opal-presentity.cpp | 118 +-
lib/engine/components/opal/opal-presentity.h | 28 +-
.../engine/components/opal/opal-process.cpp | 10 +-
.../engine/components/opal/opal-process.h | 11 +-
lib/engine/components/opal/sip-conversation.cpp | 7 +-
lib/engine/components/opal/sip-endpoint.cpp | 101 +-
lib/engine/components/opal/sip-endpoint.h | 19 +-
lib/engine/components/opal/sip-heap.cpp | 14 +-
lib/engine/components/opal/sip-heap.h | 3 -
lib/engine/engine.cpp | 19 +-
lib/engine/framework/form-builder.cpp | 100 +-
lib/engine/framework/form-builder.h | 84 +-
lib/engine/framework/form-dumper.cpp | 41 +-
lib/engine/framework/form-dumper.h | 24 +-
lib/engine/framework/form-request-simple.cpp | 13 +-
lib/engine/framework/form-request-simple.h | 7 +-
lib/engine/framework/form-request.h | 2 +-
lib/engine/framework/form-visitor.h | 34 +-
lib/engine/framework/form.cpp | 12 +-
lib/engine/framework/form.h | 8 +-
lib/engine/framework/live-object.h | 5 -
.../framework/null-deleter.h} | 33 +-
lib/engine/framework/services.cpp | 3 +-
lib/engine/gui/gtk-core/codecsbox.cpp | 16 +-
lib/engine/gui/gtk-core/form-dialog-gtk.cpp | 687 ++++---
lib/engine/gui/gtk-core/form-dialog-gtk.h | 43 +-
lib/engine/gui/gtk-core/gactor-menu.cpp | 263 +++
lib/engine/gui/gtk-core/gactor-menu.h | 146 ++
lib/engine/gui/gtk-core/gtk-core.cpp | 3 -
lib/engine/gui/gtk-core/menu-builder-gtk.cpp | 35 +-
lib/engine/gui/gtk-core/optional-buttons-gtk.cpp | 130 --
lib/engine/gui/gtk-core/optional-buttons-gtk.h | 122 --
lib/engine/gui/gtk-frontend/accounts-window.cpp | 710 ------
lib/engine/gui/gtk-frontend/accounts-window.h | 94 -
lib/engine/gui/gtk-frontend/addressbook-window.cpp | 593 +++---
lib/engine/gui/gtk-frontend/addressbook-window.h | 4 +-
lib/engine/gui/gtk-frontend/assistant-window.cpp | 266 +--
lib/engine/gui/gtk-frontend/assistant-window.h | 13 +-
lib/engine/gui/gtk-frontend/book-view-gtk.cpp | 454 +++--
lib/engine/gui/gtk-frontend/book-view-gtk.h | 16 +-
.../gui/gtk-frontend/call-history-view-gtk.cpp | 240 +--
.../gui/gtk-frontend/call-history-view-gtk.h | 11 +-
lib/engine/gui/gtk-frontend/call-window.cpp | 2249 +++++++-------------
lib/engine/gui/gtk-frontend/call-window.h | 10 +-
lib/engine/gui/gtk-frontend/chat-area.cpp | 19 +-
lib/engine/gui/gtk-frontend/chat-window.cpp | 50 +-
lib/engine/gui/gtk-frontend/chat-window.h | 4 +-
lib/engine/gui/gtk-frontend/conversation-page.cpp | 10 -
lib/engine/gui/gtk-frontend/ekiga-app.cpp | 1036 +++++++++
lib/engine/gui/gtk-frontend/ekiga-app.h | 117 +
lib/engine/gui/gtk-frontend/gtk-frontend.cpp | 280 ---
lib/engine/gui/gtk-frontend/gtk-frontend.h | 99 -
lib/engine/gui/gtk-frontend/heap-view.cpp | 740 -------
lib/engine/gui/gtk-frontend/heap-view.h | 85 -
lib/engine/gui/gtk-frontend/main_window.cpp | 1149 ++--------
lib/engine/gui/gtk-frontend/main_window.h | 6 +-
lib/engine/gui/gtk-frontend/preferences-window.cpp | 285 ++--
lib/engine/gui/gtk-frontend/preferences-window.h | 12 +-
lib/engine/gui/gtk-frontend/presentity-view.cpp | 33 -
lib/engine/gui/gtk-frontend/roster-view-gtk.cpp | 537 +++--
lib/engine/gui/gtk-frontend/roster-view-gtk.h | 16 +-
lib/engine/gui/gtk-frontend/statusicon.cpp | 119 +-
lib/engine/gui/gtk-frontend/statusicon.h | 4 +-
lib/engine/plugin/plugin-core.cpp | 2 -
lib/engine/presence/heap.h | 11 +-
lib/engine/presence/presence-core.cpp | 38 -
lib/engine/presence/presence-core.h | 52 +-
lib/engine/presence/presentity.h | 6 +-
lib/engine/presence/proxy-presentity.cpp | 83 -
lib/engine/presence/proxy-presentity.h | 102 -
lib/engine/presence/uri-presentity.cpp | 15 +-
lib/engine/presence/uri-presentity.h | 12 +-
lib/engine/protocol/call-core.cpp | 108 +-
lib/engine/protocol/call-core.h | 47 +-
lib/engine/protocol/call-manager.h | 43 +-
lib/engine/protocol/call-protocol-manager.h | 38 +-
lib/engine/protocol/call.h | 15 +-
lib/engine/videoinput/videoinput-core.cpp | 10 -
lib/gui/dialpad.c | 53 +-
lib/gui/gm-cell-renderer-expander.c | 367 ++++
lib/gui/gm-cell-renderer-expander.h | 78 +
lib/gui/gm-entry.c | 472 ++++
lib/gui/gm-entry.h | 169 ++
lib/gui/gm-info-bar.c | 267 +++
lib/gui/gm-info-bar.h | 104 +
lib/gui/gm-sidebar.c | 526 +++++
lib/gui/gm-sidebar.h | 64 +
lib/gui/gmcallbacks.c | 219 --
lib/gui/gmcallbacks.h | 74 -
lib/gui/gmcellrendererexpander.c | 345 ---
lib/gui/gmcellrendererexpander.h | 60 -
lib/gui/gmentrydialog.c | 130 --
lib/gui/gmentrydialog.h | 109 -
lib/gui/gmmenuaddon.c | 459 ----
lib/gui/gmmenuaddon.h | 183 --
lib/gui/gmpowermeter.c | 209 --
lib/gui/gmpowermeter.h | 141 --
lib/gui/gmstatusbar.c | 205 --
lib/gui/gmstatusbar.h | 112 -
lib/gui/gmstockicons.c | 93 -
lib/gui/gmwindow.c | 50 +-
lib/gui/gmwindow.h | 25 +-
org.gnome.ekiga.gschema.xml.in.in | 13 +
pixmaps/128x128/multimedia-headset.png | Bin 12120 -> 0 bytes
pixmaps/128x128/multimedia-headset.svg | 1412 ------------
pixmaps/16x16/audio-volume.png | Bin 685 -> 0 bytes
pixmaps/16x16/brightness.png | Bin 356 -> 0 bytes
pixmaps/16x16/color.png | Bin 577 -> 0 bytes
pixmaps/16x16/contrast.png | Bin 625 -> 0 bytes
pixmaps/16x16/im-message-new.png | Bin 693 -> 0 bytes
pixmaps/16x16/multimedia-headset.png | Bin 816 -> 0 bytes
pixmaps/16x16/multimedia-headset.svg | 345 ---
pixmaps/16x16/video-settings.png | Bin 920 -> 0 bytes
pixmaps/16x16/whiteness.png | Bin 358 -> 0 bytes
pixmaps/22x22/multimedia-headset.png | Bin 1219 -> 0 bytes
pixmaps/22x22/multimedia-headset.svg | 407 ----
pixmaps/256x256/multimedia-headset.png | Bin 31534 -> 0 bytes
pixmaps/32x32/multimedia-headset.png | Bin 1884 -> 0 bytes
pixmaps/32x32/multimedia-headset.svg | 632 ------
pixmaps/48x48/multimedia-headset.png | Bin 3354 -> 0 bytes
pixmaps/HOWTO | 11 -
pixmaps/Makefile.am | 136 +-
pixmaps/conv-icon.pl | 18 +-
pixmaps/{256x256 => }/ekiga-full-icon.png | Bin 28340 -> 28340 bytes
pixmaps/gm_powermeter_default_00.xpm | 101 -
pixmaps/gm_powermeter_default_01.xpm | 98 -
pixmaps/gm_powermeter_default_02.xpm | 84 -
pixmaps/gm_powermeter_default_03.xpm | 62 -
pixmaps/gm_powermeter_default_04.xpm | 29 -
.../gnome_actions_128x128_mute-video-symbolic.png | Bin 0 -> 2676 bytes
...p.png => gnome_actions_16x16_phone-hang-up.png} | Bin 605 -> 605 bytes
...p.png => gnome_actions_16x16_phone-pick-up.png} | Bin 695 -> 695 bytes
...p.png => gnome_actions_24x24_phone-hang-up.png} | Bin 1149 -> 1149 bytes
...p.png => gnome_actions_24x24_phone-pick-up.png} | Bin 1215 -> 1215 bytes
.../gnome_actions_scalable_call-hold-symbolic.svg | 33 +
...actions_scalable_call-transfer-symbolic-rtl.svg | 33 +
...ome_actions_scalable_call-transfer-symbolic.svg | 33 +
.../gnome_actions_scalable_mute-video-symbolic.svg | 32 +
...ssage.png => gnome_status_16x16_im-message.png} | Bin 510 -> 510 bytes
...all.png => gnome_status_16x16_user-inacall.png} | Bin 676 -> 676 bytes
.../ekiga.png => hicolor_apps_128x128_ekiga.png} | Bin 11034 -> 11034 bytes
.../ekiga.png => hicolor_apps_16x16_ekiga.png} | Bin 882 -> 882 bytes
.../ekiga.png => hicolor_apps_22x22_ekiga.png} | Bin 1407 -> 1407 bytes
.../ekiga.png => hicolor_apps_24x24_ekiga.png} | Bin 1432 -> 1432 bytes
.../ekiga.png => hicolor_apps_32x32_ekiga.png} | Bin 2178 -> 2178 bytes
.../ekiga.png => hicolor_apps_48x48_ekiga.png} | Bin 3702 -> 3702 bytes
.../ekiga.png => hicolor_apps_64x64_ekiga.png} | Bin 4989 -> 4989 bytes
.../ekiga.png => hicolor_apps_72x72_ekiga.png} | Bin 4872 -> 4872 bytes
pixmaps/icon.h | 2000 +++++++++++++-----
pixmaps/scalable/multimedia-headset.svg | 667 ------
plugins/avahi/Makefile.am | 2 +
plugins/avahi/avahi-heap.cpp | 4 +-
plugins/evolution/Makefile.am | 1 +
plugins/evolution/evolution-book.cpp | 42 +-
plugins/evolution/evolution-book.h | 8 +-
plugins/evolution/evolution-contact.cpp | 109 +-
plugins/evolution/evolution-contact.h | 12 +-
plugins/kab/kab-book.h | 2 +-
plugins/ldap/Makefile.am | 1 +
plugins/ldap/ldap-book.cpp | 105 +-
plugins/ldap/ldap-book.h | 12 +-
plugins/ldap/ldap-contact.cpp | 25 -
plugins/ldap/ldap-contact.h | 2 -
plugins/ldap/ldap-source.cpp | 34 +-
plugins/ldap/ldap-source.h | 7 +-
plugins/libnotify/Makefile.am | 2 +
plugins/loudmouth/loudmouth-account.cpp | 4 +-
plugins/loudmouth/loudmouth-bank.cpp | 4 +-
plugins/loudmouth/loudmouth-heap-roster.cpp | 28 +-
plugins/loudmouth/loudmouth-heap-roster.h | 2 +-
plugins/resource-list/rl-cluster.cpp | 15 +-
plugins/resource-list/rl-cluster.h | 5 +-
plugins/resource-list/rl-heap.cpp | 26 +-
plugins/resource-list/rl-heap.h | 10 +-
plugins/resource-list/rl-presentity.cpp | 11 +-
plugins/resource-list/rl-presentity.h | 5 +-
src/Makefile.am | 11 +-
src/dbus-helper/dbus.cpp | 28 +-
src/dbus-helper/dbus.h | 4 +-
src/main.cpp | 198 +--
231 files changed, 10576 insertions(+), 16901 deletions(-)
---
diff --cc TODO
index 0fb1ad0,ff0c643..3890c66
--- a/TODO
+++ b/TODO
@@@ -1,5 -1,28 +1,29 @@@
See our wiki: http://wiki.ekiga.org/index.php/ToDo
- - Check what happens when we hide the window. Can we get it back when we want ?
- - Update DOC with 4.0 screenshots
+ - clean up signal relay. No need to have a class method for each signal "relay".
+ - Check what happens when we hide the window. Can we get it back when we want ? DONE
+ - Update DOC with 5.0 screenshots
- Make sure that automatic reREGISTER and presence reSUBSCRIBE/PUBLISH still works when a registrar is down
then comes online.
- Make sure refresh also works as expected.
+ - Simplify Call Core code by using signal relay (boost::ref)
+ - Turn LiveObject into an Actor ?
+ - add_heap does not seem to be used anymore
+ - questions from Account Edition relayed to PresenceCore ? Well why not.
+ - GSettings migration ? To check.
+ - Roster migration : to implement + implement adding Echo test and such to the roster when it is not empty.
+ - trackable object (in .h ?)
+ - Is Heap-Impl still used in the OPAL component ?
+ - This existing_group function passed to the Opal::Account ctor is so weiiiiiird....
+ - Proof check all dialogs. e.g. can we delete the SIP URI of a roster contact and save it ?
+ - Forms error checking should be simplified. Perhaps with "allow_empty" properties ? and URI handling ? DONE
+ - Check Forms for mnemonics.
+ - Check Accels
+ - Prefs should perhaps use GtkInfoBar to prevent entering wrong forward uris.
+ - Use GtkInfoBar instead of GmStatusBar. DONE
+ - Clean icons & pixmaps.
+ - Call Window : add / remove entries -> concert to add + disable actions
+ - Contact phone numbers: open a popup with all possibilities instead of right-click popup => 1 action.
Urgent.
+ - Cleanup Ekiga App. Not sure everything is initialized at the right place.
+ - Cleanup files (e.g. codecsbox which is frontend, not core)
+ - Roster should be refreshed when accounts are added/removed
+ - Global actions should be updated if an Ekiga.net/DiamondCard is added/removed.
++- Call Window: on_setup_call, check if it is the right place for blacklist handling + status change
("calling", isn't it called on incoming calls too ?)
diff --cc lib/Makefile.am
index 5c7a7a9,72f657b..63ba0fc
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@@ -34,11 -39,8 +35,10 @@@ AM_CPPFLAGS =
-I$(top_srcdir)/lib/engine/videooutput \
-I$(top_srcdir)/lib/engine/components/call-history \
-I$(top_srcdir)/lib/engine/components/echo \
+ -I$(top_srcdir)/lib/engine/components/foe-list \
-I$(top_srcdir)/lib/engine/components/gmconf-personal-details \
-I$(top_srcdir)/lib/engine/components/hal-dbus \
+ -I$(top_srcdir)/lib/engine/components/hal-gudev \
- -I$(top_srcdir)/lib/engine/components/local-roster \
-I$(top_srcdir)/lib/engine/components/mlogo-videoinput \
-I$(top_srcdir)/lib/engine/components/null-audioinput \
-I$(top_srcdir)/lib/engine/components/null-audiooutput \
@@@ -363,12 -397,12 +370,10 @@@ libekiga_la_SOURCES +=
engine/gui/gtk-frontend/default_devices.h \
engine/gui/gtk-frontend/presentity-view.h \
engine/gui/gtk-frontend/presentity-view.cpp \
- engine/gui/gtk-frontend/heap-view.h \
- engine/gui/gtk-frontend/heap-view.cpp \
engine/gui/gtk-frontend/chat-area.h \
engine/gui/gtk-frontend/chat-area.cpp \
- engine/gui/gtk-frontend/simple-chat-page.h \
- engine/gui/gtk-frontend/simple-chat-page.cpp \
- engine/gui/gtk-frontend/multiple-chat-page.h \
- engine/gui/gtk-frontend/multiple-chat-page.cpp \
+ engine/gui/gtk-frontend/conversation-page.h \
+ engine/gui/gtk-frontend/conversation-page.cpp \
engine/gui/gtk-frontend/preferences-window.cpp \
engine/gui/gtk-frontend/preferences-window.h \
engine/gui/gtk-frontend/statusicon.cpp \
diff --cc lib/engine/components/call-history/history-book.cpp
index 80b4044,be69b14..4588339
--- a/lib/engine/components/call-history/history-book.cpp
+++ b/lib/engine/components/call-history/history-book.cpp
@@@ -78,10 -78,16 +78,16 @@@ History::Book::Book (Ekiga::ServiceCore
boost::shared_ptr<Ekiga::CallCore> call_core = core.get<Ekiga::CallCore> ("call-core");
- call_core->missed_call.connect (boost::bind (&History::Book::on_missed_call, this, _1, _2));
- call_core->cleared_call.connect (boost::bind (&History::Book::on_cleared_call, this, _1, _2, _3));
+ connections.add (call_core->missed_call.connect (boost::bind (&History::Book::on_missed_call, this, _1,
_2)));
+ connections.add (call_core->cleared_call.connect (boost::bind (&History::Book::on_cleared_call, this, _1,
_2, _3)));
enforce_size_limit ();
+
+ /* Actor actions should be added */
+ add_action (Ekiga::ActionPtr (new Ekiga::Action ("history_book_clear",
+ _("Clear History"),
+ boost::bind (&History::Book::clear,
+ this))));
}
History::Book::~Book ()
diff --cc lib/engine/components/foe-list/foe-list.h
index 26e816b,be0bfa1..7bdaa3f
--- a/lib/engine/components/foe-list/foe-list.h
+++ b/lib/engine/components/foe-list/foe-list.h
@@@ -33,53 -33,40 +33,52 @@@
*
*/
-#ifndef __ECHO_DIALECT_H__
-#define __ECHO_DIALECT_H__
+#ifndef __FOE_LIST_H__
+#define __FOE_LIST_H__
-#include "services.h"
-#include "dialect-impl.h"
-#include "echo-simple.h"
+#include "contact-core.h"
+#include "friend-or-foe.h"
-namespace Echo
+namespace Ekiga
{
- class Dialect:
- public Ekiga::Service,
- public Ekiga::DialectImpl<SimpleChat>
+
+ class FoeList:
+ public Service,
- public ContactDecorator,
+ public FriendOrFoe::Helper
{
public:
-
- Dialect ();
+ FoeList(boost::shared_ptr<FriendOrFoe> friend_or_foo);
- ~Dialect ();
+ ~FoeList();
- bool populate_menu (Ekiga::MenuBuilder &builder);
+ /* Ekiga::Service api */
const std::string get_name () const
- { return "echo-dialect"; }
+ { return "foe-list"; }
const std::string get_description () const
- { return "\tProvides an echo chat for testing purposes"; }
+ { return "List of persons the user does not want to hear about"; }
- private:
+ /* Ekiga::ContactDecorator api */
- void new_chat ();
- };
+ bool populate_menu (ContactPtr contact,
+ const std::string uri,
+ MenuBuilder& builder);
+
+ /* Ekiga::FriendOrFoe::Helper api */
+
+ FriendOrFoe::Identification decide (const std::string domain,
+ const std::string token) const;
- typedef boost::shared_ptr<Dialect> DialectPtr;
+ /* specific api */
+ void add_foe (const std::string token);
+
+ private:
+
+ // beware of dependency loops!
+ boost::weak_ptr<FriendOrFoe> friend_or_foe;
+ };
};
#endif
diff --cc lib/engine/components/opal/opal-account.cpp
index 4d2fdc6,aaa1a98..dcaf94a
--- a/lib/engine/components/opal/opal-account.cpp
+++ b/lib/engine/components/opal/opal-account.cpp
@@@ -866,10 -866,7 +857,10 @@@ Opal::Account::publish (const Ekiga::Pe
presence_status = details.get_status ();
if (presentity) {
- OpalPresenceInfo opi = OpalPresenceInfo (OpalPresenceInfo::Available);
- presentity->SetLocalPresence (personal_state, presence_status);
++ OpalPresenceInfo opi = OpalPresenceInfo (personal_state);
+ opi.m_activities = PString (presence);
+ opi.m_note = presence_status;
+ presentity->SetLocalPresence (opi);
PTRACE (4, "Ekiga\tSent its own presence (publish) for " << get_aor() << ": " << presence << ", note "
<< presence_status);
}
}
@@@ -921,10 -918,10 +912,10 @@@ Opal::Account::handle_registration_even
failed_registration_already_notified = false;
if (presentity) {
- for (const_iterator iter = begin ();
- iter != end ();
- for (Ekiga::RefLister< Presentity >::const_iterator iter = Ekiga::RefLister< Presentity >::begin ();
- iter != Ekiga::RefLister< Presentity >::end ();
- ++iter)
- fetch ((*iter)->get_uri());
++ for (Ekiga::RefLister<Presentity>::const_iterator iter = Ekiga::RefLister<Presentity>::begin ();
++ iter != Ekiga::RefLister<Presentity>::end ();
+ ++iter)
+ fetch ((*iter)->get_uri());
presentity->SetLocalPresence (personal_state, presence_status);
if (type != Account::H323) {
@@@ -1012,16 -1003,13 +1003,16 @@@
std::stringstream msg;
msg << _("Could not register to ") << get_name ();
boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification
(Ekiga::Notification::Warning, msg.str (), info, _("Edit"), boost::bind (&Opal::Account::edit,
(Opal::Account*) this)));
- boost::shared_ptr<Ekiga::NotificationCore> ncore = notification_core.lock ();
- if (ncore)
- ncore->push_notification (notif);
+ boost::shared_ptr<Ekiga::NotificationCore> ncore = notification_core.lock ();
+ if (ncore)
+ ncore->push_notification (notif);
+ updated ();
}
- updated ();
failed_registration_already_notified = true;
break;
+ case SIPRegister::EndCompatibilityModes:
+ // bookkeeping code, to remove a compile warning
+ break;
default:
state = state_;
diff --cc lib/engine/components/opal/opal-bank.h
index 630b2b5,0930f80..384e7c3
--- a/lib/engine/components/opal/opal-bank.h
+++ b/lib/engine/components/opal/opal-bank.h
@@@ -116,11 -103,8 +102,11 @@@ public
/* this object is an Ekiga::Cluster */
void visit_heaps (boost::function1<bool, Ekiga::HeapPtr> visitor) const;
- const std::set<std::string> existing_groups () const;
+ const std::list<std::string> existing_groups () const;
+ /* this is useful when we want to do something with some uri and
+ would like to avoid creating a brand-new presentity on it */
+ Ekiga::PresentityPtr find_presentity_for_uri (const std::string uri) const;
// FIXME: only here for the transition off gconf
static void migrate_from_gconf (const std::list<std::string> old);
diff --cc lib/engine/components/opal/opal-main.cpp
index a2d00ba,ccd7e3c..1253867
--- a/lib/engine/components/opal/opal-main.cpp
+++ b/lib/engine/components/opal/opal-main.cpp
@@@ -38,8 -38,8 +38,9 @@@
#include "config.h"
#include "opal-main.h"
+ #include "opal-process.h"
+#include "account-core.h"
#include "chat-core.h"
#include "presence-core.h"
#include "audioinput-core.h"
diff --cc lib/engine/components/opal/sip-conversation.cpp
index ec1bd01,0000000..d193aa3
mode 100644,000000..100644
--- a/lib/engine/components/opal/sip-conversation.cpp
+++ b/lib/engine/components/opal/sip-conversation.cpp
@@@ -1,89 -1,0 +1,92 @@@
+
+/*
+ * Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
+
+ * 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.
+ */
+
+
+/*
+ * sip-conversation.cpp - description
+ * ------------------------------------------
+ * begin : written in 2014 by Julien Puydt
+ * copyright : (c) 2014 by Julien Puydt
+ * description : implementation of a SIP conversation
+ *
+ */
+
+#include "sip-conversation.h"
+#include "uri-presentity.h"
+
+SIP::Conversation::Conversation (boost::shared_ptr<Ekiga::PresenceCore> _core,
+ const std::string _uri,
+ const std::string _name,
+ boost::function1<bool, const Ekiga::Message::payload_type&> _sender):
+ presence_core(_core), uri(_uri), title(_name), sender(_sender), unreads(0)
+{
+ // FIXME: this api isn't good: we obviously don't handle correctly Conversation with several people!
+ boost::shared_ptr<Ekiga::URIPresentity> presentity =
- boost::shared_ptr<Ekiga::URIPresentity> (new Ekiga::URIPresentity (_core, title, uri,
- std::set<std::string> ()));
++ boost::shared_ptr<Ekiga::URIPresentity> (new Ekiga::URIPresentity (_core,
++ title,
++ uri,
++ std::list<std::string>
++ ()));
+ heap = boost::shared_ptr<Heap> (new Heap);
+ heap->add_presentity (boost::dynamic_pointer_cast<Ekiga::Presentity> (presentity));
+}
+
+void
+SIP::Conversation::visit_messages (boost::function1<bool, const Ekiga::Message&> visitor) const
+{
+ for (std::list<Ekiga::Message>::const_iterator iter = messages.begin();
+ iter != messages.end ();
+ ++iter) {
+
+ if (!visitor(*iter))
+ break;
+ }
+}
+
+bool
+SIP::Conversation::send_message (const Ekiga::Message::payload_type& payload)
+{
+ return sender (payload);
+}
+
+void
+SIP::Conversation::reset_unread_messages_count ()
+{
+ unreads = 0;
+ updated ();
+}
+
+void
+SIP::Conversation::receive_message (const Ekiga::Message& message)
+{
+ // if the endpoint doesn't put a real name, we'll try to find one
+ Ekiga::Message msg = { message.time,
+ heap->get_name (message.name),
+ message.payload };
+ messages.push_back (msg);
+ message_received (msg);
+ unreads++;
+ updated();
+}
diff --cc lib/engine/components/opal/sip-endpoint.cpp
index 36bfa6e,9d0aaef..c53d1ba
--- a/lib/engine/components/opal/sip-endpoint.cpp
+++ b/lib/engine/components/opal/sip-endpoint.cpp
@@@ -178,34 -174,16 +178,18 @@@ Opal::Sip::EndPoint::setup (std::strin
bool
- Opal::Sip::EndPoint::populate_menu (const std::string& fullname,
- const std::string& uri,
- Ekiga::MenuBuilder& builder)
- {
- if (0 == GetConnectionCount ())
- builder.add_action ("phone-pick-up", _("Call"),
- boost::bind (&Opal::Sip::EndPoint::on_dial, this, uri));
- else
- builder.add_action ("mail-forward", _("Transfer"),
- boost::bind (&Opal::Sip::EndPoint::on_transfer, this, uri));
- builder.add_action ("im-message-new", _("Message"),
- boost::bind (&Opal::Sip::EndPoint::on_message, this, uri, fullname));
-
- return true;
- }
-
-
- bool
Opal::Sip::EndPoint::send_message (const std::string & _uri,
- const std::string & _message)
+ const Ekiga::Message::payload_type payload)
{
- if (is_supported_uri (_uri) && !_message.empty ()) {
+ // FIXME: here we should check which kind of payload we have
+ Ekiga::Message::payload_type::const_iterator iter = payload.find("text/plain");
+ if (!_uri.empty () && (_uri.find ("sip:") == 0 || _uri.find (':') == string::npos) && iter != payload.end
()) {
+
OpalIM im;
im.m_to = PURL (_uri);
- im.m_mimeType = "text/plain;charset=UTF-8";
- im.m_body = _message;
+ im.m_bodies.SetAt (PMIMEInfo::TextPlain(), iter->second);
Message (im);
++
return true;
}
@@@ -927,32 -923,20 +955,11 @@@ Opal::Sip::EndPoint::OnDialogInfoReceiv
}
- void Opal::Sip::EndPoint::on_dial (std::string uri)
- {
- manager.dial (uri);
- }
-
-
- void Opal::Sip::EndPoint::on_message (std::string uri,
- std::string name)
- {
- dialect->start_chat_with (uri, name);
- }
-
-
- void Opal::Sip::EndPoint::on_transfer (std::string uri)
- {
- /* FIXME : we don't handle several calls here */
- for (PSafePtr<OpalConnection> connection(connectionsActive, PSafeReference); connection != NULL;
++connection)
- if (!PIsDescendant(&(*connection), OpalPCSSConnection))
- connection->TransferConnection (uri);
- }
-
void
Opal::Sip::EndPoint::push_message_in_main (const std::string uri,
- const std::string name,
- const std::string msg)
-{
- dialect->push_message (uri, name, msg);
-}
-
-void
-Opal::Sip::EndPoint::push_notice_in_main (const std::string uri,
- const std::string name,
- const std::string msg)
+ const Ekiga::Message msg)
{
- dialect->push_notice (uri, name, msg);
+ dialect->push_message (uri, msg);
}
void
diff --cc lib/engine/components/opal/sip-endpoint.h
index a25745b,36a8b46..4104755
--- a/lib/engine/components/opal/sip-endpoint.h
+++ b/lib/engine/components/opal/sip-endpoint.h
@@@ -168,13 -169,13 +168,8 @@@ namespace Opal
/* Callbacks */
private:
- void on_dial (std::string uri);
- void on_message (std::string uri,
- std::string name);
- void on_transfer (std::string uri);
-
void push_message_in_main (const std::string uri,
- const std::string name,
- const std::string msg);
-
- void push_notice_in_main (const std::string uri,
- const std::string name,
- const std::string msg);
+ const Ekiga::Message msg);
PMutex aorMutex;
std::map<std::string, std::string> accounts;
diff --cc lib/engine/components/opal/sip-heap.cpp
index 7a8e0e9,a8854a4..3e23615
--- a/lib/engine/components/opal/sip-heap.cpp
+++ b/lib/engine/components/opal/sip-heap.cpp
@@@ -33,45 -34,34 +33,33 @@@
*
*/
-#ifndef __CHAT_MULTIPLE_H__
-#define __CHAT_MULTIPLE_H__
+#include "sip-heap.h"
+#include "uri-presentity.h"
- bool
- SIP::Heap::populate_menu (Ekiga::MenuBuilder& /*builder*/)
- {
- return false;
- }
-#include <boost/smart_ptr.hpp>
-#include "chat.h"
-#include "heap.h"
-
-namespace Ekiga
+const std::string
+SIP::Heap::get_name () const
{
+ return ""; // FIXME?
+}
- bool
- SIP::Heap::populate_menu_for_group (const std::string /*name*/,
- Ekiga::MenuBuilder& /*builder*/)
- {
- return false;
- }
-
- class MultipleChat: public Chat
- {
- public:
-
- /** The destructor.
- */
- virtual ~MultipleChat ()
- {}
-
- /** Returns the Heap associated with the MultipleChat.
- * @return The MultipleChat's Heap
- */
- virtual HeapPtr get_heap () const = 0;
- };
+const std::string
+SIP::Heap::get_name (const std::string uri) const
+{
+ bool found = false;
+ std::string result = uri; // sensible default
- typedef boost::shared_ptr<MultipleChat> MultipleChatPtr;
+ for (const_iterator iter = begin ();
+ iter != end () and not found;
+ ++iter) {
-};
+ boost::shared_ptr<Ekiga::URIPresentity> pres
+ = boost::dynamic_pointer_cast<Ekiga::URIPresentity> (*iter);
+ if (pres and pres->get_uri () == uri) {
-
+
-#endif
+ found = true;
+ result = pres->get_name ();
+ }
+ }
+ return result;
+}
diff --cc lib/engine/components/opal/sip-heap.h
index 70e7811,f60a1ea..bbf6feb
--- a/lib/engine/components/opal/sip-heap.h
+++ b/lib/engine/components/opal/sip-heap.h
@@@ -33,29 -33,39 +33,26 @@@
*
*/
-#ifndef __ECHO_PRESENTITY__
-#define __ECHO_PRESENTITY__
+#ifndef __SIP_HEAP_H__
+#define __SIP_HEAP_H__
-#include <boost/smart_ptr.hpp>
-#include "presentity.h"
+#include "heap-impl.h"
-namespace Echo
+namespace SIP
{
- class Presentity: public Ekiga::Presentity
+ class Heap: public Ekiga::HeapImpl<Ekiga::Presentity>
{
public:
+ // let's put everything in public so SIP::Conversation can control us fully!
+ using Ekiga::HeapImpl<Ekiga::Presentity>::add_presentity;
+ using Ekiga::HeapImpl<Ekiga::Presentity>::remove_presentity;
+ using Ekiga::HeapImpl<Ekiga::Presentity>::add_connection;
- bool populate_menu (Ekiga::MenuBuilder& builder);
- Presentity ();
-
- ~Presentity ();
-
+ // this is the heap's name
const std::string get_name () const;
-
- const std::string get_presence () const;
-
- const std::string get_status () const;
-
- const std::list<std::string> get_groups () const;
-
- const std::string get_uri () const;
-
- bool has_uri (const std::string uri) const;
-
- bool populate_menu (Ekiga::MenuBuilder &);
+ // try to find a nice name to display from the uri of a presentity
+ const std::string get_name (const std::string uri) const;
- bool populate_menu_for_group (const std::string name,
- Ekiga::MenuBuilder& builder);
};
-
- typedef boost::shared_ptr<Presentity> PresentityPtr;
-
};
#endif
diff --cc lib/engine/engine.cpp
index e302429,9aa88b2..9150aa3
--- a/lib/engine/engine.cpp
+++ b/lib/engine/engine.cpp
@@@ -204,11 -183,6 +195,9 @@@ engine_init (Ekiga::ServiceCorePtr serv
hal_core->audioinput_device_added.connect (boost::bind (&Ekiga::AudioInputCore::add_device, boost::ref
(*audioinput_core), _1, _2, _3));
hal_core->audioinput_device_removed.connect (boost::bind (&Ekiga::AudioInputCore::remove_device,
boost::ref (*audioinput_core), _1, _2, _3));
-
+ /* FIXME: does it really belong here? */
+ friend_or_foe->add_helper (foe_list);
- contact_core->add_contact_decorator (foe_list);
+
#if DEBUG_STARTUP
std::cout << "Here is what ekiga is made of for this run :" << std::endl;
service_core->dump (std::cout);
diff --cc lib/engine/gui/gtk-frontend/assistant-window.cpp
index 516c73a,6d73f70..7d9a1cd
--- a/lib/engine/gui/gtk-frontend/assistant-window.cpp
+++ b/lib/engine/gui/gtk-frontend/assistant-window.cpp
@@@ -39,8 -39,10 +39,9 @@@
#include <glib/gi18n.h>
#include "services.h"
-#include "account-core.h"
#include "account.h"
+ #include "gm-entry.h"
#include "platform.h"
#include "assistant-window.h"
#include "default_devices.h"
diff --cc lib/engine/gui/gtk-frontend/call-window.cpp
index 6ba1afb,04479ec..0dabe40
--- a/lib/engine/gui/gtk-frontend/call-window.cpp
+++ b/lib/engine/gui/gtk-frontend/call-window.cpp
@@@ -117,44 -122,19 +125,36 @@@ struct _EkigaCallWindowPrivat
GtkWidget *video_widget;
bool fullscreen;
+ bool dead;
+ bool bad_connection;
- GtkWidget *call_frame;
- GtkWidget *camera_image;
-
- GtkWidget *main_menu;
GtkWidget *call_panel_toolbar;
- GtkWidget *pick_up_button;
- GtkWidget *hang_up_button;
- GtkWidget *hold_button;
- GtkWidget *audio_settings_button;
- GtkWidget *video_settings_button;
+ GtkWidget *blacklist_button;
+
+ GtkWidget *audio_settings_window;
+ GtkWidget *audio_input_volume_frame;
+ GtkWidget *audio_output_volume_frame;
+ GtkWidget *input_signal;
+ GtkWidget *output_signal;
+#if GTK_CHECK_VERSION (3, 0, 0)
+ GtkAdjustment *adj_input_volume;
+ GtkAdjustment *adj_output_volume;
+#else
+ GtkObject *adj_input_volume;
+ GtkObject *adj_output_volume;
+#endif
+#ifndef WIN32
+ GC gc;
+#endif
+ GtkWidget *settings_button;
- unsigned int levelmeter_timeout_id;
unsigned int timeout_id;
- GtkWidget *video_settings_window;
- GtkWidget *video_settings_frame;
- GtkAdjustment *adj_whiteness;
- GtkAdjustment *adj_brightness;
- GtkAdjustment *adj_colour;
- GtkAdjustment *adj_contrast;
+ GtkWidget *info_bar;
+
+ /* Audio and video settings */
+ int settings[MAX_SETTINGS];
+ GtkWidget *settings_range[MAX_SETTINGS];
std::string transmitted_video_codec;
std::string transmitted_audio_codec;
@@@ -180,48 -155,21 +175,42 @@@ enum
CHANNEL_LAST
};
- static bool notify_has_actions (EkigaCallWindow* cw);
- static void show_extended_video_window_cb (GtkWidget *widget,
+ static void show_extended_video_window_cb (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
gpointer data);
- static void fullscreen_changed_cb (GtkWidget *widget,
+ static void fullscreen_changed_cb (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
gpointer data);
+static void pick_up_call_cb (GtkWidget * /*widget*/,
+ gpointer data);
+
+static void hang_up_call_cb (GtkWidget * /*widget*/,
+ gpointer data);
+
+static void hold_current_call_cb (GtkWidget *widget,
+ gpointer data);
+
+static void blacklist_cb (GtkWidget* widget,
+ gpointer data);
+
+static void toggle_audio_stream_pause_cb (GtkWidget * /*widget*/,
+ gpointer data);
+
+static void toggle_video_stream_pause_cb (GtkWidget * /*widget*/,
+ gpointer data);
+
+static void transfer_current_call_cb (GtkWidget *widget,
+ gpointer data);
+
- static void audio_volume_changed_cb (GtkAdjustment * /*adjustment*/,
- gpointer data);
-
- static void audio_volume_window_shown_cb (GtkWidget * /*widget*/,
- gpointer data);
-
- static void audio_volume_window_hidden_cb (GtkWidget * /*widget*/,
+ static void show_call_devices_settings_cb (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
gpointer data);
- static void video_settings_changed_cb (GtkAdjustment * /*adjustment*/,
- gpointer data);
-
- static gboolean on_signal_level_refresh_cb (gpointer self);
+ static void call_devices_settings_changed_cb (GtkRange *range,
+ gpointer data);
static void on_videooutput_device_opened_cb (Ekiga::VideoOutputManager & /* manager */,
Ekiga::VideoOutputManager::VideoView type,
@@@ -451,116 -401,16 +442,36 @@@ fullscreen_changed_cb (G_GNUC_UNUSED GS
ekiga_call_window_toggle_fullscreen (EKIGA_CALL_WINDOW (data));
}
- static void
- pick_up_call_cb (GtkWidget * /*widget*/,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- if (cw->priv->current_call)
- cw->priv->current_call->answer ();
- }
-
- static void
- hang_up_call_cb (GtkWidget * /*widget*/,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- if (cw->priv->current_call)
- cw->priv->current_call->hang_up ();
- }
-
-
- static void
- hold_current_call_cb (G_GNUC_UNUSED GtkWidget *widget,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- if (cw->priv->current_call)
- cw->priv->current_call->toggle_hold ();
- }
-
+
+static void
+blacklist_cb (G_GNUC_UNUSED GtkWidget *widget,
+ gpointer data)
+{
+ EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
+
+ if (cw->priv->current_call) {
+
+ const std::string uri = cw->priv->current_call->get_remote_uri ();
+ Ekiga::FriendOrFoe::Identification id = cw->priv->friend_or_foe->decide ("call", uri);
+ if (id == Ekiga::FriendOrFoe::Unknown) {
+
+ cw->priv->foe_list->add_foe (uri);
+ gtk_widget_set_sensitive (GTK_WIDGET (cw->priv->blacklist_button), false);
+ }
+ }
+}
+
- static void
- toggle_audio_stream_pause_cb (GtkWidget * /*widget*/,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- if (cw->priv->current_call)
- cw->priv->current_call->toggle_stream_pause (Ekiga::Call::Audio);
- }
-
- static void
- toggle_video_stream_pause_cb (GtkWidget * /*widget*/,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- if (cw->priv->current_call)
- cw->priv->current_call->toggle_stream_pause (Ekiga::Call::Video);
- }
-
- static void
- transfer_current_call_cb (G_GNUC_UNUSED GtkWidget *widget,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- g_return_if_fail (data != NULL);
- ekiga_call_window_transfer_dialog_run (EKIGA_CALL_WINDOW (cw), GTK_WIDGET (data), NULL);
- }
-
- static void
- audio_volume_changed_cb (GtkAdjustment * /*adjustment*/,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- cw->priv->audiooutput_core->set_volume (Ekiga::primary, (unsigned) gtk_adjustment_get_value
(GTK_ADJUSTMENT (cw->priv->adj_output_volume)));
- cw->priv->audioinput_core->set_volume ((unsigned) gtk_adjustment_get_value (GTK_ADJUSTMENT
(cw->priv->adj_input_volume)));
- }
-
- static void
- audio_volume_window_shown_cb (GtkWidget * /*widget*/,
- gpointer data)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
-
- cw->priv->audioinput_core->set_average_collection (true);
- cw->priv->audiooutput_core->set_average_collection (true);
- cw->priv->levelmeter_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 50,
on_signal_level_refresh_cb, data, NULL);
- }
+
static void
- audio_volume_window_hidden_cb (GtkWidget * /*widget*/,
+ show_call_devices_settings_cb (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
gpointer data)
{
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (data);
+ g_return_if_fail (EKIGA_IS_CALL_WINDOW (data));
+ EkigaCallWindow *self = EKIGA_CALL_WINDOW (data);
- g_source_remove (cw->priv->levelmeter_timeout_id);
- cw->priv->audioinput_core->set_average_collection (false);
- cw->priv->audiooutput_core->set_average_collection (false);
+ gtk_widget_show_all (gm_call_window_build_settings_popover (self,
+ self->priv->settings_button));
}
static void
@@@ -958,40 -776,17 +837,25 @@@ on_setup_call_cb (boost::shared_ptr<Eki
}
else {
- cw->priv->current_call = call;
- cw->priv->calling_state = Calling;
+ self->priv->current_call = call;
+ ekiga_call_window_update_calling_state (self, Calling);
+ ekiga_call_window_update_title (self, Calling, call->get_remote_uri ());
+ ekiga_call_window_update_header_bar_actions (self, Calling);
}
+ { // do we know about this contact already?
- const std::string uri = cw->priv->current_call->get_remote_uri ();
- Ekiga::FriendOrFoe::Identification id = cw->priv->friend_or_foe->decide ("call", uri);
++ const std::string uri = self->priv->current_call->get_remote_uri ();
++ Ekiga::FriendOrFoe::Identification id = self->priv->friend_or_foe->decide ("call", uri);
+ if (id == Ekiga::FriendOrFoe::Unknown)
- gtk_widget_set_sensitive (GTK_WIDGET (cw->priv->blacklist_button), true);
++ gtk_widget_set_sensitive (GTK_WIDGET (self->priv->blacklist_button), true);
+ else
- gtk_widget_set_sensitive (GTK_WIDGET (cw->priv->blacklist_button), false);
++ gtk_widget_set_sensitive (GTK_WIDGET (self->priv->blacklist_button), false);
+ }
- gtk_window_set_title (GTK_WINDOW (cw), call->get_remote_uri ().c_str ());
-
- if (call->is_outgoing ())
- ekiga_call_window_set_status (cw, _("Calling %s..."), call->get_remote_uri ().c_str ());
-
- ekiga_call_window_update_calling_state (cw, cw->priv->calling_state);
+ conn = call->questions.connect (boost::bind (&on_handle_questions, _1, (gpointer) self));
+ self->priv->connections.add (conn);
}
- static void
- on_ringing_call_cb (G_GNUC_UNUSED boost::shared_ptr<Ekiga::CallManager> manager,
- G_GNUC_UNUSED boost::shared_ptr<Ekiga::Call> call,
- gpointer self)
- {
- EkigaCallWindow *cw = EKIGA_CALL_WINDOW (self);
-
- g_return_if_fail (cw);
-
- cw->priv->calling_state = Ringing;
-
- ekiga_call_window_update_calling_state (cw, cw->priv->calling_state);
- }
static void
on_established_call_cb (boost::shared_ptr<Ekiga::CallManager> /*manager*/,
@@@ -2412,36 -1728,35 +1796,37 @@@ ekiga_call_window_class_init (EkigaCall
}
GtkWidget *
- call_window_new (Ekiga::ServiceCore & core)
+ call_window_new (GmApplication *app)
{
- EkigaCallWindow *cw;
+ EkigaCallWindow *self;
- cw = EKIGA_CALL_WINDOW (g_object_new (EKIGA_TYPE_CALL_WINDOW,
- "key", USER_INTERFACE ".call-window",
- "hide_on_delete", false,
- "hide_on_esc", false, NULL));
+ g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
- cw->priv->libnotify = core.get ("libnotify");
- cw->priv->videoinput_core = core.get<Ekiga::VideoInputCore> ("videoinput-core");
- cw->priv->videooutput_core = core.get<Ekiga::VideoOutputCore> ("videooutput-core");
- cw->priv->audioinput_core = core.get<Ekiga::AudioInputCore> ("audioinput-core");
- cw->priv->audiooutput_core = core.get<Ekiga::AudioOutputCore> ("audiooutput-core");
- cw->priv->call_core = core.get<Ekiga::CallCore> ("call-core");
- cw->priv->friend_or_foe = core.get<Ekiga::FriendOrFoe> ("friend-or-foe");
- cw->priv->foe_list = core.get<Ekiga::FoeList> ("foe-list");
+ self = EKIGA_CALL_WINDOW (g_object_new (EKIGA_TYPE_CALL_WINDOW,
+ "application", GTK_APPLICATION (app),
+ "key", USER_INTERFACE ".call-window",
+ "hide_on_delete", false,
+ "hide_on_esc", false, NULL));
+ Ekiga::ServiceCorePtr core = gm_application_get_core (app);
- ekiga_call_window_connect_engine_signals (cw);
+ self->priv->videoinput_core = core->get<Ekiga::VideoInputCore> ("videoinput-core");
+ self->priv->videooutput_core = core->get<Ekiga::VideoOutputCore> ("videooutput-core");
+ self->priv->audioinput_core = core->get<Ekiga::AudioInputCore> ("audioinput-core");
+ self->priv->audiooutput_core = core->get<Ekiga::AudioOutputCore> ("audiooutput-core");
+ self->priv->call_core = core->get<Ekiga::CallCore> ("call-core");
++ self->priv->friend_or_foe = core->get<Ekiga::FriendOrFoe> ("friend-or-foe");
++ self->priv->foe_list = core->get<Ekiga::FoeList> ("foe-list");
- ekiga_call_window_init_gui (cw);
+ ekiga_call_window_init_gui (self);
- g_settings_bind (cw->priv->video_display_settings->get_g_settings (),
+ g_settings_bind (self->priv->video_display_settings->get_g_settings (),
"stay-on-top",
- cw,
+ self,
"stay_on_top",
G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (cw->priv->video_display_settings->get_g_settings (),
+ g_settings_bind (self->priv->video_display_settings->get_g_settings (),
"enable-pip",
- cw->priv->video_widget,
+ self->priv->video_widget,
"secondary_stream_display",
G_SETTINGS_BIND_DEFAULT);
diff --cc lib/engine/gui/gtk-frontend/chat-window.cpp
index 8e83805,9d56063..6b9651c
--- a/lib/engine/gui/gtk-frontend/chat-window.cpp
+++ b/lib/engine/gui/gtk-frontend/chat-window.cpp
@@@ -40,10 -38,10 +40,12 @@@
#include <gdk/gdkkeysyms.h>
#include <glib/gi18n.h>
+#include "menu-builder-gtk.h"
+
#include "chat-core.h"
+ #include "audiooutput-core.h"
#include "notification-core.h"
+ #include "ekiga-settings.h"
#include "form-dialog-gtk.h"
#include "scoped-connections.h"
@@@ -55,11 -53,13 +57,12 @@@
struct _ChatWindowPrivate
{
boost::shared_ptr<Ekiga::NotificationCore> notification_core;
+ boost::shared_ptr<Ekiga::AudioOutputCore> audiooutput_core;
Ekiga::scoped_connections connections;
+ boost::signals2::connection visible_conversation_connection;
- GtkWidget* notebook;
-
- /* GSettings */
- boost::shared_ptr<Ekiga::Settings> sound_events_settings;
+ GtkWidget* stack;
+ GtkWidget* gear;
};
enum {
@@@ -93,40 -110,47 +96,35 @@@ static void on_some_conversation_user_r
static void show_chat_window_cb (ChatWindow *self);
- /* internal api (declaration) */
-
- static void chat_window_update_menu (ChatWindow* self,
- Ekiga::ConversationPtr conversation);
-/* DESCRIPTION : This callback is called when the chat window alerts about
- * unread messages
- * BEHAVIOR : Plays a sound (if enabled)
- * PRE : /
- */
-static void on_chat_unread_alert (GtkWidget*,
- gpointer);
-
-
-/* helper (implementation) */
+/* helpers (implementation) */
-
static void
-update_unread (ChatWindow* self)
+on_unread_count_updated (ConversationPage* page,
+ gpointer data)
{
+ ChatWindow* self = (ChatWindow*)data;
guint unread_count = 0;
- GtkWidget* page = NULL;
- GtkWidget* hbox = NULL;
- GtkWidget* label = NULL;
- gchar *info = NULL;
-
- for (gint ii = 0;
- ii < gtk_notebook_get_n_pages (GTK_NOTEBOOK (self->priv->notebook)) ;
- ii++) {
-
- page
- = gtk_notebook_get_nth_page (GTK_NOTEBOOK (self->priv->notebook), ii);
- hbox = gtk_notebook_get_tab_label (GTK_NOTEBOOK (self->priv->notebook),
- page);
- label = (GtkWidget*)g_object_get_data (G_OBJECT (hbox), "label-widget");
- unread_count
- = unread_count
- + GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (label), "unread-count"));
+ gtk_container_child_set (GTK_CONTAINER (self->priv->stack), GTK_WIDGET (page),
+ "title", conversation_page_get_title (page),
+ NULL);
+
+ GList* pages = gtk_container_get_children (GTK_CONTAINER (self->priv->stack));
+
+ for (GList* ptr = pages; ptr != NULL; ptr = ptr->next) {
+
+ unread_count += conversation_page_get_unread_count ((ConversationPage*)ptr->data);
}
+ g_list_free (pages);
+
g_signal_emit (self, signals[UNREAD_COUNT], 0, unread_count);
+ g_signal_emit (self, signals[UNREAD_ALERT], 0, NULL);
if (unread_count > 0) {
- info = g_strdup_printf (ngettext ("You have %d unread text message",
- "You have %d unread text messages",
- unread_count), unread_count);
+ gchar* info = g_strdup_printf (ngettext ("You have %d unread text message",
+ "You have %d unread text messages",
+ unread_count), unread_count);
boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification (Ekiga::Notification::Warning,
info, "", _("Read"), boost::bind (show_chat_window_cb, self)));
self->priv->notification_core->push_notification (notif);
g_free (info);
@@@ -135,20 -159,102 +133,19 @@@
/* signal callbacks (implementations) */
-static bool on_handle_questions (ChatWindow* self,
- Ekiga::FormRequestPtr request)
-{
- GtkWidget *parent = gtk_widget_get_toplevel (GTK_WIDGET (self));
- FormDialog dialog (request, parent);
-
- dialog.run ();
-
- return true;
-}
-
-static void
-on_close_button_clicked (GtkButton* button,
- gpointer data)
-{
- ChatWindow* self = (ChatWindow*)data;
- GtkWidget* page = NULL;
- gint num = 0;
-
- page = (GtkWidget*)g_object_get_data (G_OBJECT (button), "page-widget");
- num = gtk_notebook_page_num (GTK_NOTEBOOK (self->priv->notebook), page);
-
- gtk_notebook_remove_page (GTK_NOTEBOOK (self->priv->notebook), num);
-
- if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (self->priv->notebook)) == 0)
- gtk_widget_hide (GTK_WIDGET (self));
-}
-
static void
-on_escaped (GtkWidget */*widget*/,
- gpointer data)
+on_visible_conversation_updated (ChatWindow* self)
{
- ChatWindow* self = (ChatWindow*)data;
- gint num = 0;
+ self->priv->visible_conversation_connection.disconnect ();
- num = gtk_notebook_get_current_page (GTK_NOTEBOOK (self->priv->notebook));
- gtk_notebook_remove_page (GTK_NOTEBOOK (self->priv->notebook), num);
+ GtkWidget* page = gtk_stack_get_visible_child (GTK_STACK (self->priv->stack));
- if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (self->priv->notebook)) == 0)
- gtk_widget_hide (GTK_WIDGET (self));
-}
+ if (IS_CONVERSATION_PAGE (page)) {
-static void
-on_switch_page (G_GNUC_UNUSED GtkNotebook* notebook,
- G_GNUC_UNUSED gpointer page_,
- guint num,
- gpointer data)
-{
- ChatWindow* self = (ChatWindow*)data;
- GtkWidget* page = NULL;
- GtkWidget* hbox = NULL;
- GtkWidget* label = NULL;
-
- page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (self->priv->notebook), num);
- hbox = gtk_notebook_get_tab_label (GTK_NOTEBOOK (self->priv->notebook),
- page);
- label = (GtkWidget*)g_object_get_data (G_OBJECT (hbox), "label-widget");
- gtk_label_set_text (GTK_LABEL (label),
- (const gchar*)g_object_get_data (G_OBJECT (label),
- "base-title"));
- g_object_set_data (G_OBJECT (label), "unread-count",
- GUINT_TO_POINTER (0));
-
- update_unread (self);
-
- gtk_widget_grab_focus (page);
-}
+ Ekiga::ConversationPtr conversation = conversation_page_get_conversation (CONVERSATION_PAGE (page));
-static gboolean
-on_focus_in_event (G_GNUC_UNUSED GtkWidget* widget,
- G_GNUC_UNUSED GdkEventFocus* event,
- gpointer data)
-{
- ChatWindow* self = (ChatWindow*)data;
- gint num;
- GtkWidget* page = NULL;
- GtkWidget* hbox = NULL;
- GtkWidget* label = NULL;
-
- num = gtk_notebook_get_current_page (GTK_NOTEBOOK (self->priv->notebook));
- if (num != -1) { /* the notebook may be empty */
-
- page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (self->priv->notebook), num);
- hbox = gtk_notebook_get_tab_label (GTK_NOTEBOOK (self->priv->notebook),
- page);
- label = (GtkWidget*)g_object_get_data (G_OBJECT (hbox), "label-widget");
- gtk_label_set_text (GTK_LABEL (label),
- (const gchar*)g_object_get_data (G_OBJECT (label),
- "base-title"));
- g_object_set_data (G_OBJECT (label), "unread-count",
- GUINT_TO_POINTER (0));
-
- update_unread (self);
+ self->priv->visible_conversation_connection = conversation->updated.connect (boost::bind
(&on_visible_conversation_updated, self));
- chat_window_update_menu (self, conversation);
}
-
- return FALSE;
}
static void
@@@ -221,9 -405,24 +218,8 @@@ show_chat_window_cb (ChatWindow *self
gtk_window_present (GTK_WINDOW (self));
}
-static void
-on_chat_unread_alert (G_GNUC_UNUSED GtkWidget* widget,
- gpointer data)
-{
- ChatWindow *self = CHAT_WINDOW (data);
-
- g_return_if_fail (self != NULL);
- if (!self->priv->sound_events_settings->get_bool ("enable-new-message-sound"))
- return;
-
- std::string file_name_string = self->priv->sound_events_settings->get_string ("new-message-sound");
-
- if (!file_name_string.empty ())
- self->priv->audiooutput_core->play_file (file_name_string);
-}
-
/* GObject code */
-
static void
chat_window_finalize (GObject* obj)
{
@@@ -269,72 -468,53 +265,58 @@@ chat_window_init (ChatWindow* self
{
/* we can't do much here since we get the Chat as reference... */
gtk_window_set_title (GTK_WINDOW (self), _("Chat Window"));
- }
-
- /* internal api (implementation) */
-
- static void chat_window_update_menu (ChatWindow* self,
- Ekiga::ConversationPtr conversation)
- {
- MenuBuilderGtk builder;
-
- conversation->populate_menu (builder);
- if (!builder.empty ()) {
-
- gtk_widget_show_all (builder.menu);
- gtk_menu_button_set_popup (GTK_MENU_BUTTON (self->priv->gear),
- builder.menu);
- }
- g_object_ref_sink (builder.menu);
+ self->priv = new ChatWindowPrivate;
}
- /* public api */
+ /* Public API */
GtkWidget*
- chat_window_new (Ekiga::ServiceCore& core,
- const char* key)
+ chat_window_new (GmApplication *app)
{
ChatWindow* self = NULL;
- GtkAccelGroup *accel = NULL;
- self = (ChatWindow*)g_object_new (CHAT_WINDOW_TYPE,
- "key", key,
- "hide_on_esc", FALSE,
- NULL);
+ g_return_val_if_fail (GM_IS_APPLICATION (app), NULL);
- self->priv = new ChatWindowPrivate;
+ Ekiga::ServiceCorePtr core = gm_application_get_core (app);
+ self = (ChatWindow*)g_object_new (CHAT_WINDOW_TYPE,
+ "application", GTK_APPLICATION (app),
+ "key", USER_INTERFACE ".chat-window",
+ NULL);
-
- self->priv->sound_events_settings =
- boost::shared_ptr<Ekiga::Settings> (new Ekiga::Settings (SOUND_EVENTS_SCHEMA));
self->priv->notification_core =
- core.get<Ekiga::NotificationCore>("notification-core");
+ core->get<Ekiga::NotificationCore>("notification-core");
+ self->priv->audiooutput_core =
+ core->get<Ekiga::AudioOutputCore>("audiooutput-core");
- self->priv->notebook = gtk_notebook_new ();
- gtk_container_add (GTK_CONTAINER (self), self->priv->notebook);
- gtk_widget_show (self->priv->notebook);
-
- accel = gtk_accel_group_new ();
- gtk_window_add_accel_group (GTK_WINDOW (self), accel);
- gtk_accel_group_connect (accel, GDK_KEY_Escape, (GdkModifierType) 0, GTK_ACCEL_LOCKED,
- g_cclosure_new_swap (G_CALLBACK (on_escaped), (gpointer) self, NULL));
- g_object_unref (accel);
-
- g_signal_connect (self, "focus-in-event",
- G_CALLBACK (on_focus_in_event), self);
- g_signal_connect (self->priv->notebook, "switch-page",
- G_CALLBACK (on_switch_page), self);
- g_signal_connect (self, "unread-alert",
- G_CALLBACK (on_chat_unread_alert), self);
+ GtkWidget* vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+ gtk_container_add (GTK_CONTAINER (self), vbox);
+ gtk_widget_show (vbox);
+
+ GtkWidget* hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
+ gtk_container_add (GTK_CONTAINER (vbox), hbox);
+ gtk_widget_show (hbox);
+
+ self->priv->gear = gtk_menu_button_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), self->priv->gear,
+ FALSE, FALSE, 0);
+ gtk_widget_show (self->priv->gear);
+
+ GtkWidget* switcher = gtk_stack_switcher_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), switcher,
+ FALSE, TRUE, 0);
+ gtk_widget_show (switcher);
+
+ self->priv->stack = gtk_stack_new ();
+ gtk_stack_switcher_set_stack (GTK_STACK_SWITCHER (switcher), GTK_STACK (self->priv->stack));
+ gtk_box_pack_start (GTK_BOX (vbox), self->priv->stack,
+ TRUE, TRUE, 0);
+ gtk_widget_show (self->priv->stack);
+ g_signal_connect (self->priv->stack, "notify::visible-child",
+ G_CALLBACK (on_visible_conversation_changed), self);
boost::shared_ptr<Ekiga::ChatCore> chat_core =
- core.get<Ekiga::ChatCore> ("chat-core");
+ core->get<Ekiga::ChatCore> ("chat-core");
self->priv->connections.add (chat_core->dialect_added.connect (boost::bind (&on_dialect_added, self,
_1)));
self->priv->connections.add (chat_core->questions.connect (boost::bind (&on_handle_questions, self, _1)));
chat_core->visit_dialects (boost::bind (&on_dialect_added, self, _1));
diff --cc lib/engine/gui/gtk-frontend/conversation-page.cpp
index 6975d77,0000000..ea1d7ee
mode 100644,000000..100644
--- a/lib/engine/gui/gtk-frontend/conversation-page.cpp
+++ b/lib/engine/gui/gtk-frontend/conversation-page.cpp
@@@ -1,206 -1,0 +1,196 @@@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2009 Damien Sandras <dsandras seconix com>
+ *
+ * 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.
+ */
+
+
+/*
+ * multiple-chat-page.cpp - description
+ * --------------------------------
+ * begin : written in july 2008 by Julien Puydt
+ * copyright : (C) 2008 by Julien Puydt
+ * description : Declaration of a page displaying a Conversation
+ *
+ */
+
+#include "conversation-page.h"
+#include "chat-area.h"
- #include "heap-view.h"
+
+#include "scoped-connections.h"
+
+struct _ConversationPagePrivate {
+
+ Ekiga::ConversationPtr conversation;
+ Ekiga::scoped_connections connections;
+ GtkWidget* area;
- GtkWidget* heapview;
+ GtkWidget* header;
+ gchar* title;
+};
+
+enum {
+ UPDATED_SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0,};
+
+G_DEFINE_TYPE (ConversationPage, conversation_page, GTK_TYPE_BOX);
+
+static void
+on_conversation_updated (ConversationPage* self)
+{
+ g_signal_emit (self, signals[UPDATED_SIGNAL], 0);
+}
+
+static void
+on_page_grab_focus (GtkWidget* widget,
+ G_GNUC_UNUSED gpointer data)
+{
+ ConversationPage* self = (ConversationPage*)widget;
+
+ gtk_widget_grab_focus (self->priv->area);
+}
+
+static void
+conversation_page_update_title_and_status (ConversationPage* self)
+{
+ g_free (self->priv->title);
+ guint unread_count = self->priv->conversation->get_unread_messages_count ();
+ if (unread_count > 0) {
+
+ self->priv->title = g_strdup_printf ("[%d] %s",
+ unread_count,
+ self->priv->conversation->get_title ().c_str ());
+ } else {
+
+ self->priv->title = g_strdup_printf ("%s",
+ self->priv->conversation->get_title ().c_str ());
+ }
+ gtk_header_bar_set_title (GTK_HEADER_BAR (self->priv->header), self->priv->title);
+ gtk_header_bar_set_subtitle (GTK_HEADER_BAR (self->priv->header),
+ self->priv->conversation->get_status ().c_str ());
+}
+
+static void
+conversation_page_finalize (GObject* obj)
+{
+ ConversationPage* self = (ConversationPage*)obj;
+
+ g_free (self->priv->title);
+ delete self->priv;
+
+ G_OBJECT_CLASS (conversation_page_parent_class)->finalize (obj);
+}
+
+static void
+conversation_page_init (ConversationPage* self)
+{
+ self->priv = new ConversationPagePrivate;
+
+ g_signal_connect (self, "grab-focus",
+ G_CALLBACK (on_page_grab_focus), NULL);
+}
+
+static void
+conversation_page_class_init (ConversationPageClass* klass)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = conversation_page_finalize;
+
+ signals[UPDATED_SIGNAL] =
+ g_signal_new ("updated", G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ConversationPageClass, updated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/* implementation of the public api */
+
+GtkWidget*
+conversation_page_new (Ekiga::ConversationPtr conversation)
+{
+ ConversationPage* result = NULL;
+ GtkWidget* header = NULL;
+ GtkWidget* box = NULL;
+ GtkWidget* area = NULL;
- GtkWidget* heapview = NULL;
+
+ result = (ConversationPage*)g_object_new (TYPE_CONVERSATION_PAGE,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ NULL);
+
+ result->priv->conversation = conversation;
+ result->priv->title = NULL;
+
+ result->priv->connections.add (conversation->updated.connect (boost::bind (&on_conversation_updated,
result)));
+
+ header = gtk_header_bar_new ();
+ result->priv->header = header;
+ gtk_box_pack_start (GTK_BOX (result), header,
+ FALSE, FALSE, 2);
+ gtk_widget_show (header);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
+ gtk_box_pack_start (GTK_BOX (result), box,
+ TRUE, TRUE, 2);
+ gtk_widget_show (box);
+
+ area = chat_area_new (conversation);
+ result->priv->area = area;
+ gtk_box_pack_start (GTK_BOX (box), area,
+ TRUE, TRUE, 2);
+ gtk_widget_show (area);
+
- heapview = heap_view_new (conversation->get_heap());
-
- result->priv->heapview = heapview;
- gtk_box_pack_start (GTK_BOX (box), heapview,
- TRUE, TRUE, 2);
- gtk_widget_show (heapview);
-
+ conversation_page_update_title_and_status (result);
+
+ return GTK_WIDGET (result);
+}
+
+const gchar*
+conversation_page_get_title (ConversationPage* page)
+{
+ g_return_val_if_fail (IS_CONVERSATION_PAGE (page), NULL);
+
+ return page->priv->title;
+}
+
+guint
+conversation_page_get_unread_count (ConversationPage* page)
+{
+ g_return_val_if_fail (IS_CONVERSATION_PAGE (page), 0);
+
+ return page->priv->conversation->get_unread_messages_count ();
+}
+
+Ekiga::ConversationPtr
+conversation_page_get_conversation (ConversationPage* page)
+{
+ g_return_val_if_fail (IS_CONVERSATION_PAGE (page), Ekiga::ConversationPtr());
+
+ return page->priv->conversation;
+
+}
diff --cc lib/engine/gui/gtk-frontend/ekiga-app.cpp
index 0000000,fece8a5..f1a5268
mode 000000,100644..100644
--- a/lib/engine/gui/gtk-frontend/ekiga-app.cpp
+++ b/lib/engine/gui/gtk-frontend/ekiga-app.cpp
@@@ -1,0 -1,1037 +1,1036 @@@
+
+ /* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2014 Damien Sandras <dsandras seconix com>
+ *
+ * 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.
+ */
+
+
+ /*
+ * ekiga-app.cpp - description
+ * -----------------------------
+ * begin : written in Feb 2014 by Damien Sandras
+ * copyright : (c) 2014 by Damien Sandras
+ * description : main Ekiga GtkApplication
+ *
+ */
+
+ #include <gtk/gtk.h>
+
+ #include "config.h"
+ #include "ekiga-settings.h"
+ #include "revision.h"
+
+ #include "trigger.h"
+ #include "form-dialog-gtk.h"
+ #include "ekiga-app.h"
+ #include "account-core.h"
+ #include "chat-core.h"
+ #include "contact-core.h"
+ #include "presence-core.h"
+ #include "addressbook-window.h"
+ #include "assistant-window.h"
+ #include "preferences-window.h"
+ #include "call-window.h"
+ #include "chat-window.h"
+ #include "main_window.h"
+ #include "statusicon.h"
+ #include "roster-view-gtk.h"
+ #include "history-source.h"
+ #include "opal-bank.h"
+ #include "book-view-gtk.h"
+ #include "notification-core.h"
+ #include "personal-details.h"
+ #include "audioinput-core.h"
+ #include "audiooutput-core.h"
+ #include "videoinput-core.h"
+ #include "videooutput-core.h"
+ #include "call-core.h"
+ #include "engine.h"
+ #include "runtime.h"
+ #include "platform/platform.h"
+ #include "gactor-menu.h"
+
+ #include "gmwindow.h"
+
+ #ifdef WIN32
+ #include "platform/winpaths.h"
+ #include <windows.h>
+ #include <shellapi.h>
+ #include <gdk/gdkwin32.h>
+ #include <cstdio>
+ #define WIN32_HELP_DIR "help"
+ #define WIN32_HELP_FILE "index.html"
+ #else
+ #include <signal.h>
+ #include <gdk/gdkx.h>
+ #endif
+
+ #ifdef HAVE_DBUS
+ #include "../../../../src/dbus-helper/dbus.h"
+ #endif
+
+ #include <glib/gi18n.h>
+ #include <ptlib.h>
-#include <opal/buildopts.h>
+
+
+ /*
+ * The GmApplication
+ */
+ struct _GmApplicationPrivate
+ {
+ _GmApplicationPrivate () {}
+
+ Ekiga::ServiceCorePtr core;
+
+ GtkBuilder *builder;
+ GtkWidget *main_window;
+ GtkWidget *chat_window;
+ GtkWidget *call_window;
+
+ boost::shared_ptr<Ekiga::Settings> video_devices_settings;
+
+ EkigaDBusComponent *dbus_component;
+
+ Ekiga::GActorMenuStore banks_menu;
+ unsigned int banks_actions_count;
+ };
+
+ G_DEFINE_TYPE (GmApplication, gm_application, GTK_TYPE_APPLICATION);
+
+ static void gm_application_populate_application_menu (GmApplication *app);
+
+ static GtkWidget *gm_application_show_call_window (GmApplication *self);
+
+ static void on_created_call_cb (boost::shared_ptr<Ekiga::CallManager> manager,
+ boost::shared_ptr<Ekiga::Call> call,
+ gpointer data);
+
+ static bool on_visit_banks_cb (Ekiga::BankPtr bank,
+ gpointer data);
+
+ static bool on_handle_questions_cb (Ekiga::FormRequestPtr request,
+ GmApplication *application);
+
+ static void on_account_modified_cb (Ekiga::BankPtr bank,
+ Ekiga::AccountPtr account,
+ GmApplication *app);
+
+ static void call_window_destroyed_cb (GtkWidget *widget,
+ gpointer data);
+
+ static gboolean option_context_parse (GOptionContext *context,
+ gchar **arguments,
+ GError **error);
+
+ static void quit_activated (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer app);
+
+ static void about_activated (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer app);
+
+ static void help_activated (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer app);
+
+ static void window_activated (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer app);
+
+ static void video_preview_changed (GSettings *settings,
+ const gchar *key,
+ gpointer data);
+
+ static GActionEntry app_entries[] =
+ {
+ { "preferences", window_activated, NULL, NULL, NULL, 0 },
+ { "addressbook", window_activated, NULL, NULL, NULL, 0 },
+ { "help", help_activated, NULL, NULL, NULL, 0 },
+ { "about", about_activated, NULL, NULL, NULL, 0 },
+ { "quit", quit_activated, NULL, NULL, NULL, 0 }
+ };
+
+
+ /* Private helpers */
+ static void
+ gm_application_populate_application_menu (GmApplication *app)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (app));
+ GMenuModel *app_menu = G_MENU_MODEL (gtk_builder_get_object (app->priv->builder, "appmenu"));
+
+ boost::shared_ptr<Ekiga::AccountCore> account_core
+ = app->priv->core->get<Ekiga::AccountCore> ("account-core");
+ g_return_if_fail (account_core);
+
+ for (int i = app->priv->banks_menu.size () ;
+ i > 0 ;
+ i--)
+ g_menu_remove (G_MENU (app_menu), 0);
+
+ app->priv->banks_menu.clear ();
+ app->priv->banks_actions_count = 0;
+ account_core->visit_banks (boost::bind (&on_visit_banks_cb, _1, (gpointer) app));
+
+ for (std::list<Ekiga::GActorMenuPtr>::iterator it = app->priv->banks_menu.begin ();
+ it != app->priv->banks_menu.end ();
+ it++) {
+ g_menu_insert_section (G_MENU (app_menu), 0, NULL, (*it)->get_model ());
+ app->priv->banks_actions_count += (*it)->size ();
+ }
+ }
+
+
+ static GtkWidget *
+ gm_application_show_call_window (GmApplication *self)
+ {
+ g_return_val_if_fail (GM_IS_APPLICATION (self), NULL);
+
+ if (!self->priv->call_window)
+ self->priv->call_window = call_window_new (self);
+
+ gtk_window_present (GTK_WINDOW (self->priv->call_window));
+
+ g_signal_connect (G_OBJECT (self->priv->call_window), "destroy",
+ G_CALLBACK (call_window_destroyed_cb), self);
+
+ return self->priv->call_window;
+ }
+
+
+ /* Private callbacks */
+ static void
+ on_created_call_cb (G_GNUC_UNUSED boost::shared_ptr<Ekiga::CallManager> manager,
+ G_GNUC_UNUSED boost::shared_ptr<Ekiga::Call> call,
+ gpointer data)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (data));
+
+ GmApplication *self = GM_APPLICATION (data);
+
+ gm_application_show_call_window (self);
+ }
+
+
+ static bool
+ on_visit_banks_cb (Ekiga::BankPtr bank,
+ gpointer data)
+ {
+ g_return_val_if_fail (GM_IS_APPLICATION (data), false);
+
+ GmApplication *self = GM_APPLICATION (data);
+
+ self->priv->banks_menu.push_back (Ekiga::GActorMenuPtr (new Ekiga::GActorMenu (*bank, "", "app")));
+
+ return true;
+ }
+
+
+ static bool
+ on_handle_questions_cb (Ekiga::FormRequestPtr request,
+ GmApplication *application)
+ {
+ GtkWidget *window =
+ GTK_WIDGET (gtk_application_get_active_window (GTK_APPLICATION (application)));
+ FormDialog dialog (request, window);
+
+ dialog.run ();
+
+ return true;
+ }
+
+
+ static void
+ on_account_modified_cb (G_GNUC_UNUSED Ekiga::BankPtr bank,
+ G_GNUC_UNUSED Ekiga::AccountPtr account,
+ GmApplication *app)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (app));
+
+ gm_application_populate_application_menu (app);
+ }
+
+
+ static void
+ call_window_destroyed_cb (G_GNUC_UNUSED GtkWidget *widget,
+ gpointer data)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (data));
+
+ GmApplication *self = GM_APPLICATION (data);
+ if (self->priv->call_window)
+ self->priv->call_window = NULL;
+ }
+
+
+ static gboolean
+ option_context_parse (GOptionContext *context,
+ gchar **arguments,
+ GError **error)
+ {
+ gint argc;
+ gchar **argv;
+ gint i;
+ gboolean ret;
+
+ /* We have to make an extra copy of the array, since g_option_context_parse()
+ * assumes that it can remove strings from the array without freeing them.
+ */
+ argc = g_strv_length (arguments);
+ argv = g_new (gchar *, argc);
+ for (i = 0; i < argc; i++)
+ argv[i] = arguments[i];
+
+ ret = g_option_context_parse (context, &argc, &argv, error);
+
+ g_free (argv);
+
+ return ret;
+ }
+
+
+ static void
+ quit_activated (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer app)
+ {
+ g_application_quit (G_APPLICATION (app));
+ }
+
+
+ static void
+ about_activated (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer app)
+ {
+ gm_application_show_about (GM_APPLICATION (app));
+ }
+
+
+ static void
+ help_activated (G_GNUC_UNUSED GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer app)
+ {
+ gm_application_show_help (GM_APPLICATION (app), NULL);
+ }
+
+
+ static void
+ window_activated (GSimpleAction *action,
+ G_GNUC_UNUSED GVariant *parameter,
+ gpointer app)
+ {
+ GmApplication *self = GM_APPLICATION (app);
+
+ g_return_if_fail (self && self->priv->core);
+
+ boost::shared_ptr<Ekiga::AudioInputCore> audio_input_core =
+ self->priv->core->get<Ekiga::AudioInputCore> ("audioinput-core");
+ boost::shared_ptr<Ekiga::AudioOutputCore> audio_output_core =
+ self->priv->core->get<Ekiga::AudioOutputCore> ("audiooutput-core");
+ boost::shared_ptr<Ekiga::VideoInputCore> video_input_core =
+ self->priv->core->get<Ekiga::VideoInputCore> ("videoinput-core");
+ boost::shared_ptr<Ekiga::ContactCore> contact_core =
+ self->priv->core->get<Ekiga::ContactCore> ("contact-core");
+
+ if (!g_strcmp0 (g_action_get_name (G_ACTION (action)), "preferences"))
+ gm_application_show_preferences_window (self);
+
+ else if (!g_strcmp0 (g_action_get_name (G_ACTION (action)), "addressbook"))
+ gm_application_show_addressbook_window (self);
+ }
+
+
+ static void
+ video_preview_changed (GSettings *settings,
+ const gchar *key,
+ gpointer data)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (data));
+
+ GmApplication *self = GM_APPLICATION (data);
+ boost::shared_ptr<Ekiga::VideoInputCore> video_input_core =
+ self->priv->core->get<Ekiga::VideoInputCore> ("videoinput-core");
+
+ if (g_settings_get_boolean (settings, key)) {
+ gm_application_show_call_window (self);
+ video_input_core->start_preview ();
+ }
+ else
+ video_input_core->stop_preview ();
+ }
+
+
+ /* Public api */
+ void
+ ekiga_main (int argc,
+ char **argv)
+ {
+ GmApplication *app = gm_application_new ();
+ g_application_set_inactivity_timeout (G_APPLICATION (app), 10000);
+
+ if (g_application_get_is_remote (G_APPLICATION (app))) {
+ g_application_run (G_APPLICATION (app), argc, argv);
+ return;
+ }
+
+ Ekiga::ServiceCorePtr core(new Ekiga::ServiceCore);
+
+ Ekiga::Runtime::init ();
+ engine_init (core, argc, argv);
+
+ gm_application_set_core (app, core);
+
+ /* Create the main application window */
+ app->priv->main_window = gm_main_window_new (app);
+ gm_application_show_main_window (app);
+
+ app->priv->chat_window = chat_window_new (app);
+ status_icon_new (app);
+
+ #ifdef HAVE_DBUS
+ app->priv->dbus_component = ekiga_dbus_component_new (app);
+ #endif
+
+ boost::shared_ptr<Ekiga::Settings> general_settings (new Ekiga::Settings (GENERAL_SCHEMA));
+ const int schema_version = MAJOR_VERSION * 1000 + MINOR_VERSION * 10 + BUILD_NUMBER;
+ if (general_settings->get_int ("version") < schema_version) {
+ gm_application_show_assistant_window (app);
+ general_settings->set_int ("version", schema_version);
+ }
+
+ boost::shared_ptr<Ekiga::CallCore> call_core = app->priv->core->get<Ekiga::CallCore> ("call-core");
+ g_return_if_fail (call_core);
+ call_core->created_call.connect (boost::bind (&on_created_call_cb, _1, _2, (gpointer) app));
+
+ boost::shared_ptr<Ekiga::AccountCore> account_core = app->priv->core->get<Ekiga::AccountCore>
("account-core");
+ g_return_if_fail (account_core);
+ account_core->questions.connect (boost::bind (&on_handle_questions_cb, _1, app));
+ account_core->account_added.connect (boost::bind (&on_account_modified_cb, _1, _2, app));
+ account_core->account_removed.connect (boost::bind (&on_account_modified_cb, _1, _2, app));
+
+ gm_application_populate_application_menu (app);
+
+ core->close ();
+ g_application_run (G_APPLICATION (app), argc, argv);
+
+ g_object_unref (app);
+ }
+
+
+ /* GObject stuff */
+ static void
+ gm_application_activate (GApplication *self)
+ {
+ GmApplication *app = GM_APPLICATION (self);
+
+ gm_application_show_main_window (app);
+ }
+
+ static void
+ gm_application_startup (GApplication *app)
+ {
+ GmApplication *self = GM_APPLICATION (app);
+ GMenuModel *app_menu = NULL;
+ gchar *path = NULL;
+
+ G_APPLICATION_CLASS (gm_application_parent_class)->startup (app);
+
+ /* Globals */
+ #if !GLIB_CHECK_VERSION(2,36,0)
+ g_type_init ();
+ #endif
+ #if !GLIB_CHECK_VERSION(2,32,0)
+ g_thread_init();
+ #endif
+
+ #ifndef WIN32
+ signal (SIGPIPE, SIG_IGN);
+ #endif
+
+ /* initialize platform-specific code */
+ gm_platform_init ();
+ #ifdef WIN32
+ // plugins (i.e. the audio/video ptlib/opal codecs) are searched in ./plugins
+ chdir (win32_datadir ());
+ #endif
+
+ /* Gettext initialization */
+ path = g_build_filename (DATA_DIR, "locale", NULL);
+ textdomain (GETTEXT_PACKAGE);
+ bindtextdomain (GETTEXT_PACKAGE, path);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ g_free (path);
+
+ /* Application name */
+ g_set_application_name (_("Ekiga Softphone"));
+ #ifndef WIN32
+ setenv ("PULSE_PROP_application.name", _("Ekiga Softphone"), true);
+ setenv ("PA_PROP_MEDIA_ROLE", "phone", true);
+ #endif
+
+ /* Priv building */
+ self->priv = new _GmApplicationPrivate ();
+ self->priv->builder = gtk_builder_new ();
+
+ /* Menu */
+ g_action_map_add_action_entries (G_ACTION_MAP (self),
+ app_entries, G_N_ELEMENTS (app_entries),
+ self);
+ gtk_builder_add_from_string (self->priv->builder,
+ "<?xml version=\"1.0\"?>"
+ "<interface>"
+ " <menu id=\"appmenu\">"
+ " <section id=\"banks\">"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name=\"label\" translatable=\"yes\">Address
_Book</attribute>"
+ " <attribute name=\"action\">app.addressbook</attribute>"
+ " </item>"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name=\"label\"
translatable=\"yes\">_Preferences</attribute>"
+ " <attribute name=\"action\">app.preferences</attribute>"
+ " </item>"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name=\"label\" translatable=\"yes\">_Help</attribute>"
+ " <attribute name=\"action\">app.help</attribute>"
+ " <attribute name=\"accel\">F1</attribute>"
+ " </item>"
+ " <item>"
+ " <attribute name=\"label\" translatable=\"yes\">_About</attribute>"
+ " <attribute name=\"action\">app.about</attribute>"
+ " </item>"
+ " </section>"
+ " <section>"
+ " <item>"
+ " <attribute name=\"label\" translatable=\"yes\">_Quit</attribute>"
+ " <attribute name=\"action\">app.quit</attribute>"
+ " <attribute name=\"accel\"><Primary>q</attribute>"
+ " </item>"
+ " </section>"
+ " </menu>"
+ "</interface>", -1, NULL);
+
+ app_menu = G_MENU_MODEL (gtk_builder_get_object (self->priv->builder, "appmenu"));
+ gtk_application_set_app_menu (GTK_APPLICATION (self), app_menu);
+
+ self->priv->video_devices_settings =
+ boost::shared_ptr<Ekiga::Settings> (new Ekiga::Settings (VIDEO_DEVICES_SCHEMA));
+ g_signal_connect (self->priv->video_devices_settings->get_g_settings (),
+ "changed::enable-preview",
+ G_CALLBACK (video_preview_changed), self);
+ self->priv->call_window = NULL;
+ }
+
+
+ static void
+ gm_application_dispose (GObject *obj)
+ {
+ GmApplication *self = NULL;
+
+ self = GM_APPLICATION (obj);
+
+ #ifdef HAVE_DBUS
+ g_object_unref (self->priv->dbus_component);
+ #endif
+ g_object_unref (self->priv->builder);
+
+ delete self->priv;
+
+ G_OBJECT_CLASS (gm_application_parent_class)->dispose (obj);
+ }
+
+
+ static void
+ gm_application_shutdown (GApplication *app)
+ {
+ GmApplication *self = GM_APPLICATION (app);
+
+ g_return_if_fail (self);
+
+ PThread::Current()->Sleep (2000); // FIXME, This allows all threads to start and quit. Sucks.
+
+ gtk_widget_hide (GTK_WIDGET (self->priv->main_window));
+
+ self->priv->core.reset ();
+ Ekiga::Runtime::quit ();
+
+ gm_platform_shutdown ();
+
+ G_APPLICATION_CLASS (gm_application_parent_class)->shutdown (app);
+ }
+
+ static gint
+ gm_application_command_line (GApplication *app,
+ GApplicationCommandLine *cl)
+ {
+ gchar **arguments = NULL;
+ GOptionContext *context = NULL;
+ GError *error = NULL;
+
+ GmApplication *self = GM_APPLICATION (app);
+
+ g_return_val_if_fail (self && self->priv->core, -1);
+
+ static gchar *url = NULL;
+ static int debug_level = 0;
+ static gboolean hangup = FALSE;
+ static gboolean help = FALSE;
+ static gboolean version = FALSE;
+
+ static GOptionEntry options [] =
+ {
+ {
+ "help", '?', 0, G_OPTION_ARG_NONE, &help,
+ N_("Show the application's help"), NULL
+ },
+
+ /* Version */
+ {
+ "version", 'V', 0, G_OPTION_ARG_NONE, &version,
+ N_("Show the application's version"), NULL
+ },
+ {
+ "debug", 'd', 0, G_OPTION_ARG_INT, &debug_level,
+ N_("Prints debug messages in the console (level between 1 and 8)"),
+ NULL
+ },
+ {
+ "call", 'c', 0, G_OPTION_ARG_STRING, &url,
+ N_("Makes Ekiga call the given URI"),
+ NULL
+ },
+ {
+ "hangup", '\0', 0, G_OPTION_ARG_NONE, &hangup,
+ N_("Hangup the current call (if any)"),
+ NULL
+ },
+ {
+ NULL, 0, 0, (GOptionArg)0, NULL,
+ NULL,
+ NULL
+ }
+ };
+
+ context = g_option_context_new (NULL);
+ g_option_context_add_main_entries (context, options, PACKAGE_NAME);
+ g_option_context_add_group (context, gtk_get_option_group (FALSE));
+
+ arguments = g_application_command_line_get_arguments (cl, NULL);
+
+ /* Avoid exit() on the main instance */
+ g_option_context_set_help_enabled (context, FALSE);
+
+ if (!option_context_parse (context, arguments, &error)) {
+ /* We should never get here since parsing would have
+ * failed on the client side... */
+ g_application_command_line_printerr (cl,
+ _("%s\nRun '%s --help' to see a full list of available command
line options.\n"),
+ error->message, arguments[0]);
+
+ g_error_free (error);
+ g_application_command_line_set_exit_status (cl, 1);
+ g_application_quit (app);
+ }
+ else if (url) {
+ boost::shared_ptr<Ekiga::CallCore> call_core =
+ self->priv->core->get<Ekiga::CallCore> ("call-core");
+ call_core->dial (url);
+ }
+ else if (hangup) {
+ boost::shared_ptr<Ekiga::CallCore> call_core =
+ self->priv->core->get<Ekiga::CallCore> ("call-core");
+ call_core->hang_up ();
+ }
+ else if (version) {
+ g_print ("%s - Version %d.%d.%d\n",
+ g_get_application_name (),
+ MAJOR_VERSION, MINOR_VERSION, BUILD_NUMBER);
+ g_application_quit (app);
+ }
+ else if (help) {
+ g_print (g_option_context_get_help (context, TRUE, NULL));
+ g_application_quit (app);
+ }
+ else if (debug_level > 0) {
+ #ifndef WIN32
+ char* text_label = g_strdup_printf ("%d", debug_level);
+ setenv ("PTLIB_TRACE_CODECS", text_label, TRUE);
+ g_free (text_label);
+ #else
+ char* text_label = g_strdup_printf ("PTLIB_TRACE_CODECS=%d", debug_level);
+ _putenv (text_label);
+ g_free (text_label);
+ if (debug_level != 0) {
+ std::string desk_path = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
+ if (!desk_path.empty ())
+ std::freopen((desk_path + "\\ekiga-stderr.txt").c_str (), "w", stderr);
+ }
+ #endif
+
+ #if PTRACING
+ PTrace::Initialise (PMAX (PMIN (8, debug_level), 0), NULL,
+ PTrace::Timestamp | PTrace::Thread
+ | PTrace::Blocks | PTrace::DateAndTime);
+ PTRACE (1, "Ekiga version "
+ << MAJOR_VERSION << "." << MINOR_VERSION << "." << BUILD_NUMBER);
+ #ifdef EKIGA_REVISION
+ PTRACE (1, "Ekiga git revision: " << EKIGA_REVISION);
+ #endif
+ PTRACE (1, "PTLIB version " << PTLIB_VERSION);
+ PTRACE (1, "OPAL version " << OPAL_VERSION);
+ #ifdef HAVE_DBUS
+ PTRACE (1, "DBUS support enabled");
+ #else
+ PTRACE (1, "DBUS support disabled");
+ #endif
+ #endif
+ }
+
+ g_strfreev (arguments);
+ g_option_context_free (context);
+
+ g_application_activate (app);
+
+ g_free (url);
+ url = NULL;
+ hangup = FALSE;
+ version = FALSE;
+ help = FALSE;
+
+ return 0;
+ }
+
+ static void
+ gm_application_class_init (GmApplicationClass *klass)
+ {
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GApplicationClass *app_class = G_APPLICATION_CLASS (klass);
+
+ object_class->dispose = gm_application_dispose;
+
+ app_class->startup = gm_application_startup;
+ app_class->activate = gm_application_activate;
+ app_class->command_line = gm_application_command_line;
+ app_class->shutdown = gm_application_shutdown;
+ }
+
+
+ static void
+ gm_application_init (G_GNUC_UNUSED GmApplication *self)
+ {
+ self->priv = new GmApplicationPrivate ();
+ self->priv->banks_actions_count = 0;
+ }
+
+
+ GmApplication *
+ gm_application_new ()
+ {
+ GmApplication *self =
+ GM_APPLICATION (g_object_new (GM_TYPE_APPLICATION,
+ "application-id", "org.gnome.Ekiga",
+ "flags", G_APPLICATION_HANDLES_COMMAND_LINE,
+ NULL));
+ g_application_register (G_APPLICATION (self), NULL, NULL);
+
+ return self;
+ }
+
+
+ void
+ gm_application_set_core (GmApplication *self,
+ Ekiga::ServiceCorePtr core)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (self));
+ self->priv->core = core;
+ }
+
+
+ Ekiga::ServiceCorePtr
+ gm_application_get_core (GmApplication *self)
+ {
+ g_return_val_if_fail (GM_IS_APPLICATION (self), boost::shared_ptr<Ekiga::ServiceCore> ());
+
+ return self->priv->core;
+ }
+
+
+ void
+ gm_application_show_main_window (GmApplication *self)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (self));
+
+ gtk_window_present (GTK_WINDOW (self->priv->main_window));
+ }
+
+
+ void
+ gm_application_hide_main_window (GmApplication *self)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (self));
+
+ gtk_widget_hide (self->priv->main_window);
+ }
+
+
+ GtkWidget *
+ gm_application_get_main_window (GmApplication *self)
+ {
+ g_return_val_if_fail (GM_IS_APPLICATION (self), NULL);
+
+ return self->priv->main_window;
+ }
+
+
+ gboolean
+ gm_application_show_help (GmApplication *app,
+ G_GNUC_UNUSED const gchar *link_id)
+ {
+ g_return_val_if_fail (GM_IS_APPLICATION (app), FALSE);
+
+ GtkWindow *parent = gtk_application_get_active_window (GTK_APPLICATION (app));
+
+ #ifdef WIN32
+ gchar *locale, *loc_ , *index_path;
+ int hinst = 0;
+
+ locale = g_win32_getlocale ();
+ if (strlen (locale) > 0) {
+
+ /* try returned locale first, it may be fully qualified e.g. zh_CN */
+ index_path = g_build_filename (WIN32_HELP_DIR, locale,
+ WIN32_HELP_FILE, NULL);
+ hinst = (int) ShellExecute (NULL, "open", index_path, NULL,
+ DATA_DIR, SW_SHOWNORMAL);
+ g_free (index_path);
+ }
+
+ if (hinst <= 32 && (loc_ = g_strrstr (locale, "_"))) {
+ /* on error, try short locale */
+ *loc_ = 0;
+ index_path = g_build_filename (WIN32_HELP_DIR, locale,
+ WIN32_HELP_FILE, NULL);
+ hinst = (int) ShellExecute (NULL, "open", index_path, NULL,
+ DATA_DIR, SW_SHOWNORMAL);
+ g_free (index_path);
+ }
+
+ g_free (locale);
+
+ if (hinst <= 32) {
+
+ /* on error or missing locale, try default locale */
+ index_path = g_build_filename (WIN32_HELP_DIR, "C", WIN32_HELP_FILE, NULL);
+ (void)ShellExecute (NULL, "open", index_path, NULL,
+ DATA_DIR, SW_SHOWNORMAL);
+ g_free (index_path);
+ }
+ #else /* !WIN32 */
+ GError *err = NULL;
+ gboolean success = FALSE;
+
+ success = gtk_show_uri (NULL, "ghelp:" PACKAGE_NAME, GDK_CURRENT_TIME, &err);
+
+ if (!success) {
+ GtkWidget *d;
+ d = gtk_message_dialog_new (NULL,
+ (GtkDialogFlags) (GTK_DIALOG_MODAL),
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ "%s", _("Unable to open help file."));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (d),
+ "%s", err->message);
+ g_signal_connect (d, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_window_set_transient_for (GTK_WINDOW (d), GTK_WINDOW (parent));
+ gtk_window_present (GTK_WINDOW (d));
+ g_error_free (err);
+ return FALSE;
+ }
+ #endif
+
+ return TRUE;
+ }
+
+
+ void
+ gm_application_show_about (GmApplication *app)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (app));
+
+ GtkWidget *pixmap = NULL;
+ gchar *filename = NULL;
+
+ const gchar *authors [] = {
+ "Damien Sandras <dsandras seconix com>",
+ "",
+ N_("Contributors:"),
+ "Eugen Dedu <eugen dedu pu-pm univ-fcomte fr>",
+ "Julien Puydt <julien puydt laposte net>",
+ "Robert Jongbloed <rjongbloed postincrement com>",
+ "",
+ N_("Artwork:"),
+ "Fabian Deutsch <fabian deutsch gmx de>",
+ "Vinicius Depizzol <vdepizzol gmail com>",
+ "Andreas Kwiatkowski <post kwiat org>",
+ "Carlos Pardo <me m4de com>",
+ "Jakub Steiner <jimmac ximian com>",
+ "",
+ N_("See AUTHORS file for full credits"),
+ NULL
+ };
+
+ authors [2] = gettext (authors [2]);
+ authors [7] = gettext (authors [7]);
+ authors [14] = gettext (authors [14]);
+
+ const gchar *documenters [] = {
+ "Damien Sandras <dsandras seconix com>",
+ "Christopher Warner <zanee kernelcode com>",
+ "Matthias Redlich <m-redlich t-online de>",
+ NULL
+ };
+
+ const gchar *license[] = {
+ N_("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. "),
+ N_("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."),
+ N_("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.")
+ };
+
+ gchar *license_trans;
+
+ /* Translators: Please write translator credits here, and
+ * separate names with \n */
+ const gchar *translator_credits = _("translator-credits");
+ if (g_strcmp0 (translator_credits, "translator-credits") == 0)
+ translator_credits = "No translators, English by\n"
+ "Damien Sandras <dsandras seconix com>";
+
+ const gchar *comments = _("Ekiga is full-featured SIP and H.323 compatible VoIP, IP-Telephony and
Videoconferencing application that allows you to make audio and video calls to remote users with SIP and
H.323 hardware or software.");
+
+ license_trans = g_strconcat (_(license[0]), "\n\n", _(license[1]), "\n\n",
+ _(license[2]), "\n\n", NULL);
+
+ filename = g_build_filename (DATA_DIR, "pixmaps", PACKAGE_NAME,
+ PACKAGE_NAME "-logo.png", NULL);
+ pixmap = gtk_image_new_from_file (filename);
+
+ gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (GTK_APPLICATION (app))),
+ "name", "Ekiga",
+ "version", VERSION,
+ "copyright", "Copyright © 2000-2014 Damien Sandras",
+ "authors", authors,
+ "documenters", documenters,
+ "translator-credits", translator_credits,
+ "comments", comments,
+ "logo", gtk_image_get_pixbuf (GTK_IMAGE (pixmap)),
+ "license", license_trans,
+ "wrap-license", TRUE,
+ "website", "http://www.ekiga.org",
+ NULL);
+
+ g_free (license_trans);
+ g_free (filename);
+ }
+
+
+ void
+ gm_application_show_chat_window (GmApplication *self)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (self));
+
+ // FIXME: We should move the chat window to a build & destroy scheme
+ // but unread-alert prevents this
+ gtk_window_present (GTK_WINDOW (self->priv->chat_window));
+ }
+
+
+ GtkWidget *
+ gm_application_get_chat_window (GmApplication *self)
+ {
+ g_return_val_if_fail (GM_IS_APPLICATION (self), NULL);
+
+ return self->priv->chat_window;
+ }
+
+
+ void
+ gm_application_show_preferences_window (GmApplication *self)
+ {
+ GtkWindow *parent = NULL;
+ GtkWindow *window = NULL;
+
+ g_return_if_fail (GM_IS_APPLICATION (self));
+
+ parent = gtk_application_get_active_window (GTK_APPLICATION (self));
+
+ window = GTK_WINDOW (preferences_window_new (self));
+ gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (parent));
+ gtk_window_present (window);
+ }
+
+
+ void
+ gm_application_show_addressbook_window (GmApplication *self)
+ {
+ g_return_if_fail (GM_IS_APPLICATION (self));
+
+
+ gtk_window_present (GTK_WINDOW (addressbook_window_new (self)));
+ }
+
+
+ void
+ gm_application_show_assistant_window (GmApplication *self)
+ {
+ GtkWindow *parent = NULL;
+ GtkWindow *window = NULL;
+
+ g_return_if_fail (GM_IS_APPLICATION (self));
+
+ parent = gtk_application_get_active_window (GTK_APPLICATION (self));
+
+ window = GTK_WINDOW (assistant_window_new (self));
+ gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (parent));
+ gtk_window_present (window);
+ }
diff --cc lib/engine/gui/gtk-frontend/main_window.cpp
index 2b4b01e,9d6813e..162a47c
--- a/lib/engine/gui/gtk-frontend/main_window.cpp
+++ b/lib/engine/gui/gtk-frontend/main_window.cpp
@@@ -626,18 -416,13 +417,13 @@@ static void on_cleared_call_cb (boost::
mw->priv->current_call = boost::shared_ptr<Ekiga::Call>();
mw->priv->calling_state = Standby;
- /* Info message */
- ekiga_main_window_flash_message (mw, "%s", reason.c_str ());
/* Sound events */
- mw->priv->audiooutput_core->stop_play_event("incoming_call_sound");
- mw->priv->audiooutput_core->stop_play_event("ring_tone_sound");
+ mw->priv->audiooutput_core->stop_play_event("incoming-call-sound");
+ mw->priv->audiooutput_core->stop_play_event("ring-tone-sound");
- /* Hide call window */
- g_timeout_add_seconds (2, on_delayed_hide_call_window_cb, mw);
-
/* Sensitive a few things back */
- gtk_widget_set_sensitive (GTK_WIDGET (mw->priv->uri_toolbar), true);
+ gtk_widget_set_sensitive (GTK_WIDGET (mw->priv->entry), true);
gtk_widget_set_sensitive (GTK_WIDGET (mw->priv->preview_button), true);
}
@@@ -1049,83 -620,43 +621,44 @@@ ekiga_main_window_init_actions_toolbar
g_return_if_fail (EKIGA_IS_MAIN_WINDOW (mw));
- /* The call horizontal toolbar */
- mw->priv->actions_toolbar = gtk_toolbar_new ();
- gtk_toolbar_set_style (GTK_TOOLBAR (mw->priv->actions_toolbar), GTK_TOOLBAR_ICONS);
- gtk_toolbar_set_show_arrow (GTK_TOOLBAR (mw->priv->actions_toolbar), FALSE);
-
- /* The video preview button */
- image = gtk_image_new_from_icon_name ("camera-web", GTK_ICON_SIZE_MENU);
- mw->priv->preview_button = GTK_WIDGET (gtk_toggle_tool_button_new ());
- gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (mw->priv->preview_button), image);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (mw->priv->preview_button), false);
- gtk_toolbar_insert (GTK_TOOLBAR (mw->priv->actions_toolbar), GTK_TOOL_ITEM (mw->priv->preview_button),
-1);
+ mw->priv->actions_toolbar = gtk_header_bar_new ();
+ gtk_window_set_titlebar (GTK_WINDOW (mw), mw->priv->actions_toolbar);
+
+ /* Start packing buttons */
+ button = gtk_button_new ();
+ image = gtk_image_new_from_icon_name ("call-start-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (button),
+ _("Call the selected contact"));
+ gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.call");
+ gtk_header_bar_pack_start (GTK_HEADER_BAR (mw->priv->actions_toolbar), button);
+
+ mw->priv->preview_button = gtk_toggle_button_new ();
+ image = gtk_image_new_from_icon_name ("camera-web-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_button_set_image (GTK_BUTTON (mw->priv->preview_button), image);
gtk_widget_set_tooltip_text (GTK_WIDGET (mw->priv->preview_button),
_("Display images from your camera device"));
- g_settings_bind (mw->priv->video_devices_settings->get_g_settings (),
- "enable-preview",
- mw->priv->preview_button,
- "active",
- G_SETTINGS_BIND_DEFAULT);
- g_signal_connect (mw->priv->preview_button, "toggled",
- G_CALLBACK (video_preview_changed), mw);
-
- /* Separator */
- item = gtk_separator_tool_item_new ();
- gtk_toolbar_insert (GTK_TOOLBAR (mw->priv->actions_toolbar),
- GTK_TOOL_ITEM (item), -1);
-
- /* The roster button */
- image = gtk_image_new_from_icon_name ("avatar-default", GTK_ICON_SIZE_MENU);
- mw->priv->toggle_buttons[CONTACTS] = gtk_radio_tool_button_new (NULL);
- gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (mw->priv->toggle_buttons[CONTACTS]), image);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (mw->priv->toggle_buttons[CONTACTS]), false);
- gtk_toolbar_insert (GTK_TOOLBAR (mw->priv->actions_toolbar), mw->priv->toggle_buttons[CONTACTS], -1);
- gtk_widget_set_tooltip_text (GTK_WIDGET (mw->priv->toggle_buttons[CONTACTS]),
- _("View the contacts list"));
- g_settings_bind_with_mapping (mw->priv->user_interface_settings->get_g_settings (),
- "panel-section", mw->priv->toggle_buttons[CONTACTS],
- "active",
- G_SETTINGS_BIND_DEFAULT,
- string_gsettings_get_from_active, string_gsettings_set_from_active,
- (gpointer) "contacts",
- NULL);
-
- /* The dialpad button */
- image = gtk_image_new_from_icon_name ("input-dialpad", GTK_ICON_SIZE_MENU);
- mw->priv->toggle_buttons[DIALPAD] =
- gtk_radio_tool_button_new (gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON
(mw->priv->toggle_buttons[CONTACTS])));
- gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (mw->priv->toggle_buttons[DIALPAD]), image);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (mw->priv->toggle_buttons[DIALPAD]), false);
- gtk_toolbar_insert (GTK_TOOLBAR (mw->priv->actions_toolbar), mw->priv->toggle_buttons[DIALPAD], -1);
- gtk_widget_set_tooltip_text (GTK_WIDGET (mw->priv->toggle_buttons[DIALPAD]),
- _("View the dialpad"));
- g_settings_bind_with_mapping (mw->priv->user_interface_settings->get_g_settings (),
- "panel-section", mw->priv->toggle_buttons[DIALPAD],
- "active",
- G_SETTINGS_BIND_DEFAULT,
- string_gsettings_get_from_active, string_gsettings_set_from_active,
- (gpointer) "dialpad",
- NULL);
-
- /* The history button */
- image = gtk_image_new_from_icon_name ("document-open-recent", GTK_ICON_SIZE_MENU);
- mw->priv->toggle_buttons[CALL] =
- gtk_radio_tool_button_new (gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON
(mw->priv->toggle_buttons[CONTACTS])));
- gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (mw->priv->toggle_buttons[CALL]), image);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (mw->priv->toggle_buttons[CALL]), false);
- gtk_toolbar_insert (GTK_TOOLBAR (mw->priv->actions_toolbar), mw->priv->toggle_buttons[CALL], -1);
- gtk_widget_set_tooltip_text (GTK_WIDGET (mw->priv->toggle_buttons[CALL]),
- _("View the call history"));
- g_settings_bind_with_mapping (mw->priv->user_interface_settings->get_g_settings (),
- "panel-section", mw->priv->toggle_buttons[CALL],
- "active",
- G_SETTINGS_BIND_DEFAULT,
- string_gsettings_get_from_active, string_gsettings_set_from_active,
- (gpointer) "call-history",
- NULL);
++
+ gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (mw->priv->preview_button),
+ "win.enable-preview");
+ gtk_header_bar_pack_start (GTK_HEADER_BAR (mw->priv->actions_toolbar), mw->priv->preview_button);
+
+ switcher = gtk_stack_switcher_new ();
+ gtk_stack_switcher_set_stack (GTK_STACK_SWITCHER (switcher), GTK_STACK (mw->priv->main_stack));
+ gtk_header_bar_set_custom_title (GTK_HEADER_BAR (mw->priv->actions_toolbar), switcher);
+ gtk_widget_set_margin_end (GTK_WIDGET (switcher), 6);
+
+ mw->priv->menu_button = gtk_menu_button_new ();
+ g_object_set (G_OBJECT (mw->priv->menu_button), "use-popover", true, NULL);
+ image = gtk_image_new_from_icon_name ("open-menu-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_button_set_image (GTK_BUTTON (mw->priv->menu_button), image);
+ gtk_header_bar_pack_end (GTK_HEADER_BAR (mw->priv->actions_toolbar), mw->priv->menu_button);
+ gtk_widget_show_all (mw->priv->actions_toolbar);
+
+ gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (mw->priv->actions_toolbar), TRUE);
}
+
static void
ekiga_main_window_init_menu (EkigaMainWindow *mw)
{
diff --cc lib/engine/gui/gtk-frontend/preferences-window.cpp
index e82fde3,17be036..6d1fb08
--- a/lib/engine/gui/gtk-frontend/preferences-window.cpp
+++ b/lib/engine/gui/gtk-frontend/preferences-window.cpp
@@@ -48,11 -48,13 +48,15 @@@
#include "default_devices.h"
#include "scoped-connections.h"
+#include "form-request-simple.h"
+#include "form-dialog-gtk.h"
- #include "gmcallbacks.h"
#include "codecsbox.h"
+ #include "gm-entry.h"
+
+ #ifndef HAVE_SIDEBAR
+ #include "gm-sidebar.h"
+ #endif
#ifdef WIN32
#include "platform/winpaths.h"
@@@ -451,21 -447,6 +449,25 @@@ static void sound_event_setting_change
gpointer data);
+/* DESCRIPTION : This callback is triggered when the user asks to edit
+ * the blacklist
+ * BEHAVIOR : Display a form to edit the blacklist
+ * PRE : A pointer to the preferences window
+ */
+static void edit_blacklist_cb (GtkWidget* widget,
+ gpointer data);
+
- /* DESCRIPTION : This callback is triggered when the user submits the blacklist-editing form
++
++/* DESCRIPTION : This callback is triggered when the user submits the
++ * blacklist-editing form
+ * BEHAVIOR : /
+ * PRE : A pointer to the preferences window
+ */
- static void on_edit_blacklist_form_submitted (bool submitted,
- Ekiga::Form& result);
++static bool on_edit_blacklist_form_submitted (bool submitted,
++ Ekiga::Form& result,
++ std::string& error);
++
+
/* Implementation */
static void
gm_prefs_window_sound_events_list_build (PreferencesWindow *self)
@@@ -1668,43 -1619,6 +1653,44 @@@ sound_event_toggled_cb (G_GNUC_UNUSED G
gtk_tree_path_free (path);
}
+static void
+edit_blacklist_cb (GtkWidget* /*widget*/,
+ gpointer data)
+{
+ g_return_if_fail (data != NULL);
+
- boost::shared_ptr<Ekiga::FormRequestSimple> request(new Ekiga::FormRequestSimple
(&on_edit_blacklist_form_submitted));
++ boost::shared_ptr<Ekiga::FormRequestSimple> request (new Ekiga::FormRequestSimple
(&on_edit_blacklist_form_submitted));
+
- request->title (_("Blacklist edition"));
- request->instructions (_("This form lets you add and remove tokens from the blacklist"));
++ request->title (_("Edit the Blacklist"));
+
+ boost::scoped_ptr<Ekiga::Settings> settings(new Ekiga::Settings (CONTACTS_SCHEMA));
+ std::list<std::string> foes(settings->get_string_list ("foe-list"));
+
- request->editable_set ("foes", _("Current list of undesirables"),
- std::set<std::string> (foes.begin (), foes.end ()),
- std::set<std::string>());
++ request->editable_list ("foes", _("Current list of undesirables"),
++ std::list<std::string> (foes.begin (), foes.end ()),
++ std::list<std::string>());
+
+ FormDialog dialog(request, GTK_WIDGET (data));
+
+ dialog.run ();
+}
+
- static void
++static bool
+on_edit_blacklist_form_submitted (bool submitted,
- Ekiga::Form& result)
++ Ekiga::Form& result,
++ G_GNUC_UNUSED std::string& error)
+{
+ if (!submitted)
- return;
++ return false;
+
- std::set<std::string> foes = result.editable_set ("foes");
++ std::list<std::string> foes = result.editable_list ("foes");
+ boost::scoped_ptr<Ekiga::Settings> settings(new Ekiga::Settings (CONTACTS_SCHEMA));
- settings->set_string_list ("foe-list",
- std::list<std::string> (foes.begin (), foes.end ()));
++ settings->set_string_list ("foe-list", foes);
++
++ return true;
+}
+
+
void on_videoinput_device_added_cb (const Ekiga::VideoInputDevice & device,
PreferencesWindow *self)
{
diff --cc lib/engine/presence/presence-core.h
index 718f933,cb299d4..0978766
--- a/lib/engine/presence/presence-core.h
+++ b/lib/engine/presence/presence-core.h
@@@ -41,7 -41,9 +41,8 @@@
#include "services.h"
#include "scoped-connections.h"
#include "cluster.h"
-#include "account-core.h"
#include "personal-details.h"
+ #include "action-provider.h"
namespace Ekiga
{
diff --cc lib/engine/presence/uri-presentity.cpp
index 12f874e,7b14947..60e320e
--- a/lib/engine/presence/uri-presentity.cpp
+++ b/lib/engine/presence/uri-presentity.cpp
@@@ -48,17 -48,11 +48,17 @@@ struct null_delete
Ekiga::URIPresentity::URIPresentity (boost::shared_ptr<Ekiga::PresenceCore> pcore,
std::string name_,
std::string uri_,
- std::set<std::string> groups_):
+ std::list<std::string> groups_):
presence_core(pcore), name(name_), uri(uri_), presence("unknown"), groups(groups_)
{
- pcore->presence_received.connect (boost::bind (&Ekiga::URIPresentity::on_presence_received, this, _1,
_2));
- pcore->status_received.connect (boost::bind (&Ekiga::URIPresentity::on_status_received, this, _1, _2));
+ boost::signals2::connection conn;
+
+ conn = pcore->presence_received.connect (boost::bind (&Ekiga::URIPresentity::on_presence_received, this,
_1, _2));
+ connections.add (conn);
+
+ conn = pcore->status_received.connect (boost::bind (&Ekiga::URIPresentity::on_status_received, this, _1,
_2));
+ connections.add (conn);
+
pcore->fetch_presence (uri);
}
diff --cc lib/engine/presence/uri-presentity.h
index 1076bc7,dc1c12a..466a7ec
--- a/lib/engine/presence/uri-presentity.h
+++ b/lib/engine/presence/uri-presentity.h
@@@ -90,15 -90,8 +90,9 @@@ namespace Ekig
const std::string get_uri () const;
- /** Populates the given Ekiga::MenuBuilder with the actions.
- * @param: A MenuBuilder.
- */
- bool populate_menu (Ekiga::MenuBuilder& builder);
-
private:
-
boost::weak_ptr<Ekiga::PresenceCore> presence_core;
+ Ekiga::scoped_connections connections;
std::string name;
std::string uri;
diff --cc lib/engine/protocol/call-core.cpp
index 4002251,6f42846..81bfdea
--- a/lib/engine/protocol/call-core.cpp
+++ b/lib/engine/protocol/call-core.cpp
@@@ -40,8 -45,7 +45,7 @@@
using namespace Ekiga;
- CallCore::CallCore (boost::shared_ptr<Ekiga::FriendOrFoe> iff_):
- iff(iff_)
-CallCore::CallCore ()
++CallCore::CallCore (boost::shared_ptr<Ekiga::FriendOrFoe> iff_): iff(iff_)
{
nr_ready = 0;
}
@@@ -92,31 -97,84 +97,92 @@@ bool CallCore::dial (const std::string
}
- void
- CallCore::add_call (boost::shared_ptr<Call> call,
- boost::shared_ptr<CallManager> manager)
+ void CallCore::hang_up ()
+ {
+ for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
+ iter != managers.end ();
+ iter++)
+ (*iter)->hang_up ();
+ }
+
+
+ bool CallCore::transfer (const std::string & uri,
+ bool attended)
+ {
+ for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
+ iter != managers.end ();
+ iter++) {
+ if ((*iter)->transfer (uri, attended))
+ return true;
+ }
+
+ return false;
+ }
+
+
+ bool CallCore::message (const ContactPtr & contact,
+ const std::string & uri)
+ {
+ for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
+ iter != managers.end ();
+ iter++) {
+ if ((*iter)->message (contact, uri))
+ return true;
+ }
+
+ return false;
+ }
+
+
+ bool CallCore::is_supported_uri (const std::string & uri)
+ {
+ for (std::set<boost::shared_ptr<CallManager> >::iterator iter = managers.begin ();
+ iter != managers.end ();
+ iter++) {
+ if ((*iter)->is_supported_uri (uri))
+ return true;
+ }
+
+ return false;
+ }
+
+
+ void CallCore::add_call (boost::shared_ptr<Call> call, boost::shared_ptr<CallManager> manager)
{
+ Ekiga::FriendOrFoe::Identification id = iff->decide ("call", call->get_remote_uri ());
+
+ if (id == Ekiga::FriendOrFoe::Foe) {
+
+ call->hang_up ();
+ return;
+ }
+
+ created_call (manager, call);
+
boost::shared_ptr<Ekiga::scoped_connections> conns(new Ekiga::scoped_connections);
- conns->add (call->ringing.connect (boost::bind (&CallCore::on_ringing_call, this, call, manager)));
- conns->add (call->setup.connect (boost::bind (&CallCore::on_setup_call, this, call, manager)));
- conns->add (call->missed.connect (boost::bind (&CallCore::on_missed_call, this, call, manager)));
- conns->add (call->cleared.connect (boost::bind (&CallCore::on_cleared_call, this, _1, call, manager)));
- conns->add (call->established.connect (boost::bind (&CallCore::on_established_call, this, call,
manager)));
- conns->add (call->held.connect (boost::bind (&CallCore::on_held_call, this, call, manager)));
- conns->add (call->retrieved.connect (boost::bind (&CallCore::on_retrieved_call, this, call, manager)));
- conns->add (call->stream_opened.connect (boost::bind (&CallCore::on_stream_opened, this, _1, _2, _3,
call, manager)));
- conns->add (call->stream_closed.connect (boost::bind (&CallCore::on_stream_closed, this, _1, _2, _3,
call, manager)));
- conns->add (call->stream_paused.connect (boost::bind (&CallCore::on_stream_paused, this, _1, _2, call,
manager)));
- conns->add (call->stream_resumed.connect (boost::bind (&CallCore::on_stream_resumed, this, _1, _2, call,
manager)));
+ conns->add (call->ringing.connect (boost::bind (&CallCore::on_ringing_call, this,
+ call, manager)));
+ conns->add (call->setup.connect (boost::bind (&CallCore::on_setup_call, this,
+ call, manager)));
+ conns->add (call->missed.connect (boost::bind (&CallCore::on_missed_call, this,
+ call, manager)));
+ conns->add (call->cleared.connect (boost::bind (&CallCore::on_cleared_call, this,
+ _1, call, manager)));
+ conns->add (call->established.connect (boost::bind (&CallCore::on_established_call, this,
+ call, manager)));
+ conns->add (call->held.connect (boost::bind (&CallCore::on_held_call, this,
+ call, manager)));
+ conns->add (call->retrieved.connect (boost::bind (&CallCore::on_retrieved_call, this,
+ call, manager)));
+ conns->add (call->stream_opened.connect (boost::bind (&CallCore::on_stream_opened, this,
+ _1, _2, _3, call, manager)));
+ conns->add (call->stream_closed.connect (boost::bind (&CallCore::on_stream_closed, this,
+ _1, _2, _3, call, manager)));
+ conns->add (call->stream_paused.connect (boost::bind (&CallCore::on_stream_paused, this,
+ _1, _2, call, manager)));
+ conns->add (call->stream_resumed.connect (boost::bind (&CallCore::on_stream_resumed, this,
+ _1, _2, call, manager)));
conns->add (call->removed.connect (boost::bind (&CallCore::on_call_removed, this, call)));
call_connections [call->get_id ()] = conns;
diff --cc plugins/avahi/Makefile.am
index 82bcd51,f57626d..1cd9cb8
--- a/plugins/avahi/Makefile.am
+++ b/plugins/avahi/Makefile.am
@@@ -2,7 -2,7 +2,8 @@@ plugin_LTLIBRARIES = libgmavahi.l
AM_CXXFLAGS = \
$(BOOST_CPPFLAGS) $(AVAHI_CFLAGS) \
+ -I$(top_srcdir)/lib/engine \
+ -I$(top_srcdir)/lib/engine/action \
-I$(top_srcdir)/lib/engine/framework \
-I$(top_srcdir)/lib/engine/account \
-I$(top_srcdir)/lib/engine/presence \
diff --cc plugins/libnotify/Makefile.am
index b7ca344,69996d5..72e8fdc
--- a/plugins/libnotify/Makefile.am
+++ b/plugins/libnotify/Makefile.am
@@@ -2,9 -2,10 +2,11 @@@ plugin_LTLIBRARIES = libgmlibnotify.l
AM_CXXFLAGS = \
$(BOOST_CPPFLAGS) $(NOTIFY_CFLAGS) \
+ -I$(top_srcdir)/lib/engine \
-I$(top_srcdir)/lib/engine/framework \
-I$(top_srcdir)/lib/engine/notification \
+ -I$(top_srcdir)/lib/engine/action \
+ -I$(top_srcdir)/lib/engine/addressbook \
-I$(top_srcdir)/lib/engine/protocol
libgmlibnotify_la_SOURCES = \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]