aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@src.gnome.org>2008-04-20 02:36:22 +0800
committerXavier Claessens <xclaesse@src.gnome.org>2008-04-20 02:36:22 +0800
commit5151e57366bbbe7b04ab03bcb6cda8afcd240a61 (patch)
tree83818fbc7da2bbe377873ef15602fcc2eb4a8294 /src
parent6bb385c3ada233409a10088f2de1a134d0707fda (diff)
downloadgsoc2013-empathy-5151e57366bbbe7b04ab03bcb6cda8afcd240a61.tar
gsoc2013-empathy-5151e57366bbbe7b04ab03bcb6cda8afcd240a61.tar.gz
gsoc2013-empathy-5151e57366bbbe7b04ab03bcb6cda8afcd240a61.tar.bz2
gsoc2013-empathy-5151e57366bbbe7b04ab03bcb6cda8afcd240a61.tar.lz
gsoc2013-empathy-5151e57366bbbe7b04ab03bcb6cda8afcd240a61.tar.xz
gsoc2013-empathy-5151e57366bbbe7b04ab03bcb6cda8afcd240a61.tar.zst
gsoc2013-empathy-5151e57366bbbe7b04ab03bcb6cda8afcd240a61.zip
Drop Chandler and Filter, do not use MC for dispatching channels, do it ourself.
svn path=/trunk/; revision=967
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am31
-rw-r--r--src/empathy-call-chandler.c86
-rw-r--r--src/empathy-call.chandler5
-rw-r--r--src/empathy-chat.chandler5
-rw-r--r--src/empathy-filter.c555
-rw-r--r--src/empathy-filter.h61
-rw-r--r--src/empathy-status-icon.c736
-rw-r--r--src/empathy.c77
-rw-r--r--src/org.gnome.Empathy.Call.service.in3
-rw-r--r--src/org.gnome.Empathy.Chat.service.in3
10 files changed, 786 insertions, 776 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 133f7f5b5..6c3fc1e1c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,23 +29,13 @@ empathy_SOURCES = \
empathy-chatrooms-window.c empathy-chatrooms-window.h \
empathy-main-window.c empathy-main-window.h \
empathy-preferences.c empathy-preferences.h \
+ empathy-call-window.c empathy-call-window.h \
+ empathy-filter.c empathy-filter.h \
ephy-spinner.c ephy-spinner.h
empathy_accounts_SOURCES = empathy-accounts.c
empathy_logs_SOURCES = empathy-logs.c
-# Dbus service files
-servicedir = $(datadir)/dbus-1/services
-service_DATA = \
- org.gnome.Empathy.Chat.service
-
-%.service: %.service.in Makefile
- @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< | sed -e "s|\@bindir\@|$(bindir)|" > $@
-
-chandlerdir = $(datadir)/telepathy/managers
-chandler_DATA = \
- empathy-chat.chandler
-
gladedir = $(datadir)/empathy
glade_DATA = \
empathy-call-window.glade \
@@ -56,26 +46,9 @@ glade_DATA = \
empathy-new-chatroom-dialog.glade \
empathy-status-icon.glade
-BUILT_SOURCES = \
- $(service_DATA)
-
EXTRA_DIST = \
- org.gnome.Empathy.Chat.service.in \
- org.gnome.Empathy.Call.service.in \
$(autostart_DATA) \
- $(chandler_DATA) \
$(glade_DATA)
CLEANFILES = $(BUILT_SOURCES)
-if HAVE_VOIP
-libexec_PROGRAMS = empathy-call-chandler
-empathy_call_chandler_SOURCES = \
- empathy-call-chandler.c \
- empathy-call-window.c empathy-call-window.h
-service_DATA += org.gnome.Empathy.Call.service
-chandler_DATA += empathy-call.chandler
-else
-EXTRA_DIST += empathy-call.chandler
-endif
-
diff --git a/src/empathy-call-chandler.c b/src/empathy-call-chandler.c
deleted file mode 100644
index 313fe73c6..000000000
--- a/src/empathy-call-chandler.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2007 Elliot Fairweather
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Elliot Fairweather <elliot.fairweather@collabora.co.uk>
- */
-
-#include <gtk/gtk.h>
-
-#include <libmissioncontrol/mission-control.h>
-
-#include <libempathy/empathy-tp-call.h>
-#include <libempathy/empathy-chandler.h>
-#include <libempathy/empathy-debug.h>
-#include <libempathy/empathy-utils.h>
-
-#include "empathy-call-window.h"
-
-#define DEBUG_DOMAIN "CallChandler"
-
-static guint nb_calls = 0;
-
-static void
-weak_notify (gpointer data,
- GObject *where_the_object_was)
-{
- nb_calls--;
- if (nb_calls == 0)
- {
- empathy_debug (DEBUG_DOMAIN, "No more calls, leaving...");
- gtk_main_quit ();
- }
-}
-
-static void
-new_channel_cb (EmpathyChandler *chandler,
- TpChannel *channel,
- MissionControl *mc)
-{
- EmpathyTpCall *call;
-
- call = empathy_tp_call_new (channel);
- empathy_call_window_new (call);
- g_object_unref (call);
-
- nb_calls++;
- g_object_weak_ref (G_OBJECT (call), weak_notify, NULL);
-}
-
-int
-main (int argc, char *argv[])
-{
- MissionControl *mc;
- EmpathyChandler *chandler;
-
- gtk_init (&argc, &argv);
-
- mc = empathy_mission_control_new ();
-
- chandler = empathy_chandler_new ("org.gnome.Empathy.CallChandler",
- "/org/gnome/Empathy/CallChandler");
- g_signal_connect (chandler, "new-channel",
- G_CALLBACK (new_channel_cb), mc);
-
- empathy_debug (DEBUG_DOMAIN, "Ready to handle new streamed media channels");
-
- gtk_main ();
-
- g_object_unref (chandler);
- g_object_unref (mc);
-
- return EXIT_SUCCESS;
-}
diff --git a/src/empathy-call.chandler b/src/empathy-call.chandler
deleted file mode 100644
index 88ad9e747..000000000
--- a/src/empathy-call.chandler
+++ /dev/null
@@ -1,5 +0,0 @@
-[ChannelHandler]
-BusName = org.gnome.Empathy.CallChandler
-ObjectPath = /org/gnome/Empathy/CallChandler
-ChannelType = org.freedesktop.Telepathy.Channel.Type.StreamedMedia
-TypeSpecificCapabilities = 15
diff --git a/src/empathy-chat.chandler b/src/empathy-chat.chandler
deleted file mode 100644
index 7de2f28d6..000000000
--- a/src/empathy-chat.chandler
+++ /dev/null
@@ -1,5 +0,0 @@
-[ChannelHandler]
-BusName = org.gnome.Empathy.ChatChandler
-ObjectPath = /org/gnome/Empathy/ChatChandler
-ChannelType = org.freedesktop.Telepathy.Channel.Type.Text
-
diff --git a/src/empathy-filter.c b/src/empathy-filter.c
new file mode 100644
index 000000000..d7a6d659f
--- /dev/null
+++ b/src/empathy-filter.c
@@ -0,0 +1,555 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007-2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+#include <telepathy-glib/enums.h>
+#include <telepathy-glib/channel.h>
+#include <telepathy-glib/connection.h>
+#include <telepathy-glib/util.h>
+
+#include <libmissioncontrol/mission-control.h>
+#include <libmissioncontrol/mc-account.h>
+
+#include <libempathy/empathy-tp-chat.h>
+#include <libempathy/empathy-tp-call.h>
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-debug.h>
+
+#include <libempathy-gtk/empathy-chat.h>
+#include <libempathy-gtk/empathy-images.h>
+
+#include "empathy-filter.h"
+#include "empathy-chat-window.h"
+#include "empathy-call-window.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ EMPATHY_TYPE_FILTER, EmpathyFilterPriv))
+
+#define DEBUG_DOMAIN "Filter"
+
+struct _EmpathyFilterPriv {
+ GSList *events;
+ GHashTable *accounts;
+ gpointer token;
+ MissionControl *mc;
+};
+
+static void empathy_filter_class_init (EmpathyFilterClass *klass);
+static void empathy_filter_init (EmpathyFilter *filter);
+
+G_DEFINE_TYPE (EmpathyFilter, empathy_filter, G_TYPE_OBJECT);
+
+enum {
+ PROP_0,
+ PROP_TOP_EVENT,
+};
+
+typedef void (*FilterFunc) (EmpathyFilter *filter,
+ gpointer user_data);
+
+typedef struct {
+ EmpathyFilterEvent public;
+ FilterFunc func;
+ gpointer user_data;
+} EmpathyFilterEventExt;
+
+static void
+filter_event_free (EmpathyFilterEventExt *event)
+{
+ g_free (event->public.icon_name);
+ g_free (event->public.message);
+ g_slice_free (EmpathyFilterEventExt, event);
+}
+
+static void
+filter_emit_event (EmpathyFilter *filter,
+ const gchar *icon_name,
+ const gchar *message,
+ FilterFunc func,
+ gpointer user_data)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (filter);
+ EmpathyFilterEventExt *event;
+
+ empathy_debug (DEBUG_DOMAIN, "Emit event, icon_name=%s message='%s'",
+ icon_name, message);
+
+ event = g_slice_new0 (EmpathyFilterEventExt);
+ event->func = func;
+ event->user_data = user_data;
+ event->public.icon_name = g_strdup (icon_name);
+ event->public.message = g_strdup (message);
+
+ priv->events = g_slist_append (priv->events, event);
+ if (priv->events->data == event) {
+ g_object_notify (G_OBJECT (filter), "top-event");
+ }
+}
+
+void
+empathy_filter_activate_event (EmpathyFilter *filter,
+ EmpathyFilterEvent *event)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (filter);
+ EmpathyFilterEventExt *event_ext;
+ GSList *l;
+ gboolean is_top;
+
+ g_return_if_fail (EMPATHY_IS_FILTER (filter));
+ g_return_if_fail (event != NULL);
+
+ if (!(l = g_slist_find (priv->events, event))) {
+ return;
+ }
+
+ empathy_debug (DEBUG_DOMAIN, "Activating event");
+
+ event_ext = (EmpathyFilterEventExt*) event;
+ if (event_ext->func) {
+ event_ext->func (filter, event_ext->user_data);
+ }
+
+ is_top = (l == priv->events);
+ priv->events = g_slist_delete_link (priv->events, l);
+ if (is_top) {
+ g_object_notify (G_OBJECT (filter), "top-event");
+ }
+
+ filter_event_free (event_ext);
+}
+
+EmpathyFilterEvent *
+empathy_filter_get_top_event (EmpathyFilter *filter)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (filter);
+
+ g_return_val_if_fail (EMPATHY_IS_FILTER (filter), NULL);
+
+ return priv->events ? priv->events->data : NULL;
+}
+
+static void
+filter_chat_dispatch (EmpathyFilter *filter,
+ gpointer user_data)
+{
+ EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (user_data);
+ McAccount *account;
+ EmpathyChat *chat;
+ const gchar *id;
+
+ id = empathy_tp_chat_get_id (tp_chat);
+ account = empathy_tp_chat_get_account (tp_chat);
+ chat = empathy_chat_window_find_chat (account, id);
+
+ if (chat) {
+ empathy_chat_set_tp_chat (chat, tp_chat);
+ } else {
+ chat = empathy_chat_new (tp_chat);
+ }
+
+ empathy_chat_window_present_chat (chat);
+ g_object_unref (tp_chat);
+}
+
+static void
+filter_chat_message_received_cb (EmpathyTpChat *tp_chat,
+ EmpathyMessage *message,
+ EmpathyFilter *filter)
+{
+ EmpathyContact *sender;
+ gchar *msg;
+
+ g_signal_handlers_disconnect_by_func (tp_chat,
+ filter_chat_message_received_cb,
+ filter);
+
+ sender = empathy_message_get_sender (message);
+ msg = g_strdup_printf (_("New message from %s:\n%s"),
+ empathy_contact_get_name (sender),
+ empathy_message_get_body (message));
+
+ filter_emit_event (filter, EMPATHY_IMAGE_NEW_MESSAGE, msg,
+ filter_chat_dispatch, tp_chat);
+
+ g_free (msg);
+}
+
+static void
+filter_chat_handle_channel (EmpathyFilter *filter,
+ TpChannel *channel,
+ gboolean is_incoming)
+{
+ EmpathyTpChat *tp_chat;
+
+ empathy_debug (DEBUG_DOMAIN, "New text channel to be filtered: %p",
+ channel);
+
+ tp_chat = empathy_tp_chat_new (channel, FALSE);
+ if (is_incoming) {
+ filter_chat_dispatch (filter, tp_chat);
+ } else {
+ g_signal_connect (tp_chat, "message-received",
+ G_CALLBACK (filter_chat_message_received_cb),
+ filter);
+ }
+}
+
+static void
+filter_call_dispatch (EmpathyFilter *filter,
+ gpointer user_data)
+{
+ EmpathyTpCall *call = EMPATHY_TP_CALL (user_data);
+
+ empathy_call_window_new (call);
+ g_object_unref (call);
+}
+
+static void
+filter_call_contact_notify_cb (EmpathyTpCall *call,
+ gpointer unused,
+ EmpathyFilter *filter)
+{
+ EmpathyContact *contact;
+ gchar *msg;
+
+ g_object_get (call, "contact", &contact, NULL);
+ if (!contact) {
+ return;
+ }
+
+ empathy_contact_run_until_ready (contact,
+ EMPATHY_CONTACT_READY_NAME,
+ NULL);
+
+ msg = g_strdup_printf (_("Incoming call from %s"),
+ empathy_contact_get_name (contact));
+
+ filter_emit_event (filter, EMPATHY_IMAGE_VOIP, msg,
+ filter_call_dispatch, call);
+
+ g_free (msg);
+ g_object_unref (contact);
+}
+
+static void
+filter_call_handle_channel (EmpathyFilter *filter,
+ TpChannel *channel,
+ gboolean is_incoming)
+{
+ EmpathyTpCall *call;
+
+ empathy_debug (DEBUG_DOMAIN, "New media channel to be filtered: %p",
+ channel);
+
+ call = empathy_tp_call_new (channel);
+ if (is_incoming) {
+ filter_call_dispatch (filter, call);
+ } else {
+ g_signal_connect (call, "notify::contact",
+ G_CALLBACK (filter_call_contact_notify_cb),
+ filter);
+ }
+}
+
+#if 0
+static void
+status_icon_pendings_changed_cb (EmpathyContactManager *manager,
+ EmpathyContact *contact,
+ EmpathyContact *actor,
+ guint reason,
+ gchar *message,
+ gboolean is_pending,
+ EmpathyStatusIcon *icon)
+{
+ EmpathyStatusIconPriv *priv;
+ StatusIconEvent *event;
+ GString *str;
+
+ priv = GET_PRIV (icon);
+
+ if (!is_pending) {
+ /* FIXME: We should remove the event */
+ return;
+ }
+
+ empathy_contact_run_until_ready (contact,
+ EMPATHY_CONTACT_READY_NAME,
+ NULL);
+
+ str = g_string_new (NULL);
+ g_string_printf (str, _("Subscription requested by %s"),
+ empathy_contact_get_name (contact));
+ if (!G_STR_EMPTY (message)) {
+ g_string_append_printf (str, _("\nMessage: %s"), message);
+ }
+
+ event = status_icon_event_new (icon, GTK_STOCK_DIALOG_QUESTION, str->str);
+ event->user_data = g_object_ref (contact);
+ event->func = status_icon_event_subscribe_cb;
+
+ g_string_free (str, TRUE);
+}
+
+static void
+status_icon_event_subscribe_cb (StatusIconEvent *event)
+{
+ EmpathyContact *contact;
+
+ contact = EMPATHY_CONTACT (event->user_data);
+
+ empathy_subscription_dialog_show (contact, NULL);
+
+ g_object_unref (contact);
+}
+ g_signal_connect (priv->manager, "pendings-changed",
+ G_CALLBACK (status_icon_pendings_changed_cb),
+ icon);
+
+ pendings = empathy_contact_list_get_pendings (EMPATHY_CONTACT_LIST (priv->manager));
+ for (l = pendings; l; l = l->next) {
+ EmpathyPendingInfo *info;
+
+ info = l->data;
+ status_icon_pendings_changed_cb (priv->manager,
+ info->member,
+ info->actor,
+ 0,
+ info->message,
+ TRUE,
+ icon);
+ empathy_pending_info_free (info);
+ }
+ g_list_free (pendings);
+#endif
+
+static void
+filter_connection_invalidated_cb (TpConnection *connection,
+ guint domain,
+ gint code,
+ gchar *message,
+ EmpathyFilter *filter)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (filter);
+ GHashTableIter iter;
+ gpointer key, value;
+
+ empathy_debug (DEBUG_DOMAIN, "connection invalidated: %s", message);
+
+ g_hash_table_iter_init (&iter, priv->accounts);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (value == connection) {
+ g_hash_table_remove (priv->accounts, key);
+ break;
+ }
+ }
+}
+
+typedef void (*HandleChannelFunc) (EmpathyFilter *filter,
+ TpChannel *channel,
+ gboolean is_incoming);
+
+static void
+filter_conection_new_channel_cb (TpConnection *connection,
+ const gchar *object_path,
+ const gchar *channel_type,
+ guint handle_type,
+ guint handle,
+ gboolean suppress_handler,
+ gpointer user_data,
+ GObject *filter)
+{
+ HandleChannelFunc func = NULL;
+ TpChannel *channel;
+
+ if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT)) {
+ func = filter_chat_handle_channel;
+ }
+ else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA)) {
+ func = filter_call_handle_channel;
+ } else {
+ empathy_debug (DEBUG_DOMAIN, "Unknown channel type %s",
+ channel_type);
+ return;
+ }
+
+ channel = tp_channel_new (connection, object_path, channel_type,
+ handle_type, handle, NULL);
+ tp_channel_run_until_ready (channel, NULL, NULL);
+
+ /* We abuse of suppress_handler, TRUE means OUTGOING */
+ func (EMPATHY_FILTER (filter), channel, suppress_handler);
+
+ g_object_unref (channel);
+}
+
+static void
+filter_connection_ready_cb (TpConnection *connection,
+ gpointer unused,
+ EmpathyFilter *filter)
+{
+ empathy_debug (DEBUG_DOMAIN, "Connection ready, accepting new channels");
+ tp_cli_connection_connect_to_new_channel (connection,
+ filter_conection_new_channel_cb,
+ NULL, NULL,
+ G_OBJECT (filter), NULL);
+}
+
+static void
+filter_update_account (EmpathyFilter *filter,
+ McAccount *account)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (filter);
+ TpConnection *connection;
+ gboolean ready;
+
+ connection = g_hash_table_lookup (priv->accounts, account);
+ if (connection) {
+ return;
+ }
+
+ connection = mission_control_get_tpconnection (priv->mc, account, NULL);
+ if (!connection) {
+ return;
+ }
+
+ g_hash_table_insert (priv->accounts, g_object_ref (account), connection);
+ g_signal_connect (connection, "invalidated",
+ G_CALLBACK (filter_connection_invalidated_cb),
+ filter);
+
+ g_object_get (connection, "connection-ready", &ready, NULL);
+ if (ready) {
+ filter_connection_ready_cb (connection, NULL, filter);
+ } else {
+ g_signal_connect (connection, "notify::connection-ready",
+ G_CALLBACK (filter_connection_ready_cb),
+ filter);
+ }
+}
+
+static void
+filter_status_changed_cb (MissionControl *mc,
+ TpConnectionStatus status,
+ McPresence presence,
+ TpConnectionStatusReason reason,
+ const gchar *unique_name,
+ EmpathyFilter *filter)
+{
+ McAccount *account;
+
+ account = mc_account_lookup (unique_name);
+ filter_update_account (filter, account);
+ g_object_unref (account);
+}
+
+static void
+filter_finalize (GObject *object)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (object);
+
+ empathy_disconnect_account_status_changed (priv->token);
+ g_object_unref (priv->mc);
+
+ g_slist_foreach (priv->events, (GFunc) filter_event_free, NULL);
+ g_slist_free (priv->events);
+
+ g_hash_table_destroy (priv->accounts);
+}
+
+static void
+filter_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_TOP_EVENT:
+ g_value_set_pointer (value, priv->events ? priv->events->data : NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ };
+}
+
+static void
+empathy_filter_class_init (EmpathyFilterClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = filter_finalize;
+ object_class->get_property = filter_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_TOP_EVENT,
+ g_param_spec_pointer ("top-event",
+ "The top event",
+ "The first event in the events list",
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (object_class, sizeof (EmpathyFilterPriv));
+}
+
+static void
+empathy_filter_init (EmpathyFilter *filter)
+{
+ EmpathyFilterPriv *priv = GET_PRIV (filter);
+ GList *accounts, *l;
+
+ priv->mc = empathy_mission_control_new ();
+ priv->token = empathy_connect_to_account_status_changed (priv->mc,
+ G_CALLBACK (filter_status_changed_cb),
+ filter, NULL);
+
+ priv->accounts = g_hash_table_new_full (empathy_account_hash,
+ empathy_account_equal,
+ g_object_unref,
+ g_object_unref);
+ accounts = mc_accounts_list_by_enabled (TRUE);
+ for (l = accounts; l; l = l->next) {
+ filter_update_account (filter, l->data);
+ g_object_unref (l->data);
+ }
+ g_list_free (accounts);
+}
+
+EmpathyFilter *
+empathy_filter_new (void)
+{
+ static EmpathyFilter *filter = NULL;
+
+ if (!filter) {
+ filter = g_object_new (EMPATHY_TYPE_FILTER, NULL);
+ g_object_add_weak_pointer (G_OBJECT (filter), (gpointer) &filter);
+ } else {
+ g_object_ref (filter);
+ }
+
+ return filter;
+}
+
diff --git a/src/empathy-filter.h b/src/empathy-filter.h
new file mode 100644
index 000000000..bf3c7461f
--- /dev/null
+++ b/src/empathy-filter.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007-2008 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#ifndef __EMPATHY_FILTER_H__
+#define __EMPATHY_FILTER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_FILTER (empathy_filter_get_type ())
+#define EMPATHY_FILTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_FILTER, EmpathyFilter))
+#define EMPATHY_FILTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_FILTER, EmpathyFilterClass))
+#define EMPATHY_IS_FILTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_FILTER))
+#define EMPATHY_IS_FILTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_FILTER))
+#define EMPATHY_FILTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_FILTER, EmpathyFilterClass))
+
+typedef struct _EmpathyFilter EmpathyFilter;
+typedef struct _EmpathyFilterClass EmpathyFilterClass;
+typedef struct _EmpathyFilterPriv EmpathyFilterPriv;
+
+struct _EmpathyFilter {
+ GObject parent;
+};
+
+struct _EmpathyFilterClass {
+ GObjectClass parent_class;
+};
+
+typedef struct {
+ gchar *icon_name;
+ gchar *message;
+} EmpathyFilterEvent;
+
+GType empathy_filter_get_type (void) G_GNUC_CONST;
+EmpathyFilter * empathy_filter_new (void);
+void empathy_filter_activate_event (EmpathyFilter *filter,
+ EmpathyFilterEvent *event);
+EmpathyFilterEvent *empathy_filter_get_top_event (EmpathyFilter *filter);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_FILTER_H__ */
diff --git a/src/empathy-status-icon.c b/src/empathy-status-icon.c
index 18788fb7d..cd086d199 100644
--- a/src/empathy-status-icon.c
+++ b/src/empathy-status-icon.c
@@ -27,18 +27,10 @@
#include <glade/glade.h>
#include <glib/gi18n.h>
-#include <libmissioncontrol/mission-control.h>
-
-#include <libempathy/empathy-contact-list.h>
-#include <libempathy/empathy-contact-manager.h>
-#include <libempathy/empathy-contact.h>
-#include <libempathy/empathy-tp-chat.h>
#include <libempathy/empathy-debug.h>
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-idle.h>
-#include <libempathy/empathy-filter.h>
-#include <libempathy-gtk/empathy-contact-dialogs.h>
#include <libempathy-gtk/empathy-presence-chooser.h>
#include <libempathy-gtk/empathy-conf.h>
#include <libempathy-gtk/empathy-ui-utils.h>
@@ -48,7 +40,7 @@
#include "empathy-status-icon.h"
#include "empathy-preferences.h"
-
+#include "empathy-filter.h"
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIconPriv))
@@ -61,88 +53,52 @@
typedef struct _StatusIconEvent StatusIconEvent;
struct _EmpathyStatusIconPriv {
- GtkStatusIcon *icon;
- EmpathyContactManager *manager;
- EmpathyFilter *text_filter;
- EmpathyFilter *call_filter;
- EmpathyIdle *idle;
- MissionControl *mc;
- GList *events;
- gboolean showing_event_icon;
- StatusIconEvent *flash_state_event;
- guint blink_timeout;
-
- GtkWindow *window;
- GtkWidget *popup_menu;
- GtkWidget *show_window_item;
- GtkWidget *message_item;
- GtkWidget *status_item;
+ GtkStatusIcon *icon;
+ EmpathyIdle *idle;
+ EmpathyFilter *filter;
+ EmpathyFilterEvent *event;
+ gboolean showing_event_icon;
+ guint blink_timeout;
+
+ GtkWindow *window;
+ GtkWidget *popup_menu;
+ GtkWidget *show_window_item;
+ GtkWidget *message_item;
+ GtkWidget *status_item;
};
-typedef void (*EventActivatedFunc) (StatusIconEvent *event);
+G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
-struct _StatusIconEvent {
- gchar *icon_name;
- gchar *message;
- EventActivatedFunc func;
- gpointer user_data;
-};
+static void
+status_icon_set_visibility (EmpathyStatusIcon *icon,
+ gboolean visible,
+ gboolean store)
+{
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+ if (store) {
+ empathy_conf_set_bool (empathy_conf_get (),
+ EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, !visible);
+ }
-static void empathy_status_icon_class_init (EmpathyStatusIconClass *klass);
-static void empathy_status_icon_init (EmpathyStatusIcon *icon);
-static void status_icon_finalize (GObject *object);
-static void status_icon_text_filter_new_channel (EmpathyFilter *filter,
- TpChannel *channel,
- EmpathyStatusIcon *icon);
-static void status_icon_call_filter_new_channel (EmpathyFilter *filter,
- TpChannel *channel,
- EmpathyStatusIcon *icon);
-static void status_icon_message_received_cb (EmpathyTpChat *tp_chat,
- EmpathyMessage *message,
- EmpathyStatusIcon *icon);
-static void status_icon_idle_notify_cb (EmpathyStatusIcon *icon);
-static void status_icon_update_tooltip (EmpathyStatusIcon *icon);
-static void status_icon_set_from_state (EmpathyStatusIcon *icon);
-static void status_icon_set_visibility (EmpathyStatusIcon *icon,
- gboolean visible,
- gboolean store);
-static void status_icon_toggle_visibility (EmpathyStatusIcon *icon);
-static void status_icon_activate_cb (GtkStatusIcon *status_icon,
- EmpathyStatusIcon *icon);
-static gboolean status_icon_delete_event_cb (GtkWidget *widget,
- GdkEvent *event,
- EmpathyStatusIcon *icon);
-static void status_icon_popup_menu_cb (GtkStatusIcon *status_icon,
- guint button,
- guint activate_time,
- EmpathyStatusIcon *icon);
-static void status_icon_create_menu (EmpathyStatusIcon *icon);
-static void status_icon_new_message_cb (GtkWidget *widget,
- EmpathyStatusIcon *icon);
-static void status_icon_quit_cb (GtkWidget *window,
- EmpathyStatusIcon *icon);
-static void status_icon_show_hide_window_cb (GtkWidget *widget,
- EmpathyStatusIcon *icon);
-static void status_icon_pendings_changed_cb (EmpathyContactManager *manager,
- EmpathyContact *contact,
- EmpathyContact *actor,
- guint reason,
- gchar *message,
- gboolean is_pending,
- EmpathyStatusIcon *icon);
-static void status_icon_event_subscribe_cb (StatusIconEvent *event);
-static void status_icon_event_flash_state_cb (StatusIconEvent *event);
-static void status_icon_event_msg_cb (StatusIconEvent *event);
-static StatusIconEvent * status_icon_event_new (EmpathyStatusIcon *icon,
- const gchar *icon_name,
- const gchar *message);
-static void status_icon_event_remove (EmpathyStatusIcon *icon,
- StatusIconEvent *event);
-static gboolean status_icon_event_timeout_cb (EmpathyStatusIcon *icon);
-static void status_icon_event_free (StatusIconEvent *event);
+ if (!visible) {
+ empathy_window_iconify (priv->window, priv->icon);
+ } else {
+ GList *accounts;
-G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
+ empathy_window_present (GTK_WINDOW (priv->window), TRUE);
+
+ /* Show the accounts dialog if there is no enabled accounts */
+ accounts = mc_accounts_list_by_enabled (TRUE);
+ if (accounts) {
+ mc_accounts_list_free (accounts);
+ } else {
+ empathy_debug (DEBUG_DOMAIN,
+ "No enabled account, Showing account dialog");
+ empathy_accounts_dialog_show (GTK_WINDOW (priv->window));
+ }
+ }
+}
static void
status_icon_notify_visibility_cb (EmpathyConf *conf,
@@ -158,389 +114,112 @@ status_icon_notify_visibility_cb (EmpathyConf *conf,
}
static void
-empathy_status_icon_class_init (EmpathyStatusIconClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = status_icon_finalize;
-
- g_type_class_add_private (object_class, sizeof (EmpathyStatusIconPriv));
-}
-
-static void
-empathy_status_icon_init (EmpathyStatusIcon *icon)
+status_icon_toggle_visibility (EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
- GList *pendings, *l;
-
- priv = GET_PRIV (icon);
-
- priv->icon = gtk_status_icon_new ();
- priv->manager = empathy_contact_manager_new ();
- priv->mc = empathy_mission_control_new ();
- priv->text_filter = empathy_filter_new ("org.gnome.Empathy.ChatFilter",
- "/org/gnome/Empathy/ChatFilter",
- TP_IFACE_CHANNEL_TYPE_TEXT,
- MC_FILTER_PRIORITY_DIALOG,
- MC_FILTER_FLAG_INCOMING);
- priv->call_filter = empathy_filter_new ("org.gnome.Empathy.CallFilter",
- "/org/gnome/Empathy/CallFilter",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
- MC_FILTER_PRIORITY_DIALOG,
- MC_FILTER_FLAG_INCOMING);
-
- priv->idle = empathy_idle_new ();
-
- /* make icon listen and respond to MAIN_WINDOW_HIDDEN changes */
- empathy_conf_notify_add (empathy_conf_get (),
- EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
- status_icon_notify_visibility_cb,
- icon);
-
- status_icon_create_menu (icon);
- status_icon_idle_notify_cb (icon);
-
- g_signal_connect (priv->text_filter, "new-channel",
- G_CALLBACK (status_icon_text_filter_new_channel),
- icon);
- g_signal_connect (priv->call_filter, "new-channel",
- G_CALLBACK (status_icon_call_filter_new_channel),
- icon);
- g_signal_connect_swapped (priv->idle, "notify",
- G_CALLBACK (status_icon_idle_notify_cb),
- icon);
- g_signal_connect (priv->icon, "activate",
- G_CALLBACK (status_icon_activate_cb),
- icon);
- g_signal_connect (priv->icon, "popup-menu",
- G_CALLBACK (status_icon_popup_menu_cb),
- icon);
- g_signal_connect (priv->manager, "pendings-changed",
- G_CALLBACK (status_icon_pendings_changed_cb),
- icon);
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+ gboolean visible;
- pendings = empathy_contact_list_get_pendings (EMPATHY_CONTACT_LIST (priv->manager));
- for (l = pendings; l; l = l->next) {
- EmpathyPendingInfo *info;
-
- info = l->data;
- status_icon_pendings_changed_cb (priv->manager,
- info->member,
- info->actor,
- 0,
- info->message,
- TRUE,
- icon);
- empathy_pending_info_free (info);
- }
- g_list_free (pendings);
+ visible = gtk_window_is_active (priv->window);
+ status_icon_set_visibility (icon, !visible, TRUE);
}
static void
-status_icon_finalize (GObject *object)
+status_icon_update_tooltip (EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
-
- priv = GET_PRIV (object);
-
- g_list_foreach (priv->events, (GFunc) status_icon_event_free, NULL);
- g_list_free (priv->events);
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+ const gchar *tooltip = NULL;
- if (priv->blink_timeout) {
- g_source_remove (priv->blink_timeout);
+ if (priv->event) {
+ tooltip = priv->event->message;
}
- g_object_unref (priv->icon);
- g_object_unref (priv->window);
- g_object_unref (priv->idle);
- g_object_unref (priv->manager);
- g_object_unref (priv->mc);
- g_object_unref (priv->text_filter);
- g_object_unref (priv->call_filter);
-}
-
-EmpathyStatusIcon *
-empathy_status_icon_new (GtkWindow *window)
-{
- EmpathyStatusIconPriv *priv;
- EmpathyStatusIcon *icon;
- gboolean should_hide;
-
- g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
-
- icon = g_object_new (EMPATHY_TYPE_STATUS_ICON, NULL);
- priv = GET_PRIV (icon);
-
- priv->window = g_object_ref (window);
-
- g_signal_connect (priv->window, "delete-event",
- G_CALLBACK (status_icon_delete_event_cb),
- icon);
-
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
- &should_hide);
-
- if (gtk_window_is_active (priv->window) == should_hide) {
- status_icon_set_visibility (icon, !should_hide, FALSE);
+ if (!tooltip) {
+ tooltip = empathy_idle_get_status (priv->idle);
}
- return icon;
-}
-
-static void
-status_icon_text_filter_new_channel (EmpathyFilter *filter,
- TpChannel *channel,
- EmpathyStatusIcon *icon)
-{
- EmpathyTpChat *tp_chat;
-
- empathy_debug (DEBUG_DOMAIN, "New text channel to be filtered for contact %p",
- channel);
-
- tp_chat = empathy_tp_chat_new (channel, FALSE);
- g_object_set_data (G_OBJECT (tp_chat), "filter", filter);
- g_object_set_data (G_OBJECT (tp_chat), "channel", channel);
-
- g_signal_connect (tp_chat, "message-received",
- G_CALLBACK (status_icon_message_received_cb),
- icon);
-}
-
-static void
-status_icon_message_received_cb (EmpathyTpChat *tp_chat,
- EmpathyMessage *message,
- EmpathyStatusIcon *icon)
-{
- EmpathyContact *sender;
- gchar *msg;
- StatusIconEvent *event;
-
- empathy_debug (DEBUG_DOMAIN, "Message received, add event");
-
- g_signal_handlers_disconnect_by_func (tp_chat,
- status_icon_message_received_cb,
- icon);
-
- sender = empathy_message_get_sender (message);
- msg = g_strdup_printf (_("New message from %s:\n%s"),
- empathy_contact_get_name (sender),
- empathy_message_get_body (message));
-
- event = status_icon_event_new (icon, EMPATHY_IMAGE_NEW_MESSAGE, msg);
- event->func = status_icon_event_msg_cb;
- event->user_data = tp_chat;
- g_free (msg);
+ gtk_status_icon_set_tooltip (priv->icon, tooltip);
}
static void
-status_icon_event_call_cb (StatusIconEvent *event)
+status_icon_update_icon (EmpathyStatusIcon *icon)
{
- EmpathyTpGroup *group;
- EmpathyFilter *filter;
- TpChannel *channel;
-
- empathy_debug (DEBUG_DOMAIN, "Dispatching call channel");
-
- group = event->user_data;
- filter = g_object_get_data (G_OBJECT (group), "filter");
- channel = g_object_get_data (G_OBJECT (group), "channel");
- empathy_filter_process (filter, channel, TRUE);
- g_object_unref (group);
-}
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+ const gchar *icon_name;
-static void
-status_icon_call_filter_new_channel (EmpathyFilter *filter,
- TpChannel *channel,
- EmpathyStatusIcon *icon)
-{
- EmpathyTpGroup *group;
- EmpathyPendingInfo *invitation;
- EmpathyContact *contact = NULL;
-
- empathy_debug (DEBUG_DOMAIN, "New media channel to be filtered");
-
- /* FIXME: We have to check if the user is member or local-pending to
- * know if it's an incoming or outgoing call because of the way we
- * request media channels MC can't know if it's incoming or outgoing */
- group = empathy_tp_group_new (channel);
- empathy_run_until_ready (group);
-
- invitation = empathy_tp_group_get_invitation (group, &contact);
- if (!invitation) {
- empathy_debug (DEBUG_DOMAIN, "Process OUTGOING call channel");
- empathy_filter_process (filter, channel, TRUE);
+ if (priv->event && priv->showing_event_icon) {
+ icon_name = priv->event->icon_name;
} else {
- StatusIconEvent *event;
- gchar *msg;
-
- /* We are local pending, it's an incoming call, we need to ask
- * the user if he wants to accept the call. */
- empathy_contact_run_until_ready (contact,
- EMPATHY_CONTACT_READY_NAME,
- NULL);
-
- empathy_debug (DEBUG_DOMAIN, "INCOMING call, add event");
-
- msg = g_strdup_printf (_("Incoming call from %s:\n%s"),
- empathy_contact_get_name (contact),
- invitation->message);
-
- g_object_set_data (G_OBJECT (group), "filter", filter);
- g_object_set_data (G_OBJECT (group), "channel", channel);
- event = status_icon_event_new (icon, EMPATHY_IMAGE_VOIP, msg);
- event->func = status_icon_event_call_cb;
- event->user_data = group;
- g_free (msg);
- }
+ McPresence state;
- if (contact) {
- g_object_unref (contact);
+ state = empathy_idle_get_state (priv->idle);
+ icon_name = empathy_icon_name_for_presence (state);
}
+
+ gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
}
static void
status_icon_idle_notify_cb (EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
- McPresence flash_state;
-
- priv = GET_PRIV (icon);
-
- flash_state = empathy_idle_get_flash_state (priv->idle);
- if (flash_state != MC_PRESENCE_UNSET) {
- const gchar *icon_name;
-
- icon_name = empathy_icon_name_for_presence (flash_state);
- if (!priv->flash_state_event) {
- /* We are now flashing */
- priv->flash_state_event = status_icon_event_new (icon, icon_name, NULL);
- priv->flash_state_event->user_data = icon;
- priv->flash_state_event->func = status_icon_event_flash_state_cb;
- } else {
- /* We are still flashing but with another state */
- g_free (priv->flash_state_event->icon_name);
- priv->flash_state_event->icon_name = g_strdup (icon_name);
- }
- }
- else if (priv->flash_state_event) {
- /* We are no more flashing */
- status_icon_event_remove (icon, priv->flash_state_event);
- priv->flash_state_event = NULL;
- }
-
- if (!priv->showing_event_icon) {
- status_icon_set_from_state (icon);
- }
-
+ status_icon_update_icon (icon);
status_icon_update_tooltip (icon);
}
-static void
-status_icon_update_tooltip (EmpathyStatusIcon *icon)
-{
- EmpathyStatusIconPriv *priv;
- const gchar *tooltip = NULL;
-
- priv = GET_PRIV (icon);
-
- if (priv->events) {
- StatusIconEvent *event;
-
- event = priv->events->data;
- tooltip = event->message;
- }
-
- if (!tooltip) {
- tooltip = empathy_idle_get_status (priv->idle);
- }
-
- gtk_status_icon_set_tooltip (priv->icon, tooltip);
-}
-
-static void
-status_icon_set_from_state (EmpathyStatusIcon *icon)
+static gboolean
+status_icon_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
- McPresence state;
- const gchar *icon_name;
-
- priv = GET_PRIV (icon);
-
- state = empathy_idle_get_state (priv->idle);
- icon_name = empathy_icon_name_for_presence (state);
- gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
+ status_icon_set_visibility (icon, FALSE, TRUE);
+ return TRUE;
}
static void
-status_icon_set_visibility (EmpathyStatusIcon *icon,
- gboolean visible,
- gboolean store)
+status_icon_activate_cb (GtkStatusIcon *status_icon,
+ EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
-
- priv = GET_PRIV (icon);
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
- if (store) {
- empathy_conf_set_bool (empathy_conf_get (),
- EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, !visible);
- }
+ empathy_debug (DEBUG_DOMAIN, "Activated: %s",
+ priv->event ? "event" : "toggle");
- if (!visible) {
- empathy_window_iconify (priv->window, priv->icon);
- } else {
- GList *accounts;
+ if (priv->event) {
+ empathy_filter_activate_event (priv->filter, priv->event);
+ priv->event = empathy_filter_get_top_event (priv->filter);
+ status_icon_update_tooltip (icon);
+ status_icon_update_icon (icon);
- empathy_window_present (GTK_WINDOW (priv->window), TRUE);
-
- /* Show the accounts dialog if there is no enabled accounts */
- accounts = mc_accounts_list_by_enabled (TRUE);
- if (accounts) {
- mc_accounts_list_free (accounts);
- } else {
- empathy_debug (DEBUG_DOMAIN,
- "No enabled account, Showing account dialog");
- empathy_accounts_dialog_show (GTK_WINDOW (priv->window));
+ if (!priv->event && priv->blink_timeout) {
+ g_source_remove (priv->blink_timeout);
+ priv->blink_timeout = 0;
}
+ } else {
+ status_icon_toggle_visibility (icon);
}
}
static void
-status_icon_toggle_visibility (EmpathyStatusIcon *icon)
+status_icon_show_hide_window_cb (GtkWidget *widget,
+ EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv = GET_PRIV (icon);
- gboolean visible;
+ gboolean visible;
- visible = gtk_window_is_active (priv->window);
- status_icon_set_visibility (icon, !visible, TRUE);
+ visible = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
+ status_icon_set_visibility (icon, visible, TRUE);
}
static void
-status_icon_activate_cb (GtkStatusIcon *status_icon,
- EmpathyStatusIcon *icon)
+status_icon_new_message_cb (GtkWidget *widget,
+ EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
-
- priv = GET_PRIV (icon);
-
- empathy_debug (DEBUG_DOMAIN, "Activated: %s",
- priv->events ? "event" : "toggle");
-
- if (priv->events) {
- status_icon_event_remove (icon, priv->events->data);
- } else {
- status_icon_toggle_visibility (icon);
- }
+ empathy_new_message_dialog_show (NULL);
}
-static gboolean
-status_icon_delete_event_cb (GtkWidget *widget,
- GdkEvent *event,
- EmpathyStatusIcon *icon)
+static void
+status_icon_quit_cb (GtkWidget *window,
+ EmpathyStatusIcon *icon)
{
- status_icon_set_visibility (icon, FALSE, TRUE);
-
- return TRUE;
+ gtk_main_quit ();
}
static void
@@ -549,12 +228,10 @@ status_icon_popup_menu_cb (GtkStatusIcon *status_icon,
guint activate_time,
EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
GtkWidget *submenu;
gboolean show;
- priv = GET_PRIV (icon);
-
show = empathy_window_get_is_visible (GTK_WINDOW (priv->window));
g_signal_handlers_block_by_func (priv->show_window_item,
@@ -581,12 +258,10 @@ status_icon_popup_menu_cb (GtkStatusIcon *status_icon,
static void
status_icon_create_menu (EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
GladeXML *glade;
gchar *filename;
- priv = GET_PRIV (icon);
-
filename = empathy_file_lookup ("empathy-status-icon.glade", "src");
glade = empathy_glade_get_file (filename,
"tray_menu",
@@ -608,191 +283,116 @@ status_icon_create_menu (EmpathyStatusIcon *icon)
g_object_unref (glade);
}
-static void
-status_icon_new_message_cb (GtkWidget *widget,
- EmpathyStatusIcon *icon)
+static gboolean
+status_icon_blink_timeout_cb (EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
- priv = GET_PRIV (icon);
+ priv->showing_event_icon = !priv->showing_event_icon;
+ status_icon_update_icon (icon);
- empathy_new_message_dialog_show (NULL);
+ return TRUE;
}
static void
-status_icon_quit_cb (GtkWidget *window,
- EmpathyStatusIcon *icon)
+status_icon_top_event_notify_cb (EmpathyStatusIcon *icon)
{
- gtk_main_quit ();
-}
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-static void
-status_icon_show_hide_window_cb (GtkWidget *widget,
- EmpathyStatusIcon *icon)
-{
- gboolean visible;
+ priv->event = empathy_filter_get_top_event (priv->filter);
+ priv->showing_event_icon = priv->event != NULL;
+ status_icon_update_icon (icon);
+ status_icon_update_tooltip (icon);
- visible = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
- status_icon_set_visibility (icon, visible, TRUE);
+ if (!priv->blink_timeout) {
+ priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT,
+ (GSourceFunc) status_icon_blink_timeout_cb,
+ icon);
+ }
}
static void
-status_icon_pendings_changed_cb (EmpathyContactManager *manager,
- EmpathyContact *contact,
- EmpathyContact *actor,
- guint reason,
- gchar *message,
- gboolean is_pending,
- EmpathyStatusIcon *icon)
+status_icon_finalize (GObject *object)
{
- EmpathyStatusIconPriv *priv;
- StatusIconEvent *event;
- GString *str;
-
- priv = GET_PRIV (icon);
-
- if (!is_pending) {
- /* FIXME: We should remove the event */
- return;
- }
+ EmpathyStatusIconPriv *priv = GET_PRIV (object);
- empathy_contact_run_until_ready (contact,
- EMPATHY_CONTACT_READY_NAME,
- NULL);
-
- str = g_string_new (NULL);
- g_string_printf (str, _("Subscription requested by %s"),
- empathy_contact_get_name (contact));
- if (!G_STR_EMPTY (message)) {
- g_string_append_printf (str, _("\nMessage: %s"), message);
+ if (priv->blink_timeout) {
+ g_source_remove (priv->blink_timeout);
}
- event = status_icon_event_new (icon, GTK_STOCK_DIALOG_QUESTION, str->str);
- event->user_data = g_object_ref (contact);
- event->func = status_icon_event_subscribe_cb;
-
- g_string_free (str, TRUE);
+ g_object_unref (priv->icon);
+ g_object_unref (priv->idle);
+ g_object_unref (priv->filter);
}
static void
-status_icon_event_subscribe_cb (StatusIconEvent *event)
+empathy_status_icon_class_init (EmpathyStatusIconClass *klass)
{
- EmpathyContact *contact;
-
- contact = EMPATHY_CONTACT (event->user_data);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- empathy_subscription_dialog_show (contact, NULL);
+ object_class->finalize = status_icon_finalize;
- g_object_unref (contact);
+ g_type_class_add_private (object_class, sizeof (EmpathyStatusIconPriv));
}
static void
-status_icon_event_flash_state_cb (StatusIconEvent *event)
+empathy_status_icon_init (EmpathyStatusIcon *icon)
{
- EmpathyStatusIconPriv *priv;
-
- priv = GET_PRIV (event->user_data);
-
- empathy_idle_set_flash_state (priv->idle, MC_PRESENCE_UNSET);
-}
+ EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-static void
-status_icon_event_msg_cb (StatusIconEvent *event)
-{
- EmpathyFilter *filter;
- EmpathyTpChat *tp_chat;
- TpChannel *channel;
+ priv->icon = gtk_status_icon_new ();
+ priv->idle = empathy_idle_new ();
+ priv->filter = empathy_filter_new ();
- empathy_debug (DEBUG_DOMAIN, "Dispatching text channel");
+ /* make icon listen and respond to MAIN_WINDOW_HIDDEN changes */
+ empathy_conf_notify_add (empathy_conf_get (),
+ EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
+ status_icon_notify_visibility_cb,
+ icon);
- tp_chat = event->user_data;
- filter = g_object_get_data (G_OBJECT (tp_chat), "filter");
- channel = g_object_get_data (G_OBJECT (tp_chat), "channel");
- empathy_filter_process (filter, channel, TRUE);
+ status_icon_create_menu (icon);
+ status_icon_idle_notify_cb (icon);
- g_object_unref (tp_chat);
+ g_signal_connect_swapped (priv->idle, "notify",
+ G_CALLBACK (status_icon_idle_notify_cb),
+ icon);
+ g_signal_connect_swapped (priv->filter, "notify::top-event",
+ G_CALLBACK (status_icon_top_event_notify_cb),
+ icon);
+ g_signal_connect (priv->icon, "activate",
+ G_CALLBACK (status_icon_activate_cb),
+ icon);
+ g_signal_connect (priv->icon, "popup-menu",
+ G_CALLBACK (status_icon_popup_menu_cb),
+ icon);
}
-static StatusIconEvent *
-status_icon_event_new (EmpathyStatusIcon *icon,
- const gchar *icon_name,
- const gchar *message)
+EmpathyStatusIcon *
+empathy_status_icon_new (GtkWindow *window)
{
EmpathyStatusIconPriv *priv;
- StatusIconEvent *event;
-
- priv = GET_PRIV (icon);
-
- event = g_slice_new0 (StatusIconEvent);
- event->icon_name = g_strdup (icon_name);
- event->message = g_strdup (message);
-
- priv->events = g_list_append (priv->events, event);
- if (!priv->blink_timeout) {
- priv->showing_event_icon = FALSE;
- priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT,
- (GSourceFunc) status_icon_event_timeout_cb,
- icon);
- status_icon_event_timeout_cb (icon);
- status_icon_update_tooltip (icon);
- }
-
- return event;
-}
+ EmpathyStatusIcon *icon;
+ gboolean should_hide;
-static void
-status_icon_event_remove (EmpathyStatusIcon *icon,
- StatusIconEvent *event)
-{
- EmpathyStatusIconPriv *priv;
+ g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+ icon = g_object_new (EMPATHY_TYPE_STATUS_ICON, NULL);
priv = GET_PRIV (icon);
- if (event->func) {
- event->func (event);
- }
- priv->events = g_list_remove (priv->events, event);
- status_icon_event_free (event);
- priv->showing_event_icon = FALSE;
- status_icon_update_tooltip (icon);
- status_icon_set_from_state (icon);
-
- if (priv->events) {
- return;
- }
-
- if (priv->blink_timeout) {
- g_source_remove (priv->blink_timeout);
- priv->blink_timeout = 0;
- }
-}
-
-static gboolean
-status_icon_event_timeout_cb (EmpathyStatusIcon *icon)
-{
- EmpathyStatusIconPriv *priv;
-
- priv = GET_PRIV (icon);
+ priv->window = g_object_ref (window);
- priv->showing_event_icon = !priv->showing_event_icon;
+ g_signal_connect (priv->window, "delete-event",
+ G_CALLBACK (status_icon_delete_event_cb),
+ icon);
- if (!priv->showing_event_icon) {
- status_icon_set_from_state (icon);
- } else {
- StatusIconEvent *event;
+ empathy_conf_get_bool (empathy_conf_get (),
+ EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN,
+ &should_hide);
- event = priv->events->data;
- gtk_status_icon_set_from_icon_name (priv->icon, event->icon_name);
+ if (gtk_window_is_active (priv->window) == should_hide) {
+ status_icon_set_visibility (icon, !should_hide, FALSE);
}
- return TRUE;
-}
-
-static void
-status_icon_event_free (StatusIconEvent *event)
-{
- g_free (event->icon_name);
- g_free (event->message);
- g_slice_free (StatusIconEvent, event);
+ return icon;
}
diff --git a/src/empathy.c b/src/empathy.c
index 11eb3c5d7..b55cc7bc2 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -33,92 +33,24 @@
#include <libebook/e-book.h>
#include <telepathy-glib/util.h>
-#include <telepathy-glib/channel.h>
-#include <telepathy-glib/connection.h>
#include <libmissioncontrol/mc-account.h>
#include <libmissioncontrol/mission-control.h>
#include <libempathy/empathy-idle.h>
-#include <libempathy/empathy-tp-chat.h>
-#include <libempathy/empathy-chandler.h>
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-debug.h>
#include <libempathy-gtk/empathy-conf.h>
-#include <libempathy-gtk/empathy-chat.h>
#include "empathy-main-window.h"
#include "empathy-status-icon.h"
-#include "empathy-chat-window.h"
#include "bacon-message-connection.h"
#define DEBUG_DOMAIN "EmpathyMain"
-#define BUS_NAME "org.gnome.Empathy.ChatChandler"
-#define OBJECT_PATH "/org/gnome/Empathy/ChatChandler"
static BaconMessageConnection *connection = NULL;
static void
-new_text_channel_cb (EmpathyChandler *chandler,
- TpChannel *channel,
- MissionControl *mc)
-{
- EmpathyTpChat *tp_chat;
- TpConnection *connection;
- guint handle_type;
- guint handle;
- gchar **names;
- McAccount *account;
- EmpathyChat *chat;
- gchar *id;
- GArray *handles;
-
- g_object_get (channel,
- "connection", &connection,
- "handle-type", &handle_type,
- "handle", &handle,
- NULL);
- handles = g_array_new (FALSE, FALSE, sizeof (guint));
- g_array_append_val (handles, handle);
- tp_cli_connection_run_inspect_handles (connection, -1,
- handle_type, handles,
- &names,
- NULL, NULL);
- id = *names;
- g_free (names);
- g_object_unref (connection);
- g_array_free (handles, TRUE);
-
- account = empathy_channel_get_account (channel);
- chat = empathy_chat_window_find_chat (account, id);
- g_free (id);
-
- if (chat) {
- /* The chat already exists */
- if (!empathy_chat_get_tp_chat (chat)) {
- /* The chat died, give him the new text channel */
- tp_chat = empathy_tp_chat_new (channel, TRUE);
- empathy_run_until_ready (tp_chat);
- empathy_chat_set_tp_chat (chat, tp_chat);
- g_object_unref (tp_chat);
- }
- empathy_chat_window_present_chat (chat);
-
- g_object_unref (account);
- return;
- }
-
- tp_chat = empathy_tp_chat_new (channel, TRUE);
- empathy_run_until_ready (tp_chat);
-
- chat = empathy_chat_new (tp_chat);
- empathy_chat_window_present_chat (chat);
-
- g_object_unref (account);
- g_object_unref (tp_chat);
-}
-
-static void
service_ended_cb (MissionControl *mc,
gpointer user_data)
{
@@ -374,7 +306,6 @@ main (int argc, char *argv[])
GtkWidget *window;
MissionControl *mc;
EmpathyIdle *idle;
- EmpathyChandler *chandler;
gboolean autoconnect = TRUE;
gboolean no_connect = FALSE;
GError *error = NULL;
@@ -470,18 +401,10 @@ main (int argc, char *argv[])
window);
}
- /* Handle text channels */
- chandler = empathy_chandler_new (BUS_NAME, OBJECT_PATH);
- g_signal_connect (chandler, "new-channel",
- G_CALLBACK (new_text_channel_cb),
- mc);
- empathy_debug (DEBUG_DOMAIN, "Ready to handle new text channels");
-
gtk_main ();
empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);
- g_object_unref (chandler);
g_object_unref (mc);
g_object_unref (idle);
g_object_unref (icon);
diff --git a/src/org.gnome.Empathy.Call.service.in b/src/org.gnome.Empathy.Call.service.in
deleted file mode 100644
index 1c4b95fb4..000000000
--- a/src/org.gnome.Empathy.Call.service.in
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.gnome.Empathy.CallChandler
-Exec=@libexecdir@/empathy-call-chandler
diff --git a/src/org.gnome.Empathy.Chat.service.in b/src/org.gnome.Empathy.Chat.service.in
deleted file mode 100644
index 2e614d9a2..000000000
--- a/src/org.gnome.Empathy.Chat.service.in
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.gnome.Empathy.ChatChandler
-Exec=@bindir@/empathy