aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am37
-rw-r--r--src/empathy-about-dialog.c7
-rw-r--r--src/empathy-about-dialog.h6
-rw-r--r--src/empathy-accounts-dialog.c24
-rw-r--r--src/empathy-accounts-dialog.h6
-rw-r--r--src/empathy-call-window-fullscreen.c294
-rw-r--r--src/empathy-call-window-fullscreen.h77
-rw-r--r--src/empathy-call-window-fullscreen.ui23
-rw-r--r--src/empathy-call-window.c491
-rw-r--r--src/empathy-call-window.h7
-rw-r--r--src/empathy-call-window.ui11
-rw-r--r--src/empathy-chat-window.c175
-rw-r--r--src/empathy-chat-window.h6
-rw-r--r--src/empathy-chat-window.ui14
-rw-r--r--src/empathy-chatrooms-window.c16
-rw-r--r--src/empathy-chatrooms-window.h4
-rw-r--r--src/empathy-event-manager.c68
-rw-r--r--src/empathy-ft-manager.c1388
-rw-r--r--src/empathy-ft-manager.h46
-rw-r--r--src/empathy-import-dialog.c8
-rw-r--r--src/empathy-import-dialog.h4
-rw-r--r--src/empathy-import-pidgin.c6
-rw-r--r--src/empathy-import-pidgin.h4
-rw-r--r--src/empathy-logs.c6
-rw-r--r--src/empathy-main-window.c89
-rw-r--r--src/empathy-main-window.h6
-rw-r--r--src/empathy-main-window.ui41
-rw-r--r--src/empathy-map-view.c296
-rw-r--r--src/empathy-map-view.h32
-rw-r--r--src/empathy-map-view.ui59
-rw-r--r--src/empathy-misc.c6
-rw-r--r--src/empathy-misc.h6
-rw-r--r--src/empathy-new-chatroom-dialog.c76
-rw-r--r--src/empathy-new-chatroom-dialog.h6
-rw-r--r--src/empathy-new-chatroom-dialog.ui134
-rw-r--r--src/empathy-preferences.c64
-rw-r--r--src/empathy-preferences.h4
-rw-r--r--src/empathy-preferences.ui206
-rw-r--r--src/empathy-sidebar.c16
-rw-r--r--src/empathy-sidebar.h8
-rw-r--r--src/empathy-status-icon.c7
-rw-r--r--src/empathy-tube-dispatch.c10
-rw-r--r--src/empathy-tube-dispatch.h4
-rw-r--r--src/empathy.c106
-rw-r--r--src/ephy-spinner.c6
45 files changed, 2918 insertions, 992 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b776396aa..081b6f4f2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,16 +1,20 @@
+include $(top_srcdir)/tools/shave.mk
+
AM_CPPFLAGS = \
-I$(top_srcdir) \
$(EMPATHY_CFLAGS) \
$(LIBNOTIFY_CFLAGS) \
- $(WARN_CFLAGS) \
+ $(LIBCHAMPLAIN_CFLAGS) \
$(DISABLE_DEPRECATED)
+ $(WARN_CFLAGS)
LDADD = \
$(top_builddir)/libempathy-gtk/libempathy-gtk.la \
$(top_builddir)/libempathy/libempathy.la \
$(top_builddir)/extensions/libemp-extensions.la \
$(LIBNOTIFY_LIBS) \
- $(EMPATHY_LIBS)
+ $(EMPATHY_LIBS) \
+ $(LIBCHAMPLAIN_LIBS)
bin_PROGRAMS = \
empathy \
@@ -20,12 +24,12 @@ BUILT_SOURCES= \
empathy-tube-dispatch-enumtypes.h \
empathy-tube-dispatch-enumtypes.c
-empathy_SOURCES = \
- bacon-message-connection.c bacon-message-connection.h \
+empathy_handwritten_source = \
empathy.c \
empathy-about-dialog.c empathy-about-dialog.h \
empathy-accounts-dialog.c empathy-accounts-dialog.h \
empathy-call-window.c empathy-call-window.h \
+ empathy-call-window-fullscreen.c empathy-call-window-fullscreen.h \
empathy-chatrooms-window.c empathy-chatrooms-window.h \
empathy-debug-dialog.c empathy-debug-dialog.h \
empathy-chat-window.c empathy-chat-window.h \
@@ -39,17 +43,28 @@ empathy_SOURCES = \
empathy-preferences.c empathy-preferences.h \
empathy-sidebar.c empathy-sidebar.h \
empathy-status-icon.c empathy-status-icon.h \
- empathy-tube-dispatch.c empathy-tube-dispatch.h \
+ empathy-tube-dispatch.c empathy-tube-dispatch.h
+
+empathy_SOURCES = \
+ $(empathy_handwritten_source) \
+ bacon-message-connection.c bacon-message-connection.h \
ephy-spinner.c ephy-spinner.h
nodist_empathy_SOURCES = $(BUILT_SOURCES)
empathy_logs_SOURCES = empathy-logs.c
+check_c_sources = \
+ $(empathy_handwritten_source) \
+ $(empathy_logs_SOURCES)
+include $(top_srcdir)/tools/check-coding-style.mk
+check-local: check-coding-style
+
uidir = $(datadir)/empathy
ui_DATA = \
empathy-accounts-dialog.ui \
empathy-call-window.ui \
+ empathy-call-window-fullscreen.ui \
empathy-chatrooms-window.ui \
empathy-chat-window.ui \
empathy-ft-manager.ui \
@@ -59,12 +74,20 @@ ui_DATA = \
empathy-preferences.ui \
empathy-status-icon.ui
+if HAVE_LIBCHAMPLAIN
+empathy_SOURCES += \
+ empathy-map-view.c empathy-map-view.h
+
+ui_DATA += \
+ empathy-map-view.ui
+endif
+
dist_man_MANS = \
empathy.1
# rules for making the glib enum objects
%-enumtypes.h: %.h Makefile.in
- glib-mkenums \
+ $(QUIET_GEN)glib-mkenums \
--fhead "#ifndef __$(shell echo $* | tr [:lower:]- [:upper:]_)_ENUM_TYPES_H__\n#define __$(shell echo $* | tr [:lower:]- [:upper:]_)_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
--fprod "/* enumerations from \"@filename@\" */\n" \
--vhead "GType @enum_name@_get_type (void);\n#define $(shell echo $* | tr [:lower:]- [:upper:]_ | sed 's/_.*//')_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
@@ -72,7 +95,7 @@ dist_man_MANS = \
$< > $@
%-enumtypes.c: %.h Makefile.in
- glib-mkenums \
+ $(QUIET_GEN)glib-mkenums \
--fhead "#include <$*.h>\n#include <$*-enumtypes.h>" \
--fprod "\n/* enumerations from \"@filename@\" */" \
--vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
diff --git a/src/empathy-about-dialog.c b/src/empathy-about-dialog.c
index a743f22c4..62c545864 100644
--- a/src/empathy-about-dialog.c
+++ b/src/empathy-about-dialog.c
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Martyn Russell <martyn@imendio.com>
* Xavier Claessens <xclaesse@gmail.com>
*/
@@ -44,6 +44,7 @@ static const char *authors[] = {
"Aurelien Naldi",
"Bastien Nocera",
"Christoffer Olsen",
+ "Cosimo Cecchi",
"Elliot Fairweather",
"Frederic Crozat",
"Frederic Peters",
diff --git a/src/empathy-about-dialog.h b/src/empathy-about-dialog.h
index e7eac5ff9..3e8f40531 100644
--- a/src/empathy-about-dialog.h
+++ b/src/empathy-about-dialog.h
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Martyn Russell <martyn@imendio.com>
* Xavier Claessens <xclaesse@gmail.com>
*/
diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c
index e15c0eab1..e311ac637 100644
--- a/src/empathy-accounts-dialog.c
+++ b/src/empathy-accounts-dialog.c
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Martyn Russell <martyn@imendio.com>
* Xavier Claessens <xclaesse@gmail.com>
*/
@@ -217,9 +217,9 @@ accounts_dialog_update_account (EmpathyAccountsDialog *dialog,
profile = mc_account_get_profile (account);
config_ui = mc_profile_get_configuration_ui (profile);
if (!tp_strdiff (config_ui, "jabber")) {
- dialog->settings_widget =
+ dialog->settings_widget =
empathy_account_widget_jabber_new (account);
- }
+ }
else if (!tp_strdiff (config_ui, "msn")) {
dialog ->settings_widget =
empathy_account_widget_msn_new (account);
@@ -232,11 +232,11 @@ accounts_dialog_update_account (EmpathyAccountsDialog *dialog,
dialog->settings_widget =
empathy_account_widget_irc_new (account);
}
- else if (!tp_strdiff(config_ui, "icq")) {
+ else if (!tp_strdiff (config_ui, "icq")) {
dialog->settings_widget =
empathy_account_widget_icq_new (account);
}
- else if (!tp_strdiff(config_ui, "aim")) {
+ else if (!tp_strdiff (config_ui, "aim")) {
dialog->settings_widget =
empathy_account_widget_aim_new (account);
}
@@ -253,7 +253,7 @@ accounts_dialog_update_account (EmpathyAccountsDialog *dialog,
empathy_account_widget_groupwise_new (account);
}
else {
- dialog->settings_widget =
+ dialog->settings_widget =
empathy_account_widget_generic_new (account);
}
@@ -358,7 +358,7 @@ accounts_dialog_enable_toggled_cb (GtkCellRendererToggle *cell_renderer,
mc_account_set_enabled (account, !enabled);
DEBUG ("%s account %s", enabled ? "Disabled" : "Enable",
- mc_account_get_display_name(account));
+ mc_account_get_display_name (account));
g_object_unref (account);
}
@@ -469,7 +469,7 @@ accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column,
if (pixbuf) {
if (status == TP_CONNECTION_STATUS_DISCONNECTED ||
- (status == TP_CONNECTION_STATUS_CONNECTING &&
+ (status == TP_CONNECTION_STATUS_CONNECTING &&
!dialog->connecting_show)) {
GdkPixbuf *modded_pixbuf;
@@ -954,10 +954,10 @@ accounts_dialog_button_remove_clicked_cb (GtkWidget *button,
"they will still be available."));
gtk_dialog_add_button (GTK_DIALOG (message_dialog),
- GTK_STOCK_CANCEL,
+ GTK_STOCK_CANCEL,
GTK_RESPONSE_NO);
gtk_dialog_add_button (GTK_DIALOG (message_dialog),
- GTK_STOCK_REMOVE,
+ GTK_STOCK_REMOVE,
GTK_RESPONSE_YES);
gtk_widget_show (message_dialog);
diff --git a/src/empathy-accounts-dialog.h b/src/empathy-accounts-dialog.h
index 369b2f75b..40ea24f3e 100644
--- a/src/empathy-accounts-dialog.h
+++ b/src/empathy-accounts-dialog.h
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Martyn Russell <martyn@imendio.com>
* Xavier Claessens <xclaesse@gmail.com>
*/
diff --git a/src/empathy-call-window-fullscreen.c b/src/empathy-call-window-fullscreen.c
new file mode 100644
index 000000000..33f4085b3
--- /dev/null
+++ b/src/empathy-call-window-fullscreen.c
@@ -0,0 +1,294 @@
+/*
+ * empathy-call-window-fullscreen.c - Source for EmpathyCallWindowFullscreen
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * Some code is based on the Totem Movie Player, especially
+ * totem-fullscreen.c which has the following copyright:
+ * Copyright (C) 2001-2007 Bastien Nocera <hadess@hadess.net>
+ * Copyright (C) 2007 Sunil Mohan Adapa <sunilmohan@gnu.org.in>
+ *
+ * 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
+ */
+
+#include "empathy-call-window-fullscreen.h"
+
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy-gtk/empathy-ui-utils.h>
+
+/* The number of seconds for which the "leave fullscreen" popup should
+ be shown */
+#define FULLSCREEN_POPUP_TIMEOUT 5
+
+G_DEFINE_TYPE (EmpathyCallWindowFullscreen, empathy_call_window_fullscreen,
+ G_TYPE_OBJECT)
+
+/* private structure */
+typedef struct _EmpathyCallWindowFullscreenPriv
+ EmpathyCallWindowFullscreenPriv;
+
+struct _EmpathyCallWindowFullscreenPriv
+{
+ EmpathyCallWindow *parent_window;
+
+ GtkWidget *leave_fullscreen_popup;
+ GtkWidget *video_widget;
+
+ guint popup_timeout;
+ gboolean popup_creation_in_progress;
+ gboolean dispose_has_run;
+};
+
+#define GET_PRIV(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \
+ EmpathyCallWindowFullscreenPriv))
+
+static void empathy_call_window_fullscreen_dispose (GObject *object);
+static void empathy_call_window_fullscreen_finalize (GObject *object);
+
+static gboolean empathy_call_window_fullscreen_hide_popup (
+ EmpathyCallWindowFullscreen *fs);
+
+static void
+empathy_call_window_fullscreen_set_cursor_visible (
+ EmpathyCallWindowFullscreen *fs,
+ gboolean show_cursor)
+{
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs);
+
+ if (priv->video_widget != NULL && !show_cursor)
+ {
+ gdk_window_set_cursor (priv->video_widget->window,
+ gdk_cursor_new (GDK_BLANK_CURSOR));
+ }
+ else
+ gdk_window_set_cursor (priv->video_widget->window, NULL);
+}
+
+static void
+empathy_call_window_fullscreen_add_popup_timeout (
+ EmpathyCallWindowFullscreen *self)
+{
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self);
+
+ if (priv->popup_timeout == 0)
+ {
+ priv->popup_timeout = g_timeout_add_seconds (FULLSCREEN_POPUP_TIMEOUT,
+ (GSourceFunc) empathy_call_window_fullscreen_hide_popup, self);
+ }
+}
+
+static void
+empathy_call_window_fullscreen_remove_popup_timeout (
+ EmpathyCallWindowFullscreen *self)
+{
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self);
+
+ if (priv->popup_timeout != 0)
+ {
+ g_source_remove (priv->popup_timeout);
+ priv->popup_timeout = 0;
+ }
+}
+
+void
+empathy_call_window_fullscreen_show_popup (EmpathyCallWindowFullscreen *self)
+{
+ gint leave_fullscreen_width, leave_fullscreen_height;
+ GdkScreen *screen;
+ GdkRectangle fullscreen_rect;
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self);
+
+ g_assert (self->is_fullscreen);
+
+ g_return_if_fail (priv->parent_window != NULL);
+
+ if (priv->popup_creation_in_progress)
+ return;
+
+ if (!gtk_window_is_active (GTK_WINDOW (priv->parent_window)))
+ return;
+
+ priv->popup_creation_in_progress = TRUE;
+
+ empathy_call_window_fullscreen_set_cursor_visible (self, TRUE);
+
+ /* Obtaining the screen rectangle */
+ screen = gtk_window_get_screen (GTK_WINDOW (priv->parent_window));
+ gdk_screen_get_monitor_geometry (screen,
+ gdk_screen_get_monitor_at_window (screen,
+ GTK_WIDGET (priv->parent_window)->window),
+ &fullscreen_rect);
+
+ /* Getting the popup window sizes */
+ gtk_window_get_size (GTK_WINDOW (priv->leave_fullscreen_popup),
+ &leave_fullscreen_width, &leave_fullscreen_height);
+
+ /* Moving the popup to the top-right corner (if the direction is LTR) or the
+ top-left corner (if the direction is RTL).*/
+ if (gtk_widget_get_direction (priv->leave_fullscreen_popup)
+ == GTK_TEXT_DIR_LTR)
+ {
+ gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup),
+ fullscreen_rect.width + fullscreen_rect.x - leave_fullscreen_width,
+ fullscreen_rect.y);
+
+ }
+ else
+ {
+ gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup),
+ fullscreen_rect.x, fullscreen_rect.y);
+ }
+
+ gtk_widget_show_all (priv->leave_fullscreen_popup);
+ empathy_call_window_fullscreen_add_popup_timeout (self);
+
+ priv->popup_creation_in_progress = FALSE;
+}
+
+static gboolean
+empathy_call_window_fullscreen_hide_popup (EmpathyCallWindowFullscreen *fs)
+{
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs);
+
+ if (priv->video_widget == NULL || !fs->is_fullscreen)
+ return TRUE;
+
+ gtk_widget_hide (priv->leave_fullscreen_popup);
+ empathy_call_window_fullscreen_remove_popup_timeout (fs);
+
+ empathy_call_window_fullscreen_set_cursor_visible (fs, FALSE);
+
+ return FALSE;
+}
+
+static void
+empathy_call_window_fullscreen_init (EmpathyCallWindowFullscreen *self)
+{
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self);
+ GtkBuilder *gui;
+ gchar *filename;
+
+ filename = empathy_file_lookup ("empathy-call-window-fullscreen.ui", "src");
+ gui = empathy_builder_get_file (filename,
+ "leave_fullscreen_window", &priv->leave_fullscreen_popup,
+ "leave_fullscreen_button", &self->leave_fullscreen_button,
+ NULL);
+
+ gtk_widget_add_events (priv->leave_fullscreen_popup, GDK_POINTER_MOTION_MASK);
+
+ g_object_unref (gui);
+ g_free (filename);
+}
+
+static void
+empathy_call_window_fullscreen_class_init (
+ EmpathyCallWindowFullscreenClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (EmpathyCallWindowFullscreenPriv));
+
+ object_class->dispose = empathy_call_window_fullscreen_dispose;
+ object_class->finalize = empathy_call_window_fullscreen_finalize;
+}
+
+void
+empathy_call_window_fullscreen_dispose (GObject *object)
+{
+ EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (object);
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self);
+
+ if (priv->dispose_has_run)
+ return;
+
+ priv->dispose_has_run = TRUE;
+
+ if (priv->leave_fullscreen_popup != NULL)
+ gtk_widget_destroy (priv->leave_fullscreen_popup);
+ priv->leave_fullscreen_popup = NULL;
+
+ if (G_OBJECT_CLASS (empathy_call_window_fullscreen_parent_class)->dispose)
+ {
+ G_OBJECT_CLASS (
+ empathy_call_window_fullscreen_parent_class)->dispose (object);
+ }
+}
+
+void
+empathy_call_window_fullscreen_finalize (GObject *object)
+{
+ EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (object);
+
+ empathy_call_window_fullscreen_remove_popup_timeout (self);
+
+ G_OBJECT_CLASS (
+ empathy_call_window_fullscreen_parent_class)->finalize (object);
+}
+
+static void
+empathy_call_window_fullscreen_parent_window_notify (GtkWidget *parent_window,
+ GParamSpec *property, EmpathyCallWindowFullscreen *fs)
+{
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs);
+
+ if (!fs->is_fullscreen)
+ return;
+
+ if (parent_window == GTK_WIDGET (priv->parent_window) &&
+ !gtk_window_is_active (GTK_WINDOW (parent_window)))
+ {
+ empathy_call_window_fullscreen_hide_popup (fs);
+ empathy_call_window_fullscreen_set_cursor_visible (fs, TRUE);
+ }
+}
+
+EmpathyCallWindowFullscreen *
+empathy_call_window_fullscreen_new (EmpathyCallWindow *parent_window)
+{
+ EmpathyCallWindowFullscreen *self = EMPATHY_CALL_WINDOW_FULLSCREEN (
+ g_object_new (EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, NULL));
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (self);
+
+ priv->parent_window = parent_window;
+ g_signal_connect (G_OBJECT (priv->parent_window), "notify::is-active",
+ G_CALLBACK (empathy_call_window_fullscreen_parent_window_notify), self);
+
+ return self;
+}
+
+void
+empathy_call_window_fullscreen_set_fullscreen (EmpathyCallWindowFullscreen *fs,
+ gboolean set_fullscreen)
+{
+
+ if (set_fullscreen)
+ empathy_call_window_fullscreen_remove_popup_timeout (fs);
+ else
+ empathy_call_window_fullscreen_hide_popup (fs);
+
+ empathy_call_window_fullscreen_set_cursor_visible (fs, !set_fullscreen);
+ fs->is_fullscreen = set_fullscreen;
+}
+
+void
+empathy_call_window_fullscreen_set_video_widget (
+ EmpathyCallWindowFullscreen *fs,
+ GtkWidget *video_widget)
+{
+ EmpathyCallWindowFullscreenPriv *priv = GET_PRIV (fs);
+ priv->video_widget = video_widget;
+}
diff --git a/src/empathy-call-window-fullscreen.h b/src/empathy-call-window-fullscreen.h
new file mode 100644
index 000000000..8bde16ced
--- /dev/null
+++ b/src/empathy-call-window-fullscreen.h
@@ -0,0 +1,77 @@
+/*
+ * empathy-call-window-fullscreen.h - Header for EmpathyCallWindowFullscreen
+ * Copyright (C) 2009 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
+ */
+
+#ifndef __EMPATHY_CALL_WINDOW_FULLSCREEN_H__
+#define __EMPATHY_CALL_WINDOW_FULLSCREEN_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "empathy-call-window.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EmpathyCallWindowFullscreen EmpathyCallWindowFullscreen;
+typedef struct _EmpathyCallWindowFullscreenClass
+ EmpathyCallWindowFullscreenClass;
+
+struct _EmpathyCallWindowFullscreenClass {
+ GObjectClass parent_class;
+};
+
+struct _EmpathyCallWindowFullscreen {
+ GObject parent;
+ gboolean is_fullscreen;
+ GtkWidget *leave_fullscreen_button;
+};
+
+GType empathy_call_window_fullscreen_get_type (void);
+
+/* TYPE MACROS */
+#define EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN \
+ (empathy_call_window_fullscreen_get_type ())
+#define EMPATHY_CALL_WINDOW_FULLSCREEN(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \
+ EmpathyCallWindowFullscreen))
+#define EMPATHY_CALL_WINDOW_FULLSCREEN_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \
+ EmpathyCallWindowClassFullscreen))
+#define EMPATHY_IS_CALL_WINDOW_FULLSCREEN(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN))
+#define EMPATHY_IS_CALL_WINDOW_FULLSCREEN_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN))
+#define EMPATHY_CALL_WINDOW_FULLSCREEN_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_CALL_WINDOW_FULLSCREEN, \
+ EmpathyCallWindowFullscreenClass))
+
+EmpathyCallWindowFullscreen *empathy_call_window_fullscreen_new (
+ EmpathyCallWindow *parent);
+
+void empathy_call_window_fullscreen_set_fullscreen (
+ EmpathyCallWindowFullscreen *fs,
+ gboolean set_fullscreen);
+void empathy_call_window_fullscreen_set_video_widget (
+ EmpathyCallWindowFullscreen *fs,
+ GtkWidget *video_widget);
+void empathy_call_window_fullscreen_show_popup (
+ EmpathyCallWindowFullscreen *fs);
+
+G_END_DECLS
+
+#endif /* #ifndef __EMPATHY_CALL_WINDOW_FULLSCREEN_H__*/
diff --git a/src/empathy-call-window-fullscreen.ui b/src/empathy-call-window-fullscreen.ui
new file mode 100644
index 000000000..5bf5e509b
--- /dev/null
+++ b/src/empathy-call-window-fullscreen.ui
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkWindow" id="leave_fullscreen_window">
+ <property name="type">popup</property>
+ <property name="resizable">False</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="skip_pager_hint">True</property>
+ <property name="decorated">False</property>
+ <property name="deletable">False</property>
+ <signal name="motion_notify_event" handler="empathy_call_window_fullscreen_motion_notify_cb"/>
+ <child>
+ <object class="GtkButton" id="leave_fullscreen_button">
+ <property name="label" translatable="yes">gtk-leave-fullscreen</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c
index 01c2c4f5c..08c0e7ea2 100644
--- a/src/empathy-call-window.c
+++ b/src/empathy-call-window.c
@@ -1,6 +1,6 @@
/*
* empathy-call-window.c - Source for EmpathyCallWindow
- * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008-2009 Collabora Ltd.
* @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
@@ -24,13 +24,16 @@
#include <math.h>
+#include <gdk/gdkkeysyms.h>
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <telepathy-farsight/channel.h>
+#include <libempathy/empathy-tp-contact-factory.h>
#include <libempathy/empathy-utils.h>
+#include <libempathy-gtk/empathy-avatar-image.h>
#include <libempathy-gtk/empathy-video-widget.h>
#include <libempathy-gtk/empathy-audio-src.h>
#include <libempathy-gtk/empathy-audio-sink.h>
@@ -39,10 +42,23 @@
#include "empathy-call-window.h"
+#include "empathy-call-window-fullscreen.h"
#include "empathy-sidebar.h"
#define BUTTON_ID "empathy-call-dtmf-button-id"
+#define CONTENT_HBOX_BORDER_WIDTH 6
+#define CONTENT_HBOX_SPACING 3
+#define CONTENT_HBOX_CHILDREN_PACKING_PADDING 3
+
+#define SELF_VIDEO_SECTION_WIDTH 160
+#define SELF_VIDEO_SECTION_HEIGTH 120
+
+/* The avatar's default width and height are set to the same value because we
+ want a square icon. */
+#define REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT
+#define REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT
+
G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW)
/* signal enum */
@@ -66,12 +82,15 @@ struct _EmpathyCallWindowPriv
{
gboolean dispose_has_run;
EmpathyCallHandler *handler;
+ EmpathyContact *contact;
gboolean connected;
GtkUIManager *ui_manager;
GtkWidget *video_output;
GtkWidget *video_preview;
+ GtkWidget *remote_user_avatar_widget;
+ GtkWidget *self_user_avatar_widget;
GtkWidget *sidebar;
GtkWidget *sidebar_button;
GtkWidget *statusbar;
@@ -81,6 +100,17 @@ struct _EmpathyCallWindowPriv
GtkWidget *toolbar;
GtkWidget *pane;
GtkAction *send_video;
+ GtkAction *menu_fullscreen;
+
+ /* We keep a reference on the hbox which contains the main content so we can
+ easilly repack everything when toggling fullscreen */
+ GtkWidget *content_hbox;
+
+ /* This vbox is contained in the content_hbox. When toggling fullscreen,
+ it needs to be repacked. We keep a reference on it for easier access. */
+ GtkWidget *vbox;
+
+ gulong video_output_motion_handler_id;
gdouble volume;
GtkAdjustment *audio_input_adj;
@@ -108,6 +138,15 @@ struct _EmpathyCallWindowPriv
GMutex *lock;
gboolean call_started;
gboolean sending_video;
+
+ EmpathyCallWindowFullscreen *fullscreen;
+ gboolean is_fullscreen;
+
+ /* Those fields represent the state of the window before it actually was in
+ fullscreen mode. */
+ gboolean sidebar_was_visible_before_fs;
+ gint original_width_before_fs;
+ gint original_height_before_fs;
};
#define GET_PRIV(o) \
@@ -118,7 +157,10 @@ static void empathy_call_window_realized_cb (GtkWidget *widget,
EmpathyCallWindow *window);
static gboolean empathy_call_window_delete_cb (GtkWidget *widget,
- GdkEvent*event, EmpathyCallWindow *window);
+ GdkEvent *event, EmpathyCallWindow *window);
+
+static gboolean empathy_call_window_state_event_cb (GtkWidget *widget,
+ GdkEventWindowState *event, EmpathyCallWindow *window);
static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle,
EmpathyCallWindow *window);
@@ -138,9 +180,29 @@ static void empathy_call_window_mic_toggled_cb (
static void empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar,
EmpathyCallWindow *window);
+static void empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar,
+ EmpathyCallWindow *window);
+
static void empathy_call_window_hangup_cb (gpointer object,
EmpathyCallWindow *window);
+static void empathy_call_window_fullscreen_cb (gpointer object,
+ EmpathyCallWindow *window);
+
+static void empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window);
+
+static gboolean empathy_call_window_video_button_press_cb (GtkWidget *video_output,
+ GdkEventButton *event, EmpathyCallWindow *window);
+
+static gboolean empathy_call_window_key_press_cb (GtkWidget *video_output,
+ GdkEventKey *event, EmpathyCallWindow *window);
+
+static gboolean empathy_call_window_video_output_motion_notify (GtkWidget *widget,
+ GdkEventMotion *event, EmpathyCallWindow *window);
+
+static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window,
+ guint button);
+
static void empathy_call_window_status_message (EmpathyCallWindow *window,
gchar *message);
@@ -458,10 +520,12 @@ empathy_call_window_init (EmpathyCallWindow *self)
{
EmpathyCallWindowPriv *priv = GET_PRIV (self);
GtkBuilder *gui;
- GtkWidget *vbox, *top_vbox;
- GtkWidget *hbox, *h;
+ GtkWidget *top_vbox;
+ GtkWidget *h;
GtkWidget *arrow;
GtkWidget *page;
+ GtkWidget *remote_user_output_frame, *self_user_output_frame;
+ GtkWidget *remote_user_output_hbox, *self_user_output_hbox;
GstBus *bus;
gchar *filename;
@@ -475,6 +539,7 @@ empathy_call_window_init (EmpathyCallWindow *self)
"toolbar", &priv->toolbar,
"send_video", &priv->send_video,
"ui_manager", &priv->ui_manager,
+ "menufullscreen", &priv->menu_fullscreen,
NULL);
empathy_builder_connect (gui, self,
@@ -484,6 +549,7 @@ empathy_call_window_init (EmpathyCallWindow *self)
"camera", "toggled", empathy_call_window_camera_toggled_cb,
"send_video", "toggled", empathy_call_window_send_video_toggled_cb,
"show_preview", "toggled", empathy_call_window_show_preview_toggled_cb,
+ "menufullscreen", "activate", empathy_call_window_fullscreen_cb,
NULL);
priv->lock = g_mutex_new ();
@@ -494,27 +560,66 @@ empathy_call_window_init (EmpathyCallWindow *self)
priv->pipeline = gst_pipeline_new (NULL);
- hbox = gtk_hbox_new (FALSE, 3);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
- gtk_paned_pack1 (GTK_PANED (priv->pane), hbox, TRUE, FALSE);
+ priv->content_hbox = gtk_hbox_new (FALSE, CONTENT_HBOX_SPACING);
+ gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox),
+ CONTENT_HBOX_BORDER_WIDTH);
+ gtk_paned_pack1 (GTK_PANED (priv->pane), priv->content_hbox, TRUE, FALSE);
bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
gst_bus_add_watch (bus, empathy_call_window_bus_message, self);
+ remote_user_output_frame = gtk_frame_new (NULL);
+ gtk_widget_set_size_request (remote_user_output_frame,
+ EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH, EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT);
+ remote_user_output_hbox = gtk_hbox_new (FALSE, 0);
+
+ priv->remote_user_avatar_widget = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (remote_user_output_hbox),
+ priv->remote_user_avatar_widget, TRUE, TRUE, 0);
+
priv->video_output = empathy_video_widget_new (bus);
- gtk_box_pack_start (GTK_BOX (hbox), priv->video_output, TRUE, TRUE, 3);
+ gtk_box_pack_start (GTK_BOX (remote_user_output_hbox),
+ priv->video_output, TRUE, TRUE, 0);
+
+ gtk_container_add (GTK_CONTAINER (remote_user_output_frame),
+ remote_user_output_hbox);
+
+ gtk_widget_add_events (priv->video_output,
+ GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
+ g_signal_connect (G_OBJECT (priv->video_output), "button-press-event",
+ G_CALLBACK (empathy_call_window_video_button_press_cb), self);
+ gtk_box_pack_start (GTK_BOX (priv->content_hbox), remote_user_output_frame,
+ TRUE, TRUE, CONTENT_HBOX_CHILDREN_PACKING_PADDING);
priv->video_tee = gst_element_factory_make ("tee", NULL);
gst_object_ref (priv->video_tee);
gst_object_sink (priv->video_tee);
- vbox = gtk_vbox_new (FALSE, 3);
- gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 3);
+ priv->vbox = gtk_vbox_new (FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->vbox,
+ FALSE, FALSE, CONTENT_HBOX_CHILDREN_PACKING_PADDING);
- priv->video_preview = empathy_video_widget_new_with_size (bus, 160, 120);
+ self_user_output_frame = gtk_frame_new (NULL);
+ gtk_widget_set_size_request (self_user_output_frame, SELF_VIDEO_SECTION_WIDTH,
+ SELF_VIDEO_SECTION_HEIGTH);
+ self_user_output_hbox = gtk_hbox_new (FALSE, 0);
+
+ priv->self_user_avatar_widget = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (self_user_output_hbox),
+ priv->self_user_avatar_widget, TRUE, TRUE, 0);
+
+ priv->video_preview = empathy_video_widget_new_with_size (bus,
+ SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH);
g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL);
- gtk_box_pack_start (GTK_BOX (vbox), priv->video_preview, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (self_user_output_hbox), priv->video_preview,
+ TRUE, TRUE, 0);
+
+ gtk_container_add (GTK_CONTAINER (self_user_output_frame),
+ self_user_output_hbox);
+
+ gtk_box_pack_start (GTK_BOX (priv->vbox), self_user_output_frame, FALSE,
+ FALSE, 0);
priv->video_input = empathy_video_src_new ();
gst_object_ref (priv->video_input);
@@ -538,13 +643,14 @@ empathy_call_window_init (EmpathyCallWindow *self)
gtk_button_set_image (GTK_BUTTON (priv->sidebar_button), arrow);
h = gtk_hbox_new (FALSE, 3);
- gtk_box_pack_end (GTK_BOX (vbox), h, FALSE, FALSE, 3);
+ gtk_box_pack_end (GTK_BOX (priv->vbox), h, FALSE, FALSE, 3);
gtk_box_pack_end (GTK_BOX (h), priv->sidebar_button, FALSE, FALSE, 3);
priv->sidebar = empathy_sidebar_new ();
g_signal_connect (G_OBJECT (priv->sidebar),
- "hide", G_CALLBACK (empathy_call_window_sidebar_hidden_cb),
- self);
+ "hide", G_CALLBACK (empathy_call_window_sidebar_hidden_cb), self);
+ g_signal_connect (G_OBJECT (priv->sidebar),
+ "show", G_CALLBACK (empathy_call_window_sidebar_shown_cb), self);
gtk_paned_pack2 (GTK_PANED (priv->pane), priv->sidebar, FALSE, FALSE);
priv->dtmf_panel = empathy_call_window_create_dtmf (self);
@@ -565,18 +671,153 @@ empathy_call_window_init (EmpathyCallWindow *self)
gtk_widget_hide (priv->sidebar);
+ priv->fullscreen = empathy_call_window_fullscreen_new (self);
+ empathy_call_window_fullscreen_set_video_widget (priv->fullscreen, priv->video_output);
+ g_signal_connect (G_OBJECT (priv->fullscreen->leave_fullscreen_button),
+ "clicked", G_CALLBACK (empathy_call_window_fullscreen_cb), self);
+
g_signal_connect (G_OBJECT (self), "realize",
G_CALLBACK (empathy_call_window_realized_cb), self);
g_signal_connect (G_OBJECT (self), "delete-event",
G_CALLBACK (empathy_call_window_delete_cb), self);
+ g_signal_connect (G_OBJECT (self), "window-state-event",
+ G_CALLBACK (empathy_call_window_state_event_cb), self);
+
+ g_signal_connect (G_OBJECT (self), "key-press-event",
+ G_CALLBACK (empathy_call_window_key_press_cb), self);
+
empathy_call_window_status_message (self, _("Connecting..."));
priv->timer = g_timer_new ();
g_object_ref (priv->ui_manager);
g_object_unref (gui);
+ g_free (filename);
+}
+
+/* Instead of specifying a width and a height, we specify only one size. That's
+ because we want a square avatar icon. */
+static void
+init_contact_avatar_with_size (EmpathyContact *contact, GtkWidget *image_widget,
+ gint size)
+{
+
+ GdkPixbuf *pixbuf_avatar = NULL;
+
+ if (contact != NULL)
+ {
+ pixbuf_avatar = empathy_pixbuf_avatar_from_contact_scaled (contact,
+ size, size);
+ }
+
+ if (pixbuf_avatar == NULL)
+ {
+ pixbuf_avatar = empathy_pixbuf_from_icon_name_sized ("stock_person",
+ size);
+ }
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image_widget), pixbuf_avatar);
+}
+
+static void
+set_window_title (EmpathyCallWindow *self)
+{
+ EmpathyCallWindowPriv *priv = GET_PRIV (self);
+ gchar *tmp;
+
+ tmp = g_strdup_printf (_("Call with %s"),
+ empathy_contact_get_name (priv->contact));
+ gtk_window_set_title (GTK_WINDOW (self), tmp);
+ g_free (tmp);
+}
+
+static void
+contact_name_changed_cb (EmpathyContact *contact,
+ GParamSpec *pspec, EmpathyCallWindow *self)
+{
+ set_window_title (self);
+}
+
+static void
+contact_avatar_changed_cb (EmpathyContact *contact,
+ GParamSpec *pspec, GtkWidget *avatar_widget)
+{
+ init_contact_avatar_with_size (contact, avatar_widget,
+ avatar_widget->allocation.height);
+}
+
+static void
+empathy_call_window_got_self_contact_cb (EmpathyTpContactFactory *factory,
+ EmpathyContact *contact, const GError *error, gpointer user_data,
+ GObject *weak_object)
+{
+ EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
+ EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+ init_contact_avatar_with_size (contact, priv->self_user_avatar_widget,
+ MIN (SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH));
+
+ g_signal_connect (contact, "notify::avatar",
+ G_CALLBACK (contact_avatar_changed_cb), priv->self_user_avatar_widget);
+}
+
+static void
+empathy_call_window_constructed (GObject *object)
+{
+ EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object);
+ EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+ g_assert (priv->handler != NULL);
+
+ g_object_get (priv->handler, "contact", &(priv->contact), NULL);
+
+ if (priv->contact != NULL)
+ {
+ TpConnection *connection;
+ EmpathyTpContactFactory *factory;
+
+ set_window_title (self);
+
+ g_signal_connect (priv->contact, "notify::name",
+ G_CALLBACK (contact_name_changed_cb), self);
+ g_signal_connect (priv->contact, "notify::avatar",
+ G_CALLBACK (contact_avatar_changed_cb),
+ priv->remote_user_avatar_widget);
+
+ /* Retreiving the self avatar */
+ connection = empathy_contact_get_connection (priv->contact);
+ factory = empathy_tp_contact_factory_dup_singleton (connection);
+ empathy_tp_contact_factory_get_from_handle (factory,
+ tp_connection_get_self_handle (connection),
+ empathy_call_window_got_self_contact_cb, self, NULL, NULL);
+
+ g_object_unref (factory);
+ }
+ else
+ {
+ g_warning ("call handler doesn't have a contact");
+ gtk_window_set_title (GTK_WINDOW (self), _("Call"));
+
+ /* Since we can't access the remote contact, we can't get a connection
+ to it and can't get the self contact (and its avatar). This means
+ that we have to manually set the self avatar. */
+ init_contact_avatar_with_size (NULL, priv->self_user_avatar_widget,
+ MIN (SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH));
+ }
+
+ init_contact_avatar_with_size (priv->contact,
+ priv->remote_user_avatar_widget, MIN (REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH,
+ REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT));
+
+ /* We hide the self avatar. It will be shown if a problem is
+ encountered when we try to send video. As for the remote avatar, it
+ is shown by default and will be hidden when we receive video from
+ the remote side. */
+ gtk_widget_hide (priv->self_user_avatar_widget);
+ gtk_widget_hide (priv->video_output);
+ gtk_widget_show (priv->remote_user_avatar_widget);
}
static void empathy_call_window_dispose (GObject *object);
@@ -624,6 +865,7 @@ empathy_call_window_class_init (
g_type_class_add_private (empathy_call_window_class,
sizeof (EmpathyCallWindowPriv));
+ object_class->constructed = empathy_call_window_constructed;
object_class->set_property = empathy_call_window_set_property;
object_class->get_property = empathy_call_window_get_property;
@@ -633,7 +875,7 @@ empathy_call_window_class_init (
param_spec = g_param_spec_object ("handler",
"handler", "The call handler",
EMPATHY_TYPE_CALL_HANDLER,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class,
PROP_CALL_HANDLER, param_spec);
@@ -683,6 +925,14 @@ empathy_call_window_dispose (GObject *object)
g_object_unref (priv->ui_manager);
priv->ui_manager = NULL;
+ if (priv->contact != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (priv->contact,
+ contact_name_changed_cb, self);
+ g_object_unref (priv->contact);
+ priv->contact = NULL;
+ }
+
/* release any references held by the object here */
if (G_OBJECT_CLASS (empathy_call_window_parent_class)->dispose)
G_OBJECT_CLASS (empathy_call_window_parent_class)->dispose (object);
@@ -694,6 +944,13 @@ empathy_call_window_finalize (GObject *object)
EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object);
EmpathyCallWindowPriv *priv = GET_PRIV (self);
+ if (priv->video_output_motion_handler_id != 0)
+ {
+ g_signal_handler_disconnect (G_OBJECT (priv->video_output),
+ priv->video_output_motion_handler_id);
+ priv->video_output_motion_handler_id = 0;
+ }
+
/* free any data held directly by the object here */
g_mutex_free (priv->lock);
@@ -902,6 +1159,8 @@ empathy_call_window_src_added_cb (EmpathyCallHandler *handler,
pad = empathy_call_window_get_audio_sink_pad (self);
break;
case TP_MEDIA_STREAM_TYPE_VIDEO:
+ gtk_widget_hide (priv->remote_user_avatar_widget);
+ gtk_widget_show (priv->video_output);
pad = empathy_call_window_get_video_sink_pad (self);
break;
default:
@@ -936,7 +1195,7 @@ empathy_call_window_sink_added_cb (EmpathyCallHandler *handler,
case TP_MEDIA_STREAM_TYPE_VIDEO:
if (priv->video_input != NULL)
{
- pad = gst_element_get_request_pad (priv->video_tee, "src%d");
+ pad = gst_element_get_request_pad (priv->video_tee, "src%d");
gst_pad_link (pad, sink);
}
break;
@@ -1005,6 +1264,9 @@ empathy_call_window_remove_video_input (EmpathyCallWindow *self)
priv->video_input = NULL;
g_object_unref (priv->video_tee);
priv->video_tee = NULL;
+
+ gtk_widget_hide (priv->video_preview);
+ gtk_widget_show (priv->self_user_avatar_widget);
}
@@ -1041,7 +1303,7 @@ empathy_call_window_bus_message (GstBus *bus, GstMessage *message,
break;
case GST_MESSAGE_ERROR:
{
- GError *error;
+ GError *error = NULL;
gchar *debug;
gst_message_parse_error (message, &error, &debug);
@@ -1112,6 +1374,108 @@ empathy_call_window_delete_cb (GtkWidget *widget, GdkEvent*event,
}
static void
+show_controls (EmpathyCallWindow *window, gboolean set_fullscreen)
+{
+ GtkWidget *menu;
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+ menu = gtk_ui_manager_get_widget (priv->ui_manager,
+ "/menubar1");
+
+ if (set_fullscreen)
+ {
+ gtk_widget_hide (priv->sidebar);
+ gtk_widget_hide (menu);
+ gtk_widget_hide (priv->vbox);
+ gtk_widget_hide (priv->statusbar);
+ gtk_widget_hide (priv->toolbar);
+ }
+ else
+ {
+ if (priv->sidebar_was_visible_before_fs)
+ gtk_widget_show (priv->sidebar);
+
+ gtk_widget_show (menu);
+ gtk_widget_show (priv->vbox);
+ gtk_widget_show (priv->statusbar);
+ gtk_widget_show (priv->toolbar);
+
+ gtk_window_resize (GTK_WINDOW (window), priv->original_width_before_fs,
+ priv->original_height_before_fs);
+ }
+}
+
+static void
+show_borders (EmpathyCallWindow *window, gboolean set_fullscreen)
+{
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+ gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox),
+ set_fullscreen ? 0 : CONTENT_HBOX_BORDER_WIDTH);
+ gtk_box_set_spacing (GTK_BOX (priv->content_hbox),
+ set_fullscreen ? 0 : CONTENT_HBOX_SPACING);
+ gtk_box_set_child_packing (GTK_BOX (priv->content_hbox),
+ priv->video_output, TRUE, TRUE,
+ set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING,
+ GTK_PACK_START);
+ gtk_box_set_child_packing (GTK_BOX (priv->content_hbox),
+ priv->vbox, TRUE, TRUE,
+ set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING,
+ GTK_PACK_START);
+}
+
+static gboolean
+empathy_call_window_state_event_cb (GtkWidget *widget,
+ GdkEventWindowState *event, EmpathyCallWindow *window)
+{
+ if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+ gboolean set_fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
+
+ if (set_fullscreen)
+ {
+ gboolean sidebar_was_visible;
+ gint original_width = GTK_WIDGET (window)->allocation.width;
+ gint original_height = GTK_WIDGET (window)->allocation.height;
+
+ g_object_get (priv->sidebar, "visible", &sidebar_was_visible, NULL);
+
+ priv->sidebar_was_visible_before_fs = sidebar_was_visible;
+ priv->original_width_before_fs = original_width;
+ priv->original_height_before_fs = original_height;
+
+ if (priv->video_output_motion_handler_id == 0 &&
+ priv->video_output != NULL)
+ {
+ priv->video_output_motion_handler_id = g_signal_connect (
+ G_OBJECT (priv->video_output), "motion-notify-event",
+ G_CALLBACK (empathy_call_window_video_output_motion_notify), window);
+ }
+ }
+ else
+ {
+ if (priv->video_output_motion_handler_id != 0)
+ {
+ g_signal_handler_disconnect (G_OBJECT (priv->video_output),
+ priv->video_output_motion_handler_id);
+ priv->video_output_motion_handler_id = 0;
+ }
+ }
+
+ empathy_call_window_fullscreen_set_fullscreen (priv->fullscreen,
+ set_fullscreen);
+ show_controls (window, set_fullscreen);
+ show_borders (window, set_fullscreen);
+ gtk_action_set_stock_id (priv->menu_fullscreen,
+ (set_fullscreen ? "gtk-leave-fullscreen" : "gtk-fullscreen"));
+ priv->is_fullscreen = set_fullscreen;
+ }
+
+ return FALSE;
+}
+
+static void
empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle,
EmpathyCallWindow *window)
{
@@ -1166,10 +1530,10 @@ empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle,
if (priv->sending_video == active)
return;
+ priv->sending_video = active;
empathy_call_window_set_send_video (window, active);
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priv->send_video), active);
- priv->sending_video = active;
}
static void
@@ -1183,11 +1547,11 @@ empathy_call_window_send_video_toggled_cb (GtkToggleAction *toggle,
if (priv->sending_video == active)
return;
+ priv->sending_video = active;
empathy_call_window_set_send_video (window, active);
gtk_toggle_tool_button_set_active (
GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), active);
- priv->sending_video = active;
}
static void
@@ -1236,6 +1600,16 @@ empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar,
}
static void
+empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar,
+ EmpathyCallWindow *window)
+{
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->sidebar_button),
+ TRUE);
+}
+
+static void
empathy_call_window_hangup_cb (gpointer object,
EmpathyCallWindow *window)
{
@@ -1246,6 +1620,83 @@ empathy_call_window_hangup_cb (gpointer object,
}
static void
+empathy_call_window_fullscreen_cb (gpointer object,
+ EmpathyCallWindow *window)
+{
+ empathy_call_window_fullscreen_toggle (window);
+}
+
+static void
+empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window)
+{
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+ if (priv->is_fullscreen)
+ gtk_window_unfullscreen (GTK_WINDOW (window));
+ else
+ gtk_window_fullscreen (GTK_WINDOW (window));
+}
+
+static gboolean
+empathy_call_window_video_button_press_cb (GtkWidget *video_output,
+ GdkEventButton *event, EmpathyCallWindow *window)
+{
+ if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
+ {
+ empathy_call_window_video_menu_popup (window, event->button);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+empathy_call_window_key_press_cb (GtkWidget *video_output,
+ GdkEventKey *event, EmpathyCallWindow *window)
+{
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+ if (priv->is_fullscreen && event->keyval == GDK_Escape)
+ {
+ /* Since we are in fullscreen mode, toggling will bring us back to
+ normal mode. */
+ empathy_call_window_fullscreen_toggle (window);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+empathy_call_window_video_output_motion_notify (GtkWidget *widget,
+ GdkEventMotion *event, EmpathyCallWindow *window)
+{
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+ if (priv->is_fullscreen)
+ {
+ empathy_call_window_fullscreen_show_popup (priv->fullscreen);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+empathy_call_window_video_menu_popup (EmpathyCallWindow *window,
+ guint button)
+{
+ GtkWidget *menu;
+ EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+ menu = gtk_ui_manager_get_widget (priv->ui_manager,
+ "/video-popup");
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ button, gtk_get_current_event_time ());
+ gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE);
+}
+
+static void
empathy_call_window_status_message (EmpathyCallWindow *window,
gchar *message)
{
diff --git a/src/empathy-call-window.h b/src/empathy-call-window.h
index 26b0e7881..01ea5def7 100644
--- a/src/empathy-call-window.h
+++ b/src/empathy-call-window.h
@@ -38,11 +38,11 @@ struct _EmpathyCallWindow {
GtkWindow parent;
};
-GType empathy_call_window_get_type(void);
+GType empathy_call_window_get_type (void);
/* TYPE MACROS */
#define EMPATHY_TYPE_CALL_WINDOW \
- (empathy_call_window_get_type())
+ (empathy_call_window_get_type ())
#define EMPATHY_CALL_WINDOW(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_CALL_WINDOW, \
EmpathyCallWindow))
@@ -57,8 +57,7 @@ GType empathy_call_window_get_type(void);
(G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_CALL_WINDOW, \
EmpathyCallWindowClass))
-EmpathyCallWindow *
-empathy_call_window_new (EmpathyCallHandler *handler);
+EmpathyCallWindow *empathy_call_window_new (EmpathyCallHandler *handler);
G_END_DECLS
diff --git a/src/empathy-call-window.ui b/src/empathy-call-window.ui
index ce3d85b56..a0e1e1304 100644
--- a/src/empathy-call-window.ui
+++ b/src/empathy-call-window.ui
@@ -36,6 +36,13 @@
<property name="label" translatable="yes">Video preview</property>
</object>
</child>
+ <child>
+ <object class="GtkAction" id="menufullscreen">
+ <property name="stock_id">gtk-fullscreen</property>
+ <property name="name">menufullscreen</property>
+ </object>
+ <accelerator key="F11"/>
+ </child>
</object>
</child>
<ui>
@@ -46,8 +53,12 @@
</menu>
<menu action="view">
<menuitem action="show_preview"/>
+ <menuitem action="menufullscreen"/>
</menu>
</menubar>
+ <popup name="video-popup">
+ <menuitem name="menufullscreen" action="menufullscreen"/>
+ </popup>
</ui>
</object>
<object class="GtkVBox" id="call_window_vbox">
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index 0738f6e52..bf02c3cc6 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Mikael Hallendal <micke@imendio.com>
* Richard Hult <richard@imendio.com>
* Martyn Russell <martyn@imendio.com>
@@ -76,7 +76,6 @@ typedef struct {
/* Menu items. */
GtkUIManager *ui_manager;
GtkAction *menu_conv_insert_smiley;
- GtkAction *menu_conv_contact;
GtkAction *menu_conv_favorite;
GtkAction *menu_edit_cut;
@@ -162,21 +161,39 @@ chat_window_close_clicked_cb (GtkAction *action,
}
static void
-chat_window_close_button_style_set_cb (GtkWidget *button,
+chat_tab_style_set_cb (GtkWidget *hbox,
GtkStyle *previous_style,
gpointer user_data)
{
- gint h, w;
+ GtkWidget *button;
+ int char_width, h, w;
+ PangoContext *context;
+ PangoFontMetrics *metrics;
+
+ button = g_object_get_data (G_OBJECT (user_data),
+ "chat-window-tab-close-button");
+ context = gtk_widget_get_pango_context (hbox);
+
+ metrics = pango_context_get_metrics (context, hbox->style->font_desc,
+ pango_context_get_language (context));
+ char_width = pango_font_metrics_get_approximate_char_width (metrics);
+ pango_font_metrics_unref (metrics);
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button),
GTK_ICON_SIZE_MENU, &w, &h);
+ /* Request at least about 12 chars width plus at least space for the status
+ * image and the close button */
+ gtk_widget_set_size_request (hbox,
+ 12 * PANGO_PIXELS (char_width) + 2 * w, -1);
+
gtk_widget_set_size_request (button, w, h);
}
static GtkWidget *
chat_window_create_label (EmpathyChatWindow *window,
- EmpathyChat *chat)
+ EmpathyChat *chat,
+ gboolean is_tab_label)
{
EmpathyChatWindowPriv *priv;
GtkWidget *hbox;
@@ -198,7 +215,8 @@ chat_window_create_label (EmpathyChatWindow *window,
gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
name_label = gtk_label_new (NULL);
- gtk_label_set_ellipsize (GTK_LABEL (name_label), PANGO_ELLIPSIZE_END);
+ if (is_tab_label)
+ gtk_label_set_ellipsize (GTK_LABEL (name_label), PANGO_ELLIPSIZE_END);
attr_list = pango_attr_list_new ();
attr = pango_attr_scale_new (1/1.2);
@@ -210,7 +228,9 @@ chat_window_create_label (EmpathyChatWindow *window,
gtk_misc_set_padding (GTK_MISC (name_label), 2, 0);
gtk_misc_set_alignment (GTK_MISC (name_label), 0.0, 0.5);
- g_object_set_data (G_OBJECT (chat), "chat-window-tab-label", name_label);
+ g_object_set_data (G_OBJECT (chat),
+ is_tab_label ? "chat-window-tab-label" : "chat-window-menu-label",
+ name_label);
status_image = gtk_image_new ();
@@ -220,42 +240,47 @@ chat_window_create_label (EmpathyChatWindow *window,
gtk_box_pack_start (GTK_BOX (event_box_hbox), status_image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (event_box_hbox), name_label, TRUE, TRUE, 0);
- g_object_set_data (G_OBJECT (chat), "chat-window-tab-image", status_image);
- g_object_set_data (G_OBJECT (chat), "chat-window-tab-tooltip-widget", event_box);
+ g_object_set_data (G_OBJECT (chat),
+ is_tab_label ? "chat-window-tab-image" : "chat-window-menu-image",
+ status_image);
+ g_object_set_data (G_OBJECT (chat),
+ is_tab_label ? "chat-window-tab-tooltip-widget" : "chat-window-menu-tooltip-widget",
+ event_box);
- close_button = gtk_button_new ();
- gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
- g_object_set_data (G_OBJECT (chat), "chat-window-tab-close-button", close_button);
+ gtk_container_add (GTK_CONTAINER (event_box), event_box_hbox);
+ gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, TRUE, 0);
- /* We don't want focus/keynav for the button to avoid clutter, and
- * Ctrl-W works anyway.
- */
- GTK_WIDGET_UNSET_FLAGS (close_button, GTK_CAN_FOCUS);
- GTK_WIDGET_UNSET_FLAGS (close_button, GTK_CAN_DEFAULT);
+ if (is_tab_label) {
+ close_button = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
+ g_object_set_data (G_OBJECT (chat), "chat-window-tab-close-button", close_button);
- /* Set the name to make the special rc style match. */
- gtk_widget_set_name (close_button, "empathy-close-button");
+ /* We don't want focus/keynav for the button to avoid clutter, and
+ * Ctrl-W works anyway.
+ */
+ GTK_WIDGET_UNSET_FLAGS (close_button, GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS (close_button, GTK_CAN_DEFAULT);
- close_image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
+ /* Set the name to make the special rc style match. */
+ gtk_widget_set_name (close_button, "empathy-close-button");
- gtk_container_add (GTK_CONTAINER (close_button), close_image);
+ close_image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
- gtk_container_add (GTK_CONTAINER (event_box), event_box_hbox);
- gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, TRUE, 0);
- gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (close_button), close_image);
- /* React to theme changes and also used to setup the initial size
- * correctly.
- */
- g_signal_connect (close_button,
- "style-set",
- G_CALLBACK (chat_window_close_button_style_set_cb),
- chat);
+ gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
- g_signal_connect (close_button,
- "clicked",
- G_CALLBACK (chat_window_close_clicked_cb),
- chat);
+ g_signal_connect (close_button,
+ "clicked",
+ G_CALLBACK (chat_window_close_clicked_cb),
+ chat);
+
+ /* React to theme changes and also setup the size correctly. */
+ g_signal_connect (hbox,
+ "style-set",
+ G_CALLBACK (chat_tab_style_set_cb),
+ chat);
+ }
gtk_widget_show_all (hbox);
@@ -279,6 +304,8 @@ chat_window_update (EmpathyChatWindow *window)
gboolean avatar_in_icon;
GtkWidget *chat;
GtkWidget *chat_close_button;
+ GtkWidget *submenu;
+ GtkWidget *menu;
/* Get information */
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
@@ -299,6 +326,13 @@ chat_window_update (EmpathyChatWindow *window)
gtk_action_set_sensitive (priv->menu_tabs_right, !last_page);
gtk_action_set_sensitive (priv->menu_conv_insert_smiley, is_connected);
+ /* Update Contact menu */
+ menu = gtk_ui_manager_get_widget (priv->ui_manager,
+ "/chats_menubar/menu_contact");
+ submenu = empathy_chat_get_contact_menu (priv->current_chat);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), submenu);
+ gtk_widget_show (menu);
+
/* Update window title */
if (n_chats == 1) {
gtk_window_set_title (GTK_WINDOW (priv->dialog), name);
@@ -390,6 +424,8 @@ chat_window_update_chat_tab (EmpathyChat *chat)
}
widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-image");
gtk_image_set_from_icon_name (GTK_IMAGE (widget), icon_name, GTK_ICON_SIZE_MENU);
+ widget = g_object_get_data (G_OBJECT (chat), "chat-window-menu-image");
+ gtk_image_set_from_icon_name (GTK_IMAGE (widget), icon_name, GTK_ICON_SIZE_MENU);
/* Update tab tooltip */
tooltip = g_string_new (NULL);
@@ -423,11 +459,15 @@ chat_window_update_chat_tab (EmpathyChat *chat)
markup = g_string_free (tooltip, FALSE);
widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-tooltip-widget");
gtk_widget_set_tooltip_markup (widget, markup);
+ widget = g_object_get_data (G_OBJECT (chat), "chat-window-menu-tooltip-widget");
+ gtk_widget_set_tooltip_markup (widget, markup);
g_free (markup);
- /* Update tab label */
+ /* Update tab and menu label */
widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-label");
gtk_label_set_text (GTK_LABEL (widget), name);
+ widget = g_object_get_data (G_OBJECT (chat), "chat-window-menu-label");
+ gtk_label_set_text (GTK_LABEL (widget), name);
/* Update the window if it's the current chat */
if (priv->current_chat == chat) {
@@ -488,20 +528,8 @@ chat_window_conv_activate_cb (GtkAction *action,
EmpathyChatWindow *window)
{
EmpathyChatWindowPriv *priv = GET_PRIV (window);
- GtkWidget *menu = NULL;
- GtkWidget *submenu = NULL;
gboolean is_room;
- /* Contact submenu */
- submenu = empathy_chat_get_contact_menu (priv->current_chat);
- if (submenu) {
- menu = gtk_ui_manager_get_widget (priv->ui_manager,
- "/chats_menubar/menu_conv/menu_conv_contact");
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu), submenu);
- gtk_widget_show (submenu);
- }
- gtk_action_set_visible (priv->menu_conv_contact, submenu != NULL);
-
/* Favorite room menu */
is_room = empathy_chat_is_room (priv->current_chat);
if (is_room) {
@@ -930,32 +958,23 @@ chat_window_new_message_cb (EmpathyChat *chat,
/* - if we're the sender, we play the sound if it's specified in the
* preferences and we're not away.
* - if we receive a message, we play the sound if it's specified in the
- * prefereces and the window does not have focus on the chat receiving
+ * preferences and the window does not have focus on the chat receiving
* the message.
*/
sender = empathy_message_get_sender (message);
- if (empathy_contact_is_user (sender) != FALSE) {
+ if (empathy_contact_is_user (sender)) {
empathy_sound_play (GTK_WIDGET (priv->dialog),
EMPATHY_SOUND_MESSAGE_OUTGOING);
- } else {
- if ((!has_focus || priv->current_chat != chat)) {
- empathy_sound_play (GTK_WIDGET (priv->dialog),
- EMPATHY_SOUND_MESSAGE_INCOMING);
- }
- }
-
- if (!has_focus) {
- chat_window_show_or_update_notification (window, message, chat);
}
if (has_focus && priv->current_chat == chat) {
return;
}
- /* If empathy_chat_is_room() returns TRUE, that means it's a named MUC.
- * If empathy_chat_get_remote_contact() returns NULL, that means it's
+ /* If empathy_chat_is_room () returns TRUE, that means it's a named MUC.
+ * If empathy_chat_get_remote_contact () returns NULL, that means it's
* an unamed MUC (msn-like).
* In case of a MUC, we set urgency only if the message contains our
* alias. */
@@ -966,8 +985,13 @@ chat_window_new_message_cb (EmpathyChat *chat,
needs_urgency = TRUE;
}
- if (needs_urgency && !has_focus) {
- chat_window_set_urgency_hint (window, TRUE);
+ if (needs_urgency) {
+ if (!has_focus)
+ chat_window_set_urgency_hint (window, TRUE);
+
+ empathy_sound_play (GTK_WIDGET (priv->dialog),
+ EMPATHY_SOUND_MESSAGE_INCOMING);
+ chat_window_show_or_update_notification (window, message, chat);
}
if (!g_list_find (priv->chats_new_msg, chat)) {
@@ -1213,7 +1237,7 @@ chat_window_drag_data_received (GtkWidget *widget,
/* We should return TRUE to remove the data when doing
* GDK_ACTION_MOVE, but we don't here otherwise it has
* weird consequences, and we handle that internally
- * anyway with add_chat() and remove_chat().
+ * anyway with add_chat () and remove_chat ().
*/
gtk_drag_finish (context, TRUE, FALSE, time);
}
@@ -1223,7 +1247,7 @@ chat_window_drag_data_received (GtkWidget *widget,
DEBUG ("DND tab");
- chat = (void*) selection->data;
+ chat = (void *) selection->data;
old_window = chat_window_find_chat (*chat);
if (old_window) {
@@ -1244,7 +1268,7 @@ chat_window_drag_data_received (GtkWidget *widget,
/* We should return TRUE to remove the data when doing
* GDK_ACTION_MOVE, but we don't here otherwise it has
* weird consequences, and we handle that internally
- * anyway with add_chat() and remove_chat().
+ * anyway with add_chat () and remove_chat ().
*/
gtk_drag_finish (context, TRUE, FALSE, time);
} else {
@@ -1326,7 +1350,6 @@ empathy_chat_window_init (EmpathyChatWindow *window)
"chat_vbox", &chat_vbox,
"ui_manager", &priv->ui_manager,
"menu_conv_insert_smiley", &priv->menu_conv_insert_smiley,
- "menu_conv_contact", &priv->menu_conv_contact,
"menu_conv_favorite", &priv->menu_conv_favorite,
"menu_edit_cut", &priv->menu_edit_cut,
"menu_edit_copy", &priv->menu_edit_copy,
@@ -1362,7 +1385,9 @@ empathy_chat_window_init (EmpathyChatWindow *window)
priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
priv->notebook = gtk_notebook_new ();
- gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow");
+ gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow");
+ gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
+ gtk_notebook_popup_enable (GTK_NOTEBOOK (priv->notebook));
gtk_box_pack_start (GTK_BOX (chat_vbox), priv->notebook, TRUE, TRUE, 0);
gtk_widget_show (priv->notebook);
@@ -1508,6 +1533,7 @@ empathy_chat_window_add_chat (EmpathyChatWindow *window,
{
EmpathyChatWindowPriv *priv;
GtkWidget *label;
+ GtkWidget *popup_label;
GtkWidget *child;
gint x, y, w, h;
@@ -1539,7 +1565,8 @@ empathy_chat_window_add_chat (EmpathyChatWindow *window,
}
child = GTK_WIDGET (chat);
- label = chat_window_create_label (window, chat);
+ label = chat_window_create_label (window, chat, TRUE);
+ popup_label = chat_window_create_label (window, chat, FALSE);
gtk_widget_show (child);
g_signal_connect (chat, "notify::name",
@@ -1553,11 +1580,11 @@ empathy_chat_window_add_chat (EmpathyChatWindow *window,
NULL);
chat_window_chat_notify_cb (chat);
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), child, label);
+ gtk_notebook_append_page_menu (GTK_NOTEBOOK (priv->notebook), child, label, popup_label);
gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook), child, TRUE);
gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook), child, TRUE);
gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (priv->notebook), child,
- TRUE, TRUE, GTK_PACK_START);
+ TRUE, TRUE, GTK_PACK_START);
DEBUG ("Chat added (%d references)", G_OBJECT (chat)->ref_count);
}
@@ -1713,6 +1740,6 @@ empathy_chat_window_present_chat (EmpathyChat *chat)
empathy_chat_window_switch_to_chat (window, chat);
empathy_window_present (GTK_WINDOW (priv->dialog), TRUE);
- gtk_widget_grab_focus (chat->input_text_view);
+ gtk_widget_grab_focus (chat->input_text_view);
}
diff --git a/src/empathy-chat-window.h b/src/empathy-chat-window.h
index 8b7fe06a9..835d67296 100644
--- a/src/empathy-chat-window.h
+++ b/src/empathy-chat-window.h
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Mikael Hallendal <micke@imendio.com>
* Richard Hult <richard@imendio.com>
* Martyn Russell <martyn@imendio.com>
diff --git a/src/empathy-chat-window.ui b/src/empathy-chat-window.ui
index a347a454e..0d5a83180 100644
--- a/src/empathy-chat-window.ui
+++ b/src/empathy-chat-window.ui
@@ -26,12 +26,6 @@
</object>
</child>
<child>
- <object class="GtkAction" id="menu_conv_contact">
- <property name="name">menu_conv_contact</property>
- <property name="label" translatable="yes">_Contact</property>
- </object>
- </child>
- <child>
<object class="GtkToggleAction" id="menu_conv_favorite">
<property name="name">menu_conv_favorite</property>
<property name="label" translatable="yes">_Favorite Chatroom</property>
@@ -45,6 +39,12 @@
<accelerator key="W" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
+ <object class="GtkAction" id="menu_contact">
+ <property name="name">menu_contact</property>
+ <property name="label" translatable="yes">_Contact</property>
+ </object>
+ </child>
+ <child>
<object class="GtkAction" id="menu_edit">
<property name="name">menu_edit</property>
<property name="label" translatable="yes">_Edit</property>
@@ -136,11 +136,11 @@
<menu action="menu_conv">
<menuitem action="menu_conv_clear"/>
<menuitem action="menu_conv_insert_smiley"/>
- <menuitem action="menu_conv_contact"/>
<menuitem action="menu_conv_favorite"/>
<separator/>
<menuitem action="menu_conv_close"/>
</menu>
+ <menu action="menu_contact" />
<menu action="menu_edit">
<menuitem action="menu_edit_cut"/>
<menuitem action="menu_edit_copy"/>
diff --git a/src/empathy-chatrooms-window.c b/src/empathy-chatrooms-window.c
index fa63d5a51..a0fb8e6ec 100644
--- a/src/empathy-chatrooms-window.c
+++ b/src/empathy-chatrooms-window.c
@@ -15,8 +15,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Xavier Claessens <xclaesse@gmail.com>
* Martyn Russell <martyn@imendio.com>
@@ -154,7 +154,7 @@ empathy_chatrooms_window_show (GtkWindow *parent)
empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser),
empathy_account_chooser_filter_is_connected,
NULL);
- g_object_set (window->account_chooser,
+ g_object_set (window->account_chooser,
"has-all-option", TRUE,
NULL);
empathy_account_chooser_set_account (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser), NULL);
@@ -222,7 +222,7 @@ chatrooms_window_model_setup (EmpathyChatroomsWindow *window)
gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
- /* Selection */
+ /* Selection */
selection = gtk_tree_view_get_selection (view);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
@@ -273,8 +273,8 @@ chatrooms_window_model_add_columns (EmpathyChatroomsWindow *window)
/* Room */
cell = gtk_cell_renderer_text_new ();
- column = gtk_tree_view_column_new_with_attributes (_("Room"), cell,
- "text", COL_ROOM,
+ column = gtk_tree_view_column_new_with_attributes (_("Room"), cell,
+ "text", COL_ROOM,
NULL);
count = gtk_tree_view_append_column (view, column);
gtk_tree_view_column_set_sort_column_id (column, count - 1);
@@ -293,7 +293,7 @@ chatrooms_window_model_add_columns (EmpathyChatroomsWindow *window)
window);
/* Sort model */
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0,
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0,
GTK_SORT_ASCENDING);
}
@@ -323,7 +323,7 @@ chatrooms_window_model_refresh_data (EmpathyChatroomsWindow *window,
chatrooms = empathy_chatroom_manager_get_chatrooms (window->manager, account);
/* Sort out columns, we only show the server column for
- * selected protocol types, such as Jabber.
+ * selected protocol types, such as Jabber.
*/
if (account) {
column = gtk_tree_view_get_column (view, window->room_column);
diff --git a/src/empathy-chatrooms-window.h b/src/empathy-chatrooms-window.h
index 727188f01..1d8476ecc 100644
--- a/src/empathy-chatrooms-window.h
+++ b/src/empathy-chatrooms-window.h
@@ -15,8 +15,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Xavier Claessens <xclaesse@gmail.com>
* Martyn Russell <martyn@imendio.com>
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c
index 7d8721c3e..81d98ef74 100644
--- a/src/empathy-event-manager.c
+++ b/src/empathy-event-manager.c
@@ -14,7 +14,7 @@
* 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>
* Sjoerd Simons <sjoerd.simons@collabora.co.uk>
*/
@@ -373,8 +373,7 @@ event_channel_process_voip_func (EventPriv *event)
return;
}
- dialog = gtk_message_dialog_new (GTK_WINDOW (empathy_main_window_get()),
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ dialog = gtk_message_dialog_new (NULL, 0,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("Incoming call"));
gtk_message_dialog_format_secondary_text (
GTK_MESSAGE_DIALOG (dialog),
@@ -573,7 +572,7 @@ static void
event_manager_tube_dispatch_ability_cb (GObject *object,
GParamSpec *spec, gpointer user_data)
{
- EventManagerApproval *approval = (EventManagerApproval *)user_data;
+ EventManagerApproval *approval = (EventManagerApproval *) user_data;
EmpathyTubeDispatchAbility dispatchability;
dispatchability =
@@ -594,7 +593,7 @@ event_manager_tube_got_contact_cb (EmpathyTpContactFactory *factory,
gpointer user_data,
GObject *object)
{
- EventManagerApproval *approval = (EventManagerApproval *)user_data;
+ EventManagerApproval *approval = (EventManagerApproval *) user_data;
EmpathyTubeDispatchAbility dispatchability;
if (error != NULL)
@@ -753,6 +752,32 @@ event_manager_muc_invite_got_contact_cb (EmpathyTpContactFactory *factory,
}
static void
+event_manager_ft_got_contact_cb (EmpathyTpContactFactory *factory,
+ EmpathyContact *contact,
+ const GError *error,
+ gpointer user_data,
+ GObject *object)
+{
+ EventManagerApproval *approval = (EventManagerApproval *) user_data;
+ char *header;
+
+ approval->contact = contact;
+
+ header = g_strdup_printf (_("Incoming file transfer from %s"),
+ empathy_contact_get_name (approval->contact));
+
+ event_manager_add (approval->manager, approval->contact,
+ EMPATHY_IMAGE_DOCUMENT_SEND, header, NULL, approval,
+ event_channel_process_func, NULL);
+
+ /* FIXME better sound for incoming file transfers ?*/
+ empathy_sound_play (empathy_main_window_get (),
+ EMPATHY_SOUND_CONVERSATION_NEW);
+
+ g_free (header);
+}
+
+static void
event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher,
EmpathyDispatchOperation *operation, EmpathyEventManager *manager)
{
@@ -840,26 +865,23 @@ event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher,
}
else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER))
{
- EmpathyTpFile *file;
- gchar *header;
-
- file = EMPATHY_TP_FILE (empathy_dispatch_operation_get_channel_wrapper (operation));
- approval->contact = g_object_ref (empathy_tp_file_get_contact (file));
-
- header = g_strdup_printf (_("Incoming file transfer from %s"),
- empathy_contact_get_name (approval->contact));
+ TpChannel *channel;
+ TpConnection *connection;
+ TpHandle handle;
+ EmpathyTpContactFactory *factory;
- event_manager_add (manager, approval->contact, EMPATHY_IMAGE_DOCUMENT_SEND,
- header, NULL, approval, event_channel_process_func, NULL);
+ channel = empathy_dispatch_operation_get_channel (operation);
+ handle = tp_channel_get_handle (channel, NULL);
- /* FIXME better sound for incoming file transfers ?*/
- empathy_sound_play (empathy_main_window_get (),
- EMPATHY_SOUND_CONVERSATION_NEW);
+ connection = tp_channel_borrow_connection (channel);
+ factory = empathy_tp_contact_factory_dup_singleton (connection);
+ empathy_tp_contact_factory_get_from_handle (factory, handle,
+ event_manager_ft_got_contact_cb, approval, NULL, G_OBJECT (manager));
- g_free (header);
+ g_object_unref (factory);
}
- else if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE) ||
- !tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
+ else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE) ||
+ !tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
{
TpChannel *channel;
TpHandle handle;
@@ -882,7 +904,7 @@ event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher,
}
else
{
- DEBUG ("Unknown channel type, ignoring..");
+ DEBUG ("Unknown channel type (%s), ignoring..", channel_type);
}
}
@@ -1054,7 +1076,7 @@ empathy_event_manager_get_top_event (EmpathyEventManager *manager)
void
empathy_event_activate (EmpathyEvent *event_public)
{
- EventPriv *event = (EventPriv*) event_public;
+ EventPriv *event = (EventPriv *) event_public;
g_return_if_fail (event_public != NULL);
diff --git a/src/empathy-ft-manager.c b/src/empathy-ft-manager.c
index 98e58d4f3..bc4f2a7b7 100644
--- a/src/empathy-ft-manager.c
+++ b/src/empathy-ft-manager.c
@@ -1,8 +1,7 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2003, 2004 Xan Lopez
* Copyright (C) 2007 Marco Barisione <marco@barisione.org>
- * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008-2009 Collabora Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -16,13 +15,14 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Xan Lopez
* Marco Barisione <marco@barisione.org>
* Jonny Lamb <jonny.lamb@collabora.co.uk>
* Xavier Claessens <xclaesse@gmail.com>
+ * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
*/
/* The original file transfer manager code was copied from Epiphany */
@@ -46,19 +46,6 @@
#include "empathy-ft-manager.h"
-#include "extensions/extensions.h"
-
-/**
- * SECTION:empathy-ft-manager
- * @short_description: File transfer dialog
- * @see_also: #EmpathyTpFile, empathy_dispatcher_send_file()
- * @include: libempthy-gtk/empathy-ft-manager.h
- *
- * The #EmpathyFTManager object represents the file transfer dialog,
- * it can show multiple file transfers at the same time (added
- * with empathy_ft_manager_add_tp_file()).
- */
-
enum
{
COL_PERCENT,
@@ -68,24 +55,19 @@ enum
COL_FT_OBJECT
};
-/**
- * EmpathyFTManagerPriv:
- *
- * Private fields of the #EmpathyFTManager class.
- */
-struct _EmpathyFTManagerPriv
-{
+typedef struct {
GtkTreeModel *model;
- GHashTable *tp_file_to_row_ref;
+ GHashTable *ft_handler_to_row_ref;
/* Widgets */
GtkWidget *window;
GtkWidget *treeview;
GtkWidget *open_button;
GtkWidget *abort_button;
+ GtkWidget *clear_button;
guint save_geometry_id;
-};
+} EmpathyFTManagerPriv;
enum
{
@@ -96,10 +78,15 @@ enum
G_DEFINE_TYPE (EmpathyFTManager, empathy_ft_manager, G_TYPE_OBJECT);
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyFTManager)
+
static EmpathyFTManager *manager_singleton = NULL;
+static void ft_handler_hashing_started_cb (EmpathyFTHandler *handler,
+ EmpathyFTManager *manager);
+
static gchar *
-ft_manager_format_interval (gint interval)
+ft_manager_format_interval (guint interval)
{
gint hours, mins, secs;
@@ -117,235 +104,62 @@ ft_manager_format_interval (gint interval)
return g_strdup_printf (_("%02u.%02u"), mins, secs);
}
-static GtkTreeRowReference *
-ft_manager_get_row_from_tp_file (EmpathyFTManager *ft_manager,
- EmpathyTpFile *tp_file)
-{
- return g_hash_table_lookup (ft_manager->priv->tp_file_to_row_ref, tp_file);
-}
-
static void
-ft_manager_update_buttons (EmpathyFTManager *ft_manager)
+ft_manager_update_buttons (EmpathyFTManager *manager)
{
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
- EmpathyTpFile *tp_file;
- TpFileTransferState state;
+ EmpathyFTHandler *handler;
gboolean open_enabled = FALSE;
gboolean abort_enabled = FALSE;
+ gboolean clear_enabled = FALSE;
+ gboolean is_completed, is_cancelled;
+ GHashTableIter hash_iter;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (
- ft_manager->priv->treeview));
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
- gtk_tree_model_get (model, &iter, COL_FT_OBJECT, &tp_file, -1);
- state = empathy_tp_file_get_state (tp_file, NULL);
+ gtk_tree_model_get (model, &iter, COL_FT_OBJECT, &handler, -1);
+
+ is_completed = empathy_ft_handler_is_completed (handler);
+ is_cancelled = empathy_ft_handler_is_cancelled (handler);
/* I can open the file if the transfer is completed and was incoming */
- open_enabled = (state == TP_FILE_TRANSFER_STATE_COMPLETED &&
- empathy_tp_file_is_incoming (tp_file));
+ open_enabled = (is_completed && empathy_ft_handler_is_incoming (handler));
/* I can abort if the transfer is not already finished */
- abort_enabled = (state != TP_FILE_TRANSFER_STATE_CANCELLED &&
- state != TP_FILE_TRANSFER_STATE_COMPLETED);
+ abort_enabled = (is_cancelled == FALSE && is_completed == FALSE);
- g_object_unref (tp_file);
+ g_object_unref (handler);
}
- gtk_widget_set_sensitive (ft_manager->priv->open_button, open_enabled);
- gtk_widget_set_sensitive (ft_manager->priv->abort_button, abort_enabled);
-}
+ g_hash_table_iter_init (&hash_iter, priv->ft_handler_to_row_ref);
-static const gchar *
-ft_manager_state_change_reason_to_string (TpFileTransferStateChangeReason reason)
-{
- switch (reason)
+ while (g_hash_table_iter_next (&hash_iter, (gpointer *) &handler, NULL))
{
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_NONE:
- return _("No reason was specified");
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED:
- return _("The change in state was requested");
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_STOPPED:
- return _("You canceled the file transfer");
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_STOPPED:
- return _("The other participant canceled the file transfer");
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_ERROR:
- return _("Error while trying to transfer the file");
- case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_ERROR:
- return _("The other participant is unable to transfer the file");
- }
- return _("Unknown reason");
-}
-
-static void
-ft_manager_update_ft_row (EmpathyFTManager *ft_manager,
- EmpathyTpFile *tp_file)
-{
- GtkTreeRowReference *row_ref;
- GtkTreePath *path;
- GtkTreeIter iter;
- const gchar *filename;
- const gchar *contact_name;
- const gchar *msg;
- gchar *msg_dup = NULL;
- gchar *remaining_str = NULL;
- gchar *first_line_format;
- gchar *first_line = NULL;
- gchar *second_line = NULL;
- guint64 transferred_bytes;
- guint64 total_size;
- gint remaining = -1;
- gint percent;
- TpFileTransferState state;
- TpFileTransferStateChangeReason reason;
- gboolean incoming;
-
- row_ref = ft_manager_get_row_from_tp_file (ft_manager, tp_file);
- g_return_if_fail (row_ref != NULL);
-
- filename = empathy_tp_file_get_filename (tp_file);
- contact_name = empathy_contact_get_name (empathy_tp_file_get_contact (tp_file));
- transferred_bytes = empathy_tp_file_get_transferred_bytes (tp_file);
- total_size = empathy_tp_file_get_size (tp_file);
- state = empathy_tp_file_get_state (tp_file, &reason);
- incoming = empathy_tp_file_is_incoming (tp_file);
+ if (empathy_ft_handler_is_completed (handler) ||
+ empathy_ft_handler_is_cancelled (handler))
+ clear_enabled = TRUE;
- switch (state)
- {
- case TP_FILE_TRANSFER_STATE_NONE:
- /* This should never happen, the CM is broken. But we avoid warning
- * because it's not our fault. */
- DEBUG ("State is NONE, probably a broken CM");
+ if (clear_enabled)
break;
- case TP_FILE_TRANSFER_STATE_PENDING:
- case TP_FILE_TRANSFER_STATE_OPEN:
- case TP_FILE_TRANSFER_STATE_ACCEPTED:
- if (incoming)
- /* translators: first %s is filename, second %s is the contact name */
- first_line_format = _("Receiving \"%s\" from %s");
- else
- /* translators: first %s is filename, second %s is the contact name */
- first_line_format = _("Sending \"%s\" to %s");
-
- first_line = g_strdup_printf (first_line_format, filename, contact_name);
-
- if (state == TP_FILE_TRANSFER_STATE_OPEN || incoming)
- {
- gchar *total_size_str;
- gchar *transferred_bytes_str;
-
- if (total_size == EMPATHY_TP_FILE_UNKNOWN_SIZE)
- total_size_str = g_strdup (C_("file size", "Unknown"));
- else
- total_size_str = g_format_size_for_display (total_size);
-
- transferred_bytes_str = g_format_size_for_display (transferred_bytes);
-
- /* translators: first %s is the transferred size, second %s is
- * the total file size */
- second_line = g_strdup_printf (_("%s of %s"), transferred_bytes_str,
- total_size_str);
- g_free (transferred_bytes_str);
- g_free (total_size_str);
-
- }
- else
- second_line = g_strdup (_("Waiting for the other participant's response"));
-
- remaining = empathy_tp_file_get_remaining_time (tp_file);
- break;
-
- case TP_FILE_TRANSFER_STATE_COMPLETED:
- if (incoming)
- /* translators: first %s is filename, second %s
- * is the contact name */
- first_line = g_strdup_printf (
- _("\"%s\" received from %s"), filename,
- contact_name);
- else
- /* translators: first %s is filename, second %s
- * is the contact name */
- first_line = g_strdup_printf (
- _("\"%s\" sent to %s"), filename,
- contact_name);
-
- second_line = g_strdup (_("File transfer completed"));
-
- break;
-
- case TP_FILE_TRANSFER_STATE_CANCELLED:
- if (incoming)
- /* translators: first %s is filename, second %s
- * is the contact name */
- first_line = g_strdup_printf (
- _("\"%s\" receiving from %s"), filename,
- contact_name);
- else
- /* translators: first %s is filename, second %s
- * is the contact name */
- first_line = g_strdup_printf (
- _("\"%s\" sending to %s"), filename,
- contact_name);
-
- second_line = g_strdup_printf (_("File transfer canceled: %s"),
- ft_manager_state_change_reason_to_string (reason));
-
- break;
- }
-
- if (total_size != EMPATHY_TP_FILE_UNKNOWN_SIZE && total_size != 0)
- percent = transferred_bytes * 100 / total_size;
- else
- percent = -1;
-
- if (remaining < 0)
- {
- if (state != TP_FILE_TRANSFER_STATE_COMPLETED &&
- state != TP_FILE_TRANSFER_STATE_CANCELLED)
- remaining_str = g_strdup (C_("remaining time", "Unknown"));
}
- else
- remaining_str = ft_manager_format_interval (remaining);
-
- if (first_line != NULL && second_line != NULL)
- msg = msg_dup = g_strdup_printf ("%s\n%s", first_line, second_line);
- else
- msg = first_line ? first_line : second_line;
-
- /* Set new values in the store */
- path = gtk_tree_row_reference_get_path (row_ref);
- gtk_tree_model_get_iter (ft_manager->priv->model, &iter, path);
- gtk_list_store_set (GTK_LIST_STORE (ft_manager->priv->model),
- &iter,
- COL_PERCENT, percent,
- COL_MESSAGE, msg ? msg : "",
- COL_REMAINING, remaining_str ? remaining_str : "",
- -1);
-
- gtk_tree_path_free (path);
-
- g_free (msg_dup);
- g_free (first_line);
- g_free (second_line);
- g_free (remaining_str);
- ft_manager_update_buttons (ft_manager);
-}
+ gtk_widget_set_sensitive (priv->open_button, open_enabled);
+ gtk_widget_set_sensitive (priv->abort_button, abort_enabled);
-static void
-ft_manager_transferred_bytes_changed_cb (EmpathyTpFile *tp_file,
- GParamSpec *pspec,
- EmpathyFTManager *ft_manager)
-{
- ft_manager_update_ft_row (ft_manager, tp_file);
+ if (clear_enabled)
+ gtk_widget_set_sensitive (priv->clear_button, TRUE);
}
static void
ft_manager_selection_changed (GtkTreeSelection *selection,
- EmpathyFTManager *ft_manager)
+ EmpathyFTManager *manager)
{
- ft_manager_update_buttons (ft_manager);
+ ft_manager_update_buttons (manager);
}
static void
@@ -369,79 +183,57 @@ ft_manager_progress_cell_data_func (GtkTreeViewColumn *col,
g_object_set (renderer, "text", text, "value", percent, NULL);
}
-static gboolean
-ft_manager_save_geometry_timeout_cb (EmpathyFTManager *ft_manager)
-{
- gint x, y, w, h;
-
- gtk_window_get_size (GTK_WINDOW (ft_manager->priv->window), &w, &h);
- gtk_window_get_position (GTK_WINDOW (ft_manager->priv->window), &x, &y);
-
- empathy_geometry_save ("ft-manager", x, y, w, h);
-
- ft_manager->priv->save_geometry_id = 0;
-
- return FALSE;
-}
-
-static gboolean
-ft_manager_configure_event_cb (GtkWidget *widget,
- GdkEventConfigure *event,
- EmpathyFTManager *ft_manager)
+static GtkTreeRowReference *
+ft_manager_get_row_from_handler (EmpathyFTManager *manager,
+ EmpathyFTHandler *handler)
{
- if (ft_manager->priv->save_geometry_id != 0)
- g_source_remove (ft_manager->priv->save_geometry_id);
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
- ft_manager->priv->save_geometry_id = g_timeout_add (500,
- (GSourceFunc) ft_manager_save_geometry_timeout_cb, ft_manager);
-
- return FALSE;
+ return g_hash_table_lookup (priv->ft_handler_to_row_ref, handler);
}
static void
-ft_manager_remove_file_from_model (EmpathyFTManager *ft_manager,
- EmpathyTpFile *tp_file)
+ft_manager_remove_file_from_model (EmpathyFTManager *manager,
+ EmpathyFTHandler *handler)
{
GtkTreeRowReference *row_ref;
GtkTreeSelection *selection;
GtkTreePath *path = NULL;
GtkTreeIter iter;
gboolean update_selection;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
- row_ref = ft_manager_get_row_from_tp_file (ft_manager, tp_file);
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
g_return_if_fail (row_ref);
DEBUG ("Removing file transfer from window: contact=%s, filename=%s",
- empathy_contact_get_name (empathy_tp_file_get_contact (tp_file)),
- empathy_tp_file_get_filename (tp_file));
+ empathy_contact_get_name (empathy_ft_handler_get_contact (handler)),
+ empathy_ft_handler_get_filename (handler));
/* Get the iter from the row_ref */
path = gtk_tree_row_reference_get_path (row_ref);
- gtk_tree_model_get_iter (ft_manager->priv->model, &iter, path);
+ gtk_tree_model_get_iter (priv->model, &iter, path);
gtk_tree_path_free (path);
/* We have to update the selection only if we are removing the selected row */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ft_manager->priv->treeview));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
update_selection = gtk_tree_selection_iter_is_selected (selection, &iter);
/* Remove tp_file's row. After that iter points to the next row */
- if (!gtk_list_store_remove (GTK_LIST_STORE (ft_manager->priv->model), &iter))
+ if (!gtk_list_store_remove (GTK_LIST_STORE (priv->model), &iter))
{
gint n_row;
/* There is no next row, set iter to the last row */
- n_row = gtk_tree_model_iter_n_children (ft_manager->priv->model, NULL);
+ n_row = gtk_tree_model_iter_n_children (priv->model, NULL);
if (n_row > 0)
- gtk_tree_model_iter_nth_child (ft_manager->priv->model, &iter, NULL,
- n_row - 1);
+ gtk_tree_model_iter_nth_child (priv->model, &iter, NULL, n_row - 1);
else
update_selection = FALSE;
}
if (update_selection)
gtk_tree_selection_select_iter (selection, &iter);
-
- empathy_tp_file_close (tp_file);
}
static gboolean
@@ -449,113 +241,679 @@ remove_finished_transfer_foreach (gpointer key,
gpointer value,
gpointer user_data)
{
- EmpathyTpFile *tp_file = EMPATHY_TP_FILE (key);
- EmpathyFTManager *self = EMPATHY_FT_MANAGER (user_data);
- TpFileTransferState state;
+ EmpathyFTHandler *handler = key;
+ EmpathyFTManager *manager = user_data;
- state = empathy_tp_file_get_state (tp_file, NULL);
- if (state == TP_FILE_TRANSFER_STATE_COMPLETED ||
- state == TP_FILE_TRANSFER_STATE_CANCELLED)
+ if (empathy_ft_handler_is_completed (handler) ||
+ empathy_ft_handler_is_cancelled (handler))
{
- ft_manager_remove_file_from_model (self, tp_file);
+ ft_manager_remove_file_from_model (manager, handler);
return TRUE;
}
return FALSE;
}
+static gchar *
+ft_manager_format_progress_bytes_and_percentage (guint64 current,
+ guint64 total,
+ gdouble speed,
+ int *percentage)
+{
+ char *total_str, *current_str, *retval;
+ char *speed_str = NULL;
+
+ total_str = g_format_size_for_display (total);
+ current_str = g_format_size_for_display (current);
+
+ if (speed > 0)
+ speed_str = g_format_size_for_display ((goffset) speed);
+
+ /* translators: first %s is the currently processed size, second %s is
+ * the total file size */
+ retval = speed_str ?
+ g_strdup_printf (_("%s of %s at %s/s"), current_str, total_str, speed_str) :
+ g_strdup_printf (_("%s of %s"), current_str, total_str);
+
+ g_free (total_str);
+ g_free (current_str);
+ g_free (speed_str);
+
+ if (percentage != NULL)
+ {
+ if (total != 0)
+ *percentage = current * 100 / total;
+ else
+ *percentage = -1;
+ }
+
+ return retval;
+}
+
+static gchar *
+ft_manager_format_contact_info (EmpathyFTHandler *handler)
+{
+ gboolean incoming;
+ const char *filename, *contact_name, *first_line_format;
+ char *retval;
+
+ incoming = empathy_ft_handler_is_incoming (handler);
+ contact_name = empathy_contact_get_name
+ (empathy_ft_handler_get_contact (handler));
+ filename = empathy_ft_handler_get_filename (handler);
+
+ if (incoming)
+ /* translators: first %s is filename, second %s is the contact name */
+ first_line_format = _("Receiving \"%s\" from %s");
+ else
+ /* translators: first %s is filename, second %s is the contact name */
+ first_line_format = _("Sending \"%s\" to %s");
+
+ retval = g_strdup_printf (first_line_format, filename, contact_name);
+
+ return retval;
+}
+
+static gchar *
+ft_manager_format_error_message (EmpathyFTHandler *handler,
+ const GError *error)
+{
+ const char *contact_name, *filename;
+ EmpathyContact *contact;
+ char *first_line, *message;
+ gboolean incoming;
+
+ contact_name = NULL;
+ incoming = empathy_ft_handler_is_incoming (handler);
+
+ contact = empathy_ft_handler_get_contact (handler);
+ if (contact)
+ contact_name = empathy_contact_get_name (contact);
+
+ filename = empathy_ft_handler_get_filename (handler);
+
+ if (incoming)
+ /* filename/contact_name here are either both NULL or both valid */
+ if (filename && contact_name)
+ /* translators: first %s is filename, second %s
+ * is the contact name */
+ first_line = g_strdup_printf (_("Error receiving \"%s\" from %s"), filename,
+ contact_name);
+ else
+ first_line = g_strdup (_("Error receiving a file"));
+ else
+ /* translators: first %s is filename, second %s
+ * is the contact name */
+ if (filename && contact_name)
+ first_line = g_strdup_printf (_("Error sending \"%s\" to %s"), filename,
+ contact_name);
+ else
+ first_line = g_strdup (_("Error sending a file"));
+
+ message = g_strdup_printf ("%s\n%s", first_line, error->message);
+
+ g_free (first_line);
+
+ return message;
+}
+
+static void
+ft_manager_update_handler_message (EmpathyFTManager *manager,
+ GtkTreeRowReference *row_ref,
+ const char *message)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+
+ /* Set new value in the store */
+ path = gtk_tree_row_reference_get_path (row_ref);
+ gtk_tree_model_get_iter (priv->model, &iter, path);
+ gtk_list_store_set (GTK_LIST_STORE (priv->model),
+ &iter,
+ COL_MESSAGE, message ? message : "",
+ -1);
+
+ gtk_tree_path_free (path);
+}
+
+static void
+ft_manager_update_handler_progress (EmpathyFTManager *manager,
+ GtkTreeRowReference *row_ref,
+ int percentage)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+
+ /* Set new value in the store */
+ path = gtk_tree_row_reference_get_path (row_ref);
+ gtk_tree_model_get_iter (priv->model, &iter, path);
+ gtk_list_store_set (GTK_LIST_STORE (priv->model),
+ &iter,
+ COL_PERCENT, percentage,
+ -1);
+
+ gtk_tree_path_free (path);
+
+}
+
+static void
+ft_manager_update_handler_time (EmpathyFTManager *manager,
+ GtkTreeRowReference *row_ref,
+ guint remaining_time)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+ char *remaining_str;
+
+ remaining_str = ft_manager_format_interval (remaining_time);
+
+ /* Set new value in the store */
+ path = gtk_tree_row_reference_get_path (row_ref);
+ gtk_tree_model_get_iter (priv->model, &iter, path);
+ gtk_list_store_set (GTK_LIST_STORE (priv->model),
+ &iter,
+ COL_REMAINING, remaining_str,
+ -1);
+
+ gtk_tree_path_free (path);
+ g_free (remaining_str);
+}
+
+static void
+ft_manager_clear_handler_time (EmpathyFTManager *manager,
+ GtkTreeRowReference *row_ref)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+
+ /* Set new value in the store */
+ path = gtk_tree_row_reference_get_path (row_ref);
+ gtk_tree_model_get_iter (priv->model, &iter, path);
+ gtk_list_store_set (GTK_LIST_STORE (priv->model),
+ &iter,
+ COL_REMAINING, NULL,
+ -1);
+
+ gtk_tree_path_free (path);
+}
+
+static void
+ft_handler_transfer_error_cb (EmpathyFTHandler *handler,
+ GError *error,
+ EmpathyFTManager *manager)
+{
+ char *message;
+ GtkTreeRowReference *row_ref;
+
+ DEBUG ("Transfer error %s", error->message);
+
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
+ g_return_if_fail (row_ref != NULL);
+
+ message = ft_manager_format_error_message (handler, error);
+
+ ft_manager_update_handler_message (manager, row_ref, message);
+ ft_manager_clear_handler_time (manager, row_ref);
+ ft_manager_update_buttons (manager);
+
+ g_free (message);
+}
+
+static void
+do_real_transfer_done (EmpathyFTManager *manager,
+ EmpathyFTHandler *handler)
+{
+ const char *contact_name;
+ const char *filename;
+ char *first_line, *second_line, *message;
+ char *uri;
+ gboolean incoming;
+ GtkTreeRowReference *row_ref;
+ GtkRecentManager *recent_manager;
+ GFile *file;
+
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
+ g_return_if_fail (row_ref != NULL);
+
+ incoming = empathy_ft_handler_is_incoming (handler);
+ contact_name = empathy_contact_get_name
+ (empathy_ft_handler_get_contact (handler));
+ filename = empathy_ft_handler_get_filename (handler);
+
+ if (incoming)
+ /* translators: first %s is filename, second %s
+ * is the contact name */
+ first_line = g_strdup_printf (_("\"%s\" received from %s"), filename,
+ contact_name);
+ else
+ /* translators: first %s is filename, second %s
+ * is the contact name */
+ first_line = g_strdup_printf (_("\"%s\" sent to %s"), filename,
+ contact_name);
+
+ second_line = g_strdup (_("File transfer completed"));
+
+ message = g_strdup_printf ("%s\n%s", first_line, second_line);
+ ft_manager_update_handler_message (manager, row_ref, message);
+ ft_manager_clear_handler_time (manager, row_ref);
+
+ /* update buttons */
+ ft_manager_update_buttons (manager);
+
+ g_free (message);
+ g_free (first_line);
+ g_free (second_line);
+
+ recent_manager = gtk_recent_manager_get_default ();
+ file = empathy_ft_handler_get_gfile (handler);
+ uri = g_file_get_uri (file);
+
+ gtk_recent_manager_add_item (recent_manager, uri);
+
+ g_free (uri);
+}
+
+static void
+ft_handler_transfer_done_cb (EmpathyFTHandler *handler,
+ EmpathyTpFile *tp_file,
+ EmpathyFTManager *manager)
+{
+ if (empathy_ft_handler_is_incoming (handler) &&
+ empathy_ft_handler_get_use_hash (handler))
+ {
+ DEBUG ("Transfer done, waiting for hashing-started");
+
+ /* connect to the signal and return early */
+ g_signal_connect (handler, "hashing-started",
+ G_CALLBACK (ft_handler_hashing_started_cb), manager);
+
+ return;
+ }
+
+ DEBUG ("Transfer done, no hashing");
+
+ do_real_transfer_done (manager, handler);
+}
+
+static void
+ft_handler_transfer_progress_cb (EmpathyFTHandler *handler,
+ guint64 current_bytes,
+ guint64 total_bytes,
+ guint remaining_time,
+ gdouble speed,
+ EmpathyFTManager *manager)
+{
+ char *first_line, *second_line, *message;
+ int percentage;
+ GtkTreeRowReference *row_ref;
+
+ DEBUG ("Transfer progress");
+
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
+ g_return_if_fail (row_ref != NULL);
+
+ first_line = ft_manager_format_contact_info (handler);
+ second_line = ft_manager_format_progress_bytes_and_percentage
+ (current_bytes, total_bytes, speed, &percentage);
+
+ message = g_strdup_printf ("%s\n%s", first_line, second_line);
+
+ ft_manager_update_handler_message (manager, row_ref, message);
+ ft_manager_update_handler_progress (manager, row_ref, percentage);
+
+ if (remaining_time > 0)
+ ft_manager_update_handler_time (manager, row_ref, remaining_time);
+
+ g_free (message);
+ g_free (first_line);
+ g_free (second_line);
+}
+
+static void
+ft_handler_transfer_started_cb (EmpathyFTHandler *handler,
+ EmpathyTpFile *tp_file,
+ EmpathyFTManager *manager)
+{
+ guint64 transferred_bytes, total_bytes;
+
+ DEBUG ("Transfer started");
+
+ g_signal_connect (handler, "transfer-progress",
+ G_CALLBACK (ft_handler_transfer_progress_cb), manager);
+ g_signal_connect (handler, "transfer-done",
+ G_CALLBACK (ft_handler_transfer_done_cb), manager);
+
+ transferred_bytes = empathy_ft_handler_get_transferred_bytes (handler);
+ total_bytes = empathy_ft_handler_get_total_bytes (handler);
+
+ ft_handler_transfer_progress_cb (handler, transferred_bytes, total_bytes,
+ 0, -1, manager);
+}
+
+static void
+ft_handler_hashing_done_cb (EmpathyFTHandler *handler,
+ EmpathyFTManager *manager)
+{
+ GtkTreeRowReference *row_ref;
+ char *first_line, *second_line, *message;
+
+ DEBUG ("Hashing done");
+
+ /* update the message */
+ if (empathy_ft_handler_is_incoming (handler))
+ {
+ do_real_transfer_done (manager, handler);
+ return;
+ }
+
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
+ g_return_if_fail (row_ref != NULL);
+
+ first_line = ft_manager_format_contact_info (handler);
+ second_line = g_strdup (_("Waiting for the other participant's response"));
+ message = g_strdup_printf ("%s\n%s", first_line, second_line);
+
+ ft_manager_update_handler_message (manager, row_ref, message);
+
+ g_free (message);
+ g_free (first_line);
+ g_free (second_line);
+
+ g_signal_connect (handler, "transfer-started",
+ G_CALLBACK (ft_handler_transfer_started_cb), manager);
+}
+
+static void
+ft_handler_hashing_progress_cb (EmpathyFTHandler *handler,
+ guint64 current_bytes,
+ guint64 total_bytes,
+ EmpathyFTManager *manager)
+{
+ char *first_line, *second_line, *message;
+ GtkTreeRowReference *row_ref;
+
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
+ g_return_if_fail (row_ref != NULL);
+
+ if (empathy_ft_handler_is_incoming (handler))
+ first_line = g_strdup_printf (_("Checking integrity of \"%s\""),
+ empathy_ft_handler_get_filename (handler));
+ else
+ first_line = g_strdup_printf (_("Hashing \"%s\""),
+ empathy_ft_handler_get_filename (handler));
+
+ second_line = ft_manager_format_progress_bytes_and_percentage
+ (current_bytes, total_bytes, -1, NULL);
+
+ message = g_strdup_printf ("%s\n%s", first_line, second_line);
+
+ ft_manager_update_handler_message (manager, row_ref, message);
+
+ g_free (message);
+ g_free (first_line);
+ g_free (second_line);
+}
+
+static void
+ft_handler_hashing_started_cb (EmpathyFTHandler *handler,
+ EmpathyFTManager *manager)
+{
+ char *message, *first_line, *second_line;
+ GtkTreeRowReference *row_ref;
+
+ DEBUG ("Hashing started");
+
+ g_signal_connect (handler, "hashing-progress",
+ G_CALLBACK (ft_handler_hashing_progress_cb), manager);
+ g_signal_connect (handler, "hashing-done",
+ G_CALLBACK (ft_handler_hashing_done_cb), manager);
+
+ row_ref = ft_manager_get_row_from_handler (manager, handler);
+ g_return_if_fail (row_ref != NULL);
+
+ first_line = ft_manager_format_contact_info (handler);
+
+ if (empathy_ft_handler_is_incoming (handler))
+ second_line = g_strdup_printf (_("Checking integrity of \"%s\""),
+ empathy_ft_handler_get_filename (handler));
+ else
+ second_line = g_strdup_printf (_("Hashing \"%s\""),
+ empathy_ft_handler_get_filename (handler));
+
+ message = g_strdup_printf ("%s\n%s", first_line, second_line);
+
+ ft_manager_update_handler_message (manager, row_ref, message);
+
+ g_free (first_line);
+ g_free (second_line);
+ g_free (message);
+}
+
static void
-ft_manager_state_changed_cb (EmpathyTpFile *tp_file,
- GParamSpec *pspec,
- EmpathyFTManager *ft_manager)
+ft_manager_start_transfer (EmpathyFTManager *manager,
+ EmpathyFTHandler *handler)
{
- if (empathy_tp_file_get_state (tp_file, NULL) ==
- TP_FILE_TRANSFER_STATE_COMPLETED)
+ EmpathyFTManagerPriv *priv;
+ gboolean is_outgoing;
+
+ priv = GET_PRIV (manager);
+
+ is_outgoing = !empathy_ft_handler_is_incoming (handler);
+
+ DEBUG ("Start transfer, is outgoing %s",
+ is_outgoing ? "True" : "False");
+
+ /* now connect the signals */
+ g_signal_connect (handler, "transfer-error",
+ G_CALLBACK (ft_handler_transfer_error_cb), manager);
+
+ if (is_outgoing && empathy_ft_handler_get_use_hash (handler)) {
+ g_signal_connect (handler, "hashing-started",
+ G_CALLBACK (ft_handler_hashing_started_cb), manager);
+ } else {
+ /* either incoming or outgoing without hash */
+ g_signal_connect (handler, "transfer-started",
+ G_CALLBACK (ft_handler_transfer_started_cb), manager);
+ }
+
+ empathy_ft_handler_start_transfer (handler);
+}
+
+static void
+ft_manager_add_handler_to_list (EmpathyFTManager *manager,
+ EmpathyFTHandler *handler,
+ const GError *error)
+{
+ GtkTreeRowReference *row_ref;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+ GIcon *icon;
+ const char *content_type, *second_line;
+ char *first_line, *message;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+
+ icon = NULL;
+
+ /* get the icon name from the mime-type of the file. */
+ content_type = empathy_ft_handler_get_content_type (handler);
+
+ if (content_type != NULL)
+ icon = g_content_type_get_icon (content_type);
+
+ /* append the handler in the store */
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (priv->model),
+ &iter, G_MAXINT, COL_FT_OBJECT, handler,
+ COL_ICON, icon, -1);
+
+ if (icon != NULL)
+ g_object_unref (icon);
+
+ /* insert the new row_ref in the hash table */
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->model), &iter);
+ row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (priv->model), path);
+ gtk_tree_path_free (path);
+ g_hash_table_insert (priv->ft_handler_to_row_ref, g_object_ref (handler),
+ row_ref);
+
+ /* select the new row */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
+ gtk_tree_selection_select_iter (selection, &iter);
+
+ if (error != NULL)
{
- GtkRecentManager *manager;
- const gchar *uri;
+ message = ft_manager_format_error_message (handler, error);
+ ft_manager_update_handler_message (manager, row_ref, message);
- manager = gtk_recent_manager_get_default ();
- uri = g_object_get_data (G_OBJECT (tp_file), "uri");
- if (uri != NULL)
- gtk_recent_manager_add_item (manager, uri);
+ g_free (message);
+ return;
}
- ft_manager_update_ft_row (ft_manager, tp_file);
+ /* update the row with the initial values.
+ * the only case where we postpone this is in case we're managing
+ * an outgoing+hashing transfer, as the hashing started signal will
+ * take care of updating the information.
+ */
+ if (empathy_ft_handler_is_incoming (handler) ||
+ !empathy_ft_handler_get_use_hash (handler)) {
+ first_line = ft_manager_format_contact_info (handler);
+ second_line = _("Waiting for the other participant's response");
+ message = g_strdup_printf ("%s\n%s", first_line, second_line);
+
+ ft_manager_update_handler_message (manager, row_ref, message);
+
+ g_free (first_line);
+ g_free (message);
+ }
+
+ /* hook up the signals and start the transfer */
+ ft_manager_start_transfer (manager, handler);
}
static void
-ft_manager_clear (EmpathyFTManager *ft_manager)
+ft_manager_clear (EmpathyFTManager *manager)
{
+ EmpathyFTManagerPriv *priv;
+
DEBUG ("Clearing file transfer list");
+ priv = GET_PRIV (manager);
+
/* Remove completed and cancelled transfers */
- g_hash_table_foreach_remove (ft_manager->priv->tp_file_to_row_ref,
- remove_finished_transfer_foreach, ft_manager);
+ g_hash_table_foreach_remove (priv->ft_handler_to_row_ref,
+ remove_finished_transfer_foreach, manager);
+
+ /* set the clear button back to insensitive */
+ gtk_widget_set_sensitive (priv->clear_button, FALSE);
}
static void
-ft_manager_open (EmpathyFTManager *ft_manager)
+ft_manager_open (EmpathyFTManager *manager)
{
GtkTreeSelection *selection;
GtkTreeIter iter;
GtkTreeModel *model;
- EmpathyTpFile *tp_file;
- const gchar *uri;
+ EmpathyFTHandler *handler;
+ char *uri;
+ GFile *file;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ft_manager->priv->treeview));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
return;
- gtk_tree_model_get (model, &iter, COL_FT_OBJECT, &tp_file, -1);
- g_return_if_fail (tp_file != NULL);
+ gtk_tree_model_get (model, &iter, COL_FT_OBJECT, &handler, -1);
+
+ file = empathy_ft_handler_get_gfile (handler);
+ uri = g_file_get_uri (file);
- uri = g_object_get_data (G_OBJECT (tp_file), "uri");
DEBUG ("Opening URI: %s", uri);
- empathy_url_show (GTK_WIDGET (ft_manager->priv->window), uri);
- g_object_unref (tp_file);
+ empathy_url_show (GTK_WIDGET (priv->window), uri);
+
+ g_object_unref (handler);
+ g_free (uri);
}
static void
-ft_manager_stop (EmpathyFTManager *ft_manager)
+ft_manager_stop (EmpathyFTManager *manager)
{
GtkTreeSelection *selection;
GtkTreeIter iter;
GtkTreeModel *model;
- EmpathyTpFile *tp_file;
+ EmpathyFTHandler *handler;
+ EmpathyFTManagerPriv *priv;
+
+ priv = GET_PRIV (manager);
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ft_manager->priv->treeview));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
return;
- gtk_tree_model_get (model, &iter, COL_FT_OBJECT, &tp_file, -1);
- g_return_if_fail (tp_file != NULL);
+ gtk_tree_model_get (model, &iter, COL_FT_OBJECT, &handler, -1);
+ g_return_if_fail (handler != NULL);
DEBUG ("Stopping file transfer: contact=%s, filename=%s",
- empathy_contact_get_name (empathy_tp_file_get_contact (tp_file)),
- empathy_tp_file_get_filename (tp_file));
+ empathy_contact_get_name (empathy_ft_handler_get_contact (handler)),
+ empathy_ft_handler_get_filename (handler));
- empathy_tp_file_cancel (tp_file);
- g_object_unref (tp_file);
+ empathy_ft_handler_cancel_transfer (handler);
+
+ g_object_unref (handler);
+}
+
+static gboolean
+ft_manager_save_geometry_timeout_cb (EmpathyFTManager *manager)
+{
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+ gint x, y, w, h;
+
+ gtk_window_get_size (GTK_WINDOW (priv->window), &w, &h);
+ gtk_window_get_position (GTK_WINDOW (priv->window), &x, &y);
+
+ empathy_geometry_save ("ft-manager", x, y, w, h);
+
+ priv->save_geometry_id = 0;
+
+ return FALSE;
+}
+
+static gboolean
+ft_manager_configure_event_cb (GtkWidget *widget,
+ GdkEventConfigure *event,
+ EmpathyFTManager *manager)
+{
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+
+ if (priv->save_geometry_id != 0)
+ g_source_remove (priv->save_geometry_id);
+
+ priv->save_geometry_id = g_timeout_add (500,
+ (GSourceFunc) ft_manager_save_geometry_timeout_cb, manager);
+
+ return FALSE;
}
static void
ft_manager_response_cb (GtkWidget *widget,
gint response,
- EmpathyFTManager *ft_manager)
+ EmpathyFTManager *manager)
{
switch (response)
{
case RESPONSE_CLEAR:
- ft_manager_clear (ft_manager);
+ ft_manager_clear (manager);
break;
case RESPONSE_OPEN:
- ft_manager_open (ft_manager);
+ ft_manager_open (manager);
break;
case RESPONSE_STOP:
- ft_manager_stop (ft_manager);
+ ft_manager_stop (manager);
break;
}
}
@@ -563,10 +921,16 @@ ft_manager_response_cb (GtkWidget *widget,
static gboolean
ft_manager_delete_event_cb (GtkWidget *widget,
GdkEvent *event,
- EmpathyFTManager *ft_manager)
+ EmpathyFTManager *manager)
{
- ft_manager_clear (ft_manager);
- if (g_hash_table_size (ft_manager->priv->tp_file_to_row_ref) > 0)
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
+
+ DEBUG ("%p", manager);
+
+ /* remove all the completed/cancelled/errored transfers */
+ ft_manager_clear (manager);
+
+ if (g_hash_table_size (priv->ft_handler_to_row_ref) > 0)
{
/* There is still FTs on flight, just hide the window */
DEBUG ("Hiding window");
@@ -579,16 +943,15 @@ ft_manager_delete_event_cb (GtkWidget *widget,
static void
ft_manager_destroy_cb (GtkWidget *widget,
- EmpathyFTManager *ft_manager)
+ EmpathyFTManager *manager)
{
- ft_manager->priv->window = NULL;
- if (ft_manager->priv->save_geometry_id != 0)
- g_source_remove (ft_manager->priv->save_geometry_id);
- g_hash_table_remove_all (ft_manager->priv->tp_file_to_row_ref);
+ DEBUG ("%p", manager);
+
+ g_object_unref (manager);
}
static void
-ft_manager_build_ui (EmpathyFTManager *ft_manager)
+ft_manager_build_ui (EmpathyFTManager *manager)
{
GtkBuilder *gui;
gint x, y, w, h;
@@ -598,27 +961,26 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
GtkCellRenderer *renderer;
GtkTreeSelection *selection;
gchar *filename;
-
- if (ft_manager->priv->window != NULL)
- return;
+ EmpathyFTManagerPriv *priv = GET_PRIV (manager);
filename = empathy_file_lookup ("empathy-ft-manager.ui", "src");
gui = empathy_builder_get_file (filename,
- "ft_manager_dialog", &ft_manager->priv->window,
- "ft_list", &ft_manager->priv->treeview,
- "open_button", &ft_manager->priv->open_button,
- "abort_button", &ft_manager->priv->abort_button,
+ "ft_manager_dialog", &priv->window,
+ "ft_list", &priv->treeview,
+ "clear_button", &priv->clear_button,
+ "open_button", &priv->open_button,
+ "abort_button", &priv->abort_button,
NULL);
g_free (filename);
- empathy_builder_connect (gui, ft_manager,
+ empathy_builder_connect (gui, manager,
"ft_manager_dialog", "destroy", ft_manager_destroy_cb,
"ft_manager_dialog", "response", ft_manager_response_cb,
"ft_manager_dialog", "delete-event", ft_manager_delete_event_cb,
"ft_manager_dialog", "configure-event", ft_manager_configure_event_cb,
NULL);
- g_object_unref (gui);
+ empathy_builder_unref_and_keep_widget (gui, priv->window);
/* Window geometry. */
empathy_geometry_load ("ft-manager", &x, &y, &w, &h);
@@ -627,22 +989,22 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
{
/* Let the window manager position it if we don't have
* good x, y coordinates. */
- gtk_window_move (GTK_WINDOW (ft_manager->priv->window), x, y);
+ gtk_window_move (GTK_WINDOW (priv->window), x, y);
}
if (w > 0 && h > 0)
{
/* Use the defaults from the ui file if we don't have
* good w, h geometry. */
- gtk_window_resize (GTK_WINDOW (ft_manager->priv->window), w, h);
+ gtk_window_resize (GTK_WINDOW (priv->window), w, h);
}
/* Setup the tree view */
- view = GTK_TREE_VIEW (ft_manager->priv->treeview);
+ view = GTK_TREE_VIEW (priv->treeview);
selection = gtk_tree_view_get_selection (view);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
g_signal_connect (selection, "changed",
- G_CALLBACK (ft_manager_selection_changed), ft_manager);
+ G_CALLBACK (ft_manager_selection_changed), manager);
gtk_tree_view_set_headers_visible (view, TRUE);
gtk_tree_view_set_enable_search (view, FALSE);
@@ -652,9 +1014,9 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
G_TYPE_ICON, /* icon */
G_TYPE_STRING, /* message */
G_TYPE_STRING, /* remaining */
- G_TYPE_OBJECT); /* ft_file */
+ G_TYPE_OBJECT); /* ft_handler */
gtk_tree_view_set_model (view, GTK_TREE_MODEL (liststore));
- ft_manager->priv->model = GTK_TREE_MODEL (liststore);
+ priv->model = GTK_TREE_MODEL (liststore);
g_object_unref (liststore);
/* Progress column */
@@ -702,36 +1064,45 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
gtk_tree_view_column_pack_start (column, renderer, FALSE);
gtk_tree_view_column_set_attributes (column, renderer,
"text", COL_REMAINING, NULL);
+
+ /* clear button should be sensitive only if there are completed/cancelled
+ * handlers in the store.
+ */
+ gtk_widget_set_sensitive (priv->clear_button, FALSE);
}
+/* GObject method overrides */
+
static void
empathy_ft_manager_finalize (GObject *object)
{
- EmpathyFTManager *ft_manager = (EmpathyFTManager *) object;
+ EmpathyFTManagerPriv *priv = GET_PRIV (object);
- DEBUG ("%p", object);
+ DEBUG ("FT Manager %p", object);
- if (ft_manager->priv->window)
- gtk_widget_destroy (ft_manager->priv->window);
+ g_hash_table_destroy (priv->ft_handler_to_row_ref);
- g_hash_table_destroy (ft_manager->priv->tp_file_to_row_ref);
+ if (priv->save_geometry_id != 0)
+ g_source_remove (priv->save_geometry_id);
G_OBJECT_CLASS (empathy_ft_manager_parent_class)->finalize (object);
}
static void
-empathy_ft_manager_init (EmpathyFTManager *ft_manager)
+empathy_ft_manager_init (EmpathyFTManager *manager)
{
EmpathyFTManagerPriv *priv;
- priv = G_TYPE_INSTANCE_GET_PRIVATE ((ft_manager), EMPATHY_TYPE_FT_MANAGER,
+ priv = G_TYPE_INSTANCE_GET_PRIVATE ((manager), EMPATHY_TYPE_FT_MANAGER,
EmpathyFTManagerPriv);
- ft_manager->priv = priv;
+ manager->priv = priv;
- priv->tp_file_to_row_ref = g_hash_table_new_full (g_direct_hash,
+ priv->ft_handler_to_row_ref = g_hash_table_new_full (g_direct_hash,
g_direct_equal, (GDestroyNotify) g_object_unref,
(GDestroyNotify) gtk_tree_row_reference_free);
+
+ ft_manager_build_ui (manager);
}
static GObject *
@@ -743,7 +1114,7 @@ empathy_ft_manager_constructor (GType type,
if (manager_singleton)
{
- retval = g_object_ref (manager_singleton);
+ retval = G_OBJECT (manager_singleton);
}
else
{
@@ -768,325 +1139,50 @@ empathy_ft_manager_class_init (EmpathyFTManagerClass *klass)
g_type_class_add_private (object_class, sizeof (EmpathyFTManagerPriv));
}
-/**
- * empathy_ft_manager_dup_singleton:
- *
- * Returns a reference to the #EmpathyFTManager singleton object.
- *
- * Returns: a #EmpathyFTManager
- */
-EmpathyFTManager *
-empathy_ft_manager_dup_singleton (void)
-{
- return g_object_new (EMPATHY_TYPE_FT_MANAGER, NULL);
-}
-
-/**
- * empathy_ft_manager_get_dialog:
- * @ft_manager: an #EmpathyFTManager
- *
- * Returns the #GtkWidget of @ft_manager.
- *
- * Returns: the dialog
- */
-GtkWidget *
-empathy_ft_manager_get_dialog (EmpathyFTManager *ft_manager)
-{
- g_return_val_if_fail (EMPATHY_IS_FT_MANAGER (ft_manager), NULL);
-
- ft_manager_build_ui (ft_manager);
-
- return ft_manager->priv->window;
-}
-
-static void
-ft_manager_add_tp_file_to_list (EmpathyFTManager *ft_manager,
- EmpathyTpFile *tp_file)
-{
- GtkTreeRowReference *row_ref;
- GtkTreeIter iter;
- GtkTreeSelection *selection;
- GtkTreePath *path;
- GIcon *icon;
- const gchar *content_type;
-
- ft_manager_build_ui (ft_manager);
-
- /* Get the icon name from the mime-type of the file. */
- content_type = empathy_tp_file_get_content_type (tp_file);
- icon = g_content_type_get_icon (content_type);
-
- /* Append the ft in the store */
- gtk_list_store_insert_with_values (GTK_LIST_STORE (ft_manager->priv->model),
- &iter, G_MAXINT, COL_FT_OBJECT, tp_file, COL_ICON, icon, -1);
-
- g_object_unref (icon);
-
- /* Insert the new row_ref in the hash table */
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (ft_manager->priv->model),
- &iter);
- row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (
- ft_manager->priv->model), path);
- gtk_tree_path_free (path);
- g_hash_table_insert (ft_manager->priv->tp_file_to_row_ref,
- g_object_ref (tp_file), row_ref);
-
- /* Select the new row */
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (
- ft_manager->priv->treeview));
- gtk_tree_selection_select_iter (selection, &iter);
-
- /* Update the row with the initial values, and keep track of changes */
- ft_manager_update_ft_row (ft_manager, tp_file);
- g_signal_connect (tp_file, "notify::state",
- G_CALLBACK (ft_manager_state_changed_cb), ft_manager);
- g_signal_connect (tp_file, "notify::transferred-bytes",
- G_CALLBACK (ft_manager_transferred_bytes_changed_cb), ft_manager);
-
- gtk_window_present (GTK_WINDOW (ft_manager->priv->window));
-}
-
-typedef struct {
- EmpathyFTManager *ft_manager;
- EmpathyTpFile *tp_file;
-} ReceiveResponseData;
+/* public methods */
-static void
-ft_manager_receive_response_data_free (ReceiveResponseData *response_data)
-{
- if (!response_data)
- return;
-
- g_object_unref (response_data->tp_file);
- g_object_unref (response_data->ft_manager);
- g_slice_free (ReceiveResponseData, response_data);
-}
-
-static void
-ft_manager_save_dialog_response_cb (GtkDialog *widget,
- gint response_id,
- ReceiveResponseData *response_data)
+void
+empathy_ft_manager_add_handler (EmpathyFTHandler *handler)
{
- if (response_id == GTK_RESPONSE_OK)
- {
- gchar *uri;
- gchar *folder;
-
- uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (widget));
-
- if (uri)
- {
- GFile *file;
- GError *error = NULL;
-
- file = g_file_new_for_uri (uri);
- empathy_tp_file_accept (response_data->tp_file, 0, file, &error);
-
- if (error)
- {
- GtkWidget *dialog;
-
- DEBUG ("Error with opening file to write to: %s",
- error->message ? error->message : "no error");
-
- /* Error is already translated */
- dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE, _("Cannot save file to this location"));
-
- gtk_message_dialog_format_secondary_text (
- GTK_MESSAGE_DIALOG (dialog), "%s",
- error->message);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
-
- gtk_widget_show (dialog);
-
- g_error_free (error);
- return;
- }
+ EmpathyFTManager *manager;
+ EmpathyFTManagerPriv *priv;
- g_object_set_data_full (G_OBJECT (response_data->tp_file),
- "uri", uri, g_free);
+ DEBUG ("Adding handler");
- ft_manager_add_tp_file_to_list (response_data->ft_manager,
- response_data->tp_file);
+ g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler));
- g_object_unref (file);
- }
+ manager = g_object_new (EMPATHY_TYPE_FT_MANAGER, NULL);
+ priv = GET_PRIV (manager);
- folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (widget));
- if (folder)
- {
- empathy_conf_set_string (empathy_conf_get (),
- EMPATHY_PREFS_FILE_TRANSFER_DEFAULT_FOLDER,
- folder);
- g_free (folder);
- }
- }
-
- gtk_widget_destroy (GTK_WIDGET (widget));
- ft_manager_receive_response_data_free (response_data);
+ ft_manager_add_handler_to_list (manager, handler, NULL);
+ gtk_window_present (GTK_WINDOW (priv->window));
}
-static void
-ft_manager_create_save_dialog (ReceiveResponseData *response_data)
+void
+empathy_ft_manager_display_error (EmpathyFTHandler *handler,
+ const GError *error)
{
- GtkWidget *widget;
- gchar *folder;
-
- DEBUG ("Creating save file chooser");
-
- widget = gtk_file_chooser_dialog_new (_("Save file as..."),
- NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE_AS, GTK_RESPONSE_OK,
- NULL);
-
- if (!empathy_conf_get_string (empathy_conf_get (),
- EMPATHY_PREFS_FILE_TRANSFER_DEFAULT_FOLDER,
- &folder) || !folder)
- folder = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD));
-
- if (folder)
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (widget), folder);
-
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (widget),
- empathy_tp_file_get_filename (response_data->tp_file));
-
- gtk_dialog_set_default_response (GTK_DIALOG (widget),
- GTK_RESPONSE_OK);
-
- gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (widget),
- TRUE);
-
- g_signal_connect (widget, "response",
- G_CALLBACK (ft_manager_save_dialog_response_cb), response_data);
-
- gtk_widget_show (widget);
-
- g_free (folder);
-}
+ EmpathyFTManager *manager;
+ EmpathyFTManagerPriv *priv;
-static void
-ft_manager_receive_file_response_cb (GtkWidget *dialog,
- gint response,
- ReceiveResponseData *response_data)
-{
- if (response == GTK_RESPONSE_ACCEPT)
- ft_manager_create_save_dialog (response_data);
- else
- {
- empathy_tp_file_cancel (response_data->tp_file);
- ft_manager_receive_response_data_free (response_data);
- }
+ g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler));
+ g_return_if_fail (error != NULL);
- gtk_widget_destroy (dialog);
-}
+ manager = g_object_new (EMPATHY_TYPE_FT_MANAGER, NULL);
+ priv = GET_PRIV (manager);
-static void
-ft_manager_display_accept_dialog (EmpathyFTManager *ft_manager,
- EmpathyTpFile *tp_file)
-{
- GtkWidget *dialog;
- GtkWidget *image;
- GtkWidget *button;
- const gchar *contact_name;
- const gchar *filename;
- guint64 size;
- gchar *size_str;
- ReceiveResponseData *response_data;
-
- g_return_if_fail (EMPATHY_IS_FT_MANAGER (ft_manager));
- g_return_if_fail (EMPATHY_IS_TP_FILE (tp_file));
-
- DEBUG ("Creating accept dialog");
-
- contact_name = empathy_contact_get_name (empathy_tp_file_get_contact (tp_file));
- filename = empathy_tp_file_get_filename (tp_file);
-
- size = empathy_tp_file_get_size (tp_file);
- if (size == EMPATHY_TP_FILE_UNKNOWN_SIZE)
- size_str = g_strdup (_("unknown size"));
- else
- size_str = g_format_size_for_display (size);
-
- dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_INFO,
- GTK_BUTTONS_NONE,
- _("%s would like to send you a file"),
- contact_name);
-
- gtk_message_dialog_format_secondary_text
- (GTK_MESSAGE_DIALOG (dialog),
- /* Translators: the first %s is the file name, the second %s is the file size */
- _("Do you want to accept the file \"%s\" (%s)?"),
- filename, size_str);
-
- /* Icon */
- image = gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_DIALOG);
- gtk_widget_show (image);
- gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
-
- /* Decline button */
- button = gtk_button_new_with_mnemonic (_("_Decline"));
- gtk_button_set_image (GTK_BUTTON (button),
- gtk_image_new_from_stock (GTK_STOCK_CANCEL,
- GTK_ICON_SIZE_BUTTON));
- gtk_widget_show (button);
- gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button,
- GTK_RESPONSE_REJECT);
-
- /* Accept button */
- button = gtk_button_new_with_mnemonic (_("_Accept"));
- gtk_button_set_image (GTK_BUTTON (button),
- gtk_image_new_from_stock (GTK_STOCK_SAVE,
- GTK_ICON_SIZE_BUTTON));
- gtk_widget_show (button);
- gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button,
- GTK_RESPONSE_ACCEPT);
- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
- gtk_widget_grab_default (button);
-
- response_data = g_slice_new0 (ReceiveResponseData);
- response_data->ft_manager = g_object_ref (ft_manager);
- response_data->tp_file = g_object_ref (tp_file);
-
- g_signal_connect (dialog, "response",
- G_CALLBACK (ft_manager_receive_file_response_cb), response_data);
-
- gtk_widget_show (dialog);
-
- g_free (size_str);
+ ft_manager_add_handler_to_list (manager, handler, error);
+ gtk_window_present (GTK_WINDOW (priv->window));
}
-/**
- * empathy_ft_manager_add_tp_file:
- * @ft_manager: an #EmpathyFTManager
- * @ft: an #EmpathyFT
- *
- * Adds a file transfer to the file transfer manager dialog @ft_manager.
- * The manager dialog then shows the progress and other information about
- * @ft.
- */
void
-empathy_ft_manager_add_tp_file (EmpathyFTManager *ft_manager,
- EmpathyTpFile *tp_file)
+empathy_ft_manager_show (void)
{
- TpFileTransferState state;
-
- g_return_if_fail (EMPATHY_IS_FT_MANAGER (ft_manager));
- g_return_if_fail (EMPATHY_IS_TP_FILE (tp_file));
-
- state = empathy_tp_file_get_state (tp_file, NULL);
+ EmpathyFTManager *manager;
+ EmpathyFTManagerPriv *priv;
- DEBUG ("Adding a file transfer: contact=%s, filename=%s, state=%d",
- empathy_contact_get_name (empathy_tp_file_get_contact (tp_file)),
- empathy_tp_file_get_filename (tp_file), state);
+ manager = g_object_new (EMPATHY_TYPE_FT_MANAGER, NULL);
+ priv = GET_PRIV (manager);
- if (state == TP_FILE_TRANSFER_STATE_PENDING &&
- empathy_tp_file_is_incoming (tp_file))
- ft_manager_display_accept_dialog (ft_manager, tp_file);
- else
- ft_manager_add_tp_file_to_list (ft_manager, tp_file);
+ gtk_window_present (GTK_WINDOW (priv->window));
}
-
diff --git a/src/empathy-ft-manager.h b/src/empathy-ft-manager.h
index 4803bc814..0ff820f06 100644
--- a/src/empathy-ft-manager.h
+++ b/src/empathy-ft-manager.h
@@ -1,7 +1,6 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2007 Marco Barisione <marco@barisione.org>
- * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008-2009 Collabora Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -15,11 +14,12 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Marco Barisione <marco@barisione.org>
* Jonny Lamb <jonny.lamb@collabora.co.uk>
+ * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
*/
#ifndef __EMPATHY_FT_MANAGER_H__
@@ -29,38 +29,42 @@
#include <glib-object.h>
#include <glib.h>
-#include <libempathy/empathy-tp-file.h>
+#include <libempathy/empathy-ft-handler.h>
G_BEGIN_DECLS
-#define EMPATHY_TYPE_FT_MANAGER (empathy_ft_manager_get_type ())
-#define EMPATHY_FT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_FT_MANAGER, EmpathyFTManager))
-#define EMPATHY_FT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_FT_MANAGER, EmpathyFTManagerClass))
-#define EMPATHY_IS_FT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_FT_MANAGER))
-#define EMPATHY_IS_FT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_FT_MANAGER))
-#define EMPATHY_FT_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_FT_MANAGER, EmpathyFTManagerClass))
+#define EMPATHY_TYPE_FT_MANAGER \
+ (empathy_ft_manager_get_type ())
+#define EMPATHY_FT_MANAGER(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_FT_MANAGER, EmpathyFTManager))
+#define EMPATHY_FT_MANAGER_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_FT_MANAGER, EmpathyFTManagerClass))
+#define EMPATHY_IS_FT_MANAGER(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_FT_MANAGER))
+#define EMPATHY_IS_FT_MANAGER_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_FT_MANAGER))
+#define EMPATHY_FT_MANAGER_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_FT_MANAGER, EmpathyFTManagerClass))
typedef struct _EmpathyFTManager EmpathyFTManager;
-typedef struct _EmpathyFTManagerPriv EmpathyFTManagerPriv;
typedef struct _EmpathyFTManagerClass EmpathyFTManagerClass;
-struct _EmpathyFTManager
-{
+struct _EmpathyFTManager {
GObject parent;
-
- EmpathyFTManagerPriv *priv;
+ gpointer priv;
};
-struct _EmpathyFTManagerClass
-{
+struct _EmpathyFTManagerClass {
GObjectClass parent_class;
};
GType empathy_ft_manager_get_type (void);
-EmpathyFTManager *empathy_ft_manager_dup_singleton (void);
-void empathy_ft_manager_add_tp_file (EmpathyFTManager *ft_manager, EmpathyTpFile *tp_file);
-GtkWidget *empathy_ft_manager_get_dialog (EmpathyFTManager *ft_manager);
+/* public methods */
+void empathy_ft_manager_add_handler (EmpathyFTHandler *handler);
+void empathy_ft_manager_display_error (EmpathyFTHandler *handler,
+ const GError *error);
+void empathy_ft_manager_show (void);
G_END_DECLS
diff --git a/src/empathy-import-dialog.c b/src/empathy-import-dialog.c
index c7c321f96..8e9a04595 100644
--- a/src/empathy-import-dialog.c
+++ b/src/empathy-import-dialog.c
@@ -13,8 +13,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
* */
@@ -396,10 +396,10 @@ empathy_import_dialog_show (GtkWindow *parent,
return;
}
-
+
/* We have accounts, let's display the window with them */
dialog = g_slice_new0 (EmpathyImportDialog);
- dialog->accounts = accounts;
+ dialog->accounts = accounts;
filename = empathy_file_lookup ("empathy-import-dialog.ui", "src");
gui = empathy_builder_get_file (filename,
diff --git a/src/empathy-import-dialog.h b/src/empathy-import-dialog.h
index 278afc701..a3ef3e13c 100644
--- a/src/empathy-import-dialog.h
+++ b/src/empathy-import-dialog.h
@@ -13,8 +13,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
*/
diff --git a/src/empathy-import-pidgin.c b/src/empathy-import-pidgin.c
index 76295c702..a58111d59 100644
--- a/src/empathy-import-pidgin.c
+++ b/src/empathy-import-pidgin.c
@@ -13,8 +13,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
* */
@@ -294,7 +294,7 @@ empathy_import_pidgin_load (void)
}
OUT:
- xmlFreeDoc(doc);
+ xmlFreeDoc (doc);
xmlFreeParserCtxt (ctxt);
FILENAME:
diff --git a/src/empathy-import-pidgin.h b/src/empathy-import-pidgin.h
index fc7d2e491..b72acf553 100644
--- a/src/empathy-import-pidgin.h
+++ b/src/empathy-import-pidgin.h
@@ -13,8 +13,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
*/
diff --git a/src/empathy-logs.c b/src/empathy-logs.c
index 502be67d7..b9f38e0e7 100644
--- a/src/empathy-logs.c
+++ b/src/empathy-logs.c
@@ -14,9 +14,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Xavier Claessens <xclaesse@gmail.com>
*/
diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c
index 9015a5d25..5830d2b71 100644
--- a/src/empathy-main-window.c
+++ b/src/empathy-main-window.c
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Xavier Claessens <xclaesse@gmail.com>
*/
@@ -57,8 +57,10 @@
#include "empathy-about-dialog.h"
#include "empathy-debug-dialog.h"
#include "empathy-new-chatroom-dialog.h"
+#include "empathy-map-view.h"
#include "empathy-chatrooms-window.h"
#include "empathy-event-manager.h"
+#include "empathy-ft-manager.h"
#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
#include <libempathy/empathy-debug.h>
@@ -93,7 +95,7 @@ typedef struct {
GtkWidget *errors_vbox;
GtkUIManager *ui_manager;
- GtkAction *chat_history;
+ GtkAction *view_history;
GtkAction *room_join_favorites;
GtkWidget *room_menu;
GtkWidget *room_separator;
@@ -133,7 +135,7 @@ main_window_flash_foreach (GtkTreeModel *model,
GtkTreeIter *iter,
gpointer user_data)
{
- FlashForeachData *data = (FlashForeachData*) user_data;
+ FlashForeachData *data = (FlashForeachData *) user_data;
EmpathyContact *contact;
const gchar *icon_name;
GtkTreePath *parent_path = NULL;
@@ -165,7 +167,7 @@ main_window_flash_foreach (GtkTreeModel *model,
/* To make sure the parent is shown correctly, we emit
* the row-changed signal on the parent so it prompts
- * it to be refreshed by the filter func.
+ * it to be refreshed by the filter func.
*/
if (gtk_tree_model_iter_parent (model, &parent_iter, iter)) {
parent_path = gtk_tree_model_get_path (model, &parent_iter);
@@ -562,8 +564,8 @@ main_window_connection_changed_cb (EmpathyAccountManager *manager,
static void
main_window_contact_presence_changed_cb (EmpathyContactMonitor *monitor,
EmpathyContact *contact,
- McPresence current,
- McPresence previous,
+ TpConnectionPresenceType current,
+ TpConnectionPresenceType previous,
EmpathyMainWindow *window)
{
McAccount *account;
@@ -576,18 +578,25 @@ main_window_contact_presence_changed_cb (EmpathyContactMonitor *monitor,
return;
}
- if (previous < MC_PRESENCE_AVAILABLE && current > MC_PRESENCE_OFFLINE) {
- /* someone is logging in */
- empathy_sound_play (GTK_WIDGET (window->window),
- EMPATHY_SOUND_CONTACT_CONNECTED);
- return;
- }
-
- if (previous > MC_PRESENCE_OFFLINE && current < MC_PRESENCE_AVAILABLE) {
- /* someone is logging off */
- empathy_sound_play (GTK_WIDGET (window->window),
- EMPATHY_SOUND_CONTACT_DISCONNECTED);
- }
+ if (tp_connection_presence_type_cmp_availability (previous,
+ TP_CONNECTION_PRESENCE_TYPE_OFFLINE) > 0)
+ {
+ /* contact was online */
+ if (tp_connection_presence_type_cmp_availability (current,
+ TP_CONNECTION_PRESENCE_TYPE_OFFLINE) <= 0)
+ /* someone is logging off */
+ empathy_sound_play (GTK_WIDGET (window->window),
+ EMPATHY_SOUND_CONTACT_DISCONNECTED);
+ }
+ else
+ {
+ /* contact was offline */
+ if (tp_connection_presence_type_cmp_availability (current,
+ TP_CONNECTION_PRESENCE_TYPE_OFFLINE) > 0)
+ /* someone is logging in */
+ empathy_sound_play (GTK_WIDGET (window->window),
+ EMPATHY_SOUND_CONTACT_CONNECTED);
+ }
}
static void
@@ -663,7 +672,7 @@ main_window_chat_quit_cb (GtkAction *action,
}
static void
-main_window_chat_history_cb (GtkAction *action,
+main_window_view_history_cb (GtkAction *action,
EmpathyMainWindow *window)
{
empathy_log_window_show (NULL, NULL, FALSE, GTK_WINDOW (window->window));
@@ -684,7 +693,14 @@ main_window_chat_add_contact_cb (GtkAction *action,
}
static void
-main_window_chat_show_offline_cb (GtkToggleAction *action,
+main_window_view_show_ft_manager (GtkAction *action,
+ EmpathyMainWindow *window)
+{
+ empathy_ft_manager_show ();
+}
+
+static void
+main_window_view_show_offline_cb (GtkToggleAction *action,
EmpathyMainWindow *window)
{
gboolean current;
@@ -701,6 +717,15 @@ main_window_chat_show_offline_cb (GtkToggleAction *action,
}
static void
+main_window_view_show_map_cb (GtkCheckMenuItem *item,
+ EmpathyMainWindow *window)
+{
+#if HAVE_LIBCHAMPLAIN
+ empathy_map_view_show ();
+#endif
+}
+
+static void
main_window_favorite_chatroom_join (EmpathyChatroom *chatroom)
{
EmpathyAccountManager *manager;
@@ -986,7 +1011,7 @@ main_window_account_created_or_deleted_cb (EmpathyAccountManager *manager,
McAccount *account,
EmpathyMainWindow *window)
{
- gtk_action_set_sensitive (window->chat_history,
+ gtk_action_set_sensitive (window->view_history,
empathy_account_manager_get_count (manager) > 0);
}
@@ -1046,7 +1071,7 @@ main_window_notify_sort_criterium_cb (EmpathyConf *conf,
g_free (str);
if (enum_value) {
- empathy_contact_list_store_set_sort_criterium (window->list_store,
+ empathy_contact_list_store_set_sort_criterium (window->list_store,
enum_value->value);
}
}
@@ -1090,6 +1115,7 @@ empathy_main_window_show (void)
GtkWidget *sw;
GtkToggleAction *show_offline_widget;
GtkWidget *ebox;
+ GtkAction *show_map_widget;
GtkToolItem *item;
gboolean show_offline;
gboolean show_avatars;
@@ -1112,8 +1138,9 @@ empathy_main_window_show (void)
"main_vbox", &window->main_vbox,
"errors_vbox", &window->errors_vbox,
"ui_manager", &window->ui_manager,
- "chat_show_offline", &show_offline_widget,
- "chat_history", &window->chat_history,
+ "view_show_offline", &show_offline_widget,
+ "view_history", &window->view_history,
+ "view_show_map", &show_map_widget,
"room_join_favorites", &window->room_join_favorites,
"presence_toolbar", &window->presence_toolbar,
"roster_scrolledwindow", &sw,
@@ -1125,12 +1152,14 @@ empathy_main_window_show (void)
"main_window", "configure_event", main_window_configure_event_cb,
"chat_quit", "activate", main_window_chat_quit_cb,
"chat_new_message", "activate", main_window_chat_new_message_cb,
- "chat_history", "activate", main_window_chat_history_cb,
+ "view_history", "activate", main_window_view_history_cb,
"room_join_new", "activate", main_window_room_join_new_cb,
"room_join_favorites", "activate", main_window_room_join_favorites_cb,
"room_manage_favorites", "activate", main_window_room_manage_favorites_cb,
"chat_add_contact", "activate", main_window_chat_add_contact_cb,
- "chat_show_offline", "toggled", main_window_chat_show_offline_cb,
+ "view_show_ft_manager", "activate", main_window_view_show_ft_manager,
+ "view_show_offline", "toggled", main_window_view_show_offline_cb,
+ "view_show_map", "activate", main_window_view_show_map_cb,
"edit", "activate", main_window_edit_cb,
"edit_accounts", "activate", main_window_edit_accounts_cb,
"edit_personal_information", "activate", main_window_edit_personal_information_cb,
@@ -1146,6 +1175,10 @@ empathy_main_window_show (void)
g_object_ref (window->ui_manager);
g_object_unref (gui);
+#if !HAVE_LIBCHAMPLAIN
+ gtk_action_set_visible (show_map_widget, FALSE);
+#endif
+
window->mc = empathy_mission_control_dup_singleton ();
window->account_manager = empathy_account_manager_dup_singleton ();
diff --git a/src/empathy-main-window.h b/src/empathy-main-window.h
index 7960c460c..562fa12c6 100644
--- a/src/empathy-main-window.h
+++ b/src/empathy-main-window.h
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Xavier Claessens <xclaesse@gmail.com>
*/
diff --git a/src/empathy-main-window.ui b/src/empathy-main-window.ui
index 73b49a5db..f914979f6 100644
--- a/src/empathy-main-window.ui
+++ b/src/empathy-main-window.ui
@@ -19,10 +19,10 @@
<accelerator key="N" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
- <object class="GtkAction" id="chat_history">
+ <object class="GtkAction" id="view_history">
<property name="icon-name">document-open-recent</property>
- <property name="name">chat_history</property>
- <property name="label" translatable="yes">_View Previous Conversations</property>
+ <property name="name">view_history</property>
+ <property name="label" translatable="yes">_Previous Conversations</property>
</object>
<accelerator key="F3" modifiers=""/>
</child>
@@ -34,13 +34,26 @@
</object>
</child>
<child>
- <object class="GtkToggleAction" id="chat_show_offline">
- <property name="name">chat_show_offline</property>
- <property name="label" translatable="yes">Show _Offline Contacts</property>
+ <object class="GtkAction" id="view_show_ft_manager">
+ <property name="icon-name">document-send</property>
+ <property name="name">view_show_ft_manager</property>
+ <property name="label" translatable="yes">_File Transfers</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkToggleAction" id="view_show_offline">
+ <property name="name">view_show_offline</property>
+ <property name="label" translatable="yes">_Offline Contacts</property>
</object>
<accelerator key="H" modifiers="GDK_CONTROL_MASK"/>
</child>
<child>
+ <object class="GtkAction" id="view_show_map">
+ <property name="name">view_show_map</property>
+ <property name="label" translatable="yes">Contacts on a _Map</property>
+ </object>
+ </child>
+ <child>
<object class="GtkAction" id="chat_quit">
<property name="stock_id">gtk-quit</property>
<property name="name">chat_quit</property>
@@ -80,6 +93,12 @@
</object>
</child>
<child>
+ <object class="GtkAction" id="view">
+ <property name="name">view</property>
+ <property name="label" translatable="yes">_View</property>
+ </object>
+ </child>
+ <child>
<object class="GtkAction" id="room">
<property name="name">room</property>
<property name="label" translatable="yes">_Room</property>
@@ -137,12 +156,9 @@
<menubar name="menubar">
<menu action="chat">
<menuitem action="chat_new_message"/>
- <menuitem action="chat_history"/>
<separator/>
<menuitem action="chat_add_contact"/>
<separator/>
- <menuitem action="chat_show_offline"/>
- <separator/>
<menuitem action="chat_quit"/>
</menu>
<menu action="edit">
@@ -153,6 +169,13 @@
<separator/>
<menuitem action="edit_preferences"/>
</menu>
+ <menu action="view">
+ <menuitem action="view_show_offline"/>
+ <separator/>
+ <menuitem action="view_history"/>
+ <menuitem action="view_show_ft_manager"/>
+ <menuitem action="view_show_map"/>
+ </menu>
<menu action="room">
<menuitem action="room_join_new"/>
<menuitem action="room_join_favorites"/>
diff --git a/src/empathy-map-view.c b/src/empathy-map-view.c
new file mode 100644
index 000000000..b8a32885c
--- /dev/null
+++ b/src/empathy-map-view.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2008, 2009 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: Pierre-Luc Beaudoin <pierre-luc.beaudoin@collabora.co.uk>
+ */
+
+#include <config.h>
+
+#include <sys/stat.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <champlain/champlain.h>
+#include <champlain-gtk/champlain-gtk.h>
+#include <clutter-gtk/gtk-clutter-embed.h>
+#include <telepathy-glib/util.h>
+
+#include <libempathy/empathy-contact.h>
+#include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-location.h>
+
+#include <libempathy-gtk/empathy-contact-list-store.h>
+#include <libempathy-gtk/empathy-contact-list-view.h>
+#include <libempathy-gtk/empathy-presence-chooser.h>
+#include <libempathy-gtk/empathy-ui-utils.h>
+
+#include "empathy-map-view.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_LOCATION
+#include <libempathy/empathy-debug.h>
+
+typedef struct {
+ EmpathyContactListStore *list_store;
+
+ GtkWidget *window;
+ GtkWidget *zoom_in;
+ GtkWidget *zoom_out;
+ ChamplainView *map_view;
+ ChamplainLayer *layer;
+} EmpathyMapView;
+
+static void map_view_destroy_cb (GtkWidget *widget,
+ EmpathyMapView *window);
+static gboolean map_view_contacts_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data);
+static void map_view_zoom_in_cb (GtkWidget *widget,
+ EmpathyMapView *window);
+static void map_view_zoom_out_cb (GtkWidget *widget,
+ EmpathyMapView *window);
+static void map_view_contact_location_notify (GObject *gobject,
+ GParamSpec *arg1,
+ gpointer user_data);
+
+GtkWidget *
+empathy_map_view_show (void)
+{
+ static EmpathyMapView *window = NULL;
+ GtkBuilder *gui;
+ GtkWidget *sw;
+ GtkWidget *embed;
+ gchar *filename;
+ GtkTreeModel *model;
+ EmpathyContactList *list_iface;
+ EmpathyContactListStore *list_store;
+
+ if (window)
+ {
+ empathy_window_present (GTK_WINDOW (window->window), TRUE);
+ return window->window;
+ }
+
+ window = g_slice_new0 (EmpathyMapView);
+
+ /* Set up interface */
+ filename = empathy_file_lookup ("empathy-map-view.ui", "src");
+ gui = empathy_builder_get_file (filename,
+ "map_view", &window->window,
+ "zoom_in", &window->zoom_in,
+ "zoom_out", &window->zoom_out,
+ "map_scrolledwindow", &sw,
+ NULL);
+ g_free (filename);
+
+ empathy_builder_connect (gui, window,
+ "map_view", "destroy", map_view_destroy_cb,
+ "zoom_in", "clicked", map_view_zoom_in_cb,
+ "zoom_out", "clicked", map_view_zoom_out_cb,
+ NULL);
+
+ g_object_unref (gui);
+
+ /* Clear the static pointer to window if the dialog is destroyed */
+ g_object_add_weak_pointer (G_OBJECT (window->window), (gpointer *) &window);
+
+ list_iface = EMPATHY_CONTACT_LIST (empathy_contact_manager_dup_singleton ());
+ list_store = empathy_contact_list_store_new (list_iface);
+ empathy_contact_list_store_set_show_groups (list_store, FALSE);
+ empathy_contact_list_store_set_show_avatars (list_store, TRUE);
+ g_object_unref (list_iface);
+
+ window->list_store = list_store;
+
+ /* Set up map view */
+ window->map_view = CHAMPLAIN_VIEW (champlain_view_new ());
+ g_object_set (G_OBJECT (window->map_view), "zoom-level", 1,
+ "scroll-mode", CHAMPLAIN_SCROLL_MODE_KINETIC, NULL);
+ champlain_view_center_on (window->map_view, 36, 0);
+
+ embed = champlain_view_embed_new (window->map_view);
+ gtk_container_add (GTK_CONTAINER (sw),
+ GTK_WIDGET (embed));
+ gtk_widget_show_all (embed);
+
+ window->layer = g_object_ref (champlain_layer_new ());
+ champlain_view_add_layer (window->map_view, window->layer);
+
+ /* Set up contact list. */
+ model = GTK_TREE_MODEL (window->list_store);
+ gtk_tree_model_foreach (model, map_view_contacts_foreach, window);
+
+ empathy_window_present (GTK_WINDOW (window->window), TRUE);
+ return window->window;
+}
+
+static void
+map_view_destroy_cb (GtkWidget *widget,
+ EmpathyMapView *window)
+{
+ GList *item;
+
+ item = clutter_container_get_children (window->layer);
+ while (item != NULL)
+ {
+ EmpathyContact *contact;
+ ChamplainMarker *marker;
+
+ marker = CHAMPLAIN_MARKER (item->data);
+ contact = g_object_get_data (G_OBJECT (marker), "contact");
+ g_signal_handlers_disconnect_by_func (contact, map_view_contact_location_notify, marker);
+
+ item = g_list_next (item);
+ }
+
+ g_object_unref (window->list_store);
+ g_object_unref (window->layer);
+ g_slice_free (EmpathyMapView, window);
+}
+
+static void
+map_view_marker_update_position (ChamplainMarker *marker,
+ EmpathyContact *contact)
+{
+ gdouble lon, lat;
+ GValue *value;
+ GHashTable *location;
+
+ location = empathy_contact_get_location (contact);
+
+ if (location == NULL ||
+ g_hash_table_size (location) == 0)
+ {
+ clutter_actor_hide (CLUTTER_ACTOR (marker));
+ return;
+ }
+
+ value = g_hash_table_lookup (location, EMPATHY_LOCATION_LAT);
+ if (value == NULL)
+ {
+ clutter_actor_hide (CLUTTER_ACTOR (marker));
+ return;
+ }
+ lat = g_value_get_double (value);
+
+ value = g_hash_table_lookup (location, EMPATHY_LOCATION_LON);
+ if (value == NULL)
+ {
+ clutter_actor_hide (CLUTTER_ACTOR (marker));
+ return;
+ }
+ lon = g_value_get_double (value);
+
+ clutter_actor_show (CLUTTER_ACTOR (marker));
+ champlain_base_marker_set_position (CHAMPLAIN_BASE_MARKER (marker), lat, lon);
+}
+
+static void
+map_view_contact_location_notify (GObject *gobject,
+ GParamSpec *arg1,
+ gpointer user_data)
+{
+ ChamplainMarker *marker = CHAMPLAIN_MARKER (user_data);
+ EmpathyContact *contact = EMPATHY_CONTACT (gobject);
+ map_view_marker_update_position (marker, contact);
+}
+
+static gboolean
+map_view_contacts_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ EmpathyMapView *window = (EmpathyMapView*) user_data;
+ EmpathyContact *contact;
+ ClutterActor *marker;
+ ClutterActor *texture;
+ GHashTable *location;
+ GdkPixbuf *avatar;
+ const gchar *name;
+ gchar *date;
+ gchar *label;
+ GValue *gtime;
+ time_t time;
+
+ gtk_tree_model_get (model, iter, EMPATHY_CONTACT_LIST_STORE_COL_CONTACT,
+ &contact, -1);
+
+ if (contact == NULL)
+ return FALSE;
+
+ location = empathy_contact_get_location (contact);
+
+ if (location == NULL)
+ return FALSE;
+
+ marker = champlain_marker_new ();
+
+ avatar = empathy_pixbuf_avatar_from_contact_scaled (contact, 32, 32);
+ if (avatar != NULL)
+ {
+ texture = clutter_texture_new ();
+ gtk_clutter_texture_set_from_pixbuf (CLUTTER_TEXTURE (texture), avatar);
+ champlain_marker_set_image (CHAMPLAIN_MARKER (marker), texture);
+ g_object_unref (avatar);
+ }
+ else
+ champlain_marker_set_image (CHAMPLAIN_MARKER (marker), NULL);
+
+ name = empathy_contact_get_name (contact);
+ gtime = g_hash_table_lookup (location, EMPATHY_LOCATION_TIMESTAMP);
+ if (gtime != NULL)
+ {
+ time = g_value_get_int64 (gtime);
+ date = empathy_time_to_string_relative (time);
+ label = g_strconcat ("<b>", name, "</b>\n<small>", date, "</small>", NULL);
+ g_free (date);
+ }
+ else
+ {
+ label = g_strconcat ("<b>", name, "</b>\n", NULL);
+ }
+ champlain_marker_set_use_markup (CHAMPLAIN_MARKER (marker), TRUE);
+ champlain_marker_set_text (CHAMPLAIN_MARKER (marker), label);
+ g_free (label);
+
+ clutter_container_add (CLUTTER_CONTAINER (window->layer), marker, NULL);
+
+ g_signal_connect (contact, "notify::location",
+ G_CALLBACK (map_view_contact_location_notify), marker);
+ g_object_set_data_full (G_OBJECT (marker), "contact", g_object_ref (contact), g_object_unref);
+
+ map_view_marker_update_position (CHAMPLAIN_MARKER (marker), contact);
+
+ g_object_unref (contact);
+ return FALSE;
+}
+
+static void
+map_view_zoom_in_cb (GtkWidget *widget,
+ EmpathyMapView *window)
+{
+ champlain_view_zoom_in (window->map_view);
+}
+
+static void
+map_view_zoom_out_cb (GtkWidget *widget,
+ EmpathyMapView *window)
+{
+ champlain_view_zoom_out (window->map_view);
+}
diff --git a/src/empathy-map-view.h b/src/empathy-map-view.h
new file mode 100644
index 000000000..80a05a129
--- /dev/null
+++ b/src/empathy-map-view.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 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: Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ */
+
+#ifndef __EMPATHY_MAP_VIEW_H__
+#define __EMPATHY_MAP_VIEW_H__
+
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+GtkWidget *empathy_map_view_show (void);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_MAP_VIEW_H__ */
diff --git a/src/empathy-map-view.ui b/src/empathy-map-view.ui
new file mode 100644
index 000000000..f1140399b
--- /dev/null
+++ b/src/empathy-map-view.ui
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkWindow" id="map_view">
+ <property name="title" translatable="yes">Contact Map View</property>
+ <property name="role">map_view</property>
+ <property name="window_position">center</property>
+ <property name="default_width">512</property>
+ <property name="default_height">384</property>
+ <child>
+ <object class="GtkVBox" id="main_vbox">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkToolbar" id="toolbar">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkToolButton" id="zoom_in">
+ <property name="visible">True</property>
+ <property name="stock_id">gtk-zoom-in</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="zoom_out">
+ <property name="visible">True</property>
+ <property name="stock_id">gtk-zoom-out</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkViewport" id="map_scrolledwindow">
+ <property name="visible">True</property>
+ <property name="resize_mode">queue</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/src/empathy-misc.c b/src/empathy-misc.c
index 0a943bb6d..a1a084740 100644
--- a/src/empathy-misc.c
+++ b/src/empathy-misc.c
@@ -14,9 +14,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
*
*/
diff --git a/src/empathy-misc.h b/src/empathy-misc.h
index aaa743ca6..b3fe8fdbf 100644
--- a/src/empathy-misc.h
+++ b/src/empathy-misc.h
@@ -14,9 +14,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
*
*/
diff --git a/src/empathy-new-chatroom-dialog.c b/src/empathy-new-chatroom-dialog.c
index 837d9acfe..563665932 100644
--- a/src/empathy-new-chatroom-dialog.c
+++ b/src/empathy-new-chatroom-dialog.c
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Martyn Russell <martyn@imendio.com>
* Xavier Claessens <xclaesse@gmail.com>
*/
@@ -30,6 +30,7 @@
#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gi18n.h>
+#include <glib/gprintf.h>
#include <libmissioncontrol/mission-control.h>
#include <libmissioncontrol/mc-account.h>
@@ -66,7 +67,8 @@ typedef struct {
GtkWidget *treeview;
GtkTreeModel *model;
GtkWidget *button_join;
- GtkWidget *button_close;
+ GtkWidget *label_error_message;
+ GtkWidget *viewport_error;
} EmpathyNewChatroomDialog;
enum {
@@ -75,6 +77,7 @@ enum {
COL_NAME,
COL_ROOM,
COL_MEMBERS,
+ COL_MEMBERS_INT,
COL_TOOLTIP,
COL_COUNT
};
@@ -97,6 +100,12 @@ static void new_chatroom_dialog_new_room_cb (EmpathyTpRo
static void new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list,
gpointer unused,
EmpathyNewChatroomDialog *dialog);
+static void start_listing_error_cb (EmpathyTpRoomlist *room_list,
+ GError *error,
+ EmpathyNewChatroomDialog *dialog);
+static void stop_listing_error_cb (EmpathyTpRoomlist *room_list,
+ GError *error,
+ EmpathyNewChatroomDialog *dialog);
static void new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog);
static void new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view,
GtkTreePath *path,
@@ -116,6 +125,8 @@ static void new_chatroom_dialog_expander_browse_activate_cb (GtkWidget
static gboolean new_chatroom_dialog_entry_server_focus_out_cb (GtkWidget *widget,
GdkEventFocus *event,
EmpathyNewChatroomDialog *dialog);
+static void new_chatroom_dialog_button_close_error_clicked_cb (GtkButton *button,
+ EmpathyNewChatroomDialog *dialog);
static EmpathyNewChatroomDialog *dialog_p = NULL;
@@ -146,6 +157,8 @@ empathy_new_chatroom_dialog_show (GtkWindow *parent)
"treeview", &dialog->treeview,
"button_join", &dialog->button_join,
"expander_browse", &dialog->expander_browse,
+ "label_error_message", &dialog->label_error_message,
+ "viewport_error", &dialog->viewport_error,
NULL);
g_free (filename);
@@ -157,6 +170,7 @@ empathy_new_chatroom_dialog_show (GtkWindow *parent)
"entry_server", "focus-out-event", new_chatroom_dialog_entry_server_focus_out_cb,
"entry_room", "changed", new_chatroom_dialog_entry_changed_cb,
"expander_browse", "activate", new_chatroom_dialog_expander_browse_activate_cb,
+ "button_close_error", "clicked", new_chatroom_dialog_button_close_error_clicked_cb,
NULL);
g_object_unref (gui);
@@ -227,7 +241,7 @@ new_chatroom_dialog_destroy_cb (GtkWidget *widget,
if (dialog->room_list) {
g_object_unref (dialog->room_list);
}
- g_object_unref (dialog->model);
+ g_object_unref (dialog->model);
g_free (dialog);
}
@@ -253,6 +267,7 @@ new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog)
G_TYPE_STRING, /* Name */
G_TYPE_STRING, /* Room */
G_TYPE_STRING, /* Member count */
+ G_TYPE_INT, /* Member count int */
G_TYPE_STRING); /* Tool tip */
dialog->model = GTK_TREE_MODEL (store);
@@ -295,12 +310,16 @@ new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog)
cell,
"stock-id", COL_INVITE_ONLY,
NULL);
+
+ gtk_tree_view_column_set_sort_column_id (column, COL_INVITE_ONLY);
gtk_tree_view_append_column (view, column);
column = gtk_tree_view_column_new_with_attributes (NULL,
cell,
"stock-id", COL_NEED_PASSWORD,
NULL);
+
+ gtk_tree_view_column_set_sort_column_id (column, COL_NEED_PASSWORD);
gtk_tree_view_append_column (view, column);
cell = gtk_cell_renderer_text_new ();
@@ -315,6 +334,7 @@ new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog)
"text", COL_NAME,
NULL);
+ gtk_tree_view_column_set_sort_column_id (column, COL_NAME);
gtk_tree_view_column_set_expand (column, TRUE);
gtk_tree_view_append_column (view, column);
@@ -329,6 +349,8 @@ new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog)
cell,
"text", COL_MEMBERS,
NULL);
+
+ gtk_tree_view_column_set_sort_column_id (column, COL_MEMBERS_INT);
gtk_tree_view_append_column (view, column);
}
@@ -379,6 +401,7 @@ new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox,
EmpathyAccountChooser *account_chooser;
McAccount *account;
gboolean listing = FALSE;
+ gboolean expanded = FALSE;
if (dialog->room_list) {
g_object_unref (dialog->room_list);
@@ -401,6 +424,19 @@ new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox,
g_signal_connect (dialog->room_list, "notify::is-listing",
G_CALLBACK (new_chatroom_dialog_listing_cb),
dialog);
+ g_signal_connect (dialog->room_list, "error::start",
+ G_CALLBACK (start_listing_error_cb),
+ dialog);
+ g_signal_connect (dialog->room_list, "error::stop",
+ G_CALLBACK (stop_listing_error_cb),
+ dialog);
+
+ expanded = gtk_expander_get_expanded (GTK_EXPANDER (dialog->expander_browse));
+ if (expanded) {
+ gtk_widget_hide (dialog->viewport_error);
+ gtk_widget_set_sensitive (dialog->treeview, TRUE);
+ new_chatroom_dialog_browse_start (dialog);
+ }
listing = empathy_tp_roomlist_is_listing (dialog->room_list);
if (listing) {
@@ -414,6 +450,13 @@ new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox,
}
static void
+new_chatroom_dialog_button_close_error_clicked_cb (GtkButton *button,
+ EmpathyNewChatroomDialog *dialog)
+{
+ gtk_widget_hide (dialog->viewport_error);
+}
+
+static void
new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list,
EmpathyNewChatroomDialog *dialog)
{
@@ -463,6 +506,7 @@ new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list,
COL_NAME, empathy_chatroom_get_name (chatroom),
COL_ROOM, empathy_chatroom_get_room (chatroom),
COL_MEMBERS, members,
+ COL_MEMBERS_INT, empathy_chatroom_get_members_count (chatroom),
COL_TOOLTIP, tooltip,
-1);
@@ -471,6 +515,26 @@ new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list,
}
static void
+start_listing_error_cb (EmpathyTpRoomlist *room_list,
+ GError *error,
+ EmpathyNewChatroomDialog *dialog)
+{
+ gtk_label_set_text (GTK_LABEL (dialog->label_error_message), _("Could not start room listing"));
+ gtk_widget_show_all (dialog->viewport_error);
+ gtk_widget_set_sensitive (dialog->treeview, FALSE);
+}
+
+static void
+stop_listing_error_cb (EmpathyTpRoomlist *room_list,
+ GError *error,
+ EmpathyNewChatroomDialog *dialog)
+{
+ gtk_label_set_text (GTK_LABEL (dialog->label_error_message), _("Could not stop room listing"));
+ gtk_widget_show_all (dialog->viewport_error);
+ gtk_widget_set_sensitive (dialog->treeview, FALSE);
+}
+
+static void
new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list,
gpointer unused,
EmpathyNewChatroomDialog *dialog)
@@ -606,6 +670,8 @@ new_chatroom_dialog_expander_browse_activate_cb (GtkWidget *widget
new_chatroom_dialog_browse_stop (dialog);
gtk_window_set_resizable (GTK_WINDOW (dialog->window), FALSE);
} else {
+ gtk_widget_hide (dialog->viewport_error);
+ gtk_widget_set_sensitive (dialog->treeview, TRUE);
new_chatroom_dialog_browse_start (dialog);
gtk_window_set_resizable (GTK_WINDOW (dialog->window), TRUE);
}
diff --git a/src/empathy-new-chatroom-dialog.h b/src/empathy-new-chatroom-dialog.h
index ae8b2385e..b1cef0daa 100644
--- a/src/empathy-new-chatroom-dialog.h
+++ b/src/empathy-new-chatroom-dialog.h
@@ -15,9 +15,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Martyn Russell <martyn@imendio.com>
* Xavier Claessens <xclaesse@gmail.com>
*/
diff --git a/src/empathy-new-chatroom-dialog.ui b/src/empathy-new-chatroom-dialog.ui
index ba7a326ef..a8fccf4a0 100644
--- a/src/empathy-new-chatroom-dialog.ui
+++ b/src/empathy-new-chatroom-dialog.ui
@@ -1,13 +1,14 @@
<?xml version="1.0"?>
-<!--*- mode: xml -*-->
<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy toplevel-contextual -->
<object class="GtkDialog" id="new_chatroom_dialog">
<property name="visible">True</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Join Room</property>
<property name="role">join_new_chatroom</property>
<property name="default_width">350</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="type_hint">dialog</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox4">
@@ -25,16 +26,10 @@
<property name="column_spacing">5</property>
<property name="row_spacing">5</property>
<child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
<object class="GtkEntry" id="entry_room">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="tooltip-text" translatable="yes">Enter the room name to join here or click on one or more rooms in the list.</property>
+ <property name="tooltip_text" translatable="yes">Enter the room name to join here or click on one or more rooms in the list.</property>
<property name="activates_default">True</property>
<property name="width_chars">25</property>
</object>
@@ -64,7 +59,7 @@
<object class="GtkEntry" id="entry_server">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="tooltip-text" translatable="yes">Enter the server which hosts the room, or leave it empty if the room is on the current account's server</property>
+ <property name="tooltip_text" translatable="yes">Enter the server which hosts the room, or leave it empty if the room is on the current account's server</property>
<property name="width_chars">25</property>
</object>
<packing>
@@ -73,7 +68,7 @@
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
- <property name="y_options"/>
+ <property name="y_options"></property>
</packing>
</child>
<child>
@@ -88,7 +83,7 @@
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
- <property name="y_options"/>
+ <property name="y_options"></property>
</packing>
</child>
<child>
@@ -99,13 +94,20 @@
</object>
<packing>
<property name="x_options">GTK_FILL</property>
- <property name="y_options"/>
+ <property name="y_options"></property>
</packing>
</child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
@@ -113,21 +115,90 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="width_request">350</property>
- <property name="height_request">150</property>
+ <object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkViewport" id="viewport_error">
+ <property name="resize_mode">queue</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-error</property>
+ <property name="icon-size">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">5</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_error_message">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">10</property>
+ <property name="label" translatable="yes">Couldn't load room list</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button_close_error">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-close</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
<child>
- <object class="GtkTreeView" id="treeview">
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="width_request">350</property>
+ <property name="height_request">150</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="search_column">0</property>
- <property name="show_expanders">False</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="search_column">0</property>
+ <property name="show_expanders">False</property>
+ </object>
+ </child>
</object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
</child>
@@ -150,15 +221,21 @@
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area4">
<property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button_cancel">
+ <property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
- <property name="label">gtk-cancel</property>
+ <property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
</child>
<child>
<object class="GtkButton" id="button_join">
@@ -167,6 +244,7 @@
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
+ <property name="receives_default">False</property>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
@@ -184,6 +262,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
@@ -204,13 +283,16 @@
</child>
</object>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
- <property name="pack_type">GTK_PACK_END</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
</packing>
</child>
</object>
diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c
index b2388f88d..406db4c9f 100644
--- a/src/empathy-preferences.c
+++ b/src/empathy-preferences.c
@@ -14,8 +14,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Mikael Hallendal <micke@imendio.com>
* Richard Hult <richard@imendio.com>
@@ -64,6 +64,12 @@ typedef struct {
GtkWidget *treeview_spell_checker;
+ GtkWidget *checkbutton_location_publish;
+ GtkWidget *checkbutton_location_reduce_accuracy;
+ GtkWidget *checkbutton_location_resource_network;
+ GtkWidget *checkbutton_location_resource_cell;
+ GtkWidget *checkbutton_location_resource_gps;
+
GList *notify_ids;
} EmpathyPreferences;
@@ -247,6 +253,38 @@ preferences_setup_widgets (EmpathyPreferences *preferences)
EMPATHY_PREFS_AUTOCONNECT,
preferences->checkbutton_autoconnect);
+ preferences_hookup_toggle_button (preferences,
+ EMPATHY_PREFS_LOCATION_PUBLISH,
+ preferences->checkbutton_location_publish);
+
+ preferences_hookup_toggle_button (preferences,
+ EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK,
+ preferences->checkbutton_location_resource_network);
+ preferences_hookup_sensitivity (preferences,
+ EMPATHY_PREFS_LOCATION_PUBLISH,
+ preferences->checkbutton_location_resource_network);
+
+ preferences_hookup_toggle_button (preferences,
+ EMPATHY_PREFS_LOCATION_RESOURCE_CELL,
+ preferences->checkbutton_location_resource_cell);
+ preferences_hookup_sensitivity (preferences,
+ EMPATHY_PREFS_LOCATION_PUBLISH,
+ preferences->checkbutton_location_resource_cell);
+
+ preferences_hookup_toggle_button (preferences,
+ EMPATHY_PREFS_LOCATION_RESOURCE_GPS,
+ preferences->checkbutton_location_resource_gps);
+ preferences_hookup_sensitivity (preferences,
+ EMPATHY_PREFS_LOCATION_PUBLISH,
+ preferences->checkbutton_location_resource_gps);
+
+ preferences_hookup_toggle_button (preferences,
+ EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY,
+ preferences->checkbutton_location_reduce_accuracy);
+ preferences_hookup_sensitivity (preferences,
+ EMPATHY_PREFS_LOCATION_PUBLISH,
+ preferences->checkbutton_location_reduce_accuracy);
+
id = empathy_conf_notify_add (empathy_conf_get (),
EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST,
preferences_compact_contact_list_changed_cb,
@@ -422,7 +460,7 @@ preferences_languages_add (EmpathyPreferences *preferences)
codes = empathy_spell_get_language_codes ();
- empathy_conf_set_bool (empathy_conf_get(),
+ empathy_conf_set_bool (empathy_conf_get (),
EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED,
codes != NULL);
if (!codes) {
@@ -668,7 +706,7 @@ preferences_widget_sync_string (const gchar *key, GtkWidget *widget)
enum_class = G_ENUM_CLASS (g_type_class_peek (type));
enum_value = g_enum_get_value_by_nick (enum_class, value);
- if (enum_value) {
+ if (enum_value) {
list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
toggle_widget = g_slist_nth_data (list, enum_value->value);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_widget), TRUE);
@@ -1003,12 +1041,14 @@ preferences_radio_button_toggled_cb (GtkWidget *button,
enum_value = g_enum_get_value (enum_class, g_slist_index (group, button));
if (!enum_value) {
- g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioButton index:%d",
+ g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioButton index:%d",
g_slist_index (group, button));
return;
}
value = enum_value->value_nick;
+ } else if (key && strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0) {
+ return;
}
empathy_conf_set_string (empathy_conf_get (), key, value);
@@ -1067,6 +1107,7 @@ empathy_preferences_show (GtkWindow *parent)
static EmpathyPreferences *preferences;
GtkBuilder *gui;
gchar *filename;
+ GtkWidget *page;
if (preferences) {
gtk_window_present (GTK_WINDOW (preferences->dialog));
@@ -1094,6 +1135,11 @@ empathy_preferences_show (GtkWindow *parent)
"checkbutton_sounds_disabled_away", &preferences->checkbutton_sounds_disabled_away,
"treeview_sounds", &preferences->treeview_sounds,
"treeview_spell_checker", &preferences->treeview_spell_checker,
+ "checkbutton_location_publish", &preferences->checkbutton_location_publish,
+ "checkbutton_location_reduce_accuracy", &preferences->checkbutton_location_reduce_accuracy,
+ "checkbutton_location_resource_network", &preferences->checkbutton_location_resource_network,
+ "checkbutton_location_resource_cell", &preferences->checkbutton_location_resource_cell,
+ "checkbutton_location_resource_gps", &preferences->checkbutton_location_resource_gps,
NULL);
g_free (filename);
@@ -1124,6 +1170,14 @@ empathy_preferences_show (GtkWindow *parent)
gtk_widget_show (page);
}
+ page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (preferences->notebook), 3);
+#if HAVE_GEOCLUE
+ gtk_widget_show (page);
+#else
+ gtk_widget_hide (page);
+#endif
+
+
if (parent) {
gtk_window_set_transient_for (GTK_WINDOW (preferences->dialog),
GTK_WINDOW (parent));
diff --git a/src/empathy-preferences.h b/src/empathy-preferences.h
index 07ae6b523..6cc86d1d6 100644
--- a/src/empathy-preferences.h
+++ b/src/empathy-preferences.h
@@ -14,8 +14,8 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
*
* Authors: Mikael Hallendal <micke@imendio.com>
* Richard Hult <richard@imendio.com>
diff --git a/src/empathy-preferences.ui b/src/empathy-preferences.ui
index c20d271e2..d92fc8f88 100644
--- a/src/empathy-preferences.ui
+++ b/src/empathy-preferences.ui
@@ -308,7 +308,7 @@
<property name="label" translatable="yes">Notifications</property>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -424,6 +424,202 @@
</packing>
</child>
<child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_location_publish">
+ <property name="label" translatable="yes">_Publish location to my contacts</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="yalign">0</property>
+ <property name="stock">gtk-dialog-info</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;small&gt;Reduced location accuracy means that nothing more precise than your city, state and country will be published. GPS coordinates will have a random value added (&#xB1;0.25&#xB0;).&lt;/small&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_location_reduce_accuracy">
+ <property name="label" translatable="yes">_Reduce location accuracy</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Privacy&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame5">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_location_resource_gps">
+ <property name="label" translatable="yes">Allow _GPS usage</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_location_resource_cell">
+ <property name="label" translatable="yes">Allow _cellphone usage</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_location_resource_network">
+ <property name="label" translatable="yes">Allow _network usage</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Geoclue Settings&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Location</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkVBox" id="vbox168">
<property name="visible">True</property>
<property name="border_width">12</property>
@@ -532,7 +728,7 @@
</child>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
<child type="tab">
@@ -541,7 +737,7 @@
<property name="label" translatable="yes">Spell Checking</property>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">4</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -616,7 +812,7 @@
</child>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">5</property>
</packing>
</child>
<child type="tab">
@@ -625,7 +821,7 @@
<property name="label" translatable="yes">Themes</property>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">5</property>
<property name="tab_fill">False</property>
</packing>
</child>
diff --git a/src/empathy-sidebar.c b/src/empathy-sidebar.c
index a66abc757..caca6b5e3 100644
--- a/src/empathy-sidebar.c
+++ b/src/empathy-sidebar.c
@@ -3,7 +3,7 @@
* Copyright (C) 2007 The Free Software Foundation
* Copyright (C) 2008 Marco Barisione <marco@barisione.org>
*
- * Based on evince code (shell/ev-sidebar.c) by:
+ * Based on evince code (shell/ev-sidebar.c) by:
* - Jonathan Blandford <jrb@alum.mit.edu>
*
* Base on eog code (src/eog-sidebar.c) by:
@@ -21,7 +21,7 @@
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
@@ -102,7 +102,7 @@ empathy_sidebar_select_page (EmpathySidebar *sidebar,
gint index;
gtk_tree_model_get (sidebar->priv->page_model, iter,
- PAGE_COLUMN_TITLE, &title,
+ PAGE_COLUMN_TITLE, &title,
PAGE_COLUMN_NOTEBOOK_INDEX, &index,
-1);
@@ -397,7 +397,7 @@ empathy_sidebar_init (EmpathySidebar *sidebar)
gtk_widget_show (hbox);
sidebar->priv->select_button = gtk_toggle_button_new ();
- gtk_button_set_relief (GTK_BUTTON (sidebar->priv->select_button),
+ gtk_button_set_relief (GTK_BUTTON (sidebar->priv->select_button),
GTK_RELIEF_NONE);
g_signal_connect (sidebar->priv->select_button, "button_press_event",
@@ -514,7 +514,7 @@ empathy_sidebar_add_page (EmpathySidebar *sidebar,
-1);
gtk_list_store_move_before (GTK_LIST_STORE(sidebar->priv->page_model),
- &iter,
+ &iter,
NULL);
/* Set the first item added as active */
@@ -571,15 +571,15 @@ empathy_sidebar_remove_page (EmpathySidebar *sidebar,
if (valid)
{
- gtk_notebook_remove_page (GTK_NOTEBOOK (sidebar->priv->notebook),
+ gtk_notebook_remove_page (GTK_NOTEBOOK (sidebar->priv->notebook),
index);
gtk_container_remove (GTK_CONTAINER (sidebar->priv->menu), menu_item);
- gtk_list_store_remove (GTK_LIST_STORE (sidebar->priv->page_model),
+ gtk_list_store_remove (GTK_LIST_STORE (sidebar->priv->page_model),
&iter);
- g_signal_emit (G_OBJECT (sidebar),
+ g_signal_emit (G_OBJECT (sidebar),
signals[SIGNAL_PAGE_REMOVED], 0, main_widget);
}
}
diff --git a/src/empathy-sidebar.h b/src/empathy-sidebar.h
index 6e88e789d..095336fac 100644
--- a/src/empathy-sidebar.h
+++ b/src/empathy-sidebar.h
@@ -3,7 +3,7 @@
* Copyright (C) 2007 The Free Software Foundation
* Copyright (C) 2008 Marco Barisione <marco@barisione.org>
*
- * Based on evince code (shell/ev-sidebar.h) by:
+ * Based on evince code (shell/ev-sidebar.h) by:
* - Jonathan Blandford <jrb@alum.mit.edu>
*
* Base on eog code (src/eog-sidebar.c) by:
@@ -21,7 +21,7 @@
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __EMPATHY_SIDEBAR_H__
@@ -53,10 +53,10 @@ struct _EmpathySidebarClass
{
GtkVBoxClass base_class;
- void (* page_added) (EmpathySidebar *sidebar,
+ void (* page_added) (EmpathySidebar *sidebar,
GtkWidget *main_widget);
- void (* page_removed) (EmpathySidebar *sidebar,
+ void (* page_removed) (EmpathySidebar *sidebar,
GtkWidget *main_widget);
};
diff --git a/src/empathy-status-icon.c b/src/empathy-status-icon.c
index 1824be5e6..9c2194880 100644
--- a/src/empathy-status-icon.c
+++ b/src/empathy-status-icon.c
@@ -15,7 +15,7 @@
* 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>
*/
@@ -195,13 +195,14 @@ status_icon_update_icon (EmpathyStatusIcon *icon)
if (priv->event && priv->showing_event_icon) {
icon_name = priv->event->icon_name;
} else {
- McPresence state;
+ TpConnectionPresenceType state;
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);
+ if (icon_name != NULL)
+ gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
}
static gboolean
diff --git a/src/empathy-tube-dispatch.c b/src/empathy-tube-dispatch.c
index 63b31b2b6..67db5a3a3 100644
--- a/src/empathy-tube-dispatch.c
+++ b/src/empathy-tube-dispatch.c
@@ -149,7 +149,7 @@ empathy_tube_dispatch_constructed (GObject *object)
const gchar *channel_type;
TpTubeType type;
- priv->dbus = tp_dbus_daemon_new (tp_get_bus());
+ priv->dbus = tp_dbus_daemon_new (tp_get_bus ());
channel = empathy_dispatch_operation_get_channel (priv->operation);
properties = tp_channel_borrow_immutable_properties (channel);
@@ -159,19 +159,19 @@ empathy_tube_dispatch_constructed (GObject *object)
if (channel_type == NULL)
goto failed;
- if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE))
+ if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE))
{
type = TP_TUBE_TYPE_STREAM;
service = tp_asv_get_string (properties,
- EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service");
}
- else if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
+ else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
{
GError *error = NULL;
type = TP_TUBE_TYPE_DBUS;
service = tp_asv_get_string (properties,
- EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName");
+ TP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName");
if (!tp_dbus_check_valid_bus_name (service, TP_DBUS_NAME_TYPE_WELL_KNOWN,
&error))
diff --git a/src/empathy-tube-dispatch.h b/src/empathy-tube-dispatch.h
index f1328bb68..844c88145 100644
--- a/src/empathy-tube-dispatch.h
+++ b/src/empathy-tube-dispatch.h
@@ -44,11 +44,11 @@ struct _EmpathyTubeDispatch {
GObject parent;
};
-GType empathy_tube_dispatch_get_type(void);
+GType empathy_tube_dispatch_get_type (void);
/* TYPE MACROS */
#define EMPATHY_TYPE_TUBE_DISPATCH \
- (empathy_tube_dispatch_get_type())
+ (empathy_tube_dispatch_get_type ())
#define EMPATHY_TUBE_DISPATCH(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_TUBE_DISPATCH, \
EmpathyTubeDispatch))
diff --git a/src/empathy.c b/src/empathy.c
index 817b9bc37..d5be4df8d 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -14,9 +14,9 @@
*
* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
* Authors: Xavier Claessens <xclaesse@gmail.com>
*/
@@ -31,6 +31,10 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
+#if HAVE_LIBCHAMPLAIN
+#include <clutter-gtk/gtk-clutter-embed.h>
+#endif
+
#include <libebook/e-book.h>
#include <libnotify/notify.h>
@@ -46,11 +50,13 @@
#include <libempathy/empathy-dispatcher.h>
#include <libempathy/empathy-dispatch-operation.h>
#include <libempathy/empathy-log-manager.h>
+#include <libempathy/empathy-ft-factory.h>
#include <libempathy/empathy-tp-chat.h>
#include <libempathy/empathy-tp-call.h>
#include <libempathy-gtk/empathy-conf.h>
#include <libempathy-gtk/empathy-ui-utils.h>
+#include <libempathy-gtk/empathy-location-manager.h>
#include "empathy-accounts-dialog.h"
#include "empathy-main-window.h"
@@ -124,15 +130,17 @@ dispatch_cb (EmpathyDispatcher *dispatcher,
factory = empathy_call_factory_get ();
empathy_call_factory_claim_channel (factory, operation);
} else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER) {
- EmpathyFTManager *ft_manager;
- EmpathyTpFile *tp_file;
+ EmpathyFTFactory *factory;
- ft_manager = empathy_ft_manager_dup_singleton ();
- tp_file = EMPATHY_TP_FILE (
- empathy_dispatch_operation_get_channel_wrapper (operation));
- empathy_ft_manager_add_tp_file (ft_manager, tp_file);
- empathy_dispatch_operation_claim (operation);
- g_object_unref (ft_manager);
+ factory = empathy_ft_factory_dup_singleton ();
+
+ /* if the operation is not incoming, don't claim it,
+ * as it might have been triggered by another client, and
+ * we are observing it.
+ */
+ if (empathy_dispatch_operation_is_incoming (operation)) {
+ empathy_ft_factory_claim_channel (factory, operation);
+ }
}
}
@@ -229,7 +237,7 @@ create_salut_account (void)
GError *error = NULL;
/* Check if we already created a salut account */
- empathy_conf_get_bool (empathy_conf_get(),
+ empathy_conf_get_bool (empathy_conf_get (),
EMPATHY_PREFS_SALUT_ACCOUNT_CREATED,
&salut_created);
if (salut_created) {
@@ -312,7 +320,7 @@ create_salut_account (void)
/* The code that handles single-instance and startup notification is
* copied from gedit.
*
- * Copyright (C) 2005 - Paolo Maggi
+ * Copyright (C) 2005 - Paolo Maggi
*/
static void
on_bacon_message_received (const char *message,
@@ -404,30 +412,61 @@ show_version_cb (const char *option_name,
}
static void
+new_incoming_transfer_cb (EmpathyFTFactory *factory,
+ EmpathyFTHandler *handler,
+ GError *error,
+ gpointer user_data)
+{
+ if (error) {
+ empathy_ft_manager_display_error (handler, error);
+ } else {
+ empathy_receive_file_with_file_chooser (handler);
+ }
+}
+
+static void
+new_ft_handler_cb (EmpathyFTFactory *factory,
+ EmpathyFTHandler *handler,
+ GError *error,
+ gpointer user_data)
+{
+ if (error) {
+ empathy_ft_manager_display_error (handler, error);
+ } else {
+ empathy_ft_manager_add_handler (handler);
+ }
+
+ g_object_unref (handler);
+}
+
+static void
new_call_handler_cb (EmpathyCallFactory *factory, EmpathyCallHandler *handler,
gboolean outgoing, gpointer user_data)
{
- EmpathyCallWindow *window;
+ EmpathyCallWindow *window;
- window = empathy_call_window_new (handler);
- gtk_widget_show (GTK_WIDGET (window));
+ window = empathy_call_window_new (handler);
+ gtk_widget_show (GTK_WIDGET (window));
}
int
main (int argc, char *argv[])
{
guint32 startup_timestamp;
+#if HAVE_GEOCLUE
+ EmpathyLocationManager *location_manager = NULL;
+#endif
EmpathyStatusIcon *icon;
EmpathyDispatcher *dispatcher;
EmpathyLogManager *log_manager;
EmpathyChatroomManager *chatroom_manager;
- EmpathyFTManager *ft_manager;
EmpathyCallFactory *call_factory;
+ EmpathyFTFactory *ft_factory;
GtkWidget *window;
MissionControl *mc;
EmpathyIdle *idle;
gboolean autoconnect = TRUE;
- gboolean no_connect = FALSE;
+ gboolean no_connect = FALSE;
gboolean hide_contact_list = FALSE;
gboolean accounts_dialog = FALSE;
GError *error = NULL;
@@ -462,10 +501,14 @@ main (int argc, char *argv[])
empathy_gtk_init ();
g_set_application_name (_(PACKAGE_NAME));
- g_setenv("PULSE_PROP_media.role", "phone", TRUE);
+ g_setenv ("PULSE_PROP_media.role", "phone", TRUE);
gst_init (&argc, &argv);
+#if HAVE_LIBCHAMPLAIN
+ gtk_clutter_init (&argc, &argv);
+#endif
+
gtk_window_set_default_icon_name ("empathy");
textdomain (GETTEXT_PACKAGE);
@@ -533,11 +576,12 @@ main (int argc, char *argv[])
use_nm_notify_cb, idle);
/* Autoconnect */
- empathy_conf_get_bool (empathy_conf_get(),
+ empathy_conf_get_bool (empathy_conf_get (),
EMPATHY_PREFS_AUTOCONNECT,
&autoconnect);
if (autoconnect && ! no_connect &&
- empathy_idle_get_state (idle) <= MC_PRESENCE_OFFLINE) {
+ tp_connection_presence_type_cmp_availability (empathy_idle_get_state
+ (idle), TP_CONNECTION_PRESENCE_TYPE_OFFLINE) <= 0) {
empathy_idle_set_state (idle, MC_PRESENCE_AVAILABLE);
}
@@ -565,17 +609,26 @@ main (int argc, char *argv[])
chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
empathy_chatroom_manager_observe (chatroom_manager, dispatcher);
- ft_manager = empathy_ft_manager_dup_singleton ();
-
notify_init (_(PACKAGE_NAME));
/* Create the call factory */
call_factory = empathy_call_factory_initialise ();
g_signal_connect (G_OBJECT (call_factory), "new-call-handler",
G_CALLBACK (new_call_handler_cb), NULL);
+ /* Create the FT factory */
+ ft_factory = empathy_ft_factory_dup_singleton ();
+ g_signal_connect (ft_factory, "new-ft-handler",
+ G_CALLBACK (new_ft_handler_cb), NULL);
+ g_signal_connect (ft_factory, "new-incoming-transfer",
+ G_CALLBACK (new_incoming_transfer_cb), NULL);
+
+ /* Location mananger */
+#if HAVE_GEOCLUE
+ location_manager = empathy_location_manager_dup_singleton ();
+#endif
gtk_main ();
- empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE);
+ empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_OFFLINE);
g_object_unref (mc);
g_object_unref (idle);
@@ -583,7 +636,10 @@ main (int argc, char *argv[])
g_object_unref (log_manager);
g_object_unref (dispatcher);
g_object_unref (chatroom_manager);
- g_object_unref (ft_manager);
+#if HAVE_GEOCLUE
+ g_object_unref (location_manager);
+#endif
+ g_object_unref (ft_factory);
notify_uninit ();
diff --git a/src/ephy-spinner.c b/src/ephy-spinner.c
index 43b9bc990..be82ca71b 100644
--- a/src/ephy-spinner.c
+++ b/src/ephy-spinner.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright © 2000 Eazel, Inc.
* Copyright © 2002-2004 Marco Pesenti Gritti
* Copyright © 2004, 2006 Christian Persch
@@ -20,7 +20,7 @@
* Author: Andy Hertzfeld <andy@eazel.com>
*
* Ephy port by Marco Pesenti Gritti <marco@it.gnome.org>
- *
+ *
* $Id: ephy-spinner.c 2114 2006-12-25 12:15:00Z mr $
*/
@@ -455,7 +455,7 @@ ephy_spinner_cache_init (EphySpinnerCache *cache)
static void
ephy_spinner_cache_finalize (GObject *object)
{
- EphySpinnerCache *cache = EPHY_SPINNER_CACHE (object);
+ EphySpinnerCache *cache = EPHY_SPINNER_CACHE (object);
EphySpinnerCachePrivate *priv = cache->priv;
g_hash_table_destroy (priv->hash);