diff options
Diffstat (limited to 'src')
51 files changed, 0 insertions, 18443 deletions
diff --git a/src/.gitignore b/src/.gitignore deleted file mode 100644 index a7f583649..000000000 --- a/src/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -empathy -empathy-accounts -empathy-logs -empathy-chat-chandler -empathy-call-chandler -empathy-tubes-chandler -empathy-tube-dispatch-enumtypes.c -empathy-tube-dispatch-enumtypes.h -org.gnome.Empathy.Chat.service -org.gnome.Empathy.Call.service -org.gnome.Empathy.Tubes.service diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index a49bfc5ad..000000000 --- a/src/Makefile.am +++ /dev/null @@ -1,86 +0,0 @@ -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(EMPATHY_CFLAGS) \ - $(LIBNOTIFY_CFLAGS) \ - $(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) - -bin_PROGRAMS = \ - empathy \ - empathy-logs - -BUILT_SOURCES= \ - empathy-tube-dispatch-enumtypes.h \ - empathy-tube-dispatch-enumtypes.c - -empathy_SOURCES = \ - bacon-message-connection.c bacon-message-connection.h \ - 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-chatrooms-window.c empathy-chatrooms-window.h \ - empathy-chat-window.c empathy-chat-window.h \ - empathy-event-manager.c empathy-event-manager.h \ - empathy-ft-manager.c empathy-ft-manager.h \ - empathy-import-dialog.c empathy-import-dialog.h \ - empathy-import-pidgin.c empathy-import-pidgin.h \ - empathy-main-window.c empathy-main-window.h \ - empathy-misc.c empathy-misc.h \ - empathy-new-chatroom-dialog.c empathy-new-chatroom-dialog.h \ - 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 \ - ephy-spinner.c ephy-spinner.h - -nodist_empathy_SOURCES = $(BUILT_SOURCES) - -empathy_logs_SOURCES = empathy-logs.c - -gladedir = $(datadir)/empathy -glade_DATA = \ - empathy-accounts-dialog.glade \ - empathy-call-window.glade \ - empathy-chatrooms-window.glade \ - empathy-chat-window.glade \ - empathy-ft-manager.glade \ - empathy-import-dialog.glade \ - empathy-main-window.glade \ - empathy-new-chatroom-dialog.glade \ - empathy-preferences.glade \ - empathy-status-icon.glade - -dist_man_MANS = \ - empathy.1 - -# rules for making the glib enum objects -%-enumtypes.h: %.h Makefile.in - 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" \ - --ftail "G_END_DECLS\n\n#endif /* __$(shell echo $* | tr [:lower:]- [:upper:]_)_ENUM_TYPES_H__ */" \ - $< > $@ - -%-enumtypes.c: %.h Makefile.in - 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[] = {" \ - --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@VALUENAME@\" }," \ - --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \ - $< > $@ - -EXTRA_DIST = \ - $(autostart_DATA) \ - $(glade_DATA) - -CLEANFILES = $(BUILT_SOURCES) - diff --git a/src/bacon-message-connection.c b/src/bacon-message-connection.c deleted file mode 100644 index c9fda4aeb..000000000 --- a/src/bacon-message-connection.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Totem project hereby grant permission for non-gpl compatible GStreamer - * plugins to be used and distributed together with GStreamer and Totem. This - * permission are above and beyond the permissions granted by the GPL license - * Totem is covered by. - * - * Monday 7th February 2005: Christian Schaller: Add excemption clause. - * See license_change file for details. - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <errno.h> - -#include "bacon-message-connection.h" - -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX 108 -#endif - -struct BaconMessageConnection { - /* A server accepts connections */ - gboolean is_server; - - /* The socket path itself */ - char *path; - - /* File descriptor of the socket */ - int fd; - /* Channel to watch */ - GIOChannel *chan; - /* Event id returned by g_io_add_watch() */ - int conn_id; - - /* Connections accepted by this connection */ - GSList *accepted_connections; - - /* callback */ - void (*func) (const char *message, gpointer user_data); - gpointer data; -}; - -static gboolean -test_is_socket (const char *path) -{ - struct stat s; - - if (stat (path, &s) == -1) - return FALSE; - - if (S_ISSOCK (s.st_mode)) - return TRUE; - - return FALSE; -} - -static gboolean -is_owned_by_user_and_socket (const char *path) -{ - struct stat s; - - if (stat (path, &s) == -1) - return FALSE; - - if (s.st_uid != geteuid ()) - return FALSE; - - if ((s.st_mode & S_IFSOCK) != S_IFSOCK) - return FALSE; - - return TRUE; -} - -static gboolean server_cb (GIOChannel *source, - GIOCondition condition, gpointer data); - -static gboolean -setup_connection (BaconMessageConnection *conn) -{ - int fdflags; - - g_return_val_if_fail (conn->chan == NULL, FALSE); - - /* Add CLOEXEC flag on the fd to make sure the socket get closed - * if exec is called. */ - fdflags = fcntl (conn->fd, F_GETFD, 0); - if (fdflags >= 0) { - fdflags |= FD_CLOEXEC; - fcntl (conn->fd, F_SETFD, fdflags); - } - - conn->chan = g_io_channel_unix_new (conn->fd); - if (!conn->chan) { - return FALSE; - } - g_io_channel_set_line_term (conn->chan, "\n", 1); - conn->conn_id = g_io_add_watch (conn->chan, G_IO_IN, server_cb, conn); - - return TRUE; -} - -static void -accept_new_connection (BaconMessageConnection *server_conn) -{ - BaconMessageConnection *conn; - int alen; - - g_return_if_fail (server_conn->is_server); - - conn = g_new0 (BaconMessageConnection, 1); - conn->is_server = FALSE; - conn->func = server_conn->func; - conn->data = server_conn->data; - - conn->fd = accept (server_conn->fd, NULL, (guint *)&alen); - - server_conn->accepted_connections = - g_slist_prepend (server_conn->accepted_connections, conn); - - setup_connection (conn); -} - -static gboolean -server_cb (GIOChannel *source, GIOCondition condition, gpointer data) -{ - BaconMessageConnection *conn = (BaconMessageConnection *)data; - char *message, *subs, buf; - int cd, rc, offset; - gboolean finished; - - offset = 0; - if (conn->is_server && conn->fd == g_io_channel_unix_get_fd (source)) { - accept_new_connection (conn); - return TRUE; - } - message = g_malloc (1); - cd = conn->fd; - rc = read (cd, &buf, 1); - while (rc > 0 && buf != '\n') - { - message = g_realloc (message, rc + offset + 1); - message[offset] = buf; - offset = offset + rc; - rc = read (cd, &buf, 1); - } - if (rc <= 0) { - g_io_channel_shutdown (conn->chan, FALSE, NULL); - g_io_channel_unref (conn->chan); - conn->chan = NULL; - close (conn->fd); - conn->fd = -1; - g_free (message); - conn->conn_id = 0; - - return FALSE; - } - message[offset] = '\0'; - - subs = message; - finished = FALSE; - - while (finished == FALSE && *subs != '\0') - { - if (conn->func != NULL) - (*conn->func) (subs, conn->data); - - subs += strlen (subs) + 1; - if (subs - message >= offset) - finished = TRUE; - } - - g_free (message); - - return TRUE; -} - -static char * -find_file_with_pattern (const char *dir, const char *pattern) -{ - GDir *filedir; - char *found_filename; - const char *filename; - GPatternSpec *pat; - - filedir = g_dir_open (dir, 0, NULL); - if (filedir == NULL) - return NULL; - - pat = g_pattern_spec_new (pattern); - if (pat == NULL) - { - g_dir_close (filedir); - return NULL; - } - - found_filename = NULL; - - while ((filename = g_dir_read_name (filedir))) - { - if (g_pattern_match_string (pat, filename)) - { - char *tmp = g_build_filename (dir, filename, NULL); - if (is_owned_by_user_and_socket (tmp)) - found_filename = g_strdup (filename); - g_free (tmp); - } - - if (found_filename != NULL) - break; - } - - g_pattern_spec_free (pat); - g_dir_close (filedir); - - return found_filename; -} - -static char * -socket_filename (const char *prefix) -{ - char *pattern, *newfile, *path, *filename; - const char *tmpdir; - - pattern = g_strdup_printf ("%s.%s.*", prefix, g_get_user_name ()); - tmpdir = g_get_tmp_dir (); - filename = find_file_with_pattern (tmpdir, pattern); - if (filename == NULL) - { - newfile = g_strdup_printf ("%s.%s.%u", prefix, - g_get_user_name (), g_random_int ()); - path = g_build_filename (tmpdir, newfile, NULL); - g_free (newfile); - } else { - path = g_build_filename (tmpdir, filename, NULL); - g_free (filename); - } - - g_free (pattern); - return path; -} - -static gboolean -try_server (BaconMessageConnection *conn) -{ - struct sockaddr_un uaddr; - - uaddr.sun_family = AF_UNIX; - strncpy (uaddr.sun_path, conn->path, - MIN (strlen(conn->path)+1, UNIX_PATH_MAX)); - conn->fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (bind (conn->fd, (struct sockaddr *) &uaddr, sizeof (uaddr)) == -1) - { - conn->fd = -1; - return FALSE; - } - listen (conn->fd, 5); - - return setup_connection (conn); -} - -static gboolean -try_client (BaconMessageConnection *conn) -{ - struct sockaddr_un uaddr; - - uaddr.sun_family = AF_UNIX; - strncpy (uaddr.sun_path, conn->path, - MIN(strlen(conn->path)+1, UNIX_PATH_MAX)); - conn->fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (connect (conn->fd, (struct sockaddr *) &uaddr, - sizeof (uaddr)) == -1) - { - conn->fd = -1; - return FALSE; - } - - return setup_connection (conn); -} - -BaconMessageConnection * -bacon_message_connection_new (const char *prefix) -{ - BaconMessageConnection *conn; - - g_return_val_if_fail (prefix != NULL, NULL); - - conn = g_new0 (BaconMessageConnection, 1); - conn->path = socket_filename (prefix); - - if (test_is_socket (conn->path) == FALSE) - { - if (!try_server (conn)) - { - bacon_message_connection_free (conn); - return NULL; - } - - conn->is_server = TRUE; - return conn; - } - - if (try_client (conn) == FALSE) - { - unlink (conn->path); - try_server (conn); - if (conn->fd == -1) - { - bacon_message_connection_free (conn); - return NULL; - } - - conn->is_server = TRUE; - return conn; - } - - conn->is_server = FALSE; - return conn; -} - -void -bacon_message_connection_free (BaconMessageConnection *conn) -{ - GSList *child_conn; - - g_return_if_fail (conn != NULL); - /* Only servers can accept other connections */ - g_return_if_fail (conn->is_server != FALSE || - conn->accepted_connections == NULL); - - child_conn = conn->accepted_connections; - while (child_conn != NULL) { - bacon_message_connection_free (child_conn->data); - child_conn = g_slist_next (child_conn); - } - g_slist_free (conn->accepted_connections); - - if (conn->conn_id) { - g_source_remove (conn->conn_id); - conn->conn_id = 0; - } - if (conn->chan) { - g_io_channel_shutdown (conn->chan, FALSE, NULL); - g_io_channel_unref (conn->chan); - } - - if (conn->is_server != FALSE) { - unlink (conn->path); - } - if (conn->fd != -1) { - close (conn->fd); - } - - g_free (conn->path); - g_free (conn); -} - -void -bacon_message_connection_set_callback (BaconMessageConnection *conn, - BaconMessageReceivedFunc func, - gpointer user_data) -{ - g_return_if_fail (conn != NULL); - - conn->func = func; - conn->data = user_data; -} - -void -bacon_message_connection_send (BaconMessageConnection *conn, - const char *message) -{ - g_return_if_fail (conn != NULL); - g_return_if_fail (message != NULL); - - g_io_channel_write_chars (conn->chan, message, strlen (message), - NULL, NULL); - g_io_channel_write_chars (conn->chan, "\n", 1, NULL, NULL); - g_io_channel_flush (conn->chan, NULL); -} - -gboolean -bacon_message_connection_get_is_server (BaconMessageConnection *conn) -{ - g_return_val_if_fail (conn != NULL, FALSE); - - return conn->is_server; -} - diff --git a/src/bacon-message-connection.h b/src/bacon-message-connection.h deleted file mode 100644 index db4a91262..000000000 --- a/src/bacon-message-connection.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2003 Bastien Nocera <hadess@hadess.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Totem project hereby grant permission for non-gpl compatible GStreamer - * plugins to be used and distributed together with GStreamer and Totem. This - * permission are above and beyond the permissions granted by the GPL license - * Totem is covered by. - * - * Monday 7th February 2005: Christian Schaller: Add excemption clause. - * See license_change file for details. - * - */ - -#ifndef BACON_MESSAGE_CONNECTION_H -#define BACON_MESSAGE_CONNECTION_H - -#include <glib.h> - -G_BEGIN_DECLS - -typedef void (*BaconMessageReceivedFunc) (const char *message, - gpointer user_data); - -typedef struct BaconMessageConnection BaconMessageConnection; - -BaconMessageConnection *bacon_message_connection_new (const char *prefix); -void bacon_message_connection_free (BaconMessageConnection *conn); -void bacon_message_connection_set_callback (BaconMessageConnection *conn, - BaconMessageReceivedFunc func, - gpointer user_data); -void bacon_message_connection_send (BaconMessageConnection *conn, - const char *message); -gboolean bacon_message_connection_get_is_server (BaconMessageConnection *conn); - -G_END_DECLS - -#endif /* BACON_MESSAGE_CONNECTION_H */ diff --git a/src/empathy-about-dialog.c b/src/empathy-about-dialog.c deleted file mode 100644 index 4765e6b32..000000000 --- a/src/empathy-about-dialog.c +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2006-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Martyn Russell <martyn@imendio.com> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> - -#include <glib/gi18n.h> -#include <gtk/gtkaboutdialog.h> -#include <gtk/gtksizegroup.h> -#include <glade/glade.h> - -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-about-dialog.h" - -#define WEB_SITE "http://live.gnome.org/Empathy" - -static void about_dialog_activate_link_cb (GtkAboutDialog *about, - const gchar *link, - gpointer data); - -static const char *authors[] = { - "Alban Crequy", - "Andreas Lööw", - "Aurelien Naldi", - "Bastien Nocera", - "Christoffer Olsen", - "Elliot Fairweather", - "Frederic Crozat", - "Frederic Peters", - "Geert-Jan Van den Bogaerde", - "Guillaume Desmottes", - "Johan Hammar", - "Jonatan Magnusson", - "Jonny Lamb", - "Jordi Mallach", - "Kim Andersen", - "Marco Barisione", - "Martyn Russell <martyn@gnome.org>", - "Mikael Hallendal <micke@imendio.com>", - "Mike Gratton", - "Richard Hult <richard@imendio.com>", - "Ross Burton", - "Sjoerd Simons", - "Thomas Reynolds", - "Vincent Untz", - "Xavier Claessens <xclaesse@gmail.com>", - NULL -}; - -static const char *documenters[] = { - "Milo Casagrande", - "Seth Dudenhofer", - NULL -}; - -static const char *artists[] = { - "Andreas Nilsson <nisses.mail@home.se>", - "Vinicius Depizzol <vdepizzol@gmail.com>", - NULL -}; - -static const char *license[] = { - N_("Empathy is free software; you can redistribute it and/or modify " - "it under the terms of the GNU General Public License as published by " - "the Free Software Foundation; either version 2 of the License, or " - "(at your option) any later version."), - N_("Empathy is distributed in the hope that it will be useful, " - "but WITHOUT ANY WARRANTY; without even the implied warranty of " - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " - "GNU General Public License for more details."), - N_("You should have received a copy of the GNU General Public License " - "along with Empathy; if not, write to the Free Software Foundation, Inc., " - "51 Franklin Street, Fifth Floor, Boston, MA 02110-130159 USA") -}; - -static void -about_dialog_activate_link_cb (GtkAboutDialog *about, - const gchar *link, - gpointer data) -{ - empathy_url_show (GTK_WIDGET (about), link); -} - -void -empathy_about_dialog_new (GtkWindow *parent) -{ - gchar *license_trans; - - gtk_about_dialog_set_url_hook (about_dialog_activate_link_cb, NULL, NULL); - - license_trans = g_strconcat (_(license[0]), "\n\n", - _(license[1]), "\n\n", - _(license[2]), "\n\n", - NULL); - - gtk_show_about_dialog (parent, - "artists", artists, - "authors", authors, - "comments", _("An Instant Messaging client for GNOME"), - "license", license_trans, - "wrap-license", TRUE, - "copyright", "Imendio AB 2002-2007\nCollabora Ltd 2007-2008", - "documenters", documenters, - "logo-icon-name", "empathy", - "translator-credits", _("translator-credits"), - "version", PACKAGE_VERSION, - "website", WEB_SITE, - NULL); - - g_free (license_trans); -} - - diff --git a/src/empathy-about-dialog.h b/src/empathy-about-dialog.h deleted file mode 100644 index e7eac5ff9..000000000 --- a/src/empathy-about-dialog.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2006-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Martyn Russell <martyn@imendio.com> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#ifndef __EMPATHY_ABOUT_DIALOG_H__ -#define __EMPATHY_ABOUT_DIALOG_H__ - -#include <gtk/gtkwindow.h> - -G_BEGIN_DECLS - -void empathy_about_dialog_new (GtkWindow *parent); - -G_END_DECLS - -#endif /* __EMPATHY_ABOUT_DIALOG_H__ */ diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c deleted file mode 100644 index 4d9456684..000000000 --- a/src/empathy-accounts-dialog.c +++ /dev/null @@ -1,1171 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2005-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Martyn Russell <martyn@imendio.com> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> - -#include <string.h> -#include <stdlib.h> - -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <glib/gi18n.h> -#include <dbus/dbus-glib.h> - -#include <libmissioncontrol/mc-account.h> -#include <libmissioncontrol/mc-profile.h> -#include <telepathy-glib/util.h> - -#include <libempathy/empathy-utils.h> -#include <libempathy/empathy-account-manager.h> -#include <libempathy-gtk/empathy-ui-utils.h> -#include <libempathy-gtk/empathy-profile-chooser.h> -#include <libempathy-gtk/empathy-account-widget.h> -#include <libempathy-gtk/empathy-account-widget-irc.h> -#include <libempathy-gtk/empathy-account-widget-sip.h> -#include <libempathy-gtk/empathy-conf.h> - -#include "empathy-accounts-dialog.h" -#include "empathy-import-dialog.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT -#include <libempathy/empathy-debug.h> - -/* Flashing delay for icons (milliseconds). */ -#define FLASH_TIMEOUT 500 - -typedef struct { - GtkWidget *window; - - GtkWidget *alignment_settings; - - GtkWidget *vbox_details; - GtkWidget *frame_no_profile; - - GtkWidget *treeview; - - GtkWidget *button_add; - GtkWidget *button_remove; - GtkWidget *button_import; - - GtkWidget *frame_new_account; - GtkWidget *combobox_profile; - GtkWidget *hbox_type; - GtkWidget *button_create; - GtkWidget *button_back; - GtkWidget *checkbutton_register; - - GtkWidget *image_type; - GtkWidget *label_name; - GtkWidget *label_type; - GtkWidget *settings_widget; - - gboolean connecting_show; - guint connecting_id; - - EmpathyAccountManager *account_manager; - MissionControl *mc; -} EmpathyAccountsDialog; - -enum { - COL_ENABLED, - COL_NAME, - COL_STATUS, - COL_ACCOUNT_POINTER, - COL_COUNT -}; - -static void accounts_dialog_update_account (EmpathyAccountsDialog *dialog, - McAccount *account); -static void accounts_dialog_model_setup (EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog); -static void accounts_dialog_name_editing_started_cb (GtkCellRenderer *renderer, - GtkCellEditable *editable, - gchar *path, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - EmpathyAccountsDialog *dialog); -static McAccount *accounts_dialog_model_get_selected (EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog, - McAccount *account); -static gboolean accounts_dialog_model_remove_selected (EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_add_or_update_account (EmpathyAccountsDialog *dialog, - McAccount *account); -static void accounts_dialog_account_added_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_account_removed_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyAccountsDialog *dialog); -static gboolean accounts_dialog_row_changed_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data); -static gboolean accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog *dialog); -static void accounts_dialog_connection_changed_cb (EmpathyAccountManager *manager, - McAccount *account, - TpConnectionStatusReason reason, - TpConnectionStatus current, - TpConnectionStatus previous, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_create_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_back_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_add_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_help_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_remove_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_import_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_destroy_cb (GtkWidget *widget, - EmpathyAccountsDialog *dialog); - -static void -accounts_dialog_update_name_label (EmpathyAccountsDialog *dialog, - McAccount *account) -{ - gchar *text; - - text = g_markup_printf_escaped ("<big><b>%s</b></big>", - mc_account_get_display_name (account)); - gtk_label_set_markup (GTK_LABEL (dialog->label_name), text); - - g_free (text); -} - -static void -accounts_dialog_update_account (EmpathyAccountsDialog *dialog, - McAccount *account) -{ - McProfile *profile; - const gchar *config_ui; - - if (!account) { - GtkTreeView *view; - GtkTreeModel *model; - - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); - - if (gtk_tree_model_iter_n_children (model, NULL) > 0) { - /* We have configured accounts, select the first one */ - accounts_dialog_model_select_first (dialog); - return; - } - if (empathy_profile_chooser_n_profiles (dialog->combobox_profile) > 0) { - /* We have no account configured but we have some - * profiles instsalled. The user obviously wants to add - * an account. Click on the Add button for him. */ - accounts_dialog_button_add_clicked_cb (dialog->button_add, - dialog); - return; - } - - /* No account and no profile, warn the user */ - gtk_widget_hide (dialog->vbox_details); - gtk_widget_hide (dialog->frame_new_account); - gtk_widget_show (dialog->frame_no_profile); - gtk_widget_set_sensitive (dialog->button_add, FALSE); - gtk_widget_set_sensitive (dialog->button_remove, FALSE); - return; - } - - /* We have an account selected, destroy old settings and create a new - * one for the account selected */ - gtk_widget_hide (dialog->frame_new_account); - gtk_widget_hide (dialog->frame_no_profile); - gtk_widget_show (dialog->vbox_details); - gtk_widget_set_sensitive (dialog->button_add, TRUE); - gtk_widget_set_sensitive (dialog->button_remove, TRUE); - - if (dialog->settings_widget) { - gtk_widget_destroy (dialog->settings_widget); - dialog->settings_widget = NULL; - } - - profile = mc_account_get_profile (account); - config_ui = mc_profile_get_configuration_ui (profile); - if (!tp_strdiff (config_ui, "jabber")) { - 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); - } - else if (!tp_strdiff (config_ui, "local-xmpp")) { - dialog->settings_widget = - empathy_account_widget_salut_new (account); - } - else if (!tp_strdiff (config_ui, "irc")) { - dialog->settings_widget = - empathy_account_widget_irc_new (account); - } - else if (!tp_strdiff(config_ui, "icq")) { - dialog->settings_widget = - empathy_account_widget_icq_new (account); - } - else if (!tp_strdiff(config_ui, "aim")) { - dialog->settings_widget = - empathy_account_widget_aim_new (account); - } - else if (!tp_strdiff (config_ui, "yahoo")) { - dialog->settings_widget = - empathy_account_widget_yahoo_new (account); - } - else if (!tp_strdiff (config_ui, "sofiasip")) { - dialog->settings_widget = - empathy_account_widget_sip_new (account); - } - else if (!tp_strdiff (config_ui, "groupwise")) { - dialog->settings_widget = - empathy_account_widget_groupwise_new (account); - } - else { - dialog->settings_widget = - empathy_account_widget_generic_new (account); - } - - gtk_container_add (GTK_CONTAINER (dialog->alignment_settings), - dialog->settings_widget); - - - gtk_image_set_from_icon_name (GTK_IMAGE (dialog->image_type), - mc_profile_get_icon_name (profile), - GTK_ICON_SIZE_DIALOG); - gtk_widget_set_tooltip_text (dialog->image_type, - mc_profile_get_display_name (profile)); - - accounts_dialog_update_name_label (dialog, account); - - g_object_unref (profile); -} - -static void -accounts_dialog_model_setup (EmpathyAccountsDialog *dialog) -{ - GtkListStore *store; - GtkTreeSelection *selection; - - store = gtk_list_store_new (COL_COUNT, - G_TYPE_BOOLEAN, /* enabled */ - G_TYPE_STRING, /* name */ - G_TYPE_UINT, /* status */ - MC_TYPE_ACCOUNT); /* account */ - - gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview), - GTK_TREE_MODEL (store)); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - g_signal_connect (selection, "changed", - G_CALLBACK (accounts_dialog_model_selection_changed), - dialog); - - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - COL_NAME, GTK_SORT_ASCENDING); - - accounts_dialog_model_add_columns (dialog); - - g_object_unref (store); -} - -static void -accounts_dialog_name_edited_cb (GtkCellRendererText *renderer, - gchar *path, - gchar *new_text, - EmpathyAccountsDialog *dialog) -{ - McAccount *account; - GtkTreeModel *model; - GtkTreePath *treepath; - GtkTreeIter iter; - - if (empathy_account_manager_get_connecting_accounts (dialog->account_manager) > 0) { - dialog->connecting_id = g_timeout_add (FLASH_TIMEOUT, - (GSourceFunc) accounts_dialog_flash_connecting_cb, - dialog); - } - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - treepath = gtk_tree_path_new_from_string (path); - gtk_tree_model_get_iter (model, &iter, treepath); - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_POINTER, &account, - -1); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_NAME, new_text, - -1); - gtk_tree_path_free (treepath); - - mc_account_set_display_name (account, new_text); - g_object_unref (account); -} - -static void -accounts_dialog_enable_toggled_cb (GtkCellRendererToggle *cell_renderer, - gchar *path, - EmpathyAccountsDialog *dialog) -{ - McAccount *account; - GtkTreeModel *model; - GtkTreePath *treepath; - GtkTreeIter iter; - gboolean enabled; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - treepath = gtk_tree_path_new_from_string (path); - gtk_tree_model_get_iter (model, &iter, treepath); - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_POINTER, &account, - -1); - gtk_tree_path_free (treepath); - - enabled = mc_account_is_enabled (account); - mc_account_set_enabled (account, !enabled); - - DEBUG ("%s account %s", enabled ? "Disabled" : "Enable", - mc_account_get_display_name(account)); - - g_object_unref (account); -} - -static void -accounts_dialog_name_editing_started_cb (GtkCellRenderer *renderer, - GtkCellEditable *editable, - gchar *path, - EmpathyAccountsDialog *dialog) -{ - if (dialog->connecting_id) { - g_source_remove (dialog->connecting_id); - } - DEBUG ("Editing account name started; stopping flashing"); -} - -static void -accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - - view = GTK_TREE_VIEW (dialog->treeview); - gtk_tree_view_set_headers_visible (view, TRUE); - - /* Enabled column */ - cell = gtk_cell_renderer_toggle_new (); - gtk_tree_view_insert_column_with_attributes (view, -1, - _("Enabled"), - cell, - "active", COL_ENABLED, - NULL); - g_signal_connect (cell, "toggled", - G_CALLBACK (accounts_dialog_enable_toggled_cb), - dialog); - - /* Account column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Accounts")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - /* Icon renderer */ - cell = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - gtk_tree_view_column_set_cell_data_func (column, cell, - (GtkTreeCellDataFunc) - accounts_dialog_model_pixbuf_data_func, - dialog, - NULL); - - /* Name renderer */ - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "ellipsize", PANGO_ELLIPSIZE_END, - "editable", TRUE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); - g_signal_connect (cell, "edited", - G_CALLBACK (accounts_dialog_name_edited_cb), - dialog); - g_signal_connect (cell, "editing-started", - G_CALLBACK (accounts_dialog_name_editing_started_cb), - dialog); -} - -static void -accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - - /* select first */ - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); - - if (gtk_tree_model_get_iter_first (model, &iter)) { - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_select_iter (selection, &iter); - } else { - accounts_dialog_update_account (dialog, NULL); - } -} - -static void -accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - EmpathyAccountsDialog *dialog) -{ - McAccount *account; - const gchar *icon_name; - GdkPixbuf *pixbuf; - TpConnectionStatus status; - - gtk_tree_model_get (model, iter, - COL_STATUS, &status, - COL_ACCOUNT_POINTER, &account, - -1); - - icon_name = empathy_icon_name_from_account (account); - pixbuf = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON); - - if (pixbuf) { - if (status == TP_CONNECTION_STATUS_DISCONNECTED || - (status == TP_CONNECTION_STATUS_CONNECTING && - !dialog->connecting_show)) { - GdkPixbuf *modded_pixbuf; - - modded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - TRUE, - 8, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - - gdk_pixbuf_saturate_and_pixelate (pixbuf, - modded_pixbuf, - 1.0, - TRUE); - g_object_unref (pixbuf); - pixbuf = modded_pixbuf; - } - } - - g_object_set (cell, - "visible", TRUE, - "pixbuf", pixbuf, - NULL); - - g_object_unref (account); - if (pixbuf) { - g_object_unref (pixbuf); - } -} - -static gboolean -accounts_dialog_get_account_iter (EmpathyAccountsDialog *dialog, - McAccount *account, - GtkTreeIter *iter) -{ - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeModel *model; - gboolean ok; - - /* Update the status in the model */ - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - model = gtk_tree_view_get_model (view); - - for (ok = gtk_tree_model_get_iter_first (model, iter); - ok; - ok = gtk_tree_model_iter_next (model, iter)) { - McAccount *this_account; - gboolean equal; - - gtk_tree_model_get (model, iter, - COL_ACCOUNT_POINTER, &this_account, - -1); - - equal = empathy_account_equal (this_account, account); - g_object_unref (this_account); - - if (equal) { - return TRUE; - } - } - - return FALSE; -} - -static McAccount * -accounts_dialog_model_get_selected (EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - McAccount *account; - - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return NULL; - } - - gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1); - - return account; -} - -static void -accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog, - McAccount *account) -{ - GtkTreeSelection *selection; - GtkTreeIter iter; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->treeview)); - if (accounts_dialog_get_account_iter (dialog, account, &iter)) { - gtk_tree_selection_select_iter (selection, &iter); - } -} - -static gboolean -accounts_dialog_model_remove_selected (EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return FALSE; - } - - return gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -} - -static void -accounts_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyAccountsDialog *dialog) -{ - McAccount *account; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean is_selection; - - is_selection = gtk_tree_selection_get_selected (selection, &model, &iter); - - account = accounts_dialog_model_get_selected (dialog); - accounts_dialog_update_account (dialog, account); - - if (account) { - g_object_unref (account); - } -} - -static void -accounts_dialog_add_or_update_account (EmpathyAccountsDialog *dialog, - McAccount *account) -{ - GtkTreeModel *model; - GtkTreeIter iter; - TpConnectionStatus status; - const gchar *name; - gboolean enabled; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - status = mission_control_get_connection_status (dialog->mc, account, NULL); - name = mc_account_get_display_name (account); - enabled = mc_account_is_enabled (account); - - if (!accounts_dialog_get_account_iter (dialog, account, &iter)) { - DEBUG ("Adding new account"); - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - } - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, - COL_NAME, name, - COL_STATUS, status, - COL_ACCOUNT_POINTER, account, - -1); - - accounts_dialog_connection_changed_cb (dialog->account_manager, - account, - TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED, - status, - TP_CONNECTION_STATUS_DISCONNECTED, - dialog); -} - -static void -accounts_dialog_account_added_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyAccountsDialog *dialog) -{ - const gchar *current_name; - gchar *account_param = NULL; - - accounts_dialog_add_or_update_account (dialog, account); - - /* Change the display name to "%s (%s)" % (protocol, account). - * - The protocol is the display name of the profile. - * - The account should be the normalized name of the McAccount but - * it's not set until first connection, so we get the "account" - * parameter for CM that have it. */ - current_name = mc_account_get_display_name (account); - mc_account_get_param_string (account, "account", &account_param); - if (!EMP_STR_EMPTY (account_param)) { - McProfile *profile; - const gchar *profile_name; - gchar *new_name; - - profile = mc_account_get_profile (account); - profile_name = mc_profile_get_display_name (profile); - new_name = g_strdup_printf ("%s (%s)", profile_name, - account_param); - - DEBUG ("Setting new display name for account %s: '%s'", - mc_account_get_unique_name (account), new_name); - - mc_account_set_display_name (account, new_name); - g_free (new_name); - g_object_unref (profile); - } else { - /* FIXME: This CM has no account parameter, what can be done? */ - } - g_free (account_param); -} - -static void -accounts_dialog_account_removed_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyAccountsDialog *dialog) -{ - - accounts_dialog_model_set_selected (dialog, account); - accounts_dialog_model_remove_selected (dialog); -} - -static gboolean -accounts_dialog_row_changed_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data) -{ - gtk_tree_model_row_changed (model, path, iter); - - return FALSE; -} - -static gboolean -accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeModel *model; - - dialog->connecting_show = !dialog->connecting_show; - - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); - - gtk_tree_model_foreach (model, accounts_dialog_row_changed_foreach, NULL); - - return TRUE; -} - -static void -accounts_dialog_connection_changed_cb (EmpathyAccountManager *manager, - McAccount *account, - TpConnectionStatusReason reason, - TpConnectionStatus current, - TpConnectionStatus previous, - EmpathyAccountsDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gboolean found; - - /* Update the status in the model */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - - if (accounts_dialog_get_account_iter (dialog, account, &iter)) { - GtkTreePath *path; - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_STATUS, current, - -1); - - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_row_changed (model, path, &iter); - gtk_tree_path_free (path); - } - - found = (empathy_account_manager_get_connecting_accounts (manager) > 0); - - if (!found && dialog->connecting_id) { - g_source_remove (dialog->connecting_id); - dialog->connecting_id = 0; - } - - if (found && !dialog->connecting_id) { - dialog->connecting_id = g_timeout_add (FLASH_TIMEOUT, - (GSourceFunc) accounts_dialog_flash_connecting_cb, - dialog); - } -} - -static void -enable_or_disable_account (EmpathyAccountsDialog *dialog, - McAccount *account, - gboolean enabled) -{ - GtkTreeModel *model; - GtkTreeIter iter; - - /* Update the status in the model */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - - DEBUG ("Account %s is now %s", - mc_account_get_display_name (account), - enabled ? "enabled" : "disabled"); - - if (accounts_dialog_get_account_iter (dialog, account, &iter)) { - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, - -1); - } -} - -static void -accounts_dialog_account_disabled_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyAccountsDialog *dialog) -{ - enable_or_disable_account (dialog, account, FALSE); -} - -static void -accounts_dialog_account_enabled_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyAccountsDialog *dialog) -{ - enable_or_disable_account (dialog, account, TRUE); -} - -static void -accounts_dialog_account_changed_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyAccountsDialog *dialog) -{ - McAccount *selected_account; - - accounts_dialog_add_or_update_account (dialog, account); - selected_account = accounts_dialog_model_get_selected (dialog); - if (empathy_account_equal (account, selected_account)) { - accounts_dialog_update_name_label (dialog, account); - } -} - -static void -accounts_dialog_button_create_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) -{ - McProfile *profile; - McAccount *account; - gchar *str; - McProfileCapabilityFlags cap; - - profile = empathy_profile_chooser_get_selected (dialog->combobox_profile); - - /* Create account */ - account = mc_account_create (profile); - if (account == NULL) { - /* We can't display an error to the user as MC doesn't give us - * any clue about the reason of the failure... */ - return; - } - - /* To translator: %s is the protocol name */ - str = g_strdup_printf (_("New %s account"), - mc_profile_get_display_name (profile)); - mc_account_set_display_name (account, str); - g_free (str); - - cap = mc_profile_get_capabilities (profile); - if (cap & MC_PROFILE_CAPABILITY_REGISTRATION_UI) { - gboolean active; - - active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->checkbutton_register)); - if (!active) { - mc_account_set_param_boolean (account, "register", TRUE); - } - } - - accounts_dialog_add_or_update_account (dialog, account); - accounts_dialog_model_set_selected (dialog, account); - - g_object_unref (account); - g_object_unref (profile); -} - -static void -accounts_dialog_button_back_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) -{ - McAccount *account; - - account = accounts_dialog_model_get_selected (dialog); - accounts_dialog_update_account (dialog, account); -} - -static void -accounts_dialog_profile_changed_cb (GtkWidget *widget, - EmpathyAccountsDialog *dialog) -{ - McProfile *profile; - McProfileCapabilityFlags cap; - - profile = empathy_profile_chooser_get_selected (dialog->combobox_profile); - cap = mc_profile_get_capabilities (profile); - - if (cap & MC_PROFILE_CAPABILITY_REGISTRATION_UI) { - gtk_widget_show (dialog->checkbutton_register); - } else { - gtk_widget_hide (dialog->checkbutton_register); - } - g_object_unref (profile); -} - -static void -accounts_dialog_button_add_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) -{ - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeModel *model; - - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_unselect_all (selection); - - gtk_widget_set_sensitive (dialog->button_add, FALSE); - gtk_widget_set_sensitive (dialog->button_remove, FALSE); - gtk_widget_hide (dialog->vbox_details); - gtk_widget_hide (dialog->frame_no_profile); - gtk_widget_show (dialog->frame_new_account); - - /* If we have no account, no need of a back button */ - if (gtk_tree_model_iter_n_children (model, NULL) > 0) { - gtk_widget_show (dialog->button_back); - } else { - gtk_widget_hide (dialog->button_back); - } - - accounts_dialog_profile_changed_cb (dialog->checkbutton_register, dialog); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->checkbutton_register), - TRUE); - gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combobox_profile), 0); - gtk_widget_grab_focus (dialog->combobox_profile); -} - -static void -accounts_dialog_button_help_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) -{ - empathy_url_show (button, "ghelp:empathy?empathy-create-account"); -} - -static void -accounts_dialog_button_remove_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) -{ - McAccount *account; - GtkWidget *message_dialog; - gint res; - - account = accounts_dialog_model_get_selected (dialog); - - if (!mc_account_is_complete (account)) { - accounts_dialog_model_remove_selected (dialog); - accounts_dialog_model_select_first (dialog); - return; - } - message_dialog = gtk_message_dialog_new - (GTK_WINDOW (dialog->window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("You are about to remove your %s account!\n" - "Are you sure you want to proceed?"), - mc_account_get_display_name (account)); - - gtk_message_dialog_format_secondary_text - (GTK_MESSAGE_DIALOG (message_dialog), - _("Any associated conversations and chat rooms will NOT be " - "removed if you decide to proceed.\n" - "\n" - "Should you decide to add the account back at a later time, " - "they will still be available.")); - - gtk_dialog_add_button (GTK_DIALOG (message_dialog), - GTK_STOCK_CANCEL, - GTK_RESPONSE_NO); - gtk_dialog_add_button (GTK_DIALOG (message_dialog), - GTK_STOCK_REMOVE, - GTK_RESPONSE_YES); - - gtk_widget_show (message_dialog); - res = gtk_dialog_run (GTK_DIALOG (message_dialog)); - - if (res == GTK_RESPONSE_YES) { - mc_account_delete (account); - accounts_dialog_model_select_first (dialog); - } - gtk_widget_destroy (message_dialog); -} - -static void -accounts_dialog_button_import_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) -{ - empathy_import_dialog_show (GTK_WINDOW (dialog->window), TRUE); -} - -static void -accounts_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyAccountsDialog *dialog) -{ - if (response == GTK_RESPONSE_CLOSE) { - gtk_widget_destroy (widget); - } -} - -static void -accounts_dialog_destroy_cb (GtkWidget *widget, - EmpathyAccountsDialog *dialog) -{ - GList *accounts, *l; - - /* Disconnect signals */ - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_added_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_removed_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_enabled_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_disabled_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_changed_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_connection_changed_cb, - dialog); - - /* Delete incomplete accounts */ - accounts = mc_accounts_list (); - for (l = accounts; l; l = l->next) { - McAccount *account; - - account = l->data; - if (!mc_account_is_complete (account)) { - /* FIXME: Warn the user the account is not complete - * and is going to be removed. */ - mc_account_delete (account); - } - - g_object_unref (account); - } - g_list_free (accounts); - - if (dialog->connecting_id) { - g_source_remove (dialog->connecting_id); - } - - g_object_unref (dialog->account_manager); - g_object_unref (dialog->mc); - - g_free (dialog); -} - -GtkWidget * -empathy_accounts_dialog_show (GtkWindow *parent, - McAccount *selected_account) -{ - static EmpathyAccountsDialog *dialog = NULL; - GladeXML *glade; - gchar *filename; - GList *accounts, *l; - gboolean import_asked; - - if (dialog) { - gtk_window_present (GTK_WINDOW (dialog->window)); - return dialog->window; - } - - dialog = g_new0 (EmpathyAccountsDialog, 1); - - filename = empathy_file_lookup ("empathy-accounts-dialog.glade", - "src"); - glade = empathy_glade_get_file (filename, - "accounts_dialog", - NULL, - "accounts_dialog", &dialog->window, - "vbox_details", &dialog->vbox_details, - "frame_no_profile", &dialog->frame_no_profile, - "alignment_settings", &dialog->alignment_settings, - "treeview", &dialog->treeview, - "frame_new_account", &dialog->frame_new_account, - "hbox_type", &dialog->hbox_type, - "button_create", &dialog->button_create, - "button_back", &dialog->button_back, - "checkbutton_register", &dialog->checkbutton_register, - "image_type", &dialog->image_type, - "label_name", &dialog->label_name, - "button_add", &dialog->button_add, - "button_remove", &dialog->button_remove, - "button_import", &dialog->button_import, - NULL); - g_free (filename); - - empathy_glade_connect (glade, - dialog, - "accounts_dialog", "destroy", accounts_dialog_destroy_cb, - "accounts_dialog", "response", accounts_dialog_response_cb, - "button_create", "clicked", accounts_dialog_button_create_clicked_cb, - "button_back", "clicked", accounts_dialog_button_back_clicked_cb, - "button_add", "clicked", accounts_dialog_button_add_clicked_cb, - "button_remove", "clicked", accounts_dialog_button_remove_clicked_cb, - "button_import", "clicked", accounts_dialog_button_import_clicked_cb, - "button_help", "clicked", accounts_dialog_button_help_clicked_cb, - NULL); - - g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog); - - g_object_unref (glade); - - /* Create profile chooser */ - dialog->combobox_profile = empathy_profile_chooser_new (); - gtk_box_pack_end (GTK_BOX (dialog->hbox_type), - dialog->combobox_profile, - TRUE, TRUE, 0); - gtk_widget_show (dialog->combobox_profile); - g_signal_connect (dialog->combobox_profile, "changed", - G_CALLBACK (accounts_dialog_profile_changed_cb), - dialog); - - /* Set up signalling */ - dialog->account_manager = empathy_account_manager_dup_singleton (); - dialog->mc = empathy_mission_control_dup_singleton (); - - g_signal_connect (dialog->account_manager, "account-created", - G_CALLBACK (accounts_dialog_account_added_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-deleted", - G_CALLBACK (accounts_dialog_account_removed_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-enabled", - G_CALLBACK (accounts_dialog_account_enabled_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-disabled", - G_CALLBACK (accounts_dialog_account_disabled_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-changed", - G_CALLBACK (accounts_dialog_account_changed_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-connection-changed", - G_CALLBACK (accounts_dialog_connection_changed_cb), - dialog); - - accounts_dialog_model_setup (dialog); - - /* Add existing accounts */ - accounts = mc_accounts_list (); - for (l = accounts; l; l = l->next) { - accounts_dialog_add_or_update_account (dialog, l->data); - g_object_unref (l->data); - } - g_list_free (accounts); - - if (selected_account) { - accounts_dialog_model_set_selected (dialog, selected_account); - } else { - accounts_dialog_model_select_first (dialog); - } - - if (parent) { - gtk_window_set_transient_for (GTK_WINDOW (dialog->window), - GTK_WINDOW (parent)); - } - - gtk_widget_show (dialog->window); - - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_IMPORT_ASKED, &import_asked); - - - if (empathy_import_dialog_accounts_to_import ()) { - - if (!import_asked) { - empathy_conf_set_bool (empathy_conf_get (), - EMPATHY_PREFS_IMPORT_ASKED, TRUE); - empathy_import_dialog_show (GTK_WINDOW (dialog->window), - FALSE); - } - } else { - gtk_widget_set_sensitive (dialog->button_import, FALSE); - } - - return dialog->window; -} - diff --git a/src/empathy-accounts-dialog.glade b/src/empathy-accounts-dialog.glade deleted file mode 100644 index e81daa9bf..000000000 --- a/src/empathy-accounts-dialog.glade +++ /dev/null @@ -1,399 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkDialog" id="accounts_dialog"> - <property name="border_width">5</property> - <property name="title" translatable="yes">Accounts</property> - <property name="role">accounts</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox3"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkHBox" id="hbox146"> - <property name="visible">True</property> - <property name="border_width">6</property> - <property name="spacing">18</property> - <child> - <widget class="GtkVBox" id="vbox195"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow17"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTreeView" id="treeview"> - <property name="width_request">250</property> - <property name="height_request">200</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="enable_search">False</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkVBox" id="vbox1"> - <property name="visible">True</property> - <property name="spacing">6</property> - <property name="homogeneous">True</property> - <child> - <widget class="GtkHBox" id="hbox148"> - <property name="visible">True</property> - <property name="spacing">6</property> - <property name="homogeneous">True</property> - <child> - <widget class="GtkButton" id="button_add"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-add</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="button_remove"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-remove</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="button_import"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Import Accounts...</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="vbox214"> - <property name="width_request">415</property> - <property name="visible">True</property> - <property name="spacing">18</property> - <child> - <widget class="GtkVBox" id="vbox_details"> - <property name="visible">True</property> - <property name="spacing">18</property> - <child> - <widget class="GtkHBox" id="hbox183"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkLabel" id="label_name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label"><big><b>Gmail</b></big></property> - <property name="use_markup">True</property> - <property name="selectable">True</property> - </widget> - </child> - <child> - <widget class="GtkImage" id="image_type"> - <property name="visible">True</property> - <property name="yalign">0</property> - <property name="stock">gtk-cut</property> - <property name="icon_size">6</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkFrame" id="frame2"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment_settings"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">20</property> - <child> - <placeholder/> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label599"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Settings</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkFrame" id="frame_new_account"> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment29"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">20</property> - <child> - <widget class="GtkVBox" id="vbox216"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <widget class="GtkHBox" id="hbox_type"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkLabel" id="label645"> - <property name="visible">True</property> - <property name="label" translatable="yes">Type:</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <placeholder/> - </child> - </widget> - </child> - <child> - <widget class="GtkCheckButton" id="checkbutton_register"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">I already have an account I want to use</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <widget class="GtkHBox" id="hbox181"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkButton" id="button_create"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="response_id">0</property> - <child> - <widget class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <widget class="GtkHBox" id="hbox1"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="stock">gtk-new</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Cr_eate</property> - <property name="use_underline">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">GTK_PACK_END</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="button_back"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">GTK_PACK_END</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label643"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>New Account</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkFrame" id="frame_no_profile"> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment21"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="label" translatable="yes">To add a new account, you first have to install a backend for each protocol you want to use.</property> - <property name="wrap">True</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label_no_protocol"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>No protocol installed</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="button_help"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-help</property> - <property name="use_stock">True</property> - <property name="response_id">-11</property> - </widget> - <packing> - <property name="secondary">True</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="button_close"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - <property name="response_id">-7</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-accounts-dialog.h b/src/empathy-accounts-dialog.h deleted file mode 100644 index 369b2f75b..000000000 --- a/src/empathy-accounts-dialog.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2005-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Martyn Russell <martyn@imendio.com> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#ifndef __EMPATHY_ACCOUNTS_DIALOG_H__ -#define __EMPATHY_ACCOUNTS_DIALOG_H__ - -#include <gtk/gtkwidget.h> - -#include <libmissioncontrol/mc-account.h> - -G_BEGIN_DECLS - -GtkWidget *empathy_accounts_dialog_show (GtkWindow *parent, - McAccount *selected_account); - -G_END_DECLS - -#endif /* __EMPATHY_ACCOUNTS_DIALOG_H__ */ diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c deleted file mode 100644 index a7759e7ef..000000000 --- a/src/empathy-call-window.c +++ /dev/null @@ -1,1242 +0,0 @@ -/* - * empathy-call-window.c - Source for EmpathyCallWindow - * Copyright (C) 2008 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk> - * - * 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 <stdio.h> -#include <stdlib.h> - -#include <math.h> - -#include <gst/gst.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include <telepathy-farsight/channel.h> - -#include <libempathy/empathy-utils.h> -#include <libempathy-gtk/empathy-video-widget.h> -#include <libempathy-gtk/empathy-audio-src.h> -#include <libempathy-gtk/empathy-audio-sink.h> -#include <libempathy-gtk/empathy-video-src.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-call-window.h" - -#include "empathy-sidebar.h" - -#define BUTTON_ID "empathy-call-dtmf-button-id" - -G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW) - -/* signal enum */ -#if 0 -enum -{ - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; -#endif - -enum { - PROP_CALL_HANDLER = 1, -}; - -/* private structure */ -typedef struct _EmpathyCallWindowPriv EmpathyCallWindowPriv; - -struct _EmpathyCallWindowPriv -{ - gboolean dispose_has_run; - EmpathyCallHandler *handler; - - gboolean connected; - - GtkWidget *video_output; - GtkWidget *video_preview; - GtkWidget *sidebar; - GtkWidget *sidebar_button; - GtkWidget *statusbar; - GtkWidget *volume_button; - GtkWidget *mic_button; - GtkWidget *camera_button; - - gdouble volume; - GtkAdjustment *audio_input_adj; - - GtkWidget *dtmf_panel; - - GstElement *video_input; - GstElement *audio_input; - GstElement *audio_output; - GstElement *pipeline; - GstElement *video_tee; - - GstElement *funnel; - GstElement *liveadder; - - GladeXML *glade; - guint context_id; - - GTimer *timer; - guint timer_id; - - GtkWidget *video_contrast; - GtkWidget *video_brightness; - GtkWidget *video_gamma; - - GMutex *lock; - gboolean call_started; -}; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_WINDOW, \ - EmpathyCallWindowPriv)) - -static void empathy_call_window_realized_cb (GtkWidget *widget, - EmpathyCallWindow *window); - -static gboolean empathy_call_window_delete_cb (GtkWidget *widget, - GdkEvent*event, EmpathyCallWindow *window); - -static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle, - EmpathyCallWindow *window); - -static void empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle, - EmpathyCallWindow *window); - -static void empathy_call_window_mic_toggled_cb ( - GtkToggleToolButton *toggle, EmpathyCallWindow *window); - -static void empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar, - EmpathyCallWindow *window); - -static void empathy_call_window_hangup (EmpathyCallWindow *window); - -static void empathy_call_window_status_message (EmpathyCallWindow *window, - gchar *message); - -static gboolean empathy_call_window_bus_message (GstBus *bus, - GstMessage *message, gpointer user_data); - -static void -empathy_call_window_volume_changed_cb (GtkScaleButton *button, - gdouble value, EmpathyCallWindow *window); - -static void -empathy_call_window_setup_menubar (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GtkWidget *hangup; - - hangup = glade_xml_get_widget (priv->glade, "menuhangup"); - g_signal_connect_swapped (G_OBJECT (hangup), "activate", - G_CALLBACK (empathy_call_window_hangup), self); -} - -static void -empathy_call_window_setup_toolbar (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GtkWidget *hangup; - GtkWidget *mic; - GtkWidget *camera; - GtkWidget *toolbar; - GtkToolItem *tool_item; - - hangup = glade_xml_get_widget (priv->glade, "hangup"); - - g_signal_connect_swapped (G_OBJECT (hangup), "clicked", - G_CALLBACK (empathy_call_window_hangup), self); - - mic = glade_xml_get_widget (priv->glade, "microphone"); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (mic), TRUE); - - priv->mic_button = mic; - g_signal_connect (G_OBJECT (priv->mic_button), "toggled", - G_CALLBACK (empathy_call_window_mic_toggled_cb), self); - - toolbar = glade_xml_get_widget (priv->glade, "toolbar"); - - /* Add an empty expanded GtkToolItem so the volume button is at the end of - * the toolbar. */ - tool_item = gtk_tool_item_new (); - gtk_tool_item_set_expand (tool_item, TRUE); - gtk_widget_show (GTK_WIDGET (tool_item)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tool_item, -1); - - priv->volume_button = gtk_volume_button_new (); - /* FIXME listen to the audiosinks signals and update the button according to - * that, for now starting out at 1.0 and assuming only the app changes the - * volume will do */ - gtk_scale_button_set_value (GTK_SCALE_BUTTON (priv->volume_button), 1.0); - g_signal_connect (G_OBJECT (priv->volume_button), "value-changed", - G_CALLBACK (empathy_call_window_volume_changed_cb), self); - - tool_item = gtk_tool_item_new (); - gtk_container_add (GTK_CONTAINER (tool_item), priv->volume_button); - gtk_widget_show_all (GTK_WIDGET (tool_item)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tool_item, -1); - - camera = glade_xml_get_widget (priv->glade, "camera"); - priv->camera_button = camera; - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (camera), FALSE); - gtk_widget_set_sensitive (priv->camera_button, FALSE); - - g_signal_connect (G_OBJECT (camera), "toggled", - G_CALLBACK (empathy_call_window_camera_toggled_cb), self); -} - -static void -dtmf_button_pressed_cb (GtkButton *button, EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - EmpathyTpCall *call; - GQuark button_quark; - TpDTMFEvent event; - - g_object_get (priv->handler, "tp-call", &call, NULL); - - button_quark = g_quark_from_static_string (BUTTON_ID); - event = GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (button), - button_quark)); - - empathy_tp_call_start_tone (call, event); - - g_object_unref (call); -} - -static void -dtmf_button_released_cb (GtkButton *button, EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - EmpathyTpCall *call; - - g_object_get (priv->handler, "tp-call", &call, NULL); - - empathy_tp_call_stop_tone (call); - - g_object_unref (call); -} - -static GtkWidget * -empathy_call_window_create_dtmf (EmpathyCallWindow *self) -{ - GtkWidget *table; - int i; - GQuark button_quark; - struct { - gchar *label; - TpDTMFEvent event; - } dtmfbuttons[] = { { "1", TP_DTMF_EVENT_DIGIT_1 }, - { "2", TP_DTMF_EVENT_DIGIT_2 }, - { "3", TP_DTMF_EVENT_DIGIT_3 }, - { "4", TP_DTMF_EVENT_DIGIT_4 }, - { "5", TP_DTMF_EVENT_DIGIT_5 }, - { "6", TP_DTMF_EVENT_DIGIT_6 }, - { "7", TP_DTMF_EVENT_DIGIT_7 }, - { "8", TP_DTMF_EVENT_DIGIT_8 }, - { "9", TP_DTMF_EVENT_DIGIT_9 }, - { "#", TP_DTMF_EVENT_HASH }, - { "0", TP_DTMF_EVENT_DIGIT_0 }, - { "*", TP_DTMF_EVENT_ASTERISK }, - { NULL, } }; - - button_quark = g_quark_from_static_string (BUTTON_ID); - - table = gtk_table_new (4, 3, TRUE); - - for (i = 0; dtmfbuttons[i].label != NULL; i++) - { - GtkWidget *button = gtk_button_new_with_label (dtmfbuttons[i].label); - gtk_table_attach (GTK_TABLE (table), button, i % 3, i % 3 + 1, - i/3, i/3 + 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 1, 1); - - g_object_set_qdata (G_OBJECT (button), button_quark, - GUINT_TO_POINTER (dtmfbuttons[i].event)); - - g_signal_connect (G_OBJECT (button), "pressed", - G_CALLBACK (dtmf_button_pressed_cb), self); - g_signal_connect (G_OBJECT (button), "released", - G_CALLBACK (dtmf_button_released_cb), self); - } - - return table; -} - -static GtkWidget * -empathy_call_window_create_video_input_add_slider (EmpathyCallWindow *self, - gchar *label_text, GtkWidget *bin) -{ - GtkWidget *vbox = gtk_vbox_new (FALSE, 2); - GtkWidget *scale = gtk_vscale_new_with_range (0, 100, 10); - GtkWidget *label = gtk_label_new (label_text); - - gtk_widget_set_sensitive (scale, FALSE); - - gtk_container_add (GTK_CONTAINER (bin), vbox); - - gtk_range_set_inverted (GTK_RANGE (scale), TRUE); - gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - return scale; -} - -static void -empathy_call_window_video_contrast_changed_cb (GtkAdjustment *adj, - EmpathyCallWindow *self) - -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - empathy_video_src_set_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_CONTRAST, gtk_adjustment_get_value (adj)); -} - -static void -empathy_call_window_video_brightness_changed_cb (GtkAdjustment *adj, - EmpathyCallWindow *self) - -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - empathy_video_src_set_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_BRIGHTNESS, gtk_adjustment_get_value (adj)); -} - -static void -empathy_call_window_video_gamma_changed_cb (GtkAdjustment *adj, - EmpathyCallWindow *self) - -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - empathy_video_src_set_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_GAMMA, gtk_adjustment_get_value (adj)); -} - - -static GtkWidget * -empathy_call_window_create_video_input (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GtkWidget *hbox; - - hbox = gtk_hbox_new (TRUE, 3); - - priv->video_contrast = empathy_call_window_create_video_input_add_slider ( - self, _("Contrast"), hbox); - - priv->video_brightness = empathy_call_window_create_video_input_add_slider ( - self, _("Brightness"), hbox); - - priv->video_gamma = empathy_call_window_create_video_input_add_slider ( - self, _("Gamma"), hbox); - - return hbox; -} - -static void -empathy_call_window_setup_video_input (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - guint supported; - GtkAdjustment *adj; - - supported = empathy_video_src_get_supported_channels (priv->video_input); - - if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_CONTRAST) - { - adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_contrast)); - - gtk_adjustment_set_value (adj, - empathy_video_src_get_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_CONTRAST)); - - g_signal_connect (G_OBJECT (adj), "value-changed", - G_CALLBACK (empathy_call_window_video_contrast_changed_cb), self); - - gtk_widget_set_sensitive (priv->video_contrast, TRUE); - } - - if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_BRIGHTNESS) - { - adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_brightness)); - - gtk_adjustment_set_value (adj, - empathy_video_src_get_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_BRIGHTNESS)); - - g_signal_connect (G_OBJECT (adj), "value-changed", - G_CALLBACK (empathy_call_window_video_brightness_changed_cb), self); - gtk_widget_set_sensitive (priv->video_brightness, TRUE); - } - - if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_GAMMA) - { - adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_gamma)); - - gtk_adjustment_set_value (adj, - empathy_video_src_get_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_GAMMA)); - - g_signal_connect (G_OBJECT (adj), "value-changed", - G_CALLBACK (empathy_call_window_video_gamma_changed_cb), self); - gtk_widget_set_sensitive (priv->video_gamma, TRUE); - } -} - -static void -empathy_call_window_mic_volume_changed_cb (GtkAdjustment *adj, - EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - gdouble volume; - - volume = gtk_adjustment_get_value (adj)/100.0; - - /* Don't store the volume because of muting */ - if (volume > 0 || gtk_toggle_tool_button_get_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button))) - priv->volume = volume; - - /* Ensure that the toggle button is active if the volume is > 0 and inactive - * if it's smaller then 0 */ - if ((volume > 0) != gtk_toggle_tool_button_get_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button))) - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button), volume > 0); - - empathy_audio_src_set_volume (EMPATHY_GST_AUDIO_SRC (priv->audio_input), - volume); -} - -static void -empathy_call_window_audio_input_level_changed_cb (EmpathyGstAudioSrc *src, - gdouble level, GtkProgressBar *bar) -{ - gdouble value; - - value = CLAMP (pow (10, level / 20), 0.0, 1.0); - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), value); -} - -static GtkWidget * -empathy_call_window_create_audio_input (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GtkWidget *hbox, *vbox, *scale, *progress, *label; - GtkAdjustment *adj; - - hbox = gtk_hbox_new (TRUE, 3); - - vbox = gtk_vbox_new (FALSE, 3); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 3); - - scale = gtk_vscale_new_with_range (0, 150, 100); - gtk_range_set_inverted (GTK_RANGE (scale), TRUE); - label = gtk_label_new (_("Volume")); - - priv->audio_input_adj = adj = gtk_range_get_adjustment (GTK_RANGE (scale)); - priv->volume = empathy_audio_src_get_volume (EMPATHY_GST_AUDIO_SRC - (priv->audio_input)); - gtk_adjustment_set_value (adj, priv->volume * 100); - - g_signal_connect (G_OBJECT (adj), "value-changed", - G_CALLBACK (empathy_call_window_mic_volume_changed_cb), self); - - gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 3); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 3); - - progress = gtk_progress_bar_new (); - gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (progress), - GTK_PROGRESS_BOTTOM_TO_TOP); - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), 0); - - g_signal_connect (priv->audio_input, "peak-level-changed", - G_CALLBACK (empathy_call_window_audio_input_level_changed_cb), progress); - - gtk_box_pack_start (GTK_BOX (hbox), progress, FALSE, FALSE, 3); - - return hbox; -} - -static void -empathy_call_window_init (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GtkWidget *vbox, *top_vbox; - GtkWidget *hbox, *h; - GtkWidget *arrow; - GtkWidget *page; - GstBus *bus; - gchar *filename; - GtkWidget *pane; - - filename = empathy_file_lookup ("empathy-call-window.glade", "src"); - - priv->glade = empathy_glade_get_file (filename, "call_window", NULL, - "call_window_vbox", &top_vbox, - "pane", &pane, - "statusbar", &priv->statusbar, - NULL); - - priv->lock = g_mutex_new (); - - gtk_widget_reparent (top_vbox, GTK_WIDGET (self)); - - empathy_call_window_setup_menubar (self); - empathy_call_window_setup_toolbar (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(pane), hbox, TRUE, FALSE); - - bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - - gst_bus_add_watch (bus, empathy_call_window_bus_message, self); - - priv->video_output = empathy_video_widget_new (bus); - gtk_box_pack_start (GTK_BOX (hbox), priv->video_output, TRUE, TRUE, 3); - - 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->video_preview = empathy_video_widget_new_with_size (bus, 160, 120); - g_object_set (priv->video_preview, "sync", FALSE, "async", TRUE, NULL); - gtk_box_pack_start (GTK_BOX (vbox), priv->video_preview, FALSE, FALSE, 0); - - priv->video_input = empathy_video_src_new (); - gst_object_ref (priv->video_input); - gst_object_sink (priv->video_input); - - priv->audio_input = empathy_audio_src_new (); - gst_object_ref (priv->audio_input); - gst_object_sink (priv->audio_input); - - priv->audio_output = empathy_audio_sink_new (); - gst_object_ref (priv->audio_output); - gst_object_sink (priv->audio_output); - - g_object_unref (bus); - - priv->sidebar_button = gtk_toggle_button_new_with_mnemonic (_("_Sidebar")); - arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - g_signal_connect (G_OBJECT (priv->sidebar_button), "toggled", - G_CALLBACK (empathy_call_window_sidebar_toggled_cb), 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 (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); - gtk_paned_pack2 (GTK_PANED(pane), priv->sidebar, FALSE, FALSE); - - priv->dtmf_panel = empathy_call_window_create_dtmf (self); - empathy_sidebar_add_page (EMPATHY_SIDEBAR (priv->sidebar), _("Dialpad"), - priv->dtmf_panel); - - gtk_widget_set_sensitive (priv->dtmf_panel, FALSE); - - page = empathy_call_window_create_audio_input (self); - empathy_sidebar_add_page (EMPATHY_SIDEBAR (priv->sidebar), _("Audio input"), - page); - - page = empathy_call_window_create_video_input (self); - empathy_sidebar_add_page (EMPATHY_SIDEBAR (priv->sidebar), _("Video input"), - page); - - gtk_widget_show_all (top_vbox); - - gtk_widget_hide (priv->sidebar); - - 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); - - empathy_call_window_status_message (self, _("Connecting...")); - - priv->timer = g_timer_new (); -} - -static void empathy_call_window_dispose (GObject *object); -static void empathy_call_window_finalize (GObject *object); - -static void -empathy_call_window_set_property (GObject *object, - guint property_id, const GValue *value, GParamSpec *pspec) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_CALL_HANDLER: - priv->handler = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -empathy_call_window_get_property (GObject *object, - guint property_id, GValue *value, GParamSpec *pspec) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_CALL_HANDLER: - g_value_set_object (value, priv->handler); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -empathy_call_window_class_init ( - EmpathyCallWindowClass *empathy_call_window_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (empathy_call_window_class); - GParamSpec *param_spec; - - g_type_class_add_private (empathy_call_window_class, - sizeof (EmpathyCallWindowPriv)); - - object_class->set_property = empathy_call_window_set_property; - object_class->get_property = empathy_call_window_get_property; - - object_class->dispose = empathy_call_window_dispose; - object_class->finalize = empathy_call_window_finalize; - - param_spec = g_param_spec_object ("handler", - "handler", "The call handler", - EMPATHY_TYPE_CALL_HANDLER, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_CALL_HANDLER, param_spec); - -} - -void -empathy_call_window_dispose (GObject *object) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - if (priv->handler != NULL) - g_object_unref (priv->handler); - - priv->handler = NULL; - - if (priv->pipeline != NULL) - g_object_unref (priv->pipeline); - priv->pipeline = NULL; - - if (priv->video_input != NULL) - g_object_unref (priv->video_input); - priv->video_input = NULL; - - if (priv->audio_input != NULL) - g_object_unref (priv->audio_input); - priv->audio_input = NULL; - - if (priv->audio_output != NULL) - g_object_unref (priv->audio_output); - priv->audio_output = NULL; - - if (priv->video_tee != NULL) - g_object_unref (priv->video_tee); - priv->video_tee = NULL; - - if (priv->timer_id != 0) - g_source_remove (priv->timer_id); - priv->timer_id = 0; - - /* 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); -} - -void -empathy_call_window_finalize (GObject *object) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - /* free any data held directly by the object here */ - g_mutex_free (priv->lock); - - g_timer_destroy (priv->timer); - - G_OBJECT_CLASS (empathy_call_window_parent_class)->finalize (object); -} - - -EmpathyCallWindow * -empathy_call_window_new (EmpathyCallHandler *handler) -{ - return EMPATHY_CALL_WINDOW ( - g_object_new (EMPATHY_TYPE_CALL_WINDOW, "handler", handler, NULL)); -} - -static void -empathy_call_window_conference_added_cb (EmpathyCallHandler *handler, - GstElement *conference, gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - gst_bin_add (GST_BIN (priv->pipeline), conference); - - gst_element_set_state (conference, GST_STATE_PLAYING); -} - -static gboolean -empathy_call_window_request_resource_cb (EmpathyCallHandler *handler, - FsMediaType type, FsStreamDirection direction, gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - if (type != TP_MEDIA_STREAM_TYPE_VIDEO) - return TRUE; - - if (direction == FS_DIRECTION_RECV) - return TRUE; - - /* video and direction is send */ - return priv->video_input != NULL; -} - -static void -empathy_call_window_disconnected (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - g_mutex_lock (priv->lock); - - g_timer_stop (priv->timer); - - if (priv->timer_id != 0) - g_source_remove (priv->timer_id); - priv->timer_id = 0; - - g_mutex_unlock (priv->lock); - - empathy_call_window_status_message (self, _("Disconnected")); - - gtk_widget_set_sensitive (priv->camera_button, FALSE); -} - - -static void -empathy_call_window_channel_closed_cb (TfChannel *channel, gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - - empathy_call_window_disconnected (self); -} - -/* Called with global lock held */ -static GstPad * -empathy_call_window_get_video_sink_pad (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GstPad *pad; - - if (priv->funnel == NULL) - { - GstElement *output; - - output = empathy_video_widget_get_element (EMPATHY_VIDEO_WIDGET - (priv->video_output)); - - priv->funnel = gst_element_factory_make ("fsfunnel", NULL); - - gst_bin_add (GST_BIN (priv->pipeline), priv->funnel); - gst_bin_add (GST_BIN (priv->pipeline), output); - - gst_element_link (priv->funnel, output); - - gst_element_set_state (priv->funnel, GST_STATE_PLAYING); - gst_element_set_state (output, GST_STATE_PLAYING); - } - - pad = gst_element_get_request_pad (priv->funnel, "sink%d"); - - return pad; -} - -/* Called with global lock held */ -static GstPad * -empathy_call_window_get_audio_sink_pad (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GstPad *pad; - - if (priv->liveadder == NULL) - { - priv->liveadder = gst_element_factory_make ("liveadder", NULL); - - gst_bin_add (GST_BIN (priv->pipeline), priv->liveadder); - gst_bin_add (GST_BIN (priv->pipeline), priv->audio_output); - - gst_element_link (priv->liveadder, priv->audio_output); - - gst_element_set_state (priv->liveadder, GST_STATE_PLAYING); - gst_element_set_state (priv->audio_output, GST_STATE_PLAYING); - } - - pad = gst_element_get_request_pad (priv->liveadder, "sink%d"); - - return pad; -} - -static gboolean -empathy_call_window_update_timer (gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - gchar *str; - gdouble time; - - time = g_timer_elapsed (priv->timer, NULL); - - /* Translators: number of minutes:seconds the caller has been connected */ - str = g_strdup_printf (_("Connected -- %d:%02dm"), (int) time / 60, - (int) time % 60); - empathy_call_window_status_message (self, str); - g_free (str); - - return TRUE; -} - -static gboolean -empathy_call_window_connected (gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - EmpathyTpCall *call; - - g_object_get (priv->handler, "tp-call", &call, NULL); - - if (empathy_tp_call_has_dtmf (call)) - gtk_widget_set_sensitive (priv->dtmf_panel, TRUE); - - if (priv->video_input != NULL) - gtk_widget_set_sensitive (priv->camera_button, TRUE); - - g_object_unref (call); - - g_mutex_lock (priv->lock); - - priv->timer_id = g_timeout_add_seconds (1, - empathy_call_window_update_timer, self); - - g_mutex_unlock (priv->lock); - - empathy_call_window_update_timer (self); - - return FALSE; -} - - -/* Called from the streaming thread */ -static void -empathy_call_window_src_added_cb (EmpathyCallHandler *handler, - GstPad *src, guint media_type, gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - - GstPad *pad; - - g_mutex_lock (priv->lock); - - if (priv->connected == FALSE) - { - g_timer_start (priv->timer); - priv->timer_id = g_idle_add (empathy_call_window_connected, self); - priv->connected = TRUE; - } - - switch (media_type) - { - case TP_MEDIA_STREAM_TYPE_AUDIO: - pad = empathy_call_window_get_audio_sink_pad (self); - break; - case TP_MEDIA_STREAM_TYPE_VIDEO: - pad = empathy_call_window_get_video_sink_pad (self); - break; - default: - g_assert_not_reached (); - } - - gst_pad_link (src, pad); - gst_object_unref (pad); - - g_mutex_unlock (priv->lock); -} - -/* Called from the streaming thread */ -static void -empathy_call_window_sink_added_cb (EmpathyCallHandler *handler, - GstPad *sink, guint media_type, gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GstPad *pad; - - switch (media_type) - { - case TP_MEDIA_STREAM_TYPE_AUDIO: - gst_bin_add (GST_BIN (priv->pipeline), priv->audio_input); - - pad = gst_element_get_static_pad (priv->audio_input, "src"); - gst_pad_link (pad, sink); - - gst_element_set_state (priv->audio_input, GST_STATE_PLAYING); - break; - case TP_MEDIA_STREAM_TYPE_VIDEO: - if (priv->video_input != NULL) - { - pad = gst_element_get_request_pad (priv->video_tee, "src%d"); - gst_pad_link (pad, sink); - } - break; - default: - g_assert_not_reached (); - } - -} - -static gboolean -empathy_gst_bin_has_child (GstBin *bin, GstElement *element) -{ - GstIterator *it; - gboolean ret = FALSE; - GstElement *item; - - it = gst_bin_iterate_recurse (bin); - - for (;;) - { - switch (gst_iterator_next (it, (gpointer *)&item)) - { - case GST_ITERATOR_OK: - if (item == element) - { - gst_object_unref (GST_OBJECT (item)); - ret = TRUE; - goto out; - } - gst_object_unref (GST_OBJECT (item)); - break; - case GST_ITERATOR_RESYNC: - gst_iterator_resync (it); - break; - case GST_ITERATOR_ERROR: - g_assert_not_reached (); - /* fallthrough */ - case GST_ITERATOR_DONE: - goto out; - break; - } - } - gst_iterator_free (it); - -out: - return ret; -} - -static void -empathy_call_window_remove_video_input (EmpathyCallWindow *self) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GstElement *preview; - - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - - gst_element_set_state (priv->video_input, GST_STATE_NULL); - gst_element_set_state (priv->video_tee, GST_STATE_NULL); - gst_element_set_state (preview, GST_STATE_NULL); - - gst_bin_remove_many (GST_BIN (priv->pipeline), priv->video_input, - priv->video_tee, preview, NULL); - - g_object_unref (priv->video_input); - priv->video_input = NULL; - g_object_unref (priv->video_tee); - priv->video_tee = NULL; -} - - -static gboolean -empathy_call_window_bus_message (GstBus *bus, GstMessage *message, - gpointer user_data) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - GstState newstate; - - empathy_call_handler_bus_message (priv->handler, bus, message); - - switch (GST_MESSAGE_TYPE (message)) - { - case GST_MESSAGE_STATE_CHANGED: - if (GST_MESSAGE_SRC (message) == GST_OBJECT (priv->video_input)) - { - gst_message_parse_state_changed (message, NULL, &newstate, NULL); - if (newstate == GST_STATE_PAUSED) - empathy_call_window_setup_video_input (self); - } - if (GST_MESSAGE_SRC (message) == GST_OBJECT (priv->pipeline) && - !priv->call_started) - { - gst_message_parse_state_changed (message, NULL, &newstate, NULL); - if (newstate == GST_STATE_PAUSED) - { - priv->call_started = TRUE; - empathy_call_handler_start_call (priv->handler); - gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); - } - } - break; - case GST_MESSAGE_ERROR: - { - GError *error; - gchar *debug; - - gst_message_parse_error (message, &error, &debug); - - g_message ("Element error: %s -- %s\n", error->message, debug); - - if (priv->video_input != NULL && - empathy_gst_bin_has_child (GST_BIN (priv->video_input), - GST_ELEMENT (GST_MESSAGE_SRC (message)))) - { - /* Remove the video input and continue */ - empathy_call_window_remove_video_input (self); - gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); - } - else - { - gst_element_set_state (priv->pipeline, GST_STATE_NULL); - empathy_call_window_disconnected (self); - } - g_error_free (error); - g_free (debug); - } - default: - break; - } - - return TRUE; -} - -static void -empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - GstElement *preview; - - g_signal_connect (priv->handler, "conference-added", - G_CALLBACK (empathy_call_window_conference_added_cb), window); - g_signal_connect (priv->handler, "request-resource", - G_CALLBACK (empathy_call_window_request_resource_cb), window); - g_signal_connect (priv->handler, "closed", - G_CALLBACK (empathy_call_window_channel_closed_cb), window); - g_signal_connect (priv->handler, "src-pad-added", - G_CALLBACK (empathy_call_window_src_added_cb), window); - g_signal_connect (priv->handler, "sink-pad-added", - G_CALLBACK (empathy_call_window_sink_added_cb), window); - - - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - - gst_bin_add_many (GST_BIN (priv->pipeline), priv->video_input, - priv->video_tee, preview, NULL); - gst_element_link_many (priv->video_input, priv->video_tee, - preview, NULL); - - gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); -} - -static gboolean -empathy_call_window_delete_cb (GtkWidget *widget, GdkEvent*event, - EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - - gst_element_set_state (priv->pipeline, GST_STATE_NULL); - - return FALSE; -} - -static void -empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle, - EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - GtkWidget *arrow; - GtkWidget *pane; - int w,h, handle_size; - - w = GTK_WIDGET (window)->allocation.width; - h = GTK_WIDGET (window)->allocation.height; - - pane = glade_xml_get_widget (priv->glade, "pane"); - gtk_widget_style_get (pane, "handle_size", &handle_size, NULL); - - if (gtk_toggle_button_get_active (toggle)) - { - arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE); - gtk_widget_show (priv->sidebar); - w += priv->sidebar->allocation.width + handle_size; - } - else - { - arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - w -= priv->sidebar->allocation.width + handle_size; - gtk_widget_hide (priv->sidebar); - } - - gtk_button_set_image (GTK_BUTTON (priv->sidebar_button), arrow); - - if (w > 0 && h > 0) - gtk_window_resize (GTK_WINDOW (window), w, h); -} - -static void -empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle, - EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - gboolean active; - EmpathyTpCall *call; - - active = (gtk_toggle_tool_button_get_active (toggle)); - - g_object_get (priv->handler, "tp-call", &call, NULL); - - empathy_tp_call_request_video_stream_direction (call, active); - - g_object_unref (call); -} - -static void -empathy_call_window_mic_toggled_cb (GtkToggleToolButton *toggle, - EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - gboolean active; - - active = (gtk_toggle_tool_button_get_active (toggle)); - - if (active) - { - empathy_audio_src_set_volume (EMPATHY_GST_AUDIO_SRC (priv->audio_input), - priv->volume); - gtk_adjustment_set_value (priv->audio_input_adj, priv->volume * 100); - } - else - { - /* TODO, Instead of setting the input volume to 0 we should probably - * stop sending but this would cause the audio call to drop if both - * sides mute at the same time on certain CMs AFAIK. Need to revisit this - * in the future. GNOME #574574 - */ - empathy_audio_src_set_volume (EMPATHY_GST_AUDIO_SRC (priv->audio_input), - 0); - gtk_adjustment_set_value (priv->audio_input_adj, 0); - } -} - -static void -empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar, - EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->sidebar_button), - FALSE); -} - -static void -empathy_call_window_hangup (EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - - gst_element_set_state (priv->pipeline, GST_STATE_NULL); - gtk_widget_destroy (GTK_WIDGET (window)); -} - -static void -empathy_call_window_status_message (EmpathyCallWindow *window, - gchar *message) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - - if (priv->context_id == 0) - { - priv->context_id = gtk_statusbar_get_context_id ( - GTK_STATUSBAR (priv->statusbar), "voip call status messages"); - } - else - { - gtk_statusbar_pop (GTK_STATUSBAR (priv->statusbar), priv->context_id); - } - - gtk_statusbar_push (GTK_STATUSBAR (priv->statusbar), priv->context_id, - message); -} - -static void -empathy_call_window_volume_changed_cb (GtkScaleButton *button, - gdouble value, EmpathyCallWindow *window) -{ - EmpathyCallWindowPriv *priv = GET_PRIV (window); - - empathy_audio_sink_set_volume (EMPATHY_GST_AUDIO_SINK (priv->audio_output), - value); -} diff --git a/src/empathy-call-window.glade b/src/empathy-call-window.glade deleted file mode 100644 index 712f10538..000000000 --- a/src/empathy-call-window.glade +++ /dev/null @@ -1,145 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--Generated with glade3 3.4.5 on Mon Feb 16 12:31:56 2009 --> -<glade-interface> - <widget class="GtkWindow" id="call_window"> - <child> - <widget class="GtkVBox" id="call_window_vbox"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuBar" id="menubar1"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuItem" id="menuitem1"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Call</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="menu1"> - <property name="visible">True</property> - <child> - <widget class="GtkCheckMenuItem" id="send_video"> - <property name="visible">True</property> - <property name="label" translatable="yes">Send video</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="menuhangup"> - <property name="visible">True</property> - <property name="label" translatable="yes">Hang up</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="menu-item-image1"> - <property name="visible">True</property> - <property name="stock">gtk-cancel</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menuitem3"> - <property name="visible">True</property> - <property name="label" translatable="yes">_View</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="menu2"> - <property name="visible">True</property> - <child> - <widget class="GtkCheckMenuItem" id="show_preview"> - <property name="visible">True</property> - <property name="label" translatable="yes">Video preview</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkToolbar" id="toolbar"> - <property name="visible">True</property> - <child> - <widget class="GtkToolButton" id="hangup"> - <property name="visible">True</property> - <property name="is_important">True</property> - <property name="label" translatable="yes">Hang up</property> - <property name="stock_id">gtk-cancel</property> - </widget> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <widget class="GtkSeparatorToolItem" id="toolbutton1"> - <property name="visible">True</property> - </widget> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <widget class="GtkToggleToolButton" id="microphone"> - <property name="visible">True</property> - <property name="label" translatable="yes">Send Audio</property> - <property name="icon_name">gnome-stock-mic</property> - </widget> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <widget class="GtkToggleToolButton" id="camera"> - <property name="visible">True</property> - <property name="label" translatable="yes">Send video</property> - <property name="icon_name">camera-web</property> - </widget> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkHPaned" id="pane"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <widget class="GtkStatusbar" id="statusbar"> - <property name="visible">True</property> - <property name="spacing">2</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">3</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-call-window.h b/src/empathy-call-window.h deleted file mode 100644 index 26b0e7881..000000000 --- a/src/empathy-call-window.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * empathy-call-window.h - Header for EmpathyCallWindow - * Copyright (C) 2008 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk> - * - * 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_H__ -#define __EMPATHY_CALL_WINDOW_H__ - -#include <glib-object.h> -#include <gtk/gtk.h> -#include <libempathy/empathy-call-handler.h> - -G_BEGIN_DECLS - -typedef struct _EmpathyCallWindow EmpathyCallWindow; -typedef struct _EmpathyCallWindowClass EmpathyCallWindowClass; - -struct _EmpathyCallWindowClass { - GtkWindowClass parent_class; -}; - -struct _EmpathyCallWindow { - GtkWindow parent; -}; - -GType empathy_call_window_get_type(void); - -/* TYPE MACROS */ -#define EMPATHY_TYPE_CALL_WINDOW \ - (empathy_call_window_get_type()) -#define EMPATHY_CALL_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_CALL_WINDOW, \ - EmpathyCallWindow)) -#define EMPATHY_CALL_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_CALL_WINDOW, \ - EmpathyCallWindowClass)) -#define EMPATHY_IS_CALL_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_CALL_WINDOW)) -#define EMPATHY_IS_CALL_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_CALL_WINDOW)) -#define EMPATHY_CALL_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_CALL_WINDOW, \ - EmpathyCallWindowClass)) - -EmpathyCallWindow * -empathy_call_window_new (EmpathyCallHandler *handler); - -G_END_DECLS - -#endif /* #ifndef __EMPATHY_CALL_WINDOW_H__*/ diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c deleted file mode 100644 index d7c1a398f..000000000 --- a/src/empathy-chat-window.c +++ /dev/null @@ -1,1717 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2003-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Mikael Hallendal <micke@imendio.com> - * Richard Hult <richard@imendio.com> - * Martyn Russell <martyn@imendio.com> - * Geert-Jan Van den Bogaerde <geertjan@gnome.org> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> - -#include <string.h> - -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> -#include <glade/glade.h> -#include <glib/gi18n.h> -#include <libnotify/notification.h> - -#include <telepathy-glib/util.h> -#include <libmissioncontrol/mission-control.h> - -#include <libempathy/empathy-contact-factory.h> -#include <libempathy/empathy-contact.h> -#include <libempathy/empathy-message.h> -#include <libempathy/empathy-dispatcher.h> -#include <libempathy/empathy-chatroom-manager.h> -#include <libempathy/empathy-utils.h> - -#include <libempathy-gtk/empathy-images.h> -#include <libempathy-gtk/empathy-conf.h> -#include <libempathy-gtk/empathy-contact-dialogs.h> -#include <libempathy-gtk/empathy-log-window.h> -#include <libempathy-gtk/empathy-geometry.h> -#include <libempathy-gtk/empathy-smiley-manager.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-chat-window.h" -#include "empathy-about-dialog.h" -#include "empathy-misc.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_CHAT -#include <libempathy/empathy-debug.h> - -#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChatWindow) -typedef struct { - EmpathyChat *current_chat; - GList *chats; - GList *chats_new_msg; - GList *chats_composing; - gboolean page_added; - gboolean dnd_same_window; - guint save_geometry_id; - EmpathyChatroomManager *chatroom_manager; - GtkWidget *dialog; - GtkWidget *notebook; - NotifyNotification *notification; - - /* Menu items. */ - GtkWidget *menu_conv_clear; - GtkWidget *menu_conv_insert_smiley; - GtkWidget *menu_conv_contact; - GtkWidget *menu_conv_favorite; - GtkWidget *menu_conv_close; - - GtkWidget *menu_edit_cut; - GtkWidget *menu_edit_copy; - GtkWidget *menu_edit_paste; - - GtkWidget *menu_tabs_next; - GtkWidget *menu_tabs_prev; - GtkWidget *menu_tabs_left; - GtkWidget *menu_tabs_right; - GtkWidget *menu_tabs_detach; - - GtkWidget *menu_help_contents; - GtkWidget *menu_help_about; -} EmpathyChatWindowPriv; - -static GList *chat_windows = NULL; - -static const guint tab_accel_keys[] = { - GDK_1, GDK_2, GDK_3, GDK_4, GDK_5, - GDK_6, GDK_7, GDK_8, GDK_9, GDK_0 -}; - -typedef enum { - DND_DRAG_TYPE_CONTACT_ID, - DND_DRAG_TYPE_TAB -} DndDragType; - -static const GtkTargetEntry drag_types_dest[] = { - { "text/contact-id", 0, DND_DRAG_TYPE_CONTACT_ID }, - { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, DND_DRAG_TYPE_TAB }, -}; - -G_DEFINE_TYPE (EmpathyChatWindow, empathy_chat_window, G_TYPE_OBJECT); - -static void -chat_window_accel_cb (GtkAccelGroup *accelgroup, - GObject *object, - guint key, - GdkModifierType mod, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - gint num = -1; - gint i; - - priv = GET_PRIV (window); - - for (i = 0; i < G_N_ELEMENTS (tab_accel_keys); i++) { - if (tab_accel_keys[i] == key) { - num = i; - break; - } - } - - if (num != -1) { - gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), num); - } -} - -static EmpathyChatWindow * -chat_window_find_chat (EmpathyChat *chat) -{ - EmpathyChatWindowPriv *priv; - GList *l, *ll; - - for (l = chat_windows; l; l = l->next) { - priv = GET_PRIV (l->data); - ll = g_list_find (priv->chats, chat); - if (ll) { - return l->data; - } - } - - return NULL; -} - -static void -chat_window_close_clicked_cb (GtkWidget *button, - EmpathyChat *chat) -{ - EmpathyChatWindow *window; - - window = chat_window_find_chat (chat); - empathy_chat_window_remove_chat (window, chat); -} - -static void -chat_window_close_button_style_set_cb (GtkWidget *button, - GtkStyle *previous_style, - gpointer user_data) -{ - gint h, w; - - gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (button), - GTK_ICON_SIZE_MENU, &w, &h); - - gtk_widget_set_size_request (button, w, h); -} - -static GtkWidget * -chat_window_create_label (EmpathyChatWindow *window, - EmpathyChat *chat) -{ - EmpathyChatWindowPriv *priv; - GtkWidget *hbox; - GtkWidget *name_label; - GtkWidget *status_image; - GtkWidget *close_button; - GtkWidget *close_image; - GtkWidget *event_box; - GtkWidget *event_box_hbox; - PangoAttrList *attr_list; - PangoAttribute *attr; - - priv = GET_PRIV (window); - - /* The spacing between the button and the label. */ - hbox = gtk_hbox_new (FALSE, 0); - - event_box = gtk_event_box_new (); - 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); - - attr_list = pango_attr_list_new (); - attr = pango_attr_scale_new (1/1.2); - attr->start_index = 0; - attr->end_index = -1; - pango_attr_list_insert (attr_list, attr); - gtk_label_set_attributes (GTK_LABEL (name_label), attr_list); - pango_attr_list_unref (attr_list); - - 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); - - status_image = gtk_image_new (); - - /* Spacing between the icon and label. */ - event_box_hbox = gtk_hbox_new (FALSE, 0); - - 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); - - 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); - - /* 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); - - /* Set the name to make the special rc style match. */ - gtk_widget_set_name (close_button, "empathy-close-button"); - - close_image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); - - gtk_container_add (GTK_CONTAINER (close_button), close_image); - - 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); - - /* 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); - - g_signal_connect (close_button, - "clicked", - G_CALLBACK (chat_window_close_clicked_cb), - chat); - - gtk_widget_show_all (hbox); - - return hbox; -} - -static void -chat_window_update (EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - gboolean first_page; - gboolean last_page; - gboolean is_connected; - gint num_pages; - gint page_num; - gint i; - const gchar *name; - guint n_chats; - GdkPixbuf *icon; - EmpathyContact *remote_contact; - gboolean avatar_in_icon; - GtkWidget *chat; - GtkWidget *chat_close_button; - - /* Get information */ - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook)); - num_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook)); - first_page = (page_num == 0); - last_page = (page_num == (num_pages - 1)); - is_connected = empathy_chat_get_tp_chat (priv->current_chat) != NULL; - name = empathy_chat_get_name (priv->current_chat); - n_chats = g_list_length (priv->chats); - - DEBUG ("Update window"); - - /* Update menu */ - gtk_widget_set_sensitive (priv->menu_tabs_next, !last_page); - gtk_widget_set_sensitive (priv->menu_tabs_prev, !first_page); - gtk_widget_set_sensitive (priv->menu_tabs_detach, num_pages > 1); - gtk_widget_set_sensitive (priv->menu_tabs_left, !first_page); - gtk_widget_set_sensitive (priv->menu_tabs_right, !last_page); - gtk_widget_set_sensitive (priv->menu_conv_insert_smiley, is_connected); - - /* Update window title */ - if (n_chats == 1) { - gtk_window_set_title (GTK_WINDOW (priv->dialog), name); - } else { - gchar *title; - - title = g_strdup_printf (_("Conversations (%d)"), n_chats); - gtk_window_set_title (GTK_WINDOW (priv->dialog), title); - g_free (title); - } - - /* Update window icon */ - if (priv->chats_new_msg) { - gtk_window_set_icon_name (GTK_WINDOW (priv->dialog), - EMPATHY_IMAGE_MESSAGE); - } else { - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_CHAT_AVATAR_IN_ICON, - &avatar_in_icon); - - if (n_chats == 1 && avatar_in_icon) { - remote_contact = empathy_chat_get_remote_contact (priv->current_chat); - icon = empathy_pixbuf_avatar_from_contact_scaled (remote_contact, 0, 0); - gtk_window_set_icon (GTK_WINDOW (priv->dialog), icon); - - if (icon != NULL) { - g_object_unref (icon); - } - } else { - gtk_window_set_icon_name (GTK_WINDOW (priv->dialog), NULL); - } - } - - if (num_pages == 1) { - chat = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), 0); - chat_close_button = g_object_get_data (G_OBJECT (chat), - "chat-window-tab-close-button"); - gtk_widget_hide (chat_close_button); - } else { - for (i=0; i<num_pages; i++) { - chat = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), i); - chat_close_button = g_object_get_data (G_OBJECT (chat), - "chat-window-tab-close-button"); - gtk_widget_show (chat_close_button); - } - } -} - -static void -chat_window_update_chat_tab (EmpathyChat *chat) -{ - EmpathyChatWindow *window; - EmpathyChatWindowPriv *priv; - EmpathyContact *remote_contact; - const gchar *name; - McAccount *account; - const gchar *subject; - GtkWidget *widget; - GString *tooltip; - gchar *markup; - const gchar *icon_name; - - window = chat_window_find_chat (chat); - if (!window) { - return; - } - priv = GET_PRIV (window); - - /* Get information */ - name = empathy_chat_get_name (chat); - account = empathy_chat_get_account (chat); - subject = empathy_chat_get_subject (chat); - remote_contact = empathy_chat_get_remote_contact (chat); - - DEBUG ("Updating chat tab, name=%s, account=%s, subject=%s, remote_contact=%p", - name, mc_account_get_unique_name (account), subject, remote_contact); - - /* Update tab image */ - if (g_list_find (priv->chats_new_msg, chat)) { - icon_name = EMPATHY_IMAGE_MESSAGE; - } - else if (g_list_find (priv->chats_composing, chat)) { - icon_name = EMPATHY_IMAGE_TYPING; - } - else if (remote_contact) { - icon_name = empathy_icon_name_for_contact (remote_contact); - } else { - icon_name = EMPATHY_IMAGE_GROUP_MESSAGE; - } - 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); - - /* Update tab tooltip */ - tooltip = g_string_new (NULL); - - if (remote_contact) { - markup = g_markup_printf_escaped ("<b>%s</b><small> (%s)</small>\n%s", - empathy_contact_get_id (remote_contact), - mc_account_get_display_name (account), - empathy_contact_get_status (remote_contact)); - g_string_append (tooltip, markup); - g_free (markup); - } - else { - markup = g_markup_printf_escaped ("<b>%s</b><small> (%s)</small>", name, - mc_account_get_display_name (account)); - g_string_append (tooltip, markup); - g_free (markup); - } - - if (subject) { - markup = g_markup_printf_escaped ("\n<b>%s</b> %s", _("Topic:"), subject); - g_string_append (tooltip, markup); - g_free (markup); - } - if (g_list_find (priv->chats_composing, chat)) { - markup = g_markup_printf_escaped ("\n%s", _("Typing a message.")); - g_string_append (tooltip, markup); - g_free (markup); - } - - 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); - g_free (markup); - - /* Update tab label */ - widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-label"); - gtk_label_set_text (GTK_LABEL (widget), name); - - /* Update the window if it's the current chat */ - if (priv->current_chat == chat) { - chat_window_update (window); - } -} - -static void -chat_window_chat_notify_cb (EmpathyChat *chat) -{ - EmpathyContact *old_remote_contact; - EmpathyContact *remote_contact = NULL; - - old_remote_contact = g_object_get_data (G_OBJECT (chat), "chat-window-remote-contact"); - remote_contact = empathy_chat_get_remote_contact (chat); - - if (old_remote_contact != remote_contact) { - /* The remote-contact associated with the chat changed, we need - * to keep track of any change of that contact and update the - * window each time. */ - if (remote_contact) { - g_signal_connect_swapped (remote_contact, "notify", - G_CALLBACK (chat_window_update_chat_tab), - chat); - } - if (old_remote_contact) { - g_signal_handlers_disconnect_by_func (old_remote_contact, - chat_window_update_chat_tab, - chat); - } - - g_object_set_data (G_OBJECT (chat), "chat-window-remote-contact", - remote_contact); - } - - chat_window_update_chat_tab (chat); -} - -static void -chat_window_insert_smiley_activate_cb (EmpathySmileyManager *manager, - EmpathySmiley *smiley, - gpointer window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - EmpathyChat *chat; - GtkTextBuffer *buffer; - GtkTextIter iter; - - chat = priv->current_chat; - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (chat->input_text_view)); - gtk_text_buffer_get_end_iter (buffer, &iter); - gtk_text_buffer_insert (buffer, &iter, smiley->str, -1); -} - -static void -chat_window_conv_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - GtkWidget *submenu = NULL; - - /* Contact submenu */ - submenu = empathy_chat_get_contact_menu (priv->current_chat); - if (submenu) { - gtk_menu_item_set_submenu (GTK_MENU_ITEM (priv->menu_conv_contact), - submenu); - gtk_widget_show (priv->menu_conv_contact); - gtk_widget_show (submenu); - } else { - gtk_widget_hide (priv->menu_conv_contact); - } - - /* Favorite room menu */ - if (empathy_chat_is_room (priv->current_chat)) { - const gchar *room; - McAccount *account; - gboolean found; - - room = empathy_chat_get_id (priv->current_chat); - account = empathy_chat_get_account (priv->current_chat); - found = empathy_chatroom_manager_find (priv->chatroom_manager, - account, room) != NULL; - - DEBUG ("This room %s favorite", found ? "is" : "is not"); - gtk_check_menu_item_set_active ( - GTK_CHECK_MENU_ITEM (priv->menu_conv_favorite), found); - gtk_widget_show (priv->menu_conv_favorite); - } else { - gtk_widget_hide (priv->menu_conv_favorite); - } -} - -static void -chat_window_clear_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - - empathy_chat_clear (priv->current_chat); -} - -static void -chat_window_favorite_toggled_cb (GtkCheckMenuItem *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - gboolean active; - McAccount *account; - const gchar *room; - EmpathyChatroom *chatroom; - - active = gtk_check_menu_item_get_active (menuitem); - account = empathy_chat_get_account (priv->current_chat); - room = empathy_chat_get_id (priv->current_chat); - - chatroom = empathy_chatroom_manager_find (priv->chatroom_manager, - account, room); - - if (active && !chatroom) { - const gchar *name; - - name = empathy_chat_get_name (priv->current_chat); - chatroom = empathy_chatroom_new_full (account, room, name, FALSE); - empathy_chatroom_manager_add (priv->chatroom_manager, chatroom); - g_object_unref (chatroom); - return; - } - - if (!active && chatroom) { - empathy_chatroom_manager_remove (priv->chatroom_manager, chatroom); - } -} - -static const gchar * -chat_get_window_id_for_geometry (EmpathyChat *chat) -{ - const gchar *res = NULL; - gboolean separate_windows; - - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, - &separate_windows); - - if (separate_windows) { - res = empathy_chat_get_id (chat); - } - - return res ? res : "chat-window"; -} - -static gboolean -chat_window_save_geometry_timeout_cb (EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - gint x, y, w, h; - - priv = GET_PRIV (window); - - gtk_window_get_size (GTK_WINDOW (priv->dialog), &w, &h); - gtk_window_get_position (GTK_WINDOW (priv->dialog), &x, &y); - - empathy_geometry_save (chat_get_window_id_for_geometry (priv->current_chat), - x, y, w, h); - - priv->save_geometry_id = 0; - - return FALSE; -} - -static gboolean -chat_window_configure_event_cb (GtkWidget *widget, - GdkEventConfigure *event, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - priv = GET_PRIV (window); - - if (priv->save_geometry_id != 0) { - g_source_remove (priv->save_geometry_id); - } - - priv->save_geometry_id = - g_timeout_add_seconds (1, - (GSourceFunc) chat_window_save_geometry_timeout_cb, - window); - - return FALSE; -} - -static void -chat_window_close_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - priv = GET_PRIV (window); - - g_return_if_fail (priv->current_chat != NULL); - - empathy_chat_window_remove_chat (window, priv->current_chat); -} - -static void -chat_window_edit_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - GtkClipboard *clipboard; - GtkTextBuffer *buffer; - gboolean text_available; - - priv = GET_PRIV (window); - - g_return_if_fail (priv->current_chat != NULL); - - if (!empathy_chat_get_tp_chat (priv->current_chat)) { - gtk_widget_set_sensitive (priv->menu_edit_copy, FALSE); - gtk_widget_set_sensitive (priv->menu_edit_cut, FALSE); - gtk_widget_set_sensitive (priv->menu_edit_paste, FALSE); - return; - } - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->current_chat->input_text_view)); - if (gtk_text_buffer_get_has_selection (buffer)) { - gtk_widget_set_sensitive (priv->menu_edit_copy, TRUE); - gtk_widget_set_sensitive (priv->menu_edit_cut, TRUE); - } else { - gboolean selection; - - selection = empathy_chat_view_get_has_selection (priv->current_chat->view); - - gtk_widget_set_sensitive (priv->menu_edit_cut, FALSE); - gtk_widget_set_sensitive (priv->menu_edit_copy, selection); - } - - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); - text_available = gtk_clipboard_wait_is_text_available (clipboard); - gtk_widget_set_sensitive (priv->menu_edit_paste, text_available); -} - -static void -chat_window_cut_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - g_return_if_fail (EMPATHY_IS_CHAT_WINDOW (window)); - - priv = GET_PRIV (window); - - empathy_chat_cut (priv->current_chat); -} - -static void -chat_window_copy_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - g_return_if_fail (EMPATHY_IS_CHAT_WINDOW (window)); - - priv = GET_PRIV (window); - - empathy_chat_copy (priv->current_chat); -} - -static void -chat_window_paste_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - g_return_if_fail (EMPATHY_IS_CHAT_WINDOW (window)); - - priv = GET_PRIV (window); - - empathy_chat_paste (priv->current_chat); -} - -static void -chat_window_tabs_left_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - EmpathyChat *chat; - gint index; - - priv = GET_PRIV (window); - - chat = priv->current_chat; - index = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook)); - if (index <= 0) { - return; - } - - gtk_notebook_reorder_child (GTK_NOTEBOOK (priv->notebook), - GTK_WIDGET (chat), - index - 1); -} - -static void -chat_window_tabs_right_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - EmpathyChat *chat; - gint index; - - priv = GET_PRIV (window); - - chat = priv->current_chat; - index = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook)); - - gtk_notebook_reorder_child (GTK_NOTEBOOK (priv->notebook), - GTK_WIDGET (chat), - index + 1); -} - -static void -chat_window_detach_activate_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - EmpathyChatWindow *new_window; - EmpathyChat *chat; - - priv = GET_PRIV (window); - - chat = priv->current_chat; - new_window = empathy_chat_window_new (); - - empathy_chat_window_move_chat (window, new_window, chat); - - priv = GET_PRIV (new_window); - gtk_widget_show (priv->dialog); -} - -static void -chat_window_help_contents_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - empathy_url_show (menuitem, "ghelp:empathy?chat"); -} - -static void -chat_window_help_about_cb (GtkWidget *menuitem, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - - empathy_about_dialog_new (GTK_WINDOW (priv->dialog)); -} - -static gboolean -chat_window_delete_event_cb (GtkWidget *dialog, - GdkEvent *event, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - - DEBUG ("Delete event received"); - - g_object_ref (window); - while (priv->chats) { - empathy_chat_window_remove_chat (window, priv->chats->data); - } - g_object_unref (window); - - return TRUE; -} - -static void -chat_window_composing_cb (EmpathyChat *chat, - gboolean is_composing, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - priv = GET_PRIV (window); - - if (is_composing && !g_list_find (priv->chats_composing, chat)) { - priv->chats_composing = g_list_prepend (priv->chats_composing, chat); - } else { - priv->chats_composing = g_list_remove (priv->chats_composing, chat); - } - - chat_window_update_chat_tab (chat); -} - -static void -chat_window_set_urgency_hint (EmpathyChatWindow *window, - gboolean urgent) -{ - EmpathyChatWindowPriv *priv; - - priv = GET_PRIV (window); - - DEBUG ("Turning %s urgency hint", urgent ? "on" : "off"); - gtk_window_set_urgency_hint (GTK_WINDOW (priv->dialog), urgent); -} - -typedef struct { - EmpathyChatWindow *window; - EmpathyChat *chat; -} NotificationData; - -static void -chat_window_notification_closed_cb (NotifyNotification *notify, - NotificationData *cb_data) -{ - EmpathyNotificationClosedReason reason = 0; - EmpathyChatWindowPriv *priv = GET_PRIV (cb_data->window); - -#ifdef notify_notification_get_closed_reason - reason = notify_notification_get_closed_reason (notify); -#endif - if (reason == EMPATHY_NOTIFICATION_CLOSED_DISMISSED) { - empathy_chat_window_present_chat (cb_data->chat); - } - - g_object_unref (notify); - priv->notification = NULL; - g_object_unref (cb_data->chat); - g_slice_free (NotificationData, cb_data); -} - -static void -chat_window_show_or_update_notification (EmpathyChatWindow *window, - EmpathyMessage *message, - EmpathyChat *chat) -{ - EmpathyContact *sender; - char *header, *escaped; - const char *body; - GdkPixbuf *pixbuf; - NotificationData *cb_data; - EmpathyChatWindowPriv *priv = GET_PRIV (window); - gboolean res; - - if (!empathy_notification_is_enabled ()) { - return; - } else { - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_NOTIFICATIONS_FOCUS, &res); - if (!res) { - return; - } - } - - cb_data = g_slice_new0 (NotificationData); - cb_data->chat = g_object_ref (chat); - cb_data->window = window; - - sender = empathy_message_get_sender (message); - header = g_strdup_printf (_("New message from %s"), - empathy_contact_get_name (sender)); - body = empathy_message_get_body (message); - escaped = g_markup_escape_text (body, -1); - - pixbuf = empathy_misc_get_pixbuf_for_notification (sender, EMPATHY_IMAGE_NEW_MESSAGE); - - if (priv->notification != NULL) { - notify_notification_update (priv->notification, - header, escaped, NULL); - notify_notification_set_icon_from_pixbuf (priv->notification, pixbuf); - } else { - priv->notification = notify_notification_new (header, escaped, NULL, NULL); - notify_notification_set_timeout (priv->notification, NOTIFY_EXPIRES_DEFAULT); - notify_notification_set_icon_from_pixbuf (priv->notification, pixbuf); - - g_signal_connect (priv->notification, "closed", - G_CALLBACK (chat_window_notification_closed_cb), cb_data); - } - - notify_notification_show (priv->notification, NULL); - - g_object_unref (pixbuf); - g_free (header); - g_free (escaped); -} - -static void -chat_window_new_message_cb (EmpathyChat *chat, - EmpathyMessage *message, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - gboolean has_focus; - gboolean needs_urgency; - EmpathyContact *sender; - - priv = GET_PRIV (window); - - has_focus = empathy_chat_window_has_focus (window); - - /* - 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 - * the message. - */ - - sender = empathy_message_get_sender (message); - - if (empathy_contact_is_user (sender) != FALSE) { - 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_get_members_count (chat) > 2) { - needs_urgency = empathy_message_should_highlight (message); - } else { - needs_urgency = TRUE; - } - - if (needs_urgency && !has_focus) { - chat_window_set_urgency_hint (window, TRUE); - } - - if (!g_list_find (priv->chats_new_msg, chat)) { - priv->chats_new_msg = g_list_prepend (priv->chats_new_msg, chat); - chat_window_update_chat_tab (chat); - } -} - -static GtkNotebook * -chat_window_detach_hook (GtkNotebook *source, - GtkWidget *page, - gint x, - gint y, - gpointer user_data) -{ - EmpathyChatWindowPriv *priv; - EmpathyChatWindow *window, *new_window; - EmpathyChat *chat; - - chat = EMPATHY_CHAT (page); - window = chat_window_find_chat (chat); - - new_window = empathy_chat_window_new (); - priv = GET_PRIV (new_window); - - DEBUG ("Detach hook called"); - - empathy_chat_window_move_chat (window, new_window, chat); - - gtk_window_move (GTK_WINDOW (priv->dialog), x, y); - gtk_widget_show (priv->dialog); - - return NULL; -} - -static void -chat_window_page_switched_cb (GtkNotebook *notebook, - GtkNotebookPage *page, - gint page_num, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - EmpathyChat *chat; - GtkWidget *child; - - DEBUG ("Page switched"); - - priv = GET_PRIV (window); - - child = gtk_notebook_get_nth_page (notebook, page_num); - chat = EMPATHY_CHAT (child); - - if (priv->page_added) { - priv->page_added = FALSE; - empathy_chat_scroll_down (chat); - } - else if (priv->current_chat == chat) { - return; - } - - priv->current_chat = chat; - priv->chats_new_msg = g_list_remove (priv->chats_new_msg, chat); - - chat_window_update_chat_tab (chat); -} - -static void -chat_window_page_added_cb (GtkNotebook *notebook, - GtkWidget *child, - guint page_num, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - EmpathyChat *chat; - - priv = GET_PRIV (window); - - /* If we just received DND to the same window, we don't want - * to do anything here like removing the tab and then readding - * it, so we return here and in "page-added". - */ - if (priv->dnd_same_window) { - DEBUG ("Page added (back to the same window)"); - priv->dnd_same_window = FALSE; - return; - } - - DEBUG ("Page added"); - - /* Get chat object */ - chat = EMPATHY_CHAT (child); - - /* Connect chat signals for this window */ - g_signal_connect (chat, "composing", - G_CALLBACK (chat_window_composing_cb), - window); - g_signal_connect (chat, "new-message", - G_CALLBACK (chat_window_new_message_cb), - window); - - /* Set flag so we know to perform some special operations on - * switch page due to the new page being added. - */ - priv->page_added = TRUE; - - /* Get list of chats up to date */ - priv->chats = g_list_append (priv->chats, chat); - - chat_window_update_chat_tab (chat); -} - -static void -chat_window_page_removed_cb (GtkNotebook *notebook, - GtkWidget *child, - guint page_num, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - EmpathyChat *chat; - - priv = GET_PRIV (window); - - /* If we just received DND to the same window, we don't want - * to do anything here like removing the tab and then readding - * it, so we return here and in "page-added". - */ - if (priv->dnd_same_window) { - DEBUG ("Page removed (and will be readded to same window)"); - return; - } - - DEBUG ("Page removed"); - - /* Get chat object */ - chat = EMPATHY_CHAT (child); - - /* Disconnect all signal handlers for this chat and this window */ - g_signal_handlers_disconnect_by_func (chat, - G_CALLBACK (chat_window_composing_cb), - window); - g_signal_handlers_disconnect_by_func (chat, - G_CALLBACK (chat_window_new_message_cb), - window); - - /* Keep list of chats up to date */ - priv->chats = g_list_remove (priv->chats, chat); - priv->chats_new_msg = g_list_remove (priv->chats_new_msg, chat); - priv->chats_composing = g_list_remove (priv->chats_composing, chat); - - if (priv->chats == NULL) { - g_object_unref (window); - } else { - chat_window_update (window); - } -} - -static gboolean -chat_window_focus_in_event_cb (GtkWidget *widget, - GdkEvent *event, - EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - DEBUG ("Focus in event, updating title"); - - priv = GET_PRIV (window); - - priv->chats_new_msg = g_list_remove (priv->chats_new_msg, priv->current_chat); - - chat_window_set_urgency_hint (window, FALSE); - - /* Update the title, since we now mark all unread messages as read. */ - chat_window_update_chat_tab (priv->current_chat); - - return FALSE; -} - -static void -chat_window_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - GtkSelectionData *selection, - guint info, - guint time, - EmpathyChatWindow *window) -{ - if (info == DND_DRAG_TYPE_CONTACT_ID) { - EmpathyChat *chat; - EmpathyChatWindow *old_window; - McAccount *account; - const gchar *id; - gchar **strv; - - id = (const gchar*) selection->data; - - DEBUG ("DND contact from roster with id:'%s'", id); - - strv = g_strsplit (id, "/", 2); - account = mc_account_lookup (strv[0]); - chat = empathy_chat_window_find_chat (account, strv[1]); - - if (!chat) { - empathy_dispatcher_chat_with_contact_id (account, strv[2], NULL, NULL); - g_object_unref (account); - g_strfreev (strv); - return; - } - g_object_unref (account); - g_strfreev (strv); - - old_window = chat_window_find_chat (chat); - if (old_window) { - if (old_window == window) { - gtk_drag_finish (context, TRUE, FALSE, time); - return; - } - - empathy_chat_window_move_chat (old_window, window, chat); - } else { - empathy_chat_window_add_chat (window, chat); - } - - /* Added to take care of any outstanding chat events */ - empathy_chat_window_present_chat (chat); - - /* 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(). - */ - gtk_drag_finish (context, TRUE, FALSE, time); - } - else if (info == DND_DRAG_TYPE_TAB) { - EmpathyChat **chat; - EmpathyChatWindow *old_window = NULL; - - DEBUG ("DND tab"); - - chat = (void*) selection->data; - old_window = chat_window_find_chat (*chat); - - if (old_window) { - EmpathyChatWindowPriv *priv; - - priv = GET_PRIV (window); - - if (old_window == window) { - DEBUG ("DND tab (within same window)"); - priv->dnd_same_window = TRUE; - gtk_drag_finish (context, TRUE, FALSE, time); - return; - } - - priv->dnd_same_window = FALSE; - } - - /* 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(). - */ - gtk_drag_finish (context, TRUE, FALSE, time); - } else { - DEBUG ("DND from unknown source"); - gtk_drag_finish (context, FALSE, FALSE, time); - } -} - -static void -chat_window_finalize (GObject *object) -{ - EmpathyChatWindow *window; - EmpathyChatWindowPriv *priv; - - window = EMPATHY_CHAT_WINDOW (object); - priv = GET_PRIV (window); - - DEBUG ("Finalized: %p", object); - - g_object_unref (priv->chatroom_manager); - if (priv->save_geometry_id != 0) { - g_source_remove (priv->save_geometry_id); - } - - if (priv->notification != NULL) { - notify_notification_close (priv->notification, NULL); - g_object_unref (priv->notification); - priv->notification = NULL; - } - - chat_windows = g_list_remove (chat_windows, window); - gtk_widget_destroy (priv->dialog); - - G_OBJECT_CLASS (empathy_chat_window_parent_class)->finalize (object); -} - -static void -empathy_chat_window_class_init (EmpathyChatWindowClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = chat_window_finalize; - - g_type_class_add_private (object_class, sizeof (EmpathyChatWindowPriv)); - - /* Set up a style for the close button with no focus padding. */ - gtk_rc_parse_string ( - "style \"empathy-close-button-style\"\n" - "{\n" - " GtkWidget::focus-padding = 0\n" - " xthickness = 0\n" - " ythickness = 0\n" - "}\n" - "widget \"*.empathy-close-button\" style \"empathy-close-button-style\""); - - gtk_notebook_set_window_creation_hook (chat_window_detach_hook, NULL, NULL); -} - -static void -empathy_chat_window_init (EmpathyChatWindow *window) -{ - GladeXML *glade; - GtkAccelGroup *accel_group; - GClosure *closure; - GtkWidget *menu_conv; - GtkWidget *menu; - gint i; - GtkWidget *chat_vbox; - gchar *filename; - EmpathySmileyManager *smiley_manager; - EmpathyChatWindowPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (window, - EMPATHY_TYPE_CHAT_WINDOW, EmpathyChatWindowPriv); - - window->priv = priv; - filename = empathy_file_lookup ("empathy-chat-window.glade", "src"); - glade = empathy_glade_get_file (filename, - "chat_window", - NULL, - "chat_window", &priv->dialog, - "chat_vbox", &chat_vbox, - "menu_conv", &menu_conv, - "menu_conv_clear", &priv->menu_conv_clear, - "menu_conv_insert_smiley", &priv->menu_conv_insert_smiley, - "menu_conv_contact", &priv->menu_conv_contact, - "menu_conv_favorite", &priv->menu_conv_favorite, - "menu_conv_close", &priv->menu_conv_close, - "menu_edit_cut", &priv->menu_edit_cut, - "menu_edit_copy", &priv->menu_edit_copy, - "menu_edit_paste", &priv->menu_edit_paste, - "menu_tabs_next", &priv->menu_tabs_next, - "menu_tabs_prev", &priv->menu_tabs_prev, - "menu_tabs_left", &priv->menu_tabs_left, - "menu_tabs_right", &priv->menu_tabs_right, - "menu_tabs_detach", &priv->menu_tabs_detach, - "menu_help_contents", &priv->menu_help_contents, - "menu_help_about", &priv->menu_help_about, - NULL); - g_free (filename); - - empathy_glade_connect (glade, - window, - "chat_window", "configure-event", chat_window_configure_event_cb, - "menu_conv", "activate", chat_window_conv_activate_cb, - "menu_conv_clear", "activate", chat_window_clear_activate_cb, - "menu_conv_favorite", "toggled", chat_window_favorite_toggled_cb, - "menu_conv_close", "activate", chat_window_close_activate_cb, - "menu_edit", "activate", chat_window_edit_activate_cb, - "menu_edit_cut", "activate", chat_window_cut_activate_cb, - "menu_edit_copy", "activate", chat_window_copy_activate_cb, - "menu_edit_paste", "activate", chat_window_paste_activate_cb, - "menu_tabs_left", "activate", chat_window_tabs_left_activate_cb, - "menu_tabs_right", "activate", chat_window_tabs_right_activate_cb, - "menu_tabs_detach", "activate", chat_window_detach_activate_cb, - "menu_help_contents", "activate", chat_window_help_contents_cb, - "menu_help_about", "activate", chat_window_help_about_cb, - NULL); - - g_object_unref (glade); - - priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL); - - priv->notebook = gtk_notebook_new (); - gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), "EmpathyChatWindow"); - gtk_box_pack_start (GTK_BOX (chat_vbox), priv->notebook, TRUE, TRUE, 0); - gtk_widget_show (priv->notebook); - - /* Set up accels */ - accel_group = gtk_accel_group_new (); - gtk_window_add_accel_group (GTK_WINDOW (priv->dialog), accel_group); - - for (i = 0; i < G_N_ELEMENTS (tab_accel_keys); i++) { - closure = g_cclosure_new (G_CALLBACK (chat_window_accel_cb), - window, - NULL); - gtk_accel_group_connect (accel_group, - tab_accel_keys[i], - GDK_MOD1_MASK, - 0, - closure); - } - - g_object_unref (accel_group); - - /* Set up smiley menu */ - smiley_manager = empathy_smiley_manager_dup_singleton (); - menu = empathy_smiley_menu_new (smiley_manager, - chat_window_insert_smiley_activate_cb, - window); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (priv->menu_conv_insert_smiley), - menu); - g_object_unref (smiley_manager); - - /* Set up signals we can't do with glade since we may need to - * block/unblock them at some later stage. - */ - - g_signal_connect (priv->dialog, - "delete_event", - G_CALLBACK (chat_window_delete_event_cb), - window); - - g_signal_connect_swapped (priv->menu_tabs_prev, - "activate", - G_CALLBACK (gtk_notebook_prev_page), - priv->notebook); - g_signal_connect_swapped (priv->menu_tabs_next, - "activate", - G_CALLBACK (gtk_notebook_next_page), - priv->notebook); - - g_signal_connect (priv->dialog, - "focus_in_event", - G_CALLBACK (chat_window_focus_in_event_cb), - window); - g_signal_connect_after (priv->notebook, - "switch_page", - G_CALLBACK (chat_window_page_switched_cb), - window); - g_signal_connect (priv->notebook, - "page_added", - G_CALLBACK (chat_window_page_added_cb), - window); - g_signal_connect (priv->notebook, - "page_removed", - G_CALLBACK (chat_window_page_removed_cb), - window); - - /* Set up drag and drop */ - gtk_drag_dest_set (GTK_WIDGET (priv->notebook), - GTK_DEST_DEFAULT_ALL, - drag_types_dest, - G_N_ELEMENTS (drag_types_dest), - GDK_ACTION_MOVE); - - g_signal_connect (priv->notebook, - "drag-data-received", - G_CALLBACK (chat_window_drag_data_received), - window); - - chat_windows = g_list_prepend (chat_windows, window); - - /* Set up private details */ - priv->chats = NULL; - priv->chats_new_msg = NULL; - priv->chats_composing = NULL; - priv->current_chat = NULL; -} - -EmpathyChatWindow * -empathy_chat_window_new (void) -{ - return EMPATHY_CHAT_WINDOW (g_object_new (EMPATHY_TYPE_CHAT_WINDOW, NULL)); -} - -/* Returns the window to open a new tab in if there is only one window - * visble, otherwise, returns NULL indicating that a new window should - * be added. - */ -EmpathyChatWindow * -empathy_chat_window_get_default (void) -{ - GList *l; - gboolean separate_windows = TRUE; - - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, - &separate_windows); - - if (separate_windows) { - /* Always create a new window */ - return NULL; - } - - for (l = chat_windows; l; l = l->next) { - EmpathyChatWindow *chat_window; - GtkWidget *dialog; - - chat_window = l->data; - - dialog = empathy_chat_window_get_dialog (chat_window); - if (empathy_window_get_is_visible (GTK_WINDOW (dialog))) { - /* Found a visible window on this desktop */ - return chat_window; - } - } - - return NULL; -} - -GtkWidget * -empathy_chat_window_get_dialog (EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - - g_return_val_if_fail (window != NULL, NULL); - - priv = GET_PRIV (window); - - return priv->dialog; -} - -void -empathy_chat_window_add_chat (EmpathyChatWindow *window, - EmpathyChat *chat) -{ - EmpathyChatWindowPriv *priv; - GtkWidget *label; - GtkWidget *child; - gint x, y, w, h; - - g_return_if_fail (window != NULL); - g_return_if_fail (EMPATHY_IS_CHAT (chat)); - - priv = GET_PRIV (window); - - /* Reference the chat object */ - g_object_ref (chat); - - /* If this window has just been created, position it */ - if (priv->chats == NULL) { - empathy_geometry_load (chat_get_window_id_for_geometry (chat), &x, &y, &w, &h); - - if (x >= 0 && y >= 0) { - /* Let the window manager position it if we don't have - * good x, y coordinates. - */ - gtk_window_move (GTK_WINDOW (priv->dialog), x, y); - } - - if (w > 0 && h > 0) { - /* Use the defaults from the glade file if we don't have - * good w, h geometry. - */ - gtk_window_resize (GTK_WINDOW (priv->dialog), w, h); - } - } - - child = GTK_WIDGET (chat); - label = chat_window_create_label (window, chat); - gtk_widget_show (child); - - g_signal_connect (chat, "notify::name", - G_CALLBACK (chat_window_chat_notify_cb), - NULL); - g_signal_connect (chat, "notify::subject", - G_CALLBACK (chat_window_chat_notify_cb), - NULL); - g_signal_connect (chat, "notify::remote-contact", - G_CALLBACK (chat_window_chat_notify_cb), - NULL); - chat_window_chat_notify_cb (chat); - - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), child, 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); - - DEBUG ("Chat added (%d references)", G_OBJECT (chat)->ref_count); -} - -void -empathy_chat_window_remove_chat (EmpathyChatWindow *window, - EmpathyChat *chat) -{ - EmpathyChatWindowPriv *priv; - gint position; - EmpathyContact *remote_contact; - - g_return_if_fail (window != NULL); - g_return_if_fail (EMPATHY_IS_CHAT (chat)); - - priv = GET_PRIV (window); - - g_signal_handlers_disconnect_by_func (chat, - chat_window_chat_notify_cb, - NULL); - remote_contact = g_object_get_data (G_OBJECT (chat), - "chat-window-remote-contact"); - if (remote_contact) { - g_signal_handlers_disconnect_by_func (remote_contact, - chat_window_update_chat_tab, - chat); - } - - position = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), - GTK_WIDGET (chat)); - gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), position); - - DEBUG ("Chat removed (%d references)", G_OBJECT (chat)->ref_count - 1); - - g_object_unref (chat); -} - -void -empathy_chat_window_move_chat (EmpathyChatWindow *old_window, - EmpathyChatWindow *new_window, - EmpathyChat *chat) -{ - GtkWidget *widget; - - g_return_if_fail (EMPATHY_IS_CHAT_WINDOW (old_window)); - g_return_if_fail (EMPATHY_IS_CHAT_WINDOW (new_window)); - g_return_if_fail (EMPATHY_IS_CHAT (chat)); - - widget = GTK_WIDGET (chat); - - DEBUG ("Chat moving with widget:%p (%d references)", widget, - G_OBJECT (widget)->ref_count); - - /* We reference here to make sure we don't loose the widget - * and the EmpathyChat object during the move. - */ - g_object_ref (chat); - g_object_ref (widget); - - empathy_chat_window_remove_chat (old_window, chat); - empathy_chat_window_add_chat (new_window, chat); - - g_object_unref (widget); - g_object_unref (chat); -} - -void -empathy_chat_window_switch_to_chat (EmpathyChatWindow *window, - EmpathyChat *chat) -{ - EmpathyChatWindowPriv *priv; - gint page_num; - - g_return_if_fail (window != NULL); - g_return_if_fail (EMPATHY_IS_CHAT (chat)); - - priv = GET_PRIV (window); - - page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), - GTK_WIDGET (chat)); - gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), - page_num); -} - -gboolean -empathy_chat_window_has_focus (EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv; - gboolean has_focus; - - g_return_val_if_fail (EMPATHY_IS_CHAT_WINDOW (window), FALSE); - - priv = GET_PRIV (window); - - g_object_get (priv->dialog, "has-toplevel-focus", &has_focus, NULL); - - return has_focus; -} - -EmpathyChat * -empathy_chat_window_find_chat (McAccount *account, - const gchar *id) -{ - GList *l; - - g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); - g_return_val_if_fail (!EMP_STR_EMPTY (id), NULL); - - for (l = chat_windows; l; l = l->next) { - EmpathyChatWindowPriv *priv; - EmpathyChatWindow *window; - GList *ll; - - window = l->data; - priv = GET_PRIV (window); - - for (ll = priv->chats; ll; ll = ll->next) { - EmpathyChat *chat; - - chat = ll->data; - - if (empathy_account_equal (account, empathy_chat_get_account (chat)) && - !tp_strdiff (id, empathy_chat_get_id (chat))) { - return chat; - } - } - } - - return NULL; -} - -void -empathy_chat_window_present_chat (EmpathyChat *chat) -{ - EmpathyChatWindow *window; - EmpathyChatWindowPriv *priv; - - g_return_if_fail (EMPATHY_IS_CHAT (chat)); - - window = chat_window_find_chat (chat); - - /* If the chat has no window, create one */ - if (window == NULL) { - window = empathy_chat_window_get_default (); - if (!window) { - window = empathy_chat_window_new (); - } - - empathy_chat_window_add_chat (window, chat); - } - - priv = GET_PRIV (window); - empathy_chat_window_switch_to_chat (window, chat); - empathy_window_present (GTK_WINDOW (priv->dialog), TRUE); - - gtk_widget_grab_focus (chat->input_text_view); -} - -#if 0 -static gboolean -chat_window_should_play_sound (EmpathyChatWindow *window) -{ - EmpathyChatWindowPriv *priv = GET_PRIV (window); - gboolean has_focus = FALSE; - - g_return_val_if_fail (EMPATHY_IS_CHAT_WINDOW (window), FALSE); - - g_object_get (priv->dialog, "has-toplevel-focus", &has_focus, NULL); - - return !has_focus; -} -#endif diff --git a/src/empathy-chat-window.glade b/src/empathy-chat-window.glade deleted file mode 100644 index b62a5c219..000000000 --- a/src/empathy-chat-window.glade +++ /dev/null @@ -1,359 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkWindow" id="chat_window"> - <property name="title" translatable="yes">Chat</property> - <property name="role">chat</property> - <property name="default_width">350</property> - <property name="default_height">250</property> - <child> - <widget class="GtkVBox" id="chat_vbox"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuBar" id="chats_menubar"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuItem" id="menu_conv"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Conversation</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="menu_conv_menu"> - <child> - <widget class="GtkImageMenuItem" id="menu_conv_clear"> - <property name="visible">True</property> - <property name="label" translatable="yes">C_lear</property> - <property name="use_underline">True</property> - <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image262"> - <property name="visible">True</property> - <property name="stock">gtk-clear</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="menu_conv_insert_smiley"> - <property name="visible">True</property> - <property name="label" translatable="yes">Insert _Smiley</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="menu-item-image3"> - <property name="visible">True</property> - <property name="icon_size">1</property> - <property name="icon_name">face-smile</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_conv_contact"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Contact</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkCheckMenuItem" id="menu_conv_favorite"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Favorite Chatroom</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator7"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="menu_conv_close"> - <property name="visible">True</property> - <property name="label">gtk-close</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <accelerator key="W" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_edit"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Edit</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="menu_edit_menu"> - <child> - <widget class="GtkImageMenuItem" id="menu_edit_cut"> - <property name="visible">True</property> - <property name="label">gtk-cut</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <accelerator key="X" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="menu_edit_copy"> - <property name="visible">True</property> - <property name="label">gtk-copy</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <accelerator key="C" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="menu_edit_paste"> - <property name="visible">True</property> - <property name="label">gtk-paste</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <accelerator key="V" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_tabs"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Tabs</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="menu_tabs_menu"> - <child> - <widget class="GtkMenuItem" id="menu_tabs_prev"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Previous Tab</property> - <property name="use_underline">True</property> - <accelerator key="Page_Up" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_tabs_next"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Next Tab</property> - <property name="use_underline">True</property> - <accelerator key="Page_Down" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator4"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_tabs_left"> - <property name="visible">True</property> - <property name="label" translatable="yes">Move Tab _Left</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_tabs_right"> - <property name="visible">True</property> - <property name="label" translatable="yes">Move Tab _Right</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_tabs_detach"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Detach Tab</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="menu_help"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Help</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="menu_help_menu"> - <child> - <widget class="GtkImageMenuItem" id="menu_help_contents"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Contents</property> - <property name="use_underline">True</property> - <accelerator key="F1" modifiers="" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image289"> - <property name="visible">True</property> - <property name="stock">gtk-help</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="menu_help_about"> - <property name="visible">True</property> - <property name="label">gtk-about</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <placeholder/> - </child> - </widget> - </child> - </widget> - <widget class="GtkDialog" id="chat_invite_dialog"> - <property name="border_width">5</property> - <property name="title" translatable="yes">Invite</property> - <property name="modal">True</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="default_width">275</property> - <property name="default_height">225</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="vbox6"> - <property name="visible">True</property> - <child> - <widget class="GtkVBox" id="vbox7"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="spacing">18</property> - <child> - <widget class="GtkVBox" id="vbox7"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkLabel" id="label"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Select who would you like to invite:</property> - <property name="use_markup">True</property> - <property name="wrap">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTreeView" id="treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkVBox" id="vbox8"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkLabel" id="label4"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Invitation _message:</property> - <property name="use_markup">True</property> - <property name="use_underline">True</property> - <property name="wrap">True</property> - <property name="mnemonic_widget">entry</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="activates_default">True</property> - <property name="width_chars">40</property> - <property name="text" translatable="yes">You have been invited to join a chat conference.</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="hbuttonbox1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="button_cancel"> - <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="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="button_invite"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="label">In_vite</property> - <property name="use_underline">True</property> - <property name="response_id">-5</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-chat-window.h b/src/empathy-chat-window.h deleted file mode 100644 index 8b7fe06a9..000000000 --- a/src/empathy-chat-window.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2003-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Mikael Hallendal <micke@imendio.com> - * Richard Hult <richard@imendio.com> - * Martyn Russell <martyn@imendio.com> - * Geert-Jan Van den Bogaerde <geertjan@gnome.org> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#ifndef __EMPATHY_CHAT_WINDOW_H__ -#define __EMPATHY_CHAT_WINDOW_H__ - -#include <glib-object.h> -#include <gtk/gtkwidget.h> - -#include <libmissioncontrol/mc-account.h> -#include <libempathy-gtk/empathy-chat.h> - -G_BEGIN_DECLS - -#define EMPATHY_TYPE_CHAT_WINDOW (empathy_chat_window_get_type ()) -#define EMPATHY_CHAT_WINDOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_CHAT_WINDOW, EmpathyChatWindow)) -#define EMPATHY_CHAT_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_CHAT_WINDOW, EmpathyChatWindowClass)) -#define EMPATHY_IS_CHAT_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CHAT_WINDOW)) -#define EMPATHY_IS_CHAT_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_CHAT_WINDOW)) -#define EMPATHY_CHAT_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_CHAT_WINDOW, EmpathyChatWindowClass)) - -typedef struct _EmpathyChatWindow EmpathyChatWindow; -typedef struct _EmpathyChatWindowClass EmpathyChatWindowClass; - -struct _EmpathyChatWindow { - GObject parent; - gpointer priv; -}; - -struct _EmpathyChatWindowClass { - GObjectClass parent_class; -}; - -GType empathy_chat_window_get_type (void); -EmpathyChatWindow *empathy_chat_window_get_default (void); -EmpathyChatWindow *empathy_chat_window_new (void); -GtkWidget * empathy_chat_window_get_dialog (EmpathyChatWindow *window); -void empathy_chat_window_add_chat (EmpathyChatWindow *window, - EmpathyChat *chat); -void empathy_chat_window_remove_chat (EmpathyChatWindow *window, - EmpathyChat *chat); -void empathy_chat_window_move_chat (EmpathyChatWindow *old_window, - EmpathyChatWindow *new_window, - EmpathyChat *chat); -void empathy_chat_window_switch_to_chat (EmpathyChatWindow *window, - EmpathyChat *chat); -gboolean empathy_chat_window_has_focus (EmpathyChatWindow *window); -EmpathyChat * empathy_chat_window_find_chat (McAccount *account, - const gchar *id); -void empathy_chat_window_present_chat (EmpathyChat *chat); - - -G_END_DECLS - -#endif /* __EMPATHY_CHAT_WINDOW_H__ */ diff --git a/src/empathy-chatrooms-window.c b/src/empathy-chatrooms-window.c deleted file mode 100644 index 841abf7d5..000000000 --- a/src/empathy-chatrooms-window.c +++ /dev/null @@ -1,585 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2004-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - * Martyn Russell <martyn@imendio.com> - * Mikael Hallendal <micke@imendio.com> - */ - -#include <config.h> - -#include <string.h> -#include <stdio.h> - -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <glib.h> -#include <glib/gi18n.h> - -#include <libempathy/empathy-chatroom-manager.h> -#include <libempathy/empathy-utils.h> - -#include <libempathy-gtk/empathy-account-chooser.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-chatrooms-window.h" -#include "empathy-new-chatroom-dialog.h" - -typedef struct { - EmpathyChatroomManager *manager; - - GtkWidget *window; - GtkWidget *hbox_account; - GtkWidget *label_account; - GtkWidget *account_chooser; - GtkWidget *treeview; - GtkWidget *button_remove; - GtkWidget *button_edit; - GtkWidget *button_close; - - gint room_column; -} EmpathyChatroomsWindow; - -static void chatrooms_window_destroy_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window); -static void chatrooms_window_model_setup (EmpathyChatroomsWindow *window); -static void chatrooms_window_model_add_columns (EmpathyChatroomsWindow *window); -static void chatrooms_window_model_refresh_data (EmpathyChatroomsWindow *window, - gboolean first_time); -static void chatrooms_window_model_add (EmpathyChatroomsWindow *window, - EmpathyChatroom *chatroom, - gboolean set_active); -static void chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle *cell, - gchar *path_string, - EmpathyChatroomsWindow *window); -static EmpathyChatroom * chatrooms_window_model_get_selected (EmpathyChatroomsWindow *window); -static void chatrooms_window_model_action_selected (EmpathyChatroomsWindow *window); -static void chatrooms_window_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - EmpathyChatroomsWindow *window); -static void chatrooms_window_button_remove_clicked_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window); -static void chatrooms_window_button_edit_clicked_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window); -static void chatrooms_window_button_close_clicked_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window); -static void chatrooms_window_chatroom_added_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyChatroomsWindow *window); -static void chatrooms_window_chatroom_removed_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyChatroomsWindow *window); -static gboolean chatrooms_window_remove_chatroom_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - EmpathyChatroom *chatroom); -static void chatrooms_window_account_changed_cb (GtkWidget *combo_box, - EmpathyChatroomsWindow *window); - -enum { - COL_IMAGE, - COL_NAME, - COL_ROOM, - COL_AUTO_CONNECT, - COL_POINTER, - COL_COUNT -}; - -void -empathy_chatrooms_window_show (GtkWindow *parent) -{ - static EmpathyChatroomsWindow *window = NULL; - GladeXML *glade; - gchar *filename; - - if (window) { - gtk_window_present (GTK_WINDOW (window->window)); - return; - } - - window = g_new0 (EmpathyChatroomsWindow, 1); - - filename = empathy_file_lookup ("empathy-chatrooms-window.glade", "src"); - glade = empathy_glade_get_file (filename, - "chatrooms_window", - NULL, - "chatrooms_window", &window->window, - "hbox_account", &window->hbox_account, - "label_account", &window->label_account, - "treeview", &window->treeview, - "button_edit", &window->button_edit, - "button_remove", &window->button_remove, - "button_close", &window->button_close, - NULL); - g_free (filename); - - empathy_glade_connect (glade, - window, - "chatrooms_window", "destroy", chatrooms_window_destroy_cb, - "button_remove", "clicked", chatrooms_window_button_remove_clicked_cb, - "button_edit", "clicked", chatrooms_window_button_edit_clicked_cb, - "button_close", "clicked", chatrooms_window_button_close_clicked_cb, - NULL); - - g_object_unref (glade); - - g_object_add_weak_pointer (G_OBJECT (window->window), (gpointer) &window); - - /* Get the session and chat room manager */ - window->manager = empathy_chatroom_manager_dup_singleton (NULL); - - g_signal_connect (window->manager, "chatroom-added", - G_CALLBACK (chatrooms_window_chatroom_added_cb), - window); - g_signal_connect (window->manager, "chatroom-removed", - G_CALLBACK (chatrooms_window_chatroom_removed_cb), - window); - - /* Account chooser for chat rooms */ - window->account_chooser = empathy_account_chooser_new (); - empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser), - empathy_account_chooser_filter_is_connected, - NULL); - g_object_set (window->account_chooser, - "has-all-option", TRUE, - NULL); - empathy_account_chooser_set_account (EMPATHY_ACCOUNT_CHOOSER (window->account_chooser), NULL); - - gtk_box_pack_start (GTK_BOX (window->hbox_account), - window->account_chooser, - TRUE, TRUE, 0); - - g_signal_connect (window->account_chooser, "changed", - G_CALLBACK (chatrooms_window_account_changed_cb), - window); - - gtk_widget_show (window->account_chooser); - - /* Set up chatrooms */ - chatrooms_window_model_setup (window); - - /* Set focus */ - gtk_widget_grab_focus (window->treeview); - - /* Last touches */ - if (parent) { - gtk_window_set_transient_for (GTK_WINDOW (window->window), - GTK_WINDOW (parent)); - } - - gtk_widget_show (window->window); -} - -static void -chatrooms_window_destroy_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window) -{ - g_signal_handlers_disconnect_by_func (window->manager, - chatrooms_window_chatroom_added_cb, - window); - g_signal_handlers_disconnect_by_func (window->manager, - chatrooms_window_chatroom_removed_cb, - window); - g_object_unref (window->manager); - g_free (window); -} - -static void -chatrooms_window_model_setup (EmpathyChatroomsWindow *window) -{ - GtkTreeView *view; - GtkListStore *store; - GtkTreeSelection *selection; - - /* View */ - view = GTK_TREE_VIEW (window->treeview); - - g_signal_connect (view, "row-activated", - G_CALLBACK (chatrooms_window_row_activated_cb), - window); - - /* Store */ - store = gtk_list_store_new (COL_COUNT, - G_TYPE_STRING, /* Image */ - G_TYPE_STRING, /* Name */ - G_TYPE_STRING, /* Room */ - G_TYPE_BOOLEAN, /* Auto start */ - EMPATHY_TYPE_CHATROOM); /* Chatroom */ - - gtk_tree_view_set_model (view, GTK_TREE_MODEL (store)); - - /* Selection */ - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - /* Columns */ - chatrooms_window_model_add_columns (window); - - /* Add data */ - chatrooms_window_model_refresh_data (window, TRUE); - - /* Clean up */ - g_object_unref (store); -} - -static void -chatrooms_window_model_add_columns (EmpathyChatroomsWindow *window) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - gint count; - - view = GTK_TREE_VIEW (window->treeview); - model = gtk_tree_view_get_model (view); - - gtk_tree_view_set_headers_visible (view, TRUE); - gtk_tree_view_set_headers_clickable (view, TRUE); - - /* Name & Status */ - column = gtk_tree_view_column_new (); - count = gtk_tree_view_append_column (view, column); - - gtk_tree_view_column_set_title (column, _("Name")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_column_set_sort_column_id (column, count - 1); - - cell = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - gtk_tree_view_column_add_attribute (column, cell, "icon-name", COL_IMAGE); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "xpad", 4, - "ypad", 1, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); - - /* Room */ - cell = gtk_cell_renderer_text_new (); - 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); - window->room_column = count - 1; - - /* Chatroom auto connect */ - cell = gtk_cell_renderer_toggle_new (); - column = gtk_tree_view_column_new_with_attributes (_("Auto-Connect"), cell, - "active", COL_AUTO_CONNECT, - NULL); - count = gtk_tree_view_append_column (view, column); - gtk_tree_view_column_set_sort_column_id (column, count - 1); - - g_signal_connect (cell, "toggled", - G_CALLBACK (chatrooms_window_model_cell_auto_connect_toggled), - window); - - /* Sort model */ - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0, - GTK_SORT_ASCENDING); -} - -static void -chatrooms_window_model_refresh_data (EmpathyChatroomsWindow *window, - gboolean first_time) -{ - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkListStore *store; - GtkTreeIter iter; - GtkTreeViewColumn *column; - EmpathyAccountChooser *account_chooser; - McAccount *account; - GList *chatrooms, *l; - - view = GTK_TREE_VIEW (window->treeview); - selection = gtk_tree_view_get_selection (view); - model = gtk_tree_view_get_model (view); - store = GTK_LIST_STORE (model); - - /* Look up chatrooms */ - account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser); - account = empathy_account_chooser_get_account (account_chooser); - - 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. - */ - if (account) { - column = gtk_tree_view_get_column (view, window->room_column); - gtk_tree_view_column_set_visible (column, TRUE); - } else { - column = gtk_tree_view_get_column (view, window->room_column); - gtk_tree_view_column_set_visible (column, FALSE); - } - - /* Clean out the store */ - gtk_list_store_clear (store); - - /* Populate with chatroom list. */ - for (l = chatrooms; l; l = l->next) { - chatrooms_window_model_add (window, l->data, FALSE); - } - - if (gtk_tree_model_get_iter_first (model, &iter)) { - gtk_tree_selection_select_iter (selection, &iter); - } - - if (account) { - g_object_unref (account); - } - - g_list_free (chatrooms); -} - -static void -chatrooms_window_model_add (EmpathyChatroomsWindow *window, - EmpathyChatroom *chatroom, - gboolean set_active) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkListStore *store; - GtkTreeIter iter; - - view = GTK_TREE_VIEW (window->treeview); - selection = gtk_tree_view_get_selection (view); - model = gtk_tree_view_get_model (view); - store = GTK_LIST_STORE (model); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COL_NAME, empathy_chatroom_get_name (chatroom), - COL_ROOM, empathy_chatroom_get_room (chatroom), - COL_AUTO_CONNECT, empathy_chatroom_get_auto_connect (chatroom), - COL_POINTER, chatroom, - -1); - - if (set_active) { - gtk_tree_selection_select_iter (selection, &iter); - } -} - -static void -chatrooms_window_model_cell_auto_connect_toggled (GtkCellRendererToggle *cell, - gchar *path_string, - EmpathyChatroomsWindow *window) -{ - EmpathyChatroom *chatroom; - gboolean enabled; - GtkTreeView *view; - GtkTreeModel *model; - GtkListStore *store; - GtkTreePath *path; - GtkTreeIter iter; - - view = GTK_TREE_VIEW (window->treeview); - model = gtk_tree_view_get_model (view); - store = GTK_LIST_STORE (model); - - path = gtk_tree_path_new_from_string (path_string); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, - COL_AUTO_CONNECT, &enabled, - COL_POINTER, &chatroom, - -1); - - enabled = !enabled; - - empathy_chatroom_set_auto_connect (chatroom, enabled); - - gtk_list_store_set (store, &iter, COL_AUTO_CONNECT, enabled, -1); - gtk_tree_path_free (path); - g_object_unref (chatroom); -} - -static EmpathyChatroom * -chatrooms_window_model_get_selected (EmpathyChatroomsWindow *window) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - EmpathyChatroom *chatroom = NULL; - - view = GTK_TREE_VIEW (window->treeview); - selection = gtk_tree_view_get_selection (view); - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1); - } - - return chatroom; -} - -static void -chatrooms_window_model_action_selected (EmpathyChatroomsWindow *window) -{ - EmpathyChatroom *chatroom; - GtkTreeView *view; - GtkTreeModel *model; - - view = GTK_TREE_VIEW (window->treeview); - model = gtk_tree_view_get_model (view); - - chatroom = chatrooms_window_model_get_selected (window); - if (!chatroom) { - return; - } - - //empathy_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom); - - g_object_unref (chatroom); -} - -static void -chatrooms_window_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - EmpathyChatroomsWindow *window) -{ - if (GTK_WIDGET_IS_SENSITIVE (window->button_edit)) { - chatrooms_window_model_action_selected (window); - } -} - -static void -chatrooms_window_button_remove_clicked_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window) -{ - EmpathyChatroom *chatroom; - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - - /* Remove from treeview */ - view = GTK_TREE_VIEW (window->treeview); - selection = gtk_tree_view_get_selection (view); - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return; - } - - gtk_tree_model_get (model, &iter, COL_POINTER, &chatroom, -1); - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - - /* Remove from config */ - empathy_chatroom_manager_remove (window->manager, chatroom); - - g_object_unref (chatroom); -} - -static void -chatrooms_window_button_edit_clicked_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window) -{ - EmpathyChatroom *chatroom; - - chatroom = chatrooms_window_model_get_selected (window); - if (!chatroom) { - return; - } - - //empathy_edit_chatroom_dialog_show (GTK_WINDOW (window->window), chatroom); - - g_object_unref (chatroom); -} - -static void -chatrooms_window_button_close_clicked_cb (GtkWidget *widget, - EmpathyChatroomsWindow *window) -{ - gtk_widget_destroy (window->window); -} - -static void -chatrooms_window_chatroom_added_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyChatroomsWindow *window) -{ - EmpathyAccountChooser *account_chooser; - McAccount *account; - - account_chooser = EMPATHY_ACCOUNT_CHOOSER (window->account_chooser); - account = empathy_account_chooser_get_account (account_chooser); - - if (!account) { - chatrooms_window_model_add (window, chatroom, FALSE); - } else { - if (empathy_account_equal (account, empathy_chatroom_get_account (chatroom))) { - chatrooms_window_model_add (window, chatroom, FALSE); - } - - g_object_unref (account); - } -} - -static void -chatrooms_window_chatroom_removed_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyChatroomsWindow *window) -{ - GtkTreeModel *model; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (window->treeview)); - - gtk_tree_model_foreach (model, - (GtkTreeModelForeachFunc) chatrooms_window_remove_chatroom_foreach, - chatroom); -} - -static gboolean -chatrooms_window_remove_chatroom_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - EmpathyChatroom *chatroom) -{ - EmpathyChatroom *this_chatroom; - - gtk_tree_model_get (model, iter, COL_POINTER, &this_chatroom, -1); - - if (empathy_chatroom_equal (chatroom, this_chatroom)) { - gtk_list_store_remove (GTK_LIST_STORE (model), iter); - g_object_unref (this_chatroom); - return TRUE; - } - - g_object_unref (this_chatroom); - - return FALSE; -} - -static void -chatrooms_window_account_changed_cb (GtkWidget *combo_box, - EmpathyChatroomsWindow *window) -{ - chatrooms_window_model_refresh_data (window, FALSE); -} - diff --git a/src/empathy-chatrooms-window.glade b/src/empathy-chatrooms-window.glade deleted file mode 100644 index ccccc81b0..000000000 --- a/src/empathy-chatrooms-window.glade +++ /dev/null @@ -1,307 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkDialog" id="edit_chatroom_dialog"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="title" translatable="yes">Edit Favorite Room</property> - <property name="resizable">False</property> - <property name="role">chatrooms</property> - <property name="icon_name">gtk-edit</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox3"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkTable" id="table4"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="n_rows">5</property> - <property name="n_columns">2</property> - <property name="column_spacing">12</property> - <property name="row_spacing">6</property> - <child> - <placeholder/> - </child> - <child> - <widget class="GtkCheckButton" id="checkbutton_auto_connect"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Join this chat room when Empathy starts and you are connected</property> - <property name="label" translatable="yes">Join room on start_up</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="entry_name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="width_chars">25</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_name"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">N_ame:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_name</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_nickname"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Nickname:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_nickname</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_server"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">S_erver:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_server</property> - </widget> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_room"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Room:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_room</property> - </widget> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="entry_nickname"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="entry_server"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="entry_room"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area3"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="button_cancel"> - <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="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="button_save"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-save</property> - <property name="use_stock">True</property> - <property name="response_id">-5</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="chatrooms_window"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="title" translatable="yes">Manage Favorite Rooms</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <child> - <widget class="GtkVBox" id="vbox12"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <widget class="GtkVBox" id="vbox18"> - <property name="visible">True</property> - <property name="spacing">18</property> - <child> - <widget class="GtkHBox" id="hbox_account"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <widget class="GtkLabel" id="label_account"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Account:</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="height_request">150</property> - <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> - <child> - <widget class="GtkTreeView" id="treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkHButtonBox" id="hbuttonbox3"> - <property name="visible">True</property> - <property name="spacing">6</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="button_remove"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-remove</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="button_edit"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-edit</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="button_close"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-chatrooms-window.h b/src/empathy-chatrooms-window.h deleted file mode 100644 index 727188f01..000000000 --- a/src/empathy-chatrooms-window.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2004-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - * Martyn Russell <martyn@imendio.com> - * Mikael Hallendal <micke@imendio.com> - */ - -#ifndef __EMPATHY_CHATROOMS_WINDOW_H__ -#define __EMPATHY_CHATROOMS_WINDOW_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -void empathy_chatrooms_window_show (GtkWindow *parent); - -G_END_DECLS - -#endif /* __EMPATHY_CHATROOMS_WINDOW_H__ */ diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c deleted file mode 100644 index adb5e73f9..000000000 --- a/src/empathy-event-manager.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* - * Copyright (C) 2007-2008 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - * Sjoerd Simons <sjoerd.simons@collabora.co.uk> - */ - -#include <config.h> - -#include <string.h> -#include <glib/gi18n.h> - -#include <telepathy-glib/util.h> - -#include <libempathy/empathy-dispatcher.h> -#include <libempathy/empathy-contact-factory.h> -#include <libempathy/empathy-contact-manager.h> -#include <libempathy/empathy-tp-chat.h> -#include <libempathy/empathy-tp-call.h> -#include <libempathy/empathy-utils.h> -#include <libempathy/empathy-call-factory.h> - -#include <extensions/extensions.h> - -#include <libempathy-gtk/empathy-images.h> -#include <libempathy-gtk/empathy-contact-dialogs.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-event-manager.h" -#include "empathy-main-window.h" -#include "empathy-tube-dispatch.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER -#include <libempathy/empathy-debug.h> - -#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyEventManager) - -typedef struct { - EmpathyEventManager *manager; - EmpathyDispatchOperation *operation; - gulong approved_handler; - gulong claimed_handler; - gulong invalidated_handler; - /* Remove contact if applicable */ - EmpathyContact *contact; - /* Tube dispatcher if applicable */ - EmpathyTubeDispatch *tube_dispatch; - /* option signal handler and it's instance */ - gulong handler; - GObject *handler_instance; - /* optional accept widget */ - GtkWidget *dialog; -} EventManagerApproval; - -typedef struct { - EmpathyDispatcher *dispatcher; - EmpathyContactManager *contact_manager; - GSList *events; - /* Ongoing approvals */ - GSList *approvals; - - /* voip ringing sound */ - guint voip_timeout; - gint ringing; -} EmpathyEventManagerPriv; - -typedef struct _EventPriv EventPriv; -typedef void (*EventFunc) (EventPriv *event); - -struct _EventPriv { - EmpathyEvent public; - EmpathyEventManager *manager; - EventManagerApproval *approval; - EventFunc func; - gboolean inhibit; - gpointer user_data; -}; - -enum { - EVENT_ADDED, - EVENT_REMOVED, - EVENT_UPDATED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE (EmpathyEventManager, empathy_event_manager, G_TYPE_OBJECT); - -static EmpathyEventManager * manager_singleton = NULL; - -static EventManagerApproval * -event_manager_approval_new (EmpathyEventManager *manager, - EmpathyDispatchOperation *operation) -{ - EventManagerApproval *result = g_slice_new0 (EventManagerApproval); - result->operation = g_object_ref (operation); - result->manager = manager; - - return result; -} - -static void -event_manager_approval_free (EventManagerApproval *approval) -{ - g_signal_handler_disconnect (approval->operation, - approval->approved_handler); - g_signal_handler_disconnect (approval->operation, - approval->claimed_handler); - g_signal_handler_disconnect (approval->operation, - approval->invalidated_handler); - g_object_unref (approval->operation); - - if (approval->handler != 0) - g_signal_handler_disconnect (approval->handler_instance, - approval->handler); - - if (approval->contact != NULL) - g_object_unref (approval->contact); - - if (approval->tube_dispatch != NULL) - g_object_unref (approval->tube_dispatch); - - if (approval->dialog != NULL) - { - gtk_widget_destroy (approval->dialog); - } - - g_slice_free (EventManagerApproval, approval); -} - -static void event_remove (EventPriv *event); - -static void -event_free (EventPriv *event) -{ - g_free (event->public.icon_name); - g_free (event->public.header); - g_free (event->public.message); - - if (event->public.contact) - { - g_object_unref (event->public.contact); - } - - g_slice_free (EventPriv, event); -} - -static void event_manager_ringing_finished_cb (ca_context *c, guint id, - int error_code, gpointer user_data); - -static gboolean -event_manager_ringing_timeout_cb (gpointer data) -{ - EmpathyEventManager *manager = EMPATHY_EVENT_MANAGER (data); - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - priv->voip_timeout = 0; - - empathy_sound_play_full (empathy_main_window_get (), - EMPATHY_SOUND_PHONE_INCOMING, event_manager_ringing_finished_cb, - manager); - - return FALSE; -} - -static gboolean -event_manager_ringing_idle_cb (gpointer data) -{ - EmpathyEventManager *manager = EMPATHY_EVENT_MANAGER (data); - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - if (priv->ringing > 0) - priv->voip_timeout = g_timeout_add (500, event_manager_ringing_timeout_cb, - data); - - return FALSE; -} - -static void -event_manager_ringing_finished_cb (ca_context *c, guint id, int error_code, - gpointer user_data) -{ - if (error_code == CA_ERROR_CANCELED) - return; - - g_idle_add (event_manager_ringing_idle_cb, user_data); -} - -static void -event_manager_start_ringing (EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - priv->ringing++; - - if (priv->ringing == 1) - { - empathy_sound_play_full (empathy_main_window_get (), - EMPATHY_SOUND_PHONE_INCOMING, event_manager_ringing_finished_cb, - manager); - } -} - -static void -event_manager_stop_ringing (EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - priv->ringing--; - - if (priv->ringing > 0) - return; - - empathy_sound_stop (EMPATHY_SOUND_PHONE_INCOMING); - - if (priv->voip_timeout != 0) - { - g_source_remove (priv->voip_timeout); - priv->voip_timeout = 0; - } -} - -static void -event_remove (EventPriv *event) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (event->manager); - - DEBUG ("Removing event %p", event); - priv->events = g_slist_remove (priv->events, event); - g_signal_emit (event->manager, signals[EVENT_REMOVED], 0, event); - event_free (event); -} - -static void -event_manager_add (EmpathyEventManager *manager, EmpathyContact *contact, - const gchar *icon_name, const gchar *header, const gchar *message, - EventManagerApproval *approval, EventFunc func, gpointer user_data) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - EventPriv *event; - - event = g_slice_new0 (EventPriv); - event->public.contact = contact ? g_object_ref (contact) : NULL; - event->public.icon_name = g_strdup (icon_name); - event->public.header = g_strdup (header); - event->public.message = g_strdup (message); - event->inhibit = FALSE; - event->func = func; - event->user_data = user_data; - event->manager = manager; - event->approval = approval; - - DEBUG ("Adding event %p", event); - priv->events = g_slist_prepend (priv->events, event); - g_signal_emit (event->manager, signals[EVENT_ADDED], 0, event); -} - -static void -event_channel_process_func (EventPriv *event) -{ - empathy_dispatch_operation_approve (event->approval->operation); -} - -static void -event_text_channel_process_func (EventPriv *event) -{ - EmpathyTpChat *tp_chat; - - if (event->approval->handler != 0) - { - tp_chat = EMPATHY_TP_CHAT - (empathy_dispatch_operation_get_channel_wrapper (event->approval->operation)); - - g_signal_handler_disconnect (tp_chat, event->approval->handler); - event->approval->handler = 0; - } - - empathy_dispatch_operation_approve (event->approval->operation); -} - -static EventPriv * -event_lookup_by_approval (EmpathyEventManager *manager, - EventManagerApproval *approval) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - GSList *l; - EventPriv *retval = NULL; - - for (l = priv->events; l; l = l->next) - { - EventPriv *event = l->data; - - if (event->approval == approval) - { - retval = event; - break; - } - } - - return retval; -} - -static void -event_update (EmpathyEventManager *manager, EventPriv *event, - const char *icon_name, const char *header, const char *msg) -{ - g_free (event->public.icon_name); - g_free (event->public.header); - g_free (event->public.message); - - event->public.icon_name = g_strdup (icon_name); - event->public.header = g_strdup (header); - event->public.message = g_strdup (msg); - - g_signal_emit (manager, signals[EVENT_UPDATED], 0, event); -} - -static void -event_manager_call_window_confirmation_dialog_response_cb (GtkDialog *dialog, - gint response, gpointer user_data) -{ - EventManagerApproval *approval = user_data; - - gtk_widget_destroy (approval->dialog); - approval->dialog = NULL; - - if (response != GTK_RESPONSE_ACCEPT) - { - EmpathyTpCall *call = - EMPATHY_TP_CALL ( - empathy_dispatch_operation_get_channel_wrapper ( - approval->operation)); - - g_object_ref (call); - if (empathy_dispatch_operation_claim (approval->operation)) - empathy_tp_call_close (call); - g_object_unref (call); - - } - else - { - EmpathyCallFactory *factory = empathy_call_factory_get (); - empathy_call_factory_claim_channel (factory, approval->operation); - } -} - -static void -event_channel_process_voip_func (EventPriv *event) -{ - GtkWidget *dialog; - GtkWidget *button; - GtkWidget *image; - - if (event->approval->dialog != NULL) - { - gtk_window_present (GTK_WINDOW (event->approval->dialog)); - return; - } - - dialog = gtk_message_dialog_new (GTK_WINDOW (empathy_main_window_get()), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("Incoming call")); - gtk_message_dialog_format_secondary_text ( - GTK_MESSAGE_DIALOG (dialog), - _("%s is calling you, do you want to answer?"), - empathy_contact_get_name (event->approval->contact)); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), - GTK_RESPONSE_OK); - - button = gtk_dialog_add_button (GTK_DIALOG (dialog), - _("_Reject"), GTK_RESPONSE_REJECT); - image = gtk_image_new_from_icon_name (GTK_STOCK_CANCEL, - GTK_ICON_SIZE_BUTTON); - gtk_button_set_image (GTK_BUTTON (button), image); - - button = gtk_dialog_add_button (GTK_DIALOG (dialog), - _("_Answer"), GTK_RESPONSE_ACCEPT); - - image = gtk_image_new_from_icon_name (GTK_STOCK_APPLY, GTK_ICON_SIZE_BUTTON); - gtk_button_set_image (GTK_BUTTON (button), image); - - g_signal_connect (dialog, "response", - G_CALLBACK (event_manager_call_window_confirmation_dialog_response_cb), - event->approval); - - gtk_widget_show (dialog); - - event->approval->dialog = dialog; -} - -static void -event_manager_chat_message_received_cb (EmpathyTpChat *tp_chat, - EmpathyMessage *message, EventManagerApproval *approval) -{ - EmpathyContact *sender; - gchar *header; - const gchar *msg; - TpChannel *channel; - EventPriv *event; - - /* try to update the event if it's referring to a chat which is already in the - * queue. */ - event = event_lookup_by_approval (approval->manager, approval); - - if (event != NULL && event->inhibit && approval->handler != 0) - { - g_signal_handler_disconnect (tp_chat, approval->handler); - approval->handler = 0; - return; - } - - sender = empathy_message_get_sender (message); - header = g_strdup_printf (_("New message from %s"), - empathy_contact_get_name (sender)); - msg = empathy_message_get_body (message); - - channel = empathy_tp_chat_get_channel (tp_chat); - - if (event != NULL) - event_update (approval->manager, event, EMPATHY_IMAGE_NEW_MESSAGE, header, msg); - else - event_manager_add (approval->manager, sender, EMPATHY_IMAGE_NEW_MESSAGE, header, - msg, approval, event_text_channel_process_func, NULL); - - g_free (header); - empathy_sound_play (empathy_main_window_get (), - EMPATHY_SOUND_CONVERSATION_NEW); -} - -static void -event_manager_approval_done (EventManagerApproval *approval) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); - GSList *l; - - if (approval->operation != NULL) - { - GQuark channel_type; - - channel_type = empathy_dispatch_operation_get_channel_type_id ( - approval->operation); - if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) - { - event_manager_stop_ringing (approval->manager); - } - } - - priv->approvals = g_slist_remove (priv->approvals, approval); - - for (l = priv->events; l; l = l->next) - { - EventPriv *event = l->data; - - if (event->approval == approval) - { - event_remove (event); - break; - } - } - - event_manager_approval_free (approval); -} - -static void -event_manager_operation_approved_cb (EmpathyDispatchOperation *operation, - EventManagerApproval *approval) -{ - event_manager_approval_done (approval); -} - -static void -event_manager_operation_claimed_cb (EmpathyDispatchOperation *operation, - EventManagerApproval *approval) -{ - event_manager_approval_done (approval); -} - -static void -event_manager_operation_invalidated_cb (EmpathyDispatchOperation *operation, - guint domain, gint code, gchar *message, - EventManagerApproval *approval) -{ - event_manager_approval_done (approval); -} - -static void -event_manager_media_channel_got_name_cb (EmpathyContact *contact, - const GError *error, gpointer user_data, GObject *object) -{ - EventManagerApproval *approval = user_data; - gchar *header; - - if (error != NULL) - { - /* FIXME just returning assuming the operation will be invalidated as - * well */ - return; - } - - header = g_strdup_printf (_("Incoming call from %s"), - empathy_contact_get_name (contact)); - - event_manager_add (approval->manager, - approval->contact, EMPATHY_IMAGE_VOIP, header, NULL, - approval, event_channel_process_voip_func, NULL); - - g_free (header); - event_manager_start_ringing (approval->manager); -} - -static void -event_manager_media_channel_got_contact (EventManagerApproval *approval) -{ - empathy_contact_call_when_ready (approval->contact, - EMPATHY_CONTACT_READY_NAME, event_manager_media_channel_got_name_cb, - approval, NULL, G_OBJECT (approval->manager)); -} - -static void -event_manager_media_channel_contact_changed_cb (EmpathyTpCall *call, - GParamSpec *param, EventManagerApproval *approval) -{ - EmpathyContact *contact; - - g_object_get (G_OBJECT (call), "contact", &contact, NULL); - - if (contact == NULL) - return; - - approval->contact = contact; - event_manager_media_channel_got_contact (approval); -} - -static void -event_manager_tube_approved_cb (EventPriv *event) -{ - empathy_tube_dispatch_handle (event->approval->tube_dispatch); -} - -static void -event_manager_add_tube_approval (EventManagerApproval *approval, - EmpathyTubeDispatchAbility ability) -{ - const gchar *icon_name; - gchar *header; - const gchar *msg; - - header = g_strdup_printf (_("%s is offering you an invitation"), - empathy_contact_get_name (approval->contact)); - - if (ability == EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE) - { - icon_name = GTK_STOCK_EXECUTE; - msg = _("An external application will be started to handle it."); - } - else - { - icon_name = GTK_STOCK_DIALOG_ERROR; - msg = _("You don't have the needed external " - "application to handle it."); - } - - event_manager_add (approval->manager, approval->contact, icon_name, header, - msg, approval, event_manager_tube_approved_cb, approval); - - g_free (header); - /* FIXME better sound for incoming tubes ? */ - empathy_sound_play (empathy_main_window_get (), - EMPATHY_SOUND_CONVERSATION_NEW); -} - -static void -event_manager_tube_dispatch_ability_cb (GObject *object, - GParamSpec *spec, gpointer user_data) -{ - EventManagerApproval *approval = (EventManagerApproval *)user_data; - EmpathyTubeDispatchAbility dispatchability; - - dispatchability = - empathy_tube_dispatch_is_dispatchable (approval->tube_dispatch); - - if (dispatchability != EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN) - { - event_manager_add_tube_approval (approval, dispatchability); - g_signal_handler_disconnect (object, approval->handler); - approval->handler = 0; - } -} - -static void -event_manager_tube_got_contact_name_cb (EmpathyContact *contact, - const GError *error, gpointer user_data, GObject *object) -{ - EventManagerApproval *approval = (EventManagerApproval *)user_data; - EmpathyTubeDispatchAbility dispatchability; - - if (error != NULL) - { - /* FIXME?, we assume that the operation gets invalidated as well (if it - * didn't already */ - return; - } - - dispatchability = empathy_tube_dispatch_is_dispatchable - (approval->tube_dispatch); - - - switch (dispatchability) - { - case EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN: - approval->handler = g_signal_connect (approval->tube_dispatch, - "notify::dispatchability", - G_CALLBACK (event_manager_tube_dispatch_ability_cb), approval); - approval->handler_instance = G_OBJECT (approval->tube_dispatch); - break; - case EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE: - /* fallthrough */ - case EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE: - event_manager_add_tube_approval (approval, dispatchability); - break; - } -} - -static void -invite_dialog_response_cb (GtkDialog *dialog, - gint response, - EventManagerApproval *approval) -{ - EmpathyTpChat *tp_chat; - TpChannel *channel; - TpHandle self_handle; - GArray *members; - - gtk_widget_destroy (GTK_WIDGET (approval->dialog)); - approval->dialog = NULL; - - tp_chat = EMPATHY_TP_CHAT (empathy_dispatch_operation_get_channel_wrapper ( - approval->operation)); - - if (response != GTK_RESPONSE_OK) - { - /* close channel */ - DEBUG ("Muc invitation rejected"); - - if (empathy_dispatch_operation_claim (approval->operation)) - empathy_tp_chat_close (tp_chat); - return; - } - - DEBUG ("Muc invitation accepted"); - - /* join the room */ - channel = empathy_tp_chat_get_channel (tp_chat); - - self_handle = tp_channel_group_get_self_handle (channel); - members = g_array_sized_new (FALSE, FALSE, sizeof (TpHandle), 1); - g_array_append_val (members, self_handle); - - tp_cli_channel_interface_group_call_add_members (channel, -1, members, - "", NULL, NULL, NULL, NULL); - - empathy_dispatch_operation_approve (approval->operation); - - g_array_free (members, TRUE); -} - -static void -event_room_channel_process_func (EventPriv *event) -{ - GtkWidget *dialog, *button, *image; - TpChannel *channel = empathy_dispatch_operation_get_channel ( - event->approval->operation); - - if (event->approval->dialog != NULL) - { - gtk_window_present (GTK_WINDOW (event->approval->dialog)); - return; - } - - /* create dialog */ - dialog = gtk_message_dialog_new (NULL, 0, - GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("Room invitation")); - - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - _("%s is inviting you to join %s"), - empathy_contact_get_name (event->approval->contact), - tp_channel_get_identifier (channel)); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), - GTK_RESPONSE_OK); - - button = gtk_dialog_add_button (GTK_DIALOG (dialog), - _("_Decline"), GTK_RESPONSE_CANCEL); - image = gtk_image_new_from_icon_name (GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON); - gtk_button_set_image (GTK_BUTTON (button), image); - - button = gtk_dialog_add_button (GTK_DIALOG (dialog), - _("_Join"), GTK_RESPONSE_OK); - image = gtk_image_new_from_icon_name (GTK_STOCK_APPLY, GTK_ICON_SIZE_BUTTON); - gtk_button_set_image (GTK_BUTTON (button), image); - - g_signal_connect (dialog, "response", - G_CALLBACK (invite_dialog_response_cb), event->approval); - - gtk_widget_show (dialog); - - event->approval->dialog = dialog; -} - -static void -event_manager_muc_invite_got_contact_name_cb (EmpathyContact *contact, - const GError *error, - gpointer user_data, - GObject *object) -{ - EventManagerApproval *approval = (EventManagerApproval *) user_data; - TpChannel *channel; - const gchar *invite_msg; - gchar *msg; - TpHandle self_handle; - - channel = empathy_dispatch_operation_get_channel (approval->operation); - - self_handle = tp_channel_group_get_self_handle (channel); - tp_channel_group_get_local_pending_info (channel, self_handle, NULL, NULL, - &invite_msg); - - msg = g_strdup_printf (_("%s invited you to join %s"), - empathy_contact_get_name (approval->contact), - tp_channel_get_identifier (channel)); - - event_manager_add (approval->manager, - approval->contact, EMPATHY_IMAGE_GROUP_MESSAGE, msg, invite_msg, - approval, event_room_channel_process_func, NULL); - - empathy_sound_play (empathy_main_window_get (), - EMPATHY_SOUND_CONVERSATION_NEW); - - g_free (msg); -} - -static void -event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher, - EmpathyDispatchOperation *operation, EmpathyEventManager *manager) -{ - const gchar *channel_type; - EventManagerApproval *approval; - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - channel_type = empathy_dispatch_operation_get_channel_type (operation); - - approval = event_manager_approval_new (manager, operation); - priv->approvals = g_slist_prepend (priv->approvals, approval); - - approval->approved_handler = g_signal_connect (operation, "approved", - G_CALLBACK (event_manager_operation_approved_cb), approval); - - approval->claimed_handler = g_signal_connect (operation, "claimed", - G_CALLBACK (event_manager_operation_claimed_cb), approval); - - approval->invalidated_handler = g_signal_connect (operation, "invalidated", - G_CALLBACK (event_manager_operation_invalidated_cb), approval); - - if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TEXT)) - { - EmpathyTpChat *tp_chat = - EMPATHY_TP_CHAT ( - empathy_dispatch_operation_get_channel_wrapper (operation)); - TpChannel *channel = empathy_tp_chat_get_channel (tp_chat); - - if (tp_proxy_has_interface (channel, TP_IFACE_CHANNEL_INTERFACE_GROUP)) - { - /* Are we in local-pending ? */ - TpHandle self_handle, inviter; - - self_handle = tp_channel_group_get_self_handle (channel); - - if (self_handle != 0 && tp_channel_group_get_local_pending_info ( - channel, self_handle, &inviter, NULL, NULL)) - { - /* We are invited to a room */ - EmpathyContactFactory *contact_factory; - McAccount *account; - - DEBUG ("Have been invited to %s. Ask user if he wants to accept", - tp_channel_get_identifier (channel)); - - account = empathy_tp_chat_get_account (tp_chat); - contact_factory = empathy_contact_factory_dup_singleton (); - - approval->contact = empathy_contact_factory_get_from_handle ( - contact_factory, account, inviter); - - empathy_contact_call_when_ready (approval->contact, - EMPATHY_CONTACT_READY_NAME, - event_manager_muc_invite_got_contact_name_cb, approval, NULL, - G_OBJECT (manager)); - - g_object_unref (contact_factory); - return; - } - - /* if we are not invited, let's wait for the first message */ - } - - /* 1-1 text channel, wait for the first message */ - approval->handler = g_signal_connect (tp_chat, "message-received", - G_CALLBACK (event_manager_chat_message_received_cb), approval); - approval->handler_instance = G_OBJECT (tp_chat); - } - else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA)) - { - EmpathyContact *contact; - EmpathyTpCall *call = EMPATHY_TP_CALL ( - empathy_dispatch_operation_get_channel_wrapper (operation)); - - g_object_get (G_OBJECT (call), "contact", &contact, NULL); - - if (contact == NULL) - { - g_signal_connect (call, "notify::contact", - G_CALLBACK (event_manager_media_channel_contact_changed_cb), - approval); - } - else - { - approval->contact = contact; - event_manager_media_channel_got_contact (approval); - } - - } - else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER)) - { - EmpathyContact *contact; - gchar *header; - TpHandle handle; - McAccount *account; - EmpathyContactFactory *factory; - TpChannel *channel = empathy_dispatch_operation_get_channel (operation); - - factory = empathy_contact_factory_dup_singleton (); - handle = tp_channel_get_handle (channel, NULL); - account = empathy_channel_get_account (channel); - - contact = empathy_contact_factory_get_from_handle (factory, account, - handle); - - empathy_contact_run_until_ready (contact, - EMPATHY_CONTACT_READY_NAME, NULL); - - header = g_strdup_printf (_("Incoming file transfer from %s"), - empathy_contact_get_name (contact)); - - event_manager_add (manager, 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_object_unref (factory); - g_object_unref (account); - g_free (header); - } - else if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE) || - !tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) - { - EmpathyContact *contact; - TpHandle handle; - TpHandleType handle_type; - McAccount *account; - EmpathyContactFactory *factory; - EmpathyTubeDispatch *tube_dispatch; - TpChannel *channel; - - channel = empathy_dispatch_operation_get_channel (operation); - - handle = tp_channel_get_handle (channel, &handle_type); - - /* Only understand p2p tubes */ - if (handle_type != TP_HANDLE_TYPE_CONTACT) - return; - - factory = empathy_contact_factory_dup_singleton (); - account = empathy_channel_get_account (channel); - - contact = empathy_contact_factory_get_from_handle (factory, account, - handle); - - tube_dispatch = empathy_tube_dispatch_new (operation); - - approval->contact = contact; - approval->tube_dispatch = tube_dispatch; - - empathy_contact_call_when_ready (contact, - EMPATHY_CONTACT_READY_NAME, event_manager_tube_got_contact_name_cb, - approval, NULL, G_OBJECT (manager)); - - g_object_unref (factory); - g_object_unref (account); - } - else - { - DEBUG ("Unknown channel type, ignoring.."); - } -} - -static void -event_pending_subscribe_func (EventPriv *event) -{ - empathy_subscription_dialog_show (event->public.contact, NULL); - event_remove (event); -} - -static void -event_manager_pendings_changed_cb (EmpathyContactList *list, - EmpathyContact *contact, EmpathyContact *actor, - guint reason, gchar *message, gboolean is_pending, - EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - gchar *header, *event_msg; - - if (!is_pending) - { - GSList *l; - - for (l = priv->events; l; l = l->next) - { - EventPriv *event = l->data; - - if (event->public.contact == contact && - event->func == event_pending_subscribe_func) - { - event_remove (event); - break; - } - } - - return; - } - - empathy_contact_run_until_ready (contact, EMPATHY_CONTACT_READY_NAME, NULL); - - header = g_strdup_printf (_("Subscription requested by %s"), - empathy_contact_get_name (contact)); - - if (!EMP_STR_EMPTY (message)) - event_msg = g_strdup_printf (_("\nMessage: %s"), message); - else - event_msg = NULL; - - event_manager_add (manager, contact, GTK_STOCK_DIALOG_QUESTION, header, - event_msg, NULL, event_pending_subscribe_func, NULL); - - g_free (event_msg); - g_free (header); -} - -static GObject * -event_manager_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *retval; - - if (manager_singleton) { - retval = g_object_ref (manager_singleton); - } else { - retval = G_OBJECT_CLASS (empathy_event_manager_parent_class)->constructor - (type, n_props, props); - - manager_singleton = EMPATHY_EVENT_MANAGER (retval); - g_object_add_weak_pointer (retval, (gpointer) &manager_singleton); - } - - return retval; -} - -static void -event_manager_finalize (GObject *object) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (object); - - g_slist_foreach (priv->events, (GFunc) event_free, NULL); - g_slist_free (priv->events); - g_slist_foreach (priv->approvals, (GFunc) event_manager_approval_free, NULL); - g_slist_free (priv->approvals); - g_object_unref (priv->contact_manager); - g_object_unref (priv->dispatcher); -} - -static void -empathy_event_manager_class_init (EmpathyEventManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = event_manager_finalize; - object_class->constructor = event_manager_constructor; - - signals[EVENT_ADDED] = - g_signal_new ("event-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, G_TYPE_POINTER); - - signals[EVENT_REMOVED] = - g_signal_new ("event-removed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - signals[EVENT_UPDATED] = - g_signal_new ("event-updated", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - - g_type_class_add_private (object_class, sizeof (EmpathyEventManagerPriv)); -} - -static void -empathy_event_manager_init (EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, - EMPATHY_TYPE_EVENT_MANAGER, EmpathyEventManagerPriv); - - manager->priv = priv; - - priv->dispatcher = empathy_dispatcher_dup_singleton (); - priv->contact_manager = empathy_contact_manager_dup_singleton (); - g_signal_connect (priv->dispatcher, "approve", - G_CALLBACK (event_manager_approve_channel_cb), manager); - g_signal_connect (priv->contact_manager, "pendings-changed", - G_CALLBACK (event_manager_pendings_changed_cb), manager); -} - -EmpathyEventManager * -empathy_event_manager_dup_singleton (void) -{ - return g_object_new (EMPATHY_TYPE_EVENT_MANAGER, NULL); -} - -GSList * -empathy_event_manager_get_events (EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - g_return_val_if_fail (EMPATHY_IS_EVENT_MANAGER (manager), NULL); - - return priv->events; -} - -EmpathyEvent * -empathy_event_manager_get_top_event (EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - g_return_val_if_fail (EMPATHY_IS_EVENT_MANAGER (manager), NULL); - - return priv->events ? priv->events->data : NULL; -} - -void -empathy_event_activate (EmpathyEvent *event_public) -{ - EventPriv *event = (EventPriv*) event_public; - - g_return_if_fail (event_public != NULL); - - if (event->func) - event->func (event); - else - event_remove (event); -} - -void -empathy_event_inhibit_updates (EmpathyEvent *event_public) -{ - EventPriv *event = (EventPriv *) event_public; - - g_return_if_fail (event_public != NULL); - - event->inhibit = TRUE; -} - diff --git a/src/empathy-event-manager.h b/src/empathy-event-manager.h deleted file mode 100644 index 42fd0c090..000000000 --- a/src/empathy-event-manager.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2007-2008 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - */ - -#ifndef __EMPATHY_EVENT_MANAGER_H__ -#define __EMPATHY_EVENT_MANAGER_H__ - -#include <glib.h> -#include <glib-object.h> - -#include <libempathy/empathy-contact.h> - -G_BEGIN_DECLS - -#define EMPATHY_TYPE_EVENT_MANAGER (empathy_event_manager_get_type ()) -#define EMPATHY_EVENT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_EVENT_MANAGER, EmpathyEventManager)) -#define EMPATHY_EVENT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_EVENT_MANAGER, EmpathyEventManagerClass)) -#define EMPATHY_IS_EVENT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_EVENT_MANAGER)) -#define EMPATHY_IS_EVENT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_EVENT_MANAGER)) -#define EMPATHY_EVENT_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_EVENT_MANAGER, EmpathyEventManagerClass)) - -typedef struct _EmpathyEventManager EmpathyEventManager; -typedef struct _EmpathyEventManagerClass EmpathyEventManagerClass; - -struct _EmpathyEventManager { - GObject parent; - gpointer priv; -}; - -struct _EmpathyEventManagerClass { - GObjectClass parent_class; -}; - -typedef struct { - EmpathyContact *contact; - gchar *icon_name; - gchar *header; - gchar *message; -} EmpathyEvent; - -GType empathy_event_manager_get_type (void) G_GNUC_CONST; -EmpathyEventManager *empathy_event_manager_dup_singleton (void); -EmpathyEvent * empathy_event_manager_get_top_event (EmpathyEventManager *manager); -GSList * empathy_event_manager_get_events (EmpathyEventManager *manager); -void empathy_event_activate (EmpathyEvent *event); -void empathy_event_inhibit_updates (EmpathyEvent *event); - -G_END_DECLS - -#endif /* __EMPATHY_EVENT_MANAGER_H__ */ diff --git a/src/empathy-ft-manager.c b/src/empathy-ft-manager.c deleted file mode 100644 index aa3ba710a..000000000 --- a/src/empathy-ft-manager.c +++ /dev/null @@ -1,1092 +0,0 @@ -/* -*- 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. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Xan Lopez - * Marco Barisione <marco@barisione.org> - * Jonny Lamb <jonny.lamb@collabora.co.uk> - * Xavier Claessens <xclaesse@gmail.com> - */ - -/* The original file transfer manager code was copied from Epiphany */ - -#include "config.h" - -#include <string.h> - -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#define DEBUG_FLAG EMPATHY_DEBUG_FT -#include <libempathy/empathy-debug.h> -#include <libempathy/empathy-tp-file.h> -#include <libempathy/empathy-utils.h> - -#include <libempathy-gtk/empathy-conf.h> -#include <libempathy-gtk/empathy-ui-utils.h> -#include <libempathy-gtk/empathy-geometry.h> -#include <libempathy-gtk/empathy-images.h> - -#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, - COL_ICON, - COL_MESSAGE, - COL_REMAINING, - COL_FT_OBJECT -}; - -/** - * EmpathyFTManagerPriv: - * - * Private fields of the #EmpathyFTManager class. - */ -struct _EmpathyFTManagerPriv -{ - GtkTreeModel *model; - GHashTable *tp_file_to_row_ref; - - /* Widgets */ - GtkWidget *window; - GtkWidget *treeview; - GtkWidget *open_button; - GtkWidget *abort_button; - - guint save_geometry_id; -}; - -enum -{ - RESPONSE_OPEN = 1, - RESPONSE_STOP = 2, - RESPONSE_CLEAR = 3 -}; - -G_DEFINE_TYPE (EmpathyFTManager, empathy_ft_manager, G_TYPE_OBJECT); - -static EmpathyFTManager *manager_singleton = NULL; - -static gchar * -ft_manager_format_interval (gint interval) -{ - gint hours, mins, secs; - - hours = interval / 3600; - interval -= hours * 3600; - mins = interval / 60; - interval -= mins * 60; - secs = interval; - - if (hours > 0) - /* Translators: time left, when it is more than one hour */ - return g_strdup_printf (_("%u:%02u.%02u"), hours, mins, secs); - else - /* Translators: time left, when is is less than one hour */ - 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) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - EmpathyTpFile *tp_file; - TpFileTransferState state; - gboolean open_enabled = FALSE; - gboolean abort_enabled = FALSE; - - 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); - - /* 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)); - - /* I can abort if the transfer is not already finished */ - abort_enabled = (state != TP_FILE_TRANSFER_STATE_CANCELLED && - state != TP_FILE_TRANSFER_STATE_COMPLETED); - - g_object_unref (tp_file); - } - - gtk_widget_set_sensitive (ft_manager->priv->open_button, open_enabled); - gtk_widget_set_sensitive (ft_manager->priv->abort_button, abort_enabled); -} - -static const gchar * -ft_manager_state_change_reason_to_string (TpFileTransferStateChangeReason reason) -{ - switch (reason) - { - 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); - - 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"); - 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 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); -} - -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); -} - -static void -ft_manager_selection_changed (GtkTreeSelection *selection, - EmpathyFTManager *ft_manager) -{ - ft_manager_update_buttons (ft_manager); -} - -static void -ft_manager_progress_cell_data_func (GtkTreeViewColumn *col, - GtkCellRenderer *renderer, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - const gchar *text = NULL; - gint percent; - - gtk_tree_model_get (model, iter, COL_PERCENT, &percent, -1); - - if (percent < 0) - { - percent = 0; - text = C_("file transfer percent", "Unknown"); - } - - 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) -{ - if (ft_manager->priv->save_geometry_id != 0) - g_source_remove (ft_manager->priv->save_geometry_id); - - ft_manager->priv->save_geometry_id = g_timeout_add (500, - (GSourceFunc) ft_manager_save_geometry_timeout_cb, ft_manager); - - return FALSE; -} - -static void -ft_manager_remove_file_from_model (EmpathyFTManager *ft_manager, - EmpathyTpFile *tp_file) -{ - GtkTreeRowReference *row_ref; - GtkTreeSelection *selection; - GtkTreePath *path = NULL; - GtkTreeIter iter; - gboolean update_selection; - - row_ref = ft_manager_get_row_from_tp_file (ft_manager, tp_file); - 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)); - - /* 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_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)); - 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)) - { - 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); - if (n_row > 0) - gtk_tree_model_iter_nth_child (ft_manager->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 -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; - - state = empathy_tp_file_get_state (tp_file, NULL); - if (state == TP_FILE_TRANSFER_STATE_COMPLETED || - state == TP_FILE_TRANSFER_STATE_CANCELLED) - { - ft_manager_remove_file_from_model (self, tp_file); - return TRUE; - } - - return FALSE; -} - -static void -ft_manager_state_changed_cb (EmpathyTpFile *tp_file, - GParamSpec *pspec, - EmpathyFTManager *ft_manager) -{ - if (empathy_tp_file_get_state (tp_file, NULL) == - TP_FILE_TRANSFER_STATE_COMPLETED) - { - GtkRecentManager *manager; - const gchar *uri; - - 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); - } - - ft_manager_update_ft_row (ft_manager, tp_file); -} - -static void -ft_manager_clear (EmpathyFTManager *ft_manager) -{ - DEBUG ("Clearing file transfer list"); - - /* Remove completed and cancelled transfers */ - g_hash_table_foreach_remove (ft_manager->priv->tp_file_to_row_ref, - remove_finished_transfer_foreach, ft_manager); -} - -static void -ft_manager_open (EmpathyFTManager *ft_manager) -{ - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreeModel *model; - EmpathyTpFile *tp_file; - const gchar *uri; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ft_manager->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); - - 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); -} - -static void -ft_manager_stop (EmpathyFTManager *ft_manager) -{ - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreeModel *model; - EmpathyTpFile *tp_file; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ft_manager->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); - - 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_tp_file_cancel (tp_file); - g_object_unref (tp_file); -} - -static void -ft_manager_response_cb (GtkWidget *widget, - gint response, - EmpathyFTManager *ft_manager) -{ - switch (response) - { - case RESPONSE_CLEAR: - ft_manager_clear (ft_manager); - break; - case RESPONSE_OPEN: - ft_manager_open (ft_manager); - break; - case RESPONSE_STOP: - ft_manager_stop (ft_manager); - break; - } -} - -static gboolean -ft_manager_delete_event_cb (GtkWidget *widget, - GdkEvent *event, - EmpathyFTManager *ft_manager) -{ - ft_manager_clear (ft_manager); - if (g_hash_table_size (ft_manager->priv->tp_file_to_row_ref) > 0) - { - /* There is still FTs on flight, just hide the window */ - DEBUG ("Hiding window"); - gtk_widget_hide (widget); - return TRUE; - } - - return FALSE; -} - -static void -ft_manager_destroy_cb (GtkWidget *widget, - EmpathyFTManager *ft_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); -} - -static void -ft_manager_build_ui (EmpathyFTManager *ft_manager) -{ - GladeXML *glade; - gint x, y, w, h; - GtkTreeView *view; - GtkListStore *liststore; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - GtkTreeSelection *selection; - gchar *filename; - - if (ft_manager->priv->window != NULL) - return; - - filename = empathy_file_lookup ("empathy-ft-manager.glade", "src"); - glade = empathy_glade_get_file (filename, - "ft_manager_dialog", NULL, - "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, - NULL); - g_free (filename); - - empathy_glade_connect (glade, ft_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 (glade); - - /* Window geometry. */ - empathy_geometry_load ("ft-manager", &x, &y, &w, &h); - - if (x >= 0 && y >= 0) - { - /* 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); - } - - if (w > 0 && h > 0) - { - /* Use the defaults from the glade file if we don't have - * good w, h geometry. */ - gtk_window_resize (GTK_WINDOW (ft_manager->priv->window), w, h); - } - - /* Setup the tree view */ - view = GTK_TREE_VIEW (ft_manager->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); - gtk_tree_view_set_headers_visible (view, TRUE); - gtk_tree_view_set_enable_search (view, FALSE); - - /* Setup the model */ - liststore = gtk_list_store_new (5, - G_TYPE_INT, /* percent */ - G_TYPE_ICON, /* icon */ - G_TYPE_STRING, /* message */ - G_TYPE_STRING, /* remaining */ - G_TYPE_OBJECT); /* ft_file */ - gtk_tree_view_set_model (view, GTK_TREE_MODEL (liststore)); - ft_manager->priv->model = GTK_TREE_MODEL (liststore); - g_object_unref (liststore); - - /* Progress column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("%")); - gtk_tree_view_column_set_sort_column_id (column, COL_PERCENT); - gtk_tree_view_insert_column (view, column, -1); - - renderer = gtk_cell_renderer_progress_new (); - g_object_set (renderer, "xalign", 0.5, NULL); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - gtk_tree_view_column_set_cell_data_func (column, renderer, - ft_manager_progress_cell_data_func, NULL, NULL); - - /* Icon and filename column*/ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("File")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_column_set_sort_column_id (column, COL_MESSAGE); - gtk_tree_view_column_set_spacing (column, 3); - gtk_tree_view_insert_column (view, column, -1); - - renderer = gtk_cell_renderer_pixbuf_new (); - g_object_set (renderer, "xpad", 3, - "stock-size", GTK_ICON_SIZE_DND, NULL); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - gtk_tree_view_column_set_attributes (column, renderer, - "gicon", COL_ICON, NULL); - - renderer = gtk_cell_renderer_text_new (); - g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_set_attributes (column, renderer, - "text", COL_MESSAGE, NULL); - - /* Remaining time column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Remaining")); - gtk_tree_view_column_set_sort_column_id (column, COL_REMAINING); - gtk_tree_view_insert_column (view, column, -1); - - renderer = gtk_cell_renderer_text_new (); - g_object_set (renderer, "xalign", 0.5, NULL); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - gtk_tree_view_column_set_attributes (column, renderer, - "text", COL_REMAINING, NULL); -} - -static void -empathy_ft_manager_finalize (GObject *object) -{ - EmpathyFTManager *ft_manager = (EmpathyFTManager *) object; - - DEBUG ("%p", object); - - if (ft_manager->priv->window) - gtk_widget_destroy (ft_manager->priv->window); - - g_hash_table_destroy (ft_manager->priv->tp_file_to_row_ref); - - G_OBJECT_CLASS (empathy_ft_manager_parent_class)->finalize (object); -} - -static void -empathy_ft_manager_init (EmpathyFTManager *ft_manager) -{ - EmpathyFTManagerPriv *priv; - - priv = G_TYPE_INSTANCE_GET_PRIVATE ((ft_manager), EMPATHY_TYPE_FT_MANAGER, - EmpathyFTManagerPriv); - - ft_manager->priv = priv; - - priv->tp_file_to_row_ref = g_hash_table_new_full (g_direct_hash, - g_direct_equal, (GDestroyNotify) g_object_unref, - (GDestroyNotify) gtk_tree_row_reference_free); -} - -static GObject * -empathy_ft_manager_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *retval; - - if (manager_singleton) - { - retval = g_object_ref (manager_singleton); - } - else - { - retval = G_OBJECT_CLASS (empathy_ft_manager_parent_class)->constructor - (type, n_props, props); - - manager_singleton = EMPATHY_FT_MANAGER (retval); - g_object_add_weak_pointer (retval, (gpointer) &manager_singleton); - } - - return retval; -} - -static void -empathy_ft_manager_class_init (EmpathyFTManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = empathy_ft_manager_finalize; - object_class->constructor = empathy_ft_manager_constructor; - - 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; - -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) -{ - 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; - } - - g_object_set_data_full (G_OBJECT (response_data->tp_file), - "uri", uri, g_free); - - ft_manager_add_tp_file_to_list (response_data->ft_manager, - response_data->tp_file); - - g_object_unref (file); - } - - 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); -} - -static void -ft_manager_create_save_dialog (ReceiveResponseData *response_data) -{ - 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); -} - -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); - } - - gtk_widget_destroy (dialog); -} - -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), - _("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); -} - -/** - * 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) -{ - 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); - - 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); - - 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); -} - diff --git a/src/empathy-ft-manager.glade b/src/empathy-ft-manager.glade deleted file mode 100644 index 2a386145a..000000000 --- a/src/empathy-ft-manager.glade +++ /dev/null @@ -1,89 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkDialog" id="ft_manager_dialog"> - <property name="width_request">620</property> - <property name="height_request">250</property> - <property name="border_width">5</property> - <property name="title" translatable="yes">File transfers</property> - <property name="role">empathy-ft-manager</property> - <property name="icon_name">document-send</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox31"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1134"> - <property name="height_request">100</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="border_width">5</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTreeView" id="ft_list"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area31"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="clear_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> - <property name="tooltip" translatable="yes">Remove completed, canceled and failed file transfers from the list</property> - <property name="label">gtk-clear</property> - <property name="use_stock">True</property> - <property name="response_id">3</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="open_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-open</property> - <property name="use_stock">True</property> - <property name="response_id">1</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="abort_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-stop</property> - <property name="use_stock">True</property> - <property name="response_id">2</property> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-ft-manager.h b/src/empathy-ft-manager.h deleted file mode 100644 index 4803bc814..000000000 --- a/src/empathy-ft-manager.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- 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. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Marco Barisione <marco@barisione.org> - * Jonny Lamb <jonny.lamb@collabora.co.uk> - */ - -#ifndef __EMPATHY_FT_MANAGER_H__ -#define __EMPATHY_FT_MANAGER_H__ - -#include <gtk/gtk.h> -#include <glib-object.h> -#include <glib.h> - -#include <libempathy/empathy-tp-file.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)) - -typedef struct _EmpathyFTManager EmpathyFTManager; -typedef struct _EmpathyFTManagerPriv EmpathyFTManagerPriv; -typedef struct _EmpathyFTManagerClass EmpathyFTManagerClass; - -struct _EmpathyFTManager -{ - GObject parent; - - EmpathyFTManagerPriv *priv; -}; - -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); - -G_END_DECLS - -#endif /* __EMPATHY_FT_MANAGER_H__ */ diff --git a/src/empathy-import-dialog.c b/src/empathy-import-dialog.c deleted file mode 100644 index 955e07b9c..000000000 --- a/src/empathy-import-dialog.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (C) 2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> - * */ - -#include <config.h> - -#include <string.h> - -#include <glib.h> -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <glib/gi18n.h> - -#include <libmissioncontrol/mc-account.h> -#include <telepathy-glib/util.h> - -#include "empathy-import-dialog.h" -#include "empathy-import-pidgin.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_OTHER -#include <libempathy/empathy-debug.h> -#include <libempathy/empathy-utils.h> - -#include <libempathy-gtk/empathy-ui-utils.h> - -typedef struct -{ - GtkWidget *window; - GtkWidget *treeview; - GtkWidget *button_ok; - GtkWidget *button_cancel; - GList *accounts; -} EmpathyImportDialog; - -enum -{ - COL_IMPORT = 0, - COL_PROTOCOL, - COL_NAME, - COL_SOURCE, - COL_ACCOUNT_DATA, - COL_COUNT -}; - -EmpathyImportAccountData * -empathy_import_account_data_new (const gchar *source) -{ - EmpathyImportAccountData *data; - - g_return_val_if_fail (!EMP_STR_EMPTY (source), NULL); - - data = g_slice_new0 (EmpathyImportAccountData); - data->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, - (GDestroyNotify) tp_g_value_slice_free); - data->source = g_strdup (source); - - return data; -} - -void -empathy_import_account_data_free (EmpathyImportAccountData *data) -{ - if (data == NULL) - return; - if (data->profile != NULL) - g_object_unref (data->profile); - if (data->settings != NULL) - g_hash_table_destroy (data->settings); - if (data->source != NULL) - g_free (data->source); - - g_slice_free (EmpathyImportAccountData, data); -} - -static void -import_dialog_add_account (EmpathyImportAccountData *data) -{ - McAccount *account; - GHashTableIter iter; - gpointer key, value; - gchar *display_name; - GValue *username; - - account = mc_account_create (data->profile); - - g_hash_table_iter_init (&iter, data->settings); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - const gchar *param = key; - GValue *gvalue = value; - - switch (G_VALUE_TYPE (gvalue)) - { - case G_TYPE_STRING: - DEBUG ("Set param '%s' to '%s' (string)", - param, g_value_get_string (gvalue)); - mc_account_set_param_string (account, - param, g_value_get_string (gvalue)); - break; - - case G_TYPE_BOOLEAN: - DEBUG ("Set param '%s' to %s (boolean)", - param, g_value_get_boolean (gvalue) ? "TRUE" : "FALSE"); - mc_account_set_param_boolean (account, - param, g_value_get_boolean (gvalue)); - break; - - case G_TYPE_INT: - DEBUG ("Set param '%s' to '%i' (integer)", - param, g_value_get_int (gvalue)); - mc_account_set_param_int (account, - param, g_value_get_int (gvalue)); - break; - } - } - - /* Set the display name of the account */ - username = g_hash_table_lookup (data->settings, "account"); - display_name = g_strdup_printf ("%s (%s)", - mc_profile_get_display_name (data->profile), - g_value_get_string (username)); - mc_account_set_display_name (account, display_name); - - g_free (display_name); - g_object_unref (account); -} - -static gboolean -import_dialog_account_id_in_list (GList *accounts, - const gchar *account_id) -{ - GList *l; - - for (l = accounts; l; l = l->next) - { - McAccount *account = l->data; - gchar *value; - gboolean result; - - if (mc_account_get_param_string (account, "account", &value) - == MC_ACCOUNT_SETTING_ABSENT) - continue; - - result = tp_strdiff (value, account_id); - - g_free (value); - - if (!result) - return TRUE; - } - - return FALSE; -} - -static void -import_dialog_add_accounts_to_model (EmpathyImportDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GList *l; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - - for (l = dialog->accounts; l; l = l->next) - { - GValue *value; - EmpathyImportAccountData *data = l->data; - gboolean import; - GList *accounts; - - value = g_hash_table_lookup (data->settings, "account"); - - accounts = mc_accounts_list_by_profile (data->profile); - - /* Only set the "Import" cell to be active if there isn't already an - * account set up with the same account id. */ - import = !import_dialog_account_id_in_list (accounts, - g_value_get_string (value)); - - mc_accounts_list_free (accounts); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_IMPORT, import, - COL_PROTOCOL, mc_profile_get_display_name (data->profile), - COL_NAME, g_value_get_string (value), - COL_SOURCE, data->source, - COL_ACCOUNT_DATA, data, - -1); - } -} - -static void -import_dialog_cell_toggled_cb (GtkCellRendererToggle *cell_renderer, - const gchar *path_str, - EmpathyImportDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreePath *path; - - path = gtk_tree_path_new_from_string (path_str); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - - gtk_tree_model_get_iter (model, &iter, path); - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_IMPORT, !gtk_cell_renderer_toggle_get_active (cell_renderer), - -1); - - gtk_tree_path_free (path); -} - -static void -import_dialog_set_up_account_list (EmpathyImportDialog *dialog) -{ - GtkListStore *store; - GtkTreeView *view; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - - store = gtk_list_store_new (COL_COUNT, G_TYPE_BOOLEAN, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview), - GTK_TREE_MODEL (store)); - - g_object_unref (store); - - view = GTK_TREE_VIEW (dialog->treeview); - gtk_tree_view_set_headers_visible (view, TRUE); - - /* Import column */ - cell = gtk_cell_renderer_toggle_new (); - gtk_tree_view_insert_column_with_attributes (view, -1, - /* Translators: this is the header of a treeview column */ - _("Import"), cell, - "active", COL_IMPORT, - NULL); - - g_signal_connect (cell, "toggled", - G_CALLBACK (import_dialog_cell_toggled_cb), dialog); - - /* Protocol column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Protocol")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "editable", FALSE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_PROTOCOL); - - /* Account column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Account")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "editable", FALSE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); - - /* Source column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Source")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "editable", FALSE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_SOURCE); - - import_dialog_add_accounts_to_model (dialog); -} - -static gboolean -import_dialog_tree_model_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data) -{ - gboolean to_import; - EmpathyImportAccountData *data; - - gtk_tree_model_get (model, iter, - COL_IMPORT, &to_import, - COL_ACCOUNT_DATA, &data, - -1); - - if (to_import) - import_dialog_add_account (data); - - return FALSE; -} - -static void -import_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyImportDialog *dialog) -{ - if (response == GTK_RESPONSE_OK) - { - GtkTreeModel *model; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - gtk_tree_model_foreach (model, import_dialog_tree_model_foreach, dialog); - } - - gtk_widget_destroy (dialog->window); -} - -static void -import_dialog_destroy_cb (GtkWidget *widget, - EmpathyImportDialog *dialog) -{ - g_list_foreach (dialog->accounts, (GFunc) empathy_import_account_data_free, - NULL); - g_list_free (dialog->accounts); - g_slice_free (EmpathyImportDialog, dialog); -} - -gboolean -empathy_import_dialog_accounts_to_import (void) -{ - return empathy_import_pidgin_accounts_to_import (); -} - -void -empathy_import_dialog_show (GtkWindow *parent, - gboolean warning) -{ - static EmpathyImportDialog *dialog = NULL; - GladeXML *glade; - gchar *filename; - GList *accounts = NULL; - - /* This window is a singleton. If it already exist, present it */ - if (dialog) - { - gtk_window_present (GTK_WINDOW (dialog->window)); - return; - } - - /* Load all accounts from all supported applications */ - accounts = g_list_concat (accounts, empathy_import_pidgin_load ()); - - /* Check if we have accounts to import before creating the window */ - if (!accounts) - { - GtkWidget *message; - - if (warning) - { - message = gtk_message_dialog_new (parent, - GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, - _("No accounts to import could be found. Empathy currently only " - "supports importing accounts from Pidgin.")); - - gtk_dialog_run (GTK_DIALOG (message)); - gtk_widget_destroy (message); - } - else - DEBUG ("No accounts to import; closing dialog silently."); - - return; - } - - /* We have accounts, let's display the window with them */ - dialog = g_slice_new0 (EmpathyImportDialog); - dialog->accounts = accounts; - - filename = empathy_file_lookup ("empathy-import-dialog.glade", "src"); - glade = empathy_glade_get_file (filename, - "import_dialog", - NULL, - "import_dialog", &dialog->window, - "treeview", &dialog->treeview, - NULL); - - empathy_glade_connect (glade, - dialog, - "import_dialog", "destroy", import_dialog_destroy_cb, - "import_dialog", "response", import_dialog_response_cb, - NULL); - - g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog); - - g_free (filename); - g_object_unref (glade); - - if (parent) - gtk_window_set_transient_for (GTK_WINDOW (dialog->window), parent); - - import_dialog_set_up_account_list (dialog); - - gtk_widget_show (dialog->window); -} - diff --git a/src/empathy-import-dialog.glade b/src/empathy-import-dialog.glade deleted file mode 100644 index 4521d2e89..000000000 --- a/src/empathy-import-dialog.glade +++ /dev/null @@ -1,72 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--Generated with glade3 3.4.5 on Fri Oct 17 11:01:30 2008 --> -<glade-interface> - <widget class="GtkDialog" id="import_dialog"> - <property name="border_width">5</property> - <property name="title" translatable="yes">Import Accounts</property> - <property name="modal">True</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow17"> - <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> - <child> - <widget class="GtkTreeView" id="treeview"> - <property name="height_request">200</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="enable_search">False</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="button_cancel"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="response_id">0</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="button_ok"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="response_id">-5</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-import-dialog.h b/src/empathy-import-dialog.h deleted file mode 100644 index 278afc701..000000000 --- a/src/empathy-import-dialog.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> - */ - -#include <gtk/gtk.h> - -#ifndef __EMPATHY_IMPORT_DIALOG_H__ -#define __EMPATHY_IMPORT_DIALOG_H__ - -G_BEGIN_DECLS - -typedef struct -{ - /* Table mapping CM param string to a GValue */ - GHashTable *settings; - /* The profile to use for this account */ - McProfile *profile; - /* The name of the account import source */ - gchar *source; -} EmpathyImportAccountData; - -EmpathyImportAccountData *empathy_import_account_data_new (const gchar *source); -void empathy_import_account_data_free (EmpathyImportAccountData *data); -gboolean empathy_import_dialog_accounts_to_import (void); -void empathy_import_dialog_show (GtkWindow *parent, gboolean warning); - -G_END_DECLS - -#endif /* __EMPATHY_IMPORT_DIALOG_H__ */ diff --git a/src/empathy-import-pidgin.c b/src/empathy-import-pidgin.c deleted file mode 100644 index 76295c702..000000000 --- a/src/empathy-import-pidgin.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) 2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> - * */ - -#include <config.h> - -#include <string.h> - -#include <glib.h> -#include <glib/gstdio.h> -#include <libxml/parser.h> -#include <libxml/tree.h> - -#include <libmissioncontrol/mc-account.h> -#include <telepathy-glib/util.h> - -#include "empathy-import-dialog.h" -#include "empathy-import-pidgin.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_OTHER -#include <libempathy/empathy-debug.h> -#include <libempathy/empathy-utils.h> - -#include <libempathy-gtk/empathy-ui-utils.h> - -/* Pidgin to CM map */ -typedef struct -{ - gchar *protocol; - gchar *pidgin_name; - gchar *cm_name; -} PidginCmMapItem; - -static PidginCmMapItem pidgin_cm_map[] = -{ - { "msn", "server", "server" }, - { "msn", "port", "port" }, - - { "jabber", "connect_server", "server" }, - { "jabber", "port", "port" }, - { "jabber", "require_tls", "require-encryption" }, - { "jabber", "old_ssl", "old-ssl" }, - - { "aim", "server", "server" }, - { "aim", "port", "port" }, - - { "salut", "first", "first-name" }, - { "salut", "last", "last-name" }, - { "salut", "jid", "jid" }, - { "salut", "email", "email" }, - - { "groupwise", "server", "server" }, - { "groupwise", "port", "port" }, - - { "icq", "server", "server" }, - { "icq", "port", "port" }, - - { "irc", "realname", "fullname" }, - { "irc", "ssl", "use-ssl" }, - { "irc", "port", "port" }, - - { "yahoo", "server", "server" }, - { "yahoo", "port", "port" }, - { "yahoo", "xfer_port", "xfer-port" }, - { "yahoo", "ignore_invites", "ignore-invites" }, - { "yahoo", "yahoojp", "yahoojp" }, - { "yahoo", "xferjp_host", "xferjp-host" }, - { "yahoo", "serverjp", "serverjp" }, - { "yahoo", "xfer_host", "xfer-host" }, -}; - -#define PIDGIN_ACCOUNT_TAG_NAME "name" -#define PIDGIN_ACCOUNT_TAG_ACCOUNT "account" -#define PIDGIN_ACCOUNT_TAG_PROTOCOL "protocol" -#define PIDGIN_ACCOUNT_TAG_PASSWORD "password" -#define PIDGIN_ACCOUNT_TAG_SETTINGS "settings" -#define PIDGIN_SETTING_PROP_TYPE "type" -#define PIDGIN_PROTOCOL_BONJOUR "bonjour" -#define PIDGIN_PROTOCOL_NOVELL "novell" - -static void -import_dialog_pidgin_parse_setting (EmpathyImportAccountData *data, - xmlNodePtr setting) -{ - PidginCmMapItem *item = NULL; - gchar *tag_name; - gchar *type = NULL; - gchar *content; - gint i; - GValue *value = NULL; - - /* We can't do anything if the setting don't have a name */ - tag_name = (gchar *) xmlGetProp (setting, PIDGIN_ACCOUNT_TAG_NAME); - if (!tag_name) - return; - - /* Search for the map corresponding to setting we are parsing */ - for (i = 0; i < G_N_ELEMENTS (pidgin_cm_map); i++) - { - if (!tp_strdiff (mc_profile_get_protocol_name (data->profile), - pidgin_cm_map[i].protocol) && - !tp_strdiff (tag_name, pidgin_cm_map[i].pidgin_name)) - { - item = pidgin_cm_map + i; - break; - } - } - g_free (tag_name); - - /* If we didn't find the item, there is nothing we can do */ - if (!item) - return; - - type = (gchar *) xmlGetProp (setting, PIDGIN_SETTING_PROP_TYPE); - content = (gchar *) xmlNodeGetContent (setting); - - if (!tp_strdiff (type, "bool")) - { - i = (gint) g_ascii_strtod (content, NULL); - value = tp_g_value_slice_new (G_TYPE_BOOLEAN); - g_value_set_boolean (value, i != 0); - } - else if (!tp_strdiff (type, "int")) - { - i = (gint) g_ascii_strtod (content, NULL); - value = tp_g_value_slice_new (G_TYPE_INT); - g_value_set_int (value, i); - } - else if (!tp_strdiff (type, "string")) - { - value = tp_g_value_slice_new (G_TYPE_STRING); - g_value_set_string (value, content); - } - - if (value) - g_hash_table_insert (data->settings, item->cm_name, value); - - g_free (type); - g_free (content); -} - -GList * -empathy_import_pidgin_load (void) -{ - xmlNodePtr rootnode, node, child, setting; - xmlParserCtxtPtr ctxt; - xmlDocPtr doc; - gchar *filename; - GList *accounts = NULL; - - /* Load pidgin accounts xml */ - ctxt = xmlNewParserCtxt (); - filename = g_build_filename (g_get_home_dir (), ".purple", "accounts.xml", - NULL); - - if (g_access (filename, R_OK) != 0) - goto FILENAME; - - doc = xmlCtxtReadFile (ctxt, filename, NULL, 0); - - rootnode = xmlDocGetRootElement (doc); - if (rootnode == NULL) - goto OUT; - - for (node = rootnode->children; node; node = node->next) - { - EmpathyImportAccountData *data; - - /* If it is not an account node, skip. */ - if (tp_strdiff ((gchar *) node->name, PIDGIN_ACCOUNT_TAG_ACCOUNT)) - continue; - - /* Create account data struct */ - data = empathy_import_account_data_new ("Pidgin"); - - /* Parse account's child nodes to fill the account data struct */ - for (child = node->children; child; child = child->next) - { - GValue *value; - - /* Protocol */ - if (!tp_strdiff ((gchar *) child->name, - PIDGIN_ACCOUNT_TAG_PROTOCOL)) - { - gchar *content; - const gchar *protocol; - - protocol = content = (gchar *) xmlNodeGetContent (child); - - if (g_str_has_prefix (protocol, "prpl-")) - protocol += 5; - - if (!tp_strdiff (protocol, PIDGIN_PROTOCOL_BONJOUR)) - protocol = "salut"; - else if (!tp_strdiff (protocol, PIDGIN_PROTOCOL_NOVELL)) - protocol = "groupwise"; - - data->profile = mc_profile_lookup (protocol); - g_free (content); - - if (data->profile == NULL) - break; - } - - /* Username and IRC server. */ - else if (!tp_strdiff ((gchar *) child->name, - PIDGIN_ACCOUNT_TAG_NAME)) - { - gchar *name; - GStrv name_resource = NULL; - GStrv nick_server = NULL; - const gchar *username; - - name = (gchar *) xmlNodeGetContent (child); - - /* Split "username/resource" */ - if (g_strrstr (name, "/") != NULL) - { - name_resource = g_strsplit (name, "/", 2); - username = name_resource[0]; - } - else - username = name; - - /* Split "username@server" if it is an IRC account */ - if (strstr (name, "@") && !tp_strdiff ( - mc_profile_get_protocol_name (data->profile), "irc")) - { - nick_server = g_strsplit (name, "@", 2); - username = nick_server[0]; - - /* Add the server setting */ - value = tp_g_value_slice_new (G_TYPE_STRING); - g_value_set_string (value, nick_server[1]); - g_hash_table_insert (data->settings, "server", value); - } - - /* Add the account setting */ - value = tp_g_value_slice_new (G_TYPE_STRING); - g_value_set_string (value, username); - g_hash_table_insert (data->settings, "account", value); - - g_strfreev (name_resource); - g_strfreev (nick_server); - g_free (name); - } - - /* Password */ - else if (!tp_strdiff ((gchar *) child->name, - PIDGIN_ACCOUNT_TAG_PASSWORD)) - { - gchar *password; - - password = (gchar *) xmlNodeGetContent (child); - - /* Add the password setting */ - value = tp_g_value_slice_new (G_TYPE_STRING); - g_value_set_string (value, password); - g_hash_table_insert (data->settings, "password", value); - - g_free (password); - } - - /* Other settings */ - else if (!tp_strdiff ((gchar *) child->name, - PIDGIN_ACCOUNT_TAG_SETTINGS)) - for (setting = child->children; setting; setting = setting->next) - import_dialog_pidgin_parse_setting (data, setting); - } - - /* If we have the needed settings, add the account data to the list, - * otherwise free the data */ - if (data->profile != NULL && g_hash_table_size (data->settings) > 0) - accounts = g_list_prepend (accounts, data); - else - empathy_import_account_data_free (data); - } - -OUT: - xmlFreeDoc(doc); - xmlFreeParserCtxt (ctxt); - -FILENAME: - g_free (filename); - - return accounts; -} - -gboolean -empathy_import_pidgin_accounts_to_import (void) -{ - gchar *filename; - gboolean out; - GFile *file; - - filename = g_build_filename (g_get_home_dir (), ".purple", "accounts.xml", NULL); - file = g_file_new_for_path (filename); - out = g_file_query_exists (file, NULL); - - g_free (filename); - g_object_unref (file); - - return out; -} diff --git a/src/empathy-import-pidgin.h b/src/empathy-import-pidgin.h deleted file mode 100644 index fc7d2e491..000000000 --- a/src/empathy-import-pidgin.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> - */ - -#include <gtk/gtk.h> - -#ifndef __EMPATHY_IMPORT_PIDGIN_H__ -#define __EMPATHY_IMPORT_PIDGIN_H__ - -G_BEGIN_DECLS - -GList *empathy_import_pidgin_load (void); -gboolean empathy_import_pidgin_accounts_to_import (void); - -G_END_DECLS - -#endif /* __EMPATHY_IMPORT_PIDGIN_H__ */ diff --git a/src/empathy-logs.c b/src/empathy-logs.c deleted file mode 100644 index 502be67d7..000000000 --- a/src/empathy-logs.c +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> -#include <stdlib.h> -#include <glib.h> -#include <gtk/gtk.h> - -#include <libempathy/empathy-debug.h> -#include <libempathy-gtk/empathy-log-window.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -static void -destroy_cb (GtkWidget *dialog, - gpointer user_data) -{ - gtk_main_quit (); -} - -int -main (int argc, char *argv[]) -{ - GtkWidget *window; - - g_thread_init (NULL); - gtk_init (&argc, &argv); - empathy_gtk_init (); - g_set_application_name (PACKAGE_NAME); - gtk_window_set_default_icon_name ("empathy"); - - window = empathy_log_window_show (NULL, NULL, FALSE, NULL); - - g_signal_connect (window, "destroy", - G_CALLBACK (destroy_cb), - NULL); - - gtk_main (); - - return EXIT_SUCCESS; -} - diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c deleted file mode 100644 index 77fa538d6..000000000 --- a/src/empathy-main-window.c +++ /dev/null @@ -1,1420 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2002-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> - -#include <sys/stat.h> -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <glib/gi18n.h> - -#include <libempathy/empathy-contact.h> -#include <libempathy/empathy-utils.h> -#include <libempathy/empathy-account-manager.h> -#include <libempathy/empathy-dispatcher.h> -#include <libempathy/empathy-chatroom-manager.h> -#include <libempathy/empathy-chatroom.h> -#include <libempathy/empathy-contact-list.h> -#include <libempathy/empathy-contact-manager.h> -#include <libempathy/empathy-contact-factory.h> -#include <libempathy/empathy-status-presets.h> - -#include <libempathy-gtk/empathy-contact-dialogs.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 <libempathy-gtk/empathy-geometry.h> -#include <libempathy-gtk/empathy-conf.h> -#include <libempathy-gtk/empathy-log-window.h> -#include <libempathy-gtk/empathy-new-message-dialog.h> -#include <libempathy-gtk/empathy-gtk-enum-types.h> - -#include <libmissioncontrol/mission-control.h> - -#include "empathy-accounts-dialog.h" -#include "empathy-main-window.h" -#include "ephy-spinner.h" -#include "empathy-preferences.h" -#include "empathy-about-dialog.h" -#include "empathy-new-chatroom-dialog.h" -#include "empathy-chatrooms-window.h" -#include "empathy-event-manager.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_OTHER -#include <libempathy/empathy-debug.h> - -/* Flashing delay for icons (milliseconds). */ -#define FLASH_TIMEOUT 500 - -/* Minimum width of roster window if something goes wrong. */ -#define MIN_WIDTH 50 - -/* Accels (menu shortcuts) can be configured and saved */ -#define ACCELS_FILENAME "accels.txt" - -/* Name in the geometry file */ -#define GEOMETRY_NAME "main-window" - -typedef struct { - EmpathyContactListView *list_view; - EmpathyContactListStore *list_store; - MissionControl *mc; - EmpathyAccountManager *account_manager; - EmpathyChatroomManager *chatroom_manager; - EmpathyEventManager *event_manager; - guint flash_timeout_id; - gboolean flash_on; - - GtkWidget *window; - GtkWidget *main_vbox; - GtkWidget *throbber; - GtkWidget *presence_toolbar; - GtkWidget *presence_chooser; - GtkWidget *errors_vbox; - - GtkWidget *room; - GtkWidget *room_menu; - GtkWidget *room_sep; - GtkWidget *room_join_favorites; - GtkWidget *edit_context; - GtkWidget *edit_context_separator; - GtkWidget *chat_history_menu_item; - - guint size_timeout_id; - GHashTable *errors; - - /* Widgets that are enabled when there are connected accounts */ - GList *widgets_connected; -} EmpathyMainWindow; - -static EmpathyMainWindow *window = NULL; - -static void main_window_destroy_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_favorite_chatroom_menu_setup (EmpathyMainWindow *window); -static void main_window_favorite_chatroom_menu_added_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyMainWindow *window); -static void main_window_favorite_chatroom_menu_removed_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyMainWindow *window); -static void main_window_favorite_chatroom_menu_activate_cb (GtkMenuItem *menu_item, - EmpathyChatroom *chatroom); -static void main_window_favorite_chatroom_menu_update (EmpathyMainWindow *window); -static void main_window_favorite_chatroom_menu_add (EmpathyMainWindow *window, - EmpathyChatroom *chatroom); -static void main_window_favorite_chatroom_join (EmpathyChatroom *chatroom); -static void main_window_chat_quit_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_chat_new_message_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_chat_history_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_room_join_new_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_room_join_favorites_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_room_manage_favorites_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_chat_add_contact_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_chat_show_offline_cb (GtkCheckMenuItem *item, - EmpathyMainWindow *window); -static gboolean main_window_edit_button_press_event_cb (GtkWidget *widget, - GdkEventButton *event, - EmpathyMainWindow *window); -static void main_window_edit_accounts_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_edit_personal_information_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_edit_preferences_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_help_about_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static void main_window_help_contents_cb (GtkWidget *widget, - EmpathyMainWindow *window); -static gboolean main_window_throbber_button_press_event_cb (GtkWidget *throbber_ebox, - GdkEventButton *event, - EmpathyMainWindow *window); -static void main_window_update_status (EmpathyMainWindow *window, - EmpathyAccountManager *manager); -static void main_window_error_display (EmpathyMainWindow *window, - McAccount *account, - const gchar *message); -static void main_window_accels_load (void); -static void main_window_accels_save (void); -static void main_window_connection_items_setup (EmpathyMainWindow *window, - GladeXML *glade); -static gboolean main_window_configure_event_timeout_cb (EmpathyMainWindow *window); -static gboolean main_window_configure_event_cb (GtkWidget *widget, - GdkEventConfigure *event, - EmpathyMainWindow *window); -static void main_window_notify_show_offline_cb (EmpathyConf *conf, - const gchar *key, - gpointer check_menu_item); -static void main_window_notify_show_avatars_cb (EmpathyConf *conf, - const gchar *key, - EmpathyMainWindow *window); -static void main_window_notify_compact_contact_list_cb (EmpathyConf *conf, - const gchar *key, - EmpathyMainWindow *window); -static void main_window_notify_sort_criterium_cb (EmpathyConf *conf, - const gchar *key, - EmpathyMainWindow *window); -static void main_window_account_created_or_deleted_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyMainWindow *window); - -static void -main_window_flash_stop (EmpathyMainWindow *window) -{ - if (window->flash_timeout_id == 0) { - return; - } - - DEBUG ("Stop flashing"); - g_source_remove (window->flash_timeout_id); - window->flash_timeout_id = 0; - window->flash_on = FALSE; -} - -typedef struct { - EmpathyEvent *event; - gboolean on; -} FlashForeachData; - -static gboolean -main_window_flash_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data) -{ - FlashForeachData *data = (FlashForeachData*) user_data; - EmpathyContact *contact; - const gchar *icon_name; - GtkTreePath *parent_path = NULL; - GtkTreeIter parent_iter; - - /* To be used with gtk_tree_model_foreach, update the status icon - * of the contact to show the event icon (on=TRUE) or the presence - * (on=FALSE) */ - gtk_tree_model_get (model, iter, - EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &contact, - -1); - - if (contact != data->event->contact) { - if (contact) { - g_object_unref (contact); - } - return FALSE; - } - - if (data->on) { - icon_name = data->event->icon_name; - } else { - icon_name = empathy_icon_name_for_contact (contact); - } - - gtk_tree_store_set (GTK_TREE_STORE (model), iter, - EMPATHY_CONTACT_LIST_STORE_COL_ICON_STATUS, icon_name, - -1); - - /* 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. - */ - if (gtk_tree_model_iter_parent (model, &parent_iter, iter)) { - parent_path = gtk_tree_model_get_path (model, &parent_iter); - } - if (parent_path) { - gtk_tree_model_row_changed (model, parent_path, &parent_iter); - gtk_tree_path_free (parent_path); - } - - g_object_unref (contact); - - return FALSE; -} - -static gboolean -main_window_flash_cb (EmpathyMainWindow *window) -{ - GtkTreeModel *model; - GSList *events, *l; - gboolean found_event = FALSE; - FlashForeachData data; - - window->flash_on = !window->flash_on; - data.on = window->flash_on; - model = GTK_TREE_MODEL (window->list_store); - - events = empathy_event_manager_get_events (window->event_manager); - for (l = events; l; l = l->next) { - data.event = l->data; - if (!data.event->contact) { - continue; - } - - found_event = TRUE; - gtk_tree_model_foreach (model, - main_window_flash_foreach, - &data); - } - - if (!found_event) { - main_window_flash_stop (window); - } - - return TRUE; -} - -static void -main_window_flash_start (EmpathyMainWindow *window) -{ - if (window->flash_timeout_id != 0) { - return; - } - - DEBUG ("Start flashing"); - window->flash_timeout_id = g_timeout_add (FLASH_TIMEOUT, - (GSourceFunc) main_window_flash_cb, - window); - main_window_flash_cb (window); -} - -static void -main_window_event_added_cb (EmpathyEventManager *manager, - EmpathyEvent *event, - EmpathyMainWindow *window) -{ - if (event->contact) { - main_window_flash_start (window); - } -} - -static void -main_window_event_removed_cb (EmpathyEventManager *manager, - EmpathyEvent *event, - EmpathyMainWindow *window) -{ - FlashForeachData data; - - if (!event->contact) { - return; - } - - data.on = FALSE; - data.event = event; - gtk_tree_model_foreach (GTK_TREE_MODEL (window->list_store), - main_window_flash_foreach, - &data); -} - -static void -main_window_row_activated_cb (EmpathyContactListView *view, - GtkTreePath *path, - GtkTreeViewColumn *col, - EmpathyMainWindow *window) -{ - EmpathyContact *contact; - GtkTreeModel *model; - GtkTreeIter iter; - GSList *events, *l; - - model = GTK_TREE_MODEL (window->list_store); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, - EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &contact, - -1); - - if (!contact) { - return; - } - - /* If the contact has an event activate it, otherwise the - * default handler of row-activated will be called. */ - events = empathy_event_manager_get_events (window->event_manager); - for (l = events; l; l = l->next) { - EmpathyEvent *event = l->data; - - if (event->contact == contact) { - DEBUG ("Activate event"); - empathy_event_activate (event); - - /* We don't want the default handler of this signal - * (e.g. open a chat) */ - g_signal_stop_emission_by_name (view, "row-activated"); - break; - } - } - - g_object_unref (contact); -} - -static void -main_window_connection_changed_cb (EmpathyAccountManager *manager, - McAccount *account, - TpConnectionStatusReason reason, - TpConnectionStatus current, - TpConnectionStatus previous, - EmpathyMainWindow *window) -{ - main_window_update_status (window, manager); - - if (current == TP_CONNECTION_STATUS_DISCONNECTED && - reason != TP_CONNECTION_STATUS_REASON_REQUESTED) { - const gchar *message; - - switch (reason) { - case TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED: - message = _("No error specified"); - break; - case TP_CONNECTION_STATUS_REASON_NETWORK_ERROR: - message = _("Network error"); - break; - case TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED: - message = _("Authentication failed"); - break; - case TP_CONNECTION_STATUS_REASON_ENCRYPTION_ERROR: - message = _("Encryption error"); - break; - case TP_CONNECTION_STATUS_REASON_NAME_IN_USE: - message = _("Name in use"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_NOT_PROVIDED: - message = _("Certificate not provided"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_UNTRUSTED: - message = _("Certificate untrusted"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_EXPIRED: - message = _("Certificate expired"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_NOT_ACTIVATED: - message = _("Certificate not activated"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_HOSTNAME_MISMATCH: - message = _("Certificate hostname mismatch"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_FINGERPRINT_MISMATCH: - message = _("Certificate fingerprint mismatch"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_SELF_SIGNED: - message = _("Certificate self-signed"); - break; - case TP_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR: - message = _("Certificate error"); - break; - default: - message = _("Unknown error"); - break; - } - - main_window_error_display (window, account, message); - } - - if (current == TP_CONNECTION_STATUS_DISCONNECTED) { - empathy_sound_play (GTK_WIDGET (window->window), - EMPATHY_SOUND_ACCOUNT_DISCONNECTED); - } - - if (current == TP_CONNECTION_STATUS_CONNECTED) { - GtkWidget *error_widget; - - empathy_sound_play (GTK_WIDGET (window->window), - EMPATHY_SOUND_ACCOUNT_CONNECTED); - - /* Account connected without error, remove error message if any */ - error_widget = g_hash_table_lookup (window->errors, account); - if (error_widget) { - gtk_widget_destroy (error_widget); - g_hash_table_remove (window->errors, account); - } - } -} - -static void -main_window_contact_presence_changed_cb (EmpathyContactMonitor *monitor, - EmpathyContact *contact, - McPresence current, - McPresence previous, - EmpathyMainWindow *window) -{ - McAccount *account; - gboolean should_play; - - account = empathy_contact_get_account (contact); - should_play = !empathy_account_manager_is_account_just_connected (window->account_manager, account); - - if (!should_play) { - 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); - } -} - -GtkWidget * -empathy_main_window_get (void) -{ - return window != NULL ? window->window : NULL; -} - -GtkWidget * -empathy_main_window_show (void) -{ - EmpathyContactList *list_iface; - EmpathyContactMonitor *monitor; - GladeXML *glade; - EmpathyConf *conf; - GtkWidget *sw; - GtkWidget *show_offline_widget; - GtkWidget *ebox; - GtkToolItem *item; - gboolean show_offline; - gboolean show_avatars; - gboolean compact_contact_list; - gint x, y, w, h; - gchar *filename; - GSList *l; - - if (window) { - empathy_window_present (GTK_WINDOW (window->window), TRUE); - return window->window; - } - - window = g_new0 (EmpathyMainWindow, 1); - - /* Set up interface */ - filename = empathy_file_lookup ("empathy-main-window.glade", "src"); - glade = empathy_glade_get_file (filename, - "main_window", - NULL, - "main_window", &window->window, - "main_vbox", &window->main_vbox, - "errors_vbox", &window->errors_vbox, - "chat_show_offline", &show_offline_widget, - "room", &window->room, - "room_sep", &window->room_sep, - "room_join_favorites", &window->room_join_favorites, - "edit_context", &window->edit_context, - "edit_context_separator", &window->edit_context_separator, - "presence_toolbar", &window->presence_toolbar, - "roster_scrolledwindow", &sw, - "chat_history", &window->chat_history_menu_item, - NULL); - g_free (filename); - - empathy_glade_connect (glade, - window, - "main_window", "destroy", main_window_destroy_cb, - "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, - "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, - "edit", "button-press-event", main_window_edit_button_press_event_cb, - "edit_accounts", "activate", main_window_edit_accounts_cb, - "edit_personal_information", "activate", main_window_edit_personal_information_cb, - "edit_preferences", "activate", main_window_edit_preferences_cb, - "help_about", "activate", main_window_help_about_cb, - "help_contents", "activate", main_window_help_contents_cb, - NULL); - - /* Set up connection related widgets. */ - main_window_connection_items_setup (window, glade); - g_object_unref (glade); - - window->mc = empathy_mission_control_dup_singleton (); - window->account_manager = empathy_account_manager_dup_singleton (); - - g_signal_connect (window->account_manager, - "account-connection-changed", - G_CALLBACK (main_window_connection_changed_cb), window); - - window->errors = g_hash_table_new_full (empathy_account_hash, - empathy_account_equal, - g_object_unref, - NULL); - - /* Set up menu */ - main_window_favorite_chatroom_menu_setup (window); - - gtk_widget_hide (window->edit_context); - gtk_widget_hide (window->edit_context_separator); - - /* Set up presence chooser */ - window->presence_chooser = empathy_presence_chooser_new (); - gtk_widget_show (window->presence_chooser); - item = gtk_tool_item_new (); - gtk_widget_show (GTK_WIDGET (item)); - gtk_container_add (GTK_CONTAINER (item), window->presence_chooser); - gtk_tool_item_set_is_important (item, TRUE); - gtk_tool_item_set_expand (item, TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (window->presence_toolbar), item, -1); - - /* Set up the throbber */ - ebox = gtk_event_box_new (); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), FALSE); - gtk_widget_set_tooltip_text (ebox, _("Show and edit accounts")); - g_signal_connect (ebox, - "button-press-event", - G_CALLBACK (main_window_throbber_button_press_event_cb), - window); - gtk_widget_show (ebox); - - window->throbber = ephy_spinner_new (); - ephy_spinner_set_size (EPHY_SPINNER (window->throbber), GTK_ICON_SIZE_LARGE_TOOLBAR); - gtk_container_add (GTK_CONTAINER (ebox), window->throbber); - gtk_widget_show (window->throbber); - - item = gtk_tool_item_new (); - gtk_container_add (GTK_CONTAINER (item), ebox); - gtk_toolbar_insert (GTK_TOOLBAR (window->presence_toolbar), item, -1); - gtk_widget_show (GTK_WIDGET (item)); - - /* Set up contact list. */ - empathy_status_presets_get_all (); - - list_iface = EMPATHY_CONTACT_LIST (empathy_contact_manager_dup_singleton ()); - monitor = empathy_contact_list_get_monitor (list_iface); - window->list_store = empathy_contact_list_store_new (list_iface); - window->list_view = empathy_contact_list_view_new (window->list_store, - EMPATHY_CONTACT_LIST_FEATURE_ALL, - EMPATHY_CONTACT_FEATURE_ALL); - g_signal_connect (monitor, "contact-presence-changed", - G_CALLBACK (main_window_contact_presence_changed_cb), window); - g_object_unref (list_iface); - - gtk_widget_show (GTK_WIDGET (window->list_view)); - gtk_container_add (GTK_CONTAINER (sw), - GTK_WIDGET (window->list_view)); - g_signal_connect (window->list_view, "row-activated", - G_CALLBACK (main_window_row_activated_cb), - window); - - /* Load user-defined accelerators. */ - main_window_accels_load (); - - /* Set window size. */ - empathy_geometry_load (GEOMETRY_NAME, &x, &y, &w, &h); - - if (w >= 1 && h >= 1) { - /* Use the defaults from the glade file if we - * don't have good w, h geometry. - */ - DEBUG ("Configuring window default size w:%d, h:%d", w, h); - gtk_window_set_default_size (GTK_WINDOW (window->window), w, h); - } - - if (x >= 0 && y >= 0) { - /* Let the window manager position it if we - * don't have good x, y coordinates. - */ - DEBUG ("Configuring window default position x:%d, y:%d", x, y); - gtk_window_move (GTK_WINDOW (window->window), x, y); - } - - /* Enable event handling */ - window->event_manager = empathy_event_manager_dup_singleton (); - g_signal_connect (window->event_manager, "event-added", - G_CALLBACK (main_window_event_added_cb), - window); - g_signal_connect (window->event_manager, "event-removed", - G_CALLBACK (main_window_event_removed_cb), - window); - - g_signal_connect (window->account_manager, "account-created", - G_CALLBACK (main_window_account_created_or_deleted_cb), - window); - g_signal_connect (window->account_manager, "account-deleted", - G_CALLBACK (main_window_account_created_or_deleted_cb), - window); - main_window_account_created_or_deleted_cb (window->account_manager, NULL, window); - - l = empathy_event_manager_get_events (window->event_manager); - while (l) { - main_window_event_added_cb (window->event_manager, - l->data, window); - l = l->next; - } - - conf = empathy_conf_get (); - - /* Show offline ? */ - empathy_conf_get_bool (conf, - EMPATHY_PREFS_CONTACTS_SHOW_OFFLINE, - &show_offline); - empathy_conf_notify_add (conf, - EMPATHY_PREFS_CONTACTS_SHOW_OFFLINE, - main_window_notify_show_offline_cb, - show_offline_widget); - - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (show_offline_widget), - show_offline); - - /* Show avatars ? */ - empathy_conf_get_bool (conf, - EMPATHY_PREFS_UI_SHOW_AVATARS, - &show_avatars); - empathy_conf_notify_add (conf, - EMPATHY_PREFS_UI_SHOW_AVATARS, - (EmpathyConfNotifyFunc) main_window_notify_show_avatars_cb, - window); - empathy_contact_list_store_set_show_avatars (window->list_store, show_avatars); - - /* Is compact ? */ - empathy_conf_get_bool (conf, - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - &compact_contact_list); - empathy_conf_notify_add (conf, - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - (EmpathyConfNotifyFunc) main_window_notify_compact_contact_list_cb, - window); - empathy_contact_list_store_set_is_compact (window->list_store, compact_contact_list); - - /* Sort criterium */ - empathy_conf_notify_add (conf, - EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, - (EmpathyConfNotifyFunc) main_window_notify_sort_criterium_cb, - window); - main_window_notify_sort_criterium_cb (conf, - EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, - window); - - main_window_update_status (window, window->account_manager); - - return window->window; -} - -static void -main_window_destroy_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - /* Save user-defined accelerators. */ - main_window_accels_save (); - - g_signal_handlers_disconnect_by_func (window->account_manager, - main_window_connection_changed_cb, - window); - - if (window->size_timeout_id) { - g_source_remove (window->size_timeout_id); - } - - g_list_free (window->widgets_connected); - - g_object_unref (window->mc); - g_object_unref (window->account_manager); - g_object_unref (window->list_store); - g_hash_table_destroy (window->errors); - - g_signal_handlers_disconnect_by_func (window->event_manager, - main_window_event_added_cb, - window); - g_signal_handlers_disconnect_by_func (window->event_manager, - main_window_event_removed_cb, - window); - g_object_unref (window->event_manager); - - g_free (window); -} - -static void -main_window_favorite_chatroom_menu_setup (EmpathyMainWindow *window) -{ - GList *chatrooms, *l; - - window->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL); - chatrooms = empathy_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL); - window->room_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (window->room)); - - for (l = chatrooms; l; l = l->next) { - main_window_favorite_chatroom_menu_add (window, l->data); - } - - if (!chatrooms) { - gtk_widget_hide (window->room_sep); - } - - gtk_widget_set_sensitive (window->room_join_favorites, chatrooms != NULL); - - g_signal_connect (window->chatroom_manager, "chatroom-added", - G_CALLBACK (main_window_favorite_chatroom_menu_added_cb), - window); - g_signal_connect (window->chatroom_manager, "chatroom-removed", - G_CALLBACK (main_window_favorite_chatroom_menu_removed_cb), - window); - - g_list_free (chatrooms); -} - -static void -main_window_favorite_chatroom_menu_added_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyMainWindow *window) -{ - main_window_favorite_chatroom_menu_add (window, chatroom); - gtk_widget_show (window->room_sep); - gtk_widget_set_sensitive (window->room_join_favorites, TRUE); -} - -static void -main_window_favorite_chatroom_menu_removed_cb (EmpathyChatroomManager *manager, - EmpathyChatroom *chatroom, - EmpathyMainWindow *window) -{ - GtkWidget *menu_item; - - menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item"); - - g_object_set_data (G_OBJECT (chatroom), "menu_item", NULL); - gtk_widget_destroy (menu_item); - - main_window_favorite_chatroom_menu_update (window); -} - -static void -main_window_favorite_chatroom_menu_activate_cb (GtkMenuItem *menu_item, - EmpathyChatroom *chatroom) -{ - main_window_favorite_chatroom_join (chatroom); -} - -static void -main_window_favorite_chatroom_menu_update (EmpathyMainWindow *window) -{ - GList *chatrooms; - - chatrooms = empathy_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL); - - if (chatrooms) { - gtk_widget_show (window->room_sep); - } else { - gtk_widget_hide (window->room_sep); - } - - gtk_widget_set_sensitive (window->room_join_favorites, chatrooms != NULL); - g_list_free (chatrooms); -} - -static void -main_window_favorite_chatroom_menu_add (EmpathyMainWindow *window, - EmpathyChatroom *chatroom) -{ - GtkWidget *menu_item; - const gchar *name; - - if (g_object_get_data (G_OBJECT (chatroom), "menu_item")) { - return; - } - - name = empathy_chatroom_get_name (chatroom); - menu_item = gtk_menu_item_new_with_label (name); - - g_object_set_data (G_OBJECT (chatroom), "menu_item", menu_item); - g_signal_connect (menu_item, "activate", - G_CALLBACK (main_window_favorite_chatroom_menu_activate_cb), - chatroom); - - gtk_menu_shell_insert (GTK_MENU_SHELL (window->room_menu), - menu_item, 3); - - gtk_widget_show (menu_item); -} - -static void -main_window_favorite_chatroom_join (EmpathyChatroom *chatroom) -{ - MissionControl *mc; - McAccount *account; - const gchar *room; - - mc = empathy_mission_control_dup_singleton (); - account = empathy_chatroom_get_account (chatroom); - room = empathy_chatroom_get_room (chatroom); - - if (mission_control_get_connection_status (mc, account, NULL) != - TP_CONNECTION_STATUS_CONNECTED) { - return; - } - - DEBUG ("Requesting channel for '%s'", room); - empathy_dispatcher_join_muc (account, room, NULL, NULL); - - g_object_unref (mc); -} - -static void -main_window_chat_quit_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - gtk_main_quit (); -} - -static void -main_window_chat_new_message_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_new_message_dialog_show (GTK_WINDOW (window->window)); -} - -static void -main_window_chat_history_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_log_window_show (NULL, NULL, FALSE, GTK_WINDOW (window->window)); -} - -static void -main_window_room_join_new_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_new_chatroom_dialog_show (GTK_WINDOW (window->window)); -} - -static void -main_window_room_join_favorites_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - GList *chatrooms, *l; - - chatrooms = empathy_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL); - for (l = chatrooms; l; l = l->next) { - main_window_favorite_chatroom_join (l->data); - } - g_list_free (chatrooms); -} - -static void -main_window_room_manage_favorites_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_chatrooms_window_show (GTK_WINDOW (window->window)); -} - -static void -main_window_chat_add_contact_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_new_contact_dialog_show (GTK_WINDOW (window->window)); -} - -static void -main_window_chat_show_offline_cb (GtkCheckMenuItem *item, - EmpathyMainWindow *window) -{ - gboolean current; - - current = gtk_check_menu_item_get_active (item); - - empathy_conf_set_bool (empathy_conf_get (), - EMPATHY_PREFS_CONTACTS_SHOW_OFFLINE, - current); - - /* Turn off sound just while we alter the contact list. */ - // FIXME: empathy_sound_set_enabled (FALSE); - empathy_contact_list_store_set_show_offline (window->list_store, current); - //empathy_sound_set_enabled (TRUE); -} - -static gboolean -main_window_edit_button_press_event_cb (GtkWidget *widget, - GdkEventButton *event, - EmpathyMainWindow *window) -{ - GtkWidget *submenu; - - if (!event->button == 1) { - return FALSE; - } - - submenu = empathy_contact_list_view_get_contact_menu (window->list_view); - if (submenu) { - GtkMenuItem *item; - GtkWidget *label; - - item = GTK_MENU_ITEM (window->edit_context); - label = gtk_bin_get_child (GTK_BIN (item)); - gtk_label_set_text (GTK_LABEL (label), _("Contact")); - - gtk_widget_show (window->edit_context); - gtk_widget_show (window->edit_context_separator); - - gtk_menu_item_set_submenu (item, submenu); - - return FALSE; - } - - submenu = empathy_contact_list_view_get_group_menu (window->list_view); - if (submenu) { - GtkMenuItem *item; - GtkWidget *label; - - item = GTK_MENU_ITEM (window->edit_context); - label = gtk_bin_get_child (GTK_BIN (item)); - gtk_label_set_text (GTK_LABEL (label), _("Group")); - - gtk_widget_show (window->edit_context); - gtk_widget_show (window->edit_context_separator); - - gtk_menu_item_set_submenu (item, submenu); - - return FALSE; - } - - gtk_widget_hide (window->edit_context); - gtk_widget_hide (window->edit_context_separator); - - return FALSE; -} - -static void -main_window_edit_accounts_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_accounts_dialog_show (GTK_WINDOW (window->window), NULL); -} - -static void -main_window_edit_personal_information_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - GSList *accounts; - - accounts = mission_control_get_online_connections (window->mc, NULL); - if (accounts) { - EmpathyContactFactory *factory; - EmpathyContact *contact; - McAccount *account; - - account = accounts->data; - factory = empathy_contact_factory_dup_singleton (); - contact = empathy_contact_factory_get_user (factory, account); - empathy_contact_run_until_ready (contact, - EMPATHY_CONTACT_READY_HANDLE | - EMPATHY_CONTACT_READY_ID, - NULL); - - empathy_contact_information_dialog_show (contact, - GTK_WINDOW (window->window), - TRUE, TRUE); - - g_slist_foreach (accounts, (GFunc) g_object_unref, NULL); - g_slist_free (accounts); - g_object_unref (factory); - g_object_unref (contact); - } -} - -static void -main_window_edit_preferences_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_preferences_show (GTK_WINDOW (window->window)); -} - -static void -main_window_help_about_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_about_dialog_new (GTK_WINDOW (window->window)); -} - -static void -main_window_help_contents_cb (GtkWidget *widget, - EmpathyMainWindow *window) -{ - empathy_url_show (widget, "ghelp:empathy"); -} - -static gboolean -main_window_throbber_button_press_event_cb (GtkWidget *throbber_ebox, - GdkEventButton *event, - EmpathyMainWindow *window) -{ - if (event->type != GDK_BUTTON_PRESS || - event->button != 1) { - return FALSE; - } - - empathy_accounts_dialog_show (GTK_WINDOW (window->window), NULL); - - return FALSE; -} - -static void -main_window_error_edit_clicked_cb (GtkButton *button, - EmpathyMainWindow *window) -{ - McAccount *account; - GtkWidget *error_widget; - - account = g_object_get_data (G_OBJECT (button), "account"); - empathy_accounts_dialog_show (GTK_WINDOW (window->window), account); - - error_widget = g_hash_table_lookup (window->errors, account); - gtk_widget_destroy (error_widget); - g_hash_table_remove (window->errors, account); -} - -static void -main_window_error_clear_clicked_cb (GtkButton *button, - EmpathyMainWindow *window) -{ - McAccount *account; - GtkWidget *error_widget; - - account = g_object_get_data (G_OBJECT (button), "account"); - error_widget = g_hash_table_lookup (window->errors, account); - gtk_widget_destroy (error_widget); - g_hash_table_remove (window->errors, account); -} - -static void -main_window_error_display (EmpathyMainWindow *window, - McAccount *account, - const gchar *message) -{ - GtkWidget *child; - GtkWidget *table; - GtkWidget *image; - GtkWidget *button_edit; - GtkWidget *alignment; - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *fixed; - GtkWidget *vbox; - GtkWidget *button_close; - gchar *str; - - child = g_hash_table_lookup (window->errors, account); - if (child) { - label = g_object_get_data (G_OBJECT (child), "label"); - - /* Just set the latest error and return */ - str = g_markup_printf_escaped ("<b>%s</b>\n%s", - mc_account_get_display_name (account), - message); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - - return; - } - - child = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (window->errors_vbox), child, FALSE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (child), 6); - gtk_widget_show (child); - - table = gtk_table_new (2, 4, FALSE); - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (child), table, TRUE, TRUE, 0); - gtk_table_set_row_spacings (GTK_TABLE (table), 12); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - - image = gtk_image_new_from_stock (GTK_STOCK_DISCONNECT, GTK_ICON_SIZE_MENU); - gtk_widget_show (image); - gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0); - - button_edit = gtk_button_new (); - gtk_widget_show (button_edit); - gtk_table_attach (GTK_TABLE (table), button_edit, 1, 2, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - alignment = gtk_alignment_new (0.5, 0.5, 0, 0); - gtk_widget_show (alignment); - gtk_container_add (GTK_CONTAINER (button_edit), alignment); - - hbox = gtk_hbox_new (FALSE, 2); - gtk_widget_show (hbox); - gtk_container_add (GTK_CONTAINER (alignment), hbox); - - image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (image); - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); - - label = gtk_label_new_with_mnemonic (_("_Edit account")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - fixed = gtk_fixed_new (); - gtk_widget_show (fixed); - gtk_table_attach (GTK_TABLE (table), fixed, 2, 3, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_widget_show (vbox); - gtk_table_attach (GTK_TABLE (table), vbox, 3, 4, 0, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (GTK_FILL), 0, 0); - - button_close = gtk_button_new (); - gtk_widget_show (button_close); - gtk_box_pack_start (GTK_BOX (vbox), button_close, FALSE, FALSE, 0); - gtk_button_set_relief (GTK_BUTTON (button_close), GTK_RELIEF_NONE); - - - image = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_MENU); - gtk_widget_show (image); - gtk_container_add (GTK_CONTAINER (button_close), image); - - label = gtk_label_new (""); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, 1, 3, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), - (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL), 0, 0); - gtk_widget_set_size_request (label, 175, -1); - gtk_label_set_use_markup (GTK_LABEL (label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0); - - str = g_markup_printf_escaped ("<b>%s</b>\n%s", - mc_account_get_display_name (account), - message); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - - g_object_set_data (G_OBJECT (child), "label", label); - g_object_set_data_full (G_OBJECT (button_edit), - "account", g_object_ref (account), - g_object_unref); - g_object_set_data_full (G_OBJECT (button_close), - "account", g_object_ref (account), - g_object_unref); - - g_signal_connect (button_edit, "clicked", - G_CALLBACK (main_window_error_edit_clicked_cb), - window); - - g_signal_connect (button_close, "clicked", - G_CALLBACK (main_window_error_clear_clicked_cb), - window); - - gtk_widget_show (window->errors_vbox); - - g_hash_table_insert (window->errors, g_object_ref (account), child); -} - -static void -main_window_update_status (EmpathyMainWindow *window, EmpathyAccountManager *manager) -{ - int connected; - int connecting; - GList *l; - - /* Count number of connected/connecting/disconnected accounts */ - connected = empathy_account_manager_get_connected_accounts (manager); - connecting = empathy_account_manager_get_connecting_accounts (manager); - - /* Update the spinner state */ - if (connecting > 0) { - ephy_spinner_start (EPHY_SPINNER (window->throbber)); - } else { - ephy_spinner_stop (EPHY_SPINNER (window->throbber)); - } - - /* Update widgets sensibility */ - for (l = window->widgets_connected; l; l = l->next) { - gtk_widget_set_sensitive (l->data, (connected > 0)); - } -} - -/* - * Accels - */ -static void -main_window_accels_load (void) -{ - gchar *filename; - - filename = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, ACCELS_FILENAME, NULL); - if (g_file_test (filename, G_FILE_TEST_EXISTS)) { - DEBUG ("Loading from:'%s'", filename); - gtk_accel_map_load (filename); - } - - g_free (filename); -} - -static void -main_window_accels_save (void) -{ - gchar *dir; - gchar *file_with_path; - - dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL); - g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR); - file_with_path = g_build_filename (dir, ACCELS_FILENAME, NULL); - g_free (dir); - - DEBUG ("Saving to:'%s'", file_with_path); - gtk_accel_map_save (file_with_path); - - g_free (file_with_path); -} - -static void -main_window_connection_items_setup (EmpathyMainWindow *window, - GladeXML *glade) -{ - GList *list; - GtkWidget *w; - gint i; - const gchar *widgets_connected[] = { - "room", - "chat_new_message", - "chat_add_contact", - "edit_personal_information" - }; - - for (i = 0, list = NULL; i < G_N_ELEMENTS (widgets_connected); i++) { - w = glade_xml_get_widget (glade, widgets_connected[i]); - list = g_list_prepend (list, w); - } - - window->widgets_connected = list; -} - -static gboolean -main_window_configure_event_timeout_cb (EmpathyMainWindow *window) -{ - gint x, y, w, h; - - gtk_window_get_size (GTK_WINDOW (window->window), &w, &h); - gtk_window_get_position (GTK_WINDOW (window->window), &x, &y); - - empathy_geometry_save (GEOMETRY_NAME, x, y, w, h); - - window->size_timeout_id = 0; - - return FALSE; -} - -static gboolean -main_window_configure_event_cb (GtkWidget *widget, - GdkEventConfigure *event, - EmpathyMainWindow *window) -{ - if (window->size_timeout_id) { - g_source_remove (window->size_timeout_id); - } - - window->size_timeout_id = g_timeout_add_seconds (1, - (GSourceFunc) main_window_configure_event_timeout_cb, - window); - - return FALSE; -} - -static void -main_window_notify_show_offline_cb (EmpathyConf *conf, - const gchar *key, - gpointer check_menu_item) -{ - gboolean show_offline; - - if (empathy_conf_get_bool (conf, key, &show_offline)) { - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (check_menu_item), - show_offline); - } -} - -static void -main_window_notify_show_avatars_cb (EmpathyConf *conf, - const gchar *key, - EmpathyMainWindow *window) -{ - gboolean show_avatars; - - if (empathy_conf_get_bool (conf, key, &show_avatars)) { - empathy_contact_list_store_set_show_avatars (window->list_store, - show_avatars); - } -} - -static void -main_window_notify_compact_contact_list_cb (EmpathyConf *conf, - const gchar *key, - EmpathyMainWindow *window) -{ - gboolean compact_contact_list; - - if (empathy_conf_get_bool (conf, key, &compact_contact_list)) { - empathy_contact_list_store_set_is_compact (window->list_store, - compact_contact_list); - } -} - -static void -main_window_notify_sort_criterium_cb (EmpathyConf *conf, - const gchar *key, - EmpathyMainWindow *window) -{ - gchar *str = NULL; - - if (empathy_conf_get_string (conf, key, &str) && str) { - GType type; - GEnumClass *enum_class; - GEnumValue *enum_value; - - type = empathy_contact_list_store_sort_get_type (); - enum_class = G_ENUM_CLASS (g_type_class_peek (type)); - enum_value = g_enum_get_value_by_nick (enum_class, str); - g_free (str); - - if (enum_value) { - empathy_contact_list_store_set_sort_criterium (window->list_store, - enum_value->value); - } - } -} - -static void -main_window_account_created_or_deleted_cb (EmpathyAccountManager *manager, - McAccount *account, - EmpathyMainWindow *window) -{ - gtk_widget_set_sensitive (GTK_WIDGET (window->chat_history_menu_item), - empathy_account_manager_get_count (manager) > 0); -} diff --git a/src/empathy-main-window.glade b/src/empathy-main-window.glade deleted file mode 100644 index 737105d23..000000000 --- a/src/empathy-main-window.glade +++ /dev/null @@ -1,299 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkWindow" id="main_window"> - <property name="title" translatable="yes">Contact List</property> - <property name="role">contact_list</property> - <property name="default_width">225</property> - <property name="default_height">325</property> - <child> - <widget class="GtkVBox" id="main_vbox"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuBar" id="menubar2"> - <property name="visible">True</property> - <child> - <widget class="GtkMenuItem" id="chat"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Chat</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="chat_menu"> - <child> - <widget class="GtkImageMenuItem" id="chat_new_message"> - <property name="visible">True</property> - <property name="label" translatable="yes">_New Conversation...</property> - <property name="use_underline">True</property> - <accelerator key="N" modifiers="GDK_CONTROL_MASK" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image885"> - <property name="visible">True</property> - <property name="icon_size">1</property> - <property name="icon_name">im-message-new</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="chat_history"> - <property name="visible">True</property> - <property name="label" translatable="yes">_View Previous Conversations</property> - <property name="use_underline">True</property> - <accelerator key="F3" modifiers="" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image886"> - <property name="visible">True</property> - <property name="icon_size">1</property> - <property name="icon_name">document-open-recent</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator5"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="chat_add_contact"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Add Contact...</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image887"> - <property name="visible">True</property> - <property name="stock">gtk-add</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator3"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkCheckMenuItem" id="chat_show_offline"> - <property name="visible">True</property> - <property name="label" translatable="yes">Show _Offline Contacts</property> - <property name="use_underline">True</property> - <accelerator key="H" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator6"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="chat_quit"> - <property name="visible">True</property> - <property name="label">gtk-quit</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="edit"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Edit</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="edit_menu"> - <child> - <widget class="GtkMenuItem" id="edit_context"> - <property name="visible">True</property> - <property name="label" translatable="yes">Context</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="edit_context_separator"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="edit_accounts"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Accounts</property> - <property name="use_underline">True</property> - <accelerator key="F4" modifiers="" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="edit_personal_information"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Personal Information</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image894"> - <property name="visible">True</property> - <property name="icon_size">1</property> - <property name="icon_name">user-info</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="separator2"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="edit_preferences"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Preferences</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image891"> - <property name="visible">True</property> - <property name="stock">gtk-preferences</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="room"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Room</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="room_menu"> - <child> - <widget class="GtkMenuItem" id="room_join_new"> - <property name="visible">True</property> - <property name="label" translatable="yes">Join _New...</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="room_join_favorites"> - <property name="visible">True</property> - <property name="label" translatable="yes">Join _Favorites</property> - <property name="use_underline">True</property> - <accelerator key="F5" modifiers="" signal="activate"/> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="room_sep"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="room_sep2"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="room_manage_favorites"> - <property name="visible">True</property> - <property name="label" translatable="yes">Manage Favorites</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image890"> - <property name="visible">True</property> - <property name="icon_size">1</property> - <property name="icon_name">system-users</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="help"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Help</property> - <property name="use_underline">True</property> - <child> - <widget class="GtkMenu" id="help_menu"> - <child> - <widget class="GtkImageMenuItem" id="help_contents"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Contents</property> - <property name="use_underline">True</property> - <accelerator key="F1" modifiers="" signal="activate"/> - <child internal-child="image"> - <widget class="GtkImage" id="image892"> - <property name="visible">True</property> - <property name="stock">gtk-help</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="help_about"> - <property name="visible">True</property> - <property name="label">gtk-about</property> - <property name="use_underline">True</property> - <property name="use_stock">True</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkToolbar" id="presence_toolbar"> - <property name="visible">True</property> - <property name="toolbar_style">GTK_TOOLBAR_BOTH</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="errors_vbox"> - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <widget class="GtkScrolledWindow" id="roster_scrolledwindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_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> - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="position">3</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-main-window.h b/src/empathy-main-window.h deleted file mode 100644 index 7960c460c..000000000 --- a/src/empathy-main-window.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2002-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - */ - -#ifndef __EMPATHY_MAIN_WINDOW_H__ -#define __EMPATHY_MAIN_WINDOW_H__ - -#include <gtk/gtkwidget.h> - -G_BEGIN_DECLS - -GtkWidget *empathy_main_window_get (void); -GtkWidget *empathy_main_window_show (void); - -G_END_DECLS - -#endif /* __EMPATHY_MAIN_WINDOW_H__ */ diff --git a/src/empathy-misc.c b/src/empathy-misc.c deleted file mode 100644 index 0a943bb6d..000000000 --- a/src/empathy-misc.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> - * - */ - -#include "empathy-misc.h" - -#include <libempathy/empathy-utils.h> -#include <libempathy-gtk/empathy-ui-utils.h> -#include <libempathy-gtk/empathy-conf.h> - -/* public methods */ - -GdkPixbuf * -empathy_misc_get_pixbuf_for_notification (EmpathyContact *contact, - const char *icon_name) -{ - GdkPixbuf *pixbuf = NULL; - - if (contact != NULL) { - pixbuf = empathy_pixbuf_avatar_from_contact_scaled (contact, - 48, 48); - } - - if (!pixbuf) { - pixbuf = empathy_pixbuf_from_icon_name_sized - (icon_name, 48); - } - - return pixbuf; -} - -gboolean -empathy_notification_is_enabled (void) -{ - EmpathyConf *conf; - gboolean res; - - conf = empathy_conf_get (); - res = FALSE; - - empathy_conf_get_bool (conf, EMPATHY_PREFS_NOTIFICATIONS_ENABLED, &res); - - if (!res) { - return FALSE; - } - - if (!empathy_check_available_state ()) { - empathy_conf_get_bool (conf, - EMPATHY_PREFS_NOTIFICATIONS_DISABLED_AWAY, - &res); - if (res) { - return FALSE; - } - } - - return TRUE; -} - diff --git a/src/empathy-misc.h b/src/empathy-misc.h deleted file mode 100644 index aaa743ca6..000000000 --- a/src/empathy-misc.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> - * - */ - -#ifndef __EMPATHY_MISC_H__ -#define __EMPATHY_MISC_H__ - -#include <glib.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -#include <libempathy/empathy-contact.h> - -G_BEGIN_DECLS - -/* FIXME: this should *really* belong to libnotify. */ -typedef enum { - EMPATHY_NOTIFICATION_CLOSED_INVALID = 0, - EMPATHY_NOTIFICATION_CLOSED_EXPIRED = 1, - EMPATHY_NOTIFICATION_CLOSED_DISMISSED = 2, - EMPATHY_NOTIFICATION_CLOSED_PROGRAMMATICALY = 3, - EMPATHY_NOTIFICATION_CLOSED_RESERVED = 4 -} EmpathyNotificationClosedReason; - -gboolean empathy_notification_is_enabled (void); -GdkPixbuf * empathy_misc_get_pixbuf_for_notification (EmpathyContact *contact, - const char *icon_name); - -G_END_DECLS - -#endif /* __EMPATHY_MISC_H__ */ diff --git a/src/empathy-new-chatroom-dialog.c b/src/empathy-new-chatroom-dialog.c deleted file mode 100644 index 0d2452b65..000000000 --- a/src/empathy-new-chatroom-dialog.c +++ /dev/null @@ -1,567 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2006-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Martyn Russell <martyn@imendio.com> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> - -#include <string.h> -#include <stdio.h> - -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <glib.h> -#include <glib/gi18n.h> - -#include <libmissioncontrol/mission-control.h> -#include <libmissioncontrol/mc-account.h> -#include <libmissioncontrol/mc-profile.h> - -#include <libempathy/empathy-tp-roomlist.h> -#include <libempathy/empathy-chatroom.h> -#include <libempathy/empathy-utils.h> -#include <libempathy/empathy-dispatcher.h> - -#include <libempathy-gtk/empathy-account-chooser.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-new-chatroom-dialog.h" -#include "ephy-spinner.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_OTHER -#include <libempathy/empathy-debug.h> - -typedef struct { - EmpathyTpRoomlist *room_list; - - GtkWidget *window; - GtkWidget *vbox_widgets; - GtkWidget *table_info; - GtkWidget *label_account; - GtkWidget *account_chooser; - GtkWidget *label_server; - GtkWidget *entry_server; - GtkWidget *togglebutton_refresh; - GtkWidget *label_room; - GtkWidget *entry_room; - GtkWidget *vbox_browse; - GtkWidget *image_status; - GtkWidget *label_status; - GtkWidget *hbox_status; - GtkWidget *throbber; - GtkWidget *treeview; - GtkTreeModel *model; - GtkWidget *button_join; - GtkWidget *button_close; -} EmpathyNewChatroomDialog; - -enum { - COL_NAME, - COL_ROOM, - COL_COUNT -}; - -static void new_chatroom_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_destroy_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, - EmpathyChatroom *chatroom, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, - gpointer unused, - 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, - GtkTreeViewColumn *column, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_join (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_entry_changed_cb (GtkWidget *entry, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_browse_start (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_browse_stop (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_togglebutton_refresh_toggled_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog); - -static EmpathyNewChatroomDialog *dialog_p = NULL; - -void -empathy_new_chatroom_dialog_show (GtkWindow *parent) -{ - EmpathyNewChatroomDialog *dialog; - GladeXML *glade; - GtkSizeGroup *size_group; - gchar *filename; - - if (dialog_p) { - gtk_window_present (GTK_WINDOW (dialog_p->window)); - return; - } - - dialog_p = dialog = g_new0 (EmpathyNewChatroomDialog, 1); - - filename = empathy_file_lookup ("empathy-new-chatroom-dialog.glade", "src"); - glade = empathy_glade_get_file (filename, - "new_chatroom_dialog", - NULL, - "new_chatroom_dialog", &dialog->window, - "table_info", &dialog->table_info, - "label_account", &dialog->label_account, - "label_server", &dialog->label_server, - "label_room", &dialog->label_room, - "entry_server", &dialog->entry_server, - "entry_room", &dialog->entry_room, - "togglebutton_refresh", &dialog->togglebutton_refresh, - "vbox_browse", &dialog->vbox_browse, - "image_status", &dialog->image_status, - "label_status", &dialog->label_status, - "hbox_status", &dialog->hbox_status, - "treeview", &dialog->treeview, - "button_join", &dialog->button_join, - NULL); - g_free (filename); - - empathy_glade_connect (glade, - dialog, - "new_chatroom_dialog", "response", new_chatroom_dialog_response_cb, - "new_chatroom_dialog", "destroy", new_chatroom_dialog_destroy_cb, - "entry_server", "changed", new_chatroom_dialog_entry_changed_cb, - "entry_server", "activate", new_chatroom_dialog_entry_server_activate_cb, - "entry_room", "changed", new_chatroom_dialog_entry_changed_cb, - "togglebutton_refresh", "toggled", new_chatroom_dialog_togglebutton_refresh_toggled_cb, - NULL); - - g_object_unref (glade); - - g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog_p); - - /* Label alignment */ - size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - - gtk_size_group_add_widget (size_group, dialog->label_account); - gtk_size_group_add_widget (size_group, dialog->label_server); - gtk_size_group_add_widget (size_group, dialog->label_room); - - g_object_unref (size_group); - - /* Set up chatrooms treeview */ - new_chatroom_dialog_model_setup (dialog); - - /* Add throbber */ - dialog->throbber = ephy_spinner_new (); - ephy_spinner_set_size (EPHY_SPINNER (dialog->throbber), GTK_ICON_SIZE_LARGE_TOOLBAR); - gtk_widget_show (dialog->throbber); - - gtk_box_pack_start (GTK_BOX (dialog->hbox_status), dialog->throbber, - FALSE, FALSE, 0); - - /* Account chooser for custom */ - dialog->account_chooser = empathy_account_chooser_new (); - empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser), - empathy_account_chooser_filter_is_connected, - NULL); - gtk_table_attach_defaults (GTK_TABLE (dialog->table_info), - dialog->account_chooser, - 1, 3, 0, 1); - gtk_widget_show (dialog->account_chooser); - - g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed", - G_CALLBACK (new_chatroom_dialog_account_changed_cb), - dialog); - new_chatroom_dialog_account_changed_cb (GTK_COMBO_BOX (dialog->account_chooser), - dialog); - - if (parent) { - gtk_window_set_transient_for (GTK_WINDOW (dialog->window), - GTK_WINDOW (parent)); - } - - gtk_widget_show (dialog->window); -} - -static void -new_chatroom_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyNewChatroomDialog *dialog) -{ - if (response == GTK_RESPONSE_OK) { - new_chatroom_dialog_join (dialog); - } - - gtk_widget_destroy (widget); -} - -static void -new_chatroom_dialog_destroy_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog) -{ - if (dialog->room_list) { - g_object_unref (dialog->room_list); - } - g_object_unref (dialog->model); - - g_free (dialog); -} - -static void -new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog) -{ - GtkTreeView *view; - GtkListStore *store; - GtkTreeSelection *selection; - - /* View */ - view = GTK_TREE_VIEW (dialog->treeview); - - g_signal_connect (view, "row-activated", - G_CALLBACK (new_chatroom_dialog_model_row_activated_cb), - dialog); - - /* Store/Model */ - store = gtk_list_store_new (COL_COUNT, - G_TYPE_STRING, /* Image */ - G_TYPE_STRING, /* Text */ - G_TYPE_STRING); /* Room */ - - dialog->model = GTK_TREE_MODEL (store); - gtk_tree_view_set_model (view, dialog->model); - - /* Selection */ - selection = gtk_tree_view_get_selection (view); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - COL_NAME, GTK_SORT_ASCENDING); - - g_signal_connect (selection, "changed", - G_CALLBACK (new_chatroom_dialog_model_selection_changed), - dialog); - - /* Columns */ - new_chatroom_dialog_model_add_columns (dialog); -} - -static void -new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog) -{ - GtkTreeView *view; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - - view = GTK_TREE_VIEW (dialog->treeview); - gtk_tree_view_set_headers_visible (view, FALSE); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "xpad", (guint) 4, - "ypad", (guint) 1, - "ellipsize", PANGO_ELLIPSIZE_END, - NULL); - - column = gtk_tree_view_column_new_with_attributes (_("Chat Rooms"), - cell, - "text", COL_NAME, - NULL); - - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); -} - -static void -new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog) -{ - EmpathyAccountChooser *account_chooser; - McAccount *account; - McProfile *profile; - const gchar *protocol; - const gchar *room; - - account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); - account = empathy_account_chooser_get_account (account_chooser); - profile = mc_account_get_profile (account); - protocol = mc_profile_get_protocol_name (profile); - - gtk_entry_set_text (GTK_ENTRY (dialog->entry_server), ""); - - /* hardcode here known protocols */ - if (strcmp (protocol, "jabber") == 0) { - gtk_widget_set_sensitive (dialog->entry_server, TRUE); - gtk_widget_show (dialog->vbox_browse); - - } - else if (strcmp (protocol, "local-xmpp") == 0) { - gtk_widget_set_sensitive (dialog->entry_server, FALSE); - gtk_widget_show (dialog->vbox_browse); - } - else if (strcmp (protocol, "irc") == 0) { - gtk_widget_set_sensitive (dialog->entry_server, FALSE); - gtk_widget_show (dialog->vbox_browse); - } else { - gtk_widget_set_sensitive (dialog->entry_server, TRUE); - gtk_widget_show (dialog->vbox_browse); - } - - room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - gtk_widget_set_sensitive (dialog->button_join, !EMP_STR_EMPTY (room)); - - /* Final set up of the dialog */ - gtk_widget_grab_focus (dialog->entry_room); - - g_object_unref (account); - g_object_unref (profile); -} - -static void -new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, - EmpathyNewChatroomDialog *dialog) -{ - EmpathyAccountChooser *account_chooser; - McAccount *account; - gboolean listing = FALSE; - - if (dialog->room_list) { - g_object_unref (dialog->room_list); - } - - ephy_spinner_stop (EPHY_SPINNER (dialog->throbber)); - new_chatroom_dialog_model_clear (dialog); - - account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); - account = empathy_account_chooser_get_account (account_chooser); - dialog->room_list = empathy_tp_roomlist_new (account); - - if (dialog->room_list) { - g_signal_connect (dialog->room_list, "destroy", - G_CALLBACK (new_chatroom_dialog_roomlist_destroy_cb), - dialog); - g_signal_connect (dialog->room_list, "new-room", - G_CALLBACK (new_chatroom_dialog_new_room_cb), - dialog); - g_signal_connect (dialog->room_list, "notify::is-listing", - G_CALLBACK (new_chatroom_dialog_listing_cb), - dialog); - - listing = empathy_tp_roomlist_is_listing (dialog->room_list); - if (listing) { - ephy_spinner_start (EPHY_SPINNER (dialog->throbber)); - } - } - - new_chatroom_dialog_update_widgets (dialog); -} - -static void -new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, - EmpathyNewChatroomDialog *dialog) -{ - g_object_unref (dialog->room_list); - dialog->room_list = NULL; -} - -static void -new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, - EmpathyChatroom *chatroom, - EmpathyNewChatroomDialog *dialog) -{ - GtkTreeView *view; - GtkTreeSelection *selection; - GtkListStore *store; - GtkTreeIter iter; - - DEBUG ("New chatroom listed: %s (%s)", - empathy_chatroom_get_name (chatroom), - empathy_chatroom_get_room (chatroom)); - - /* Add to model */ - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - store = GTK_LIST_STORE (dialog->model); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COL_NAME, empathy_chatroom_get_name (chatroom), - COL_ROOM, empathy_chatroom_get_room (chatroom), - -1); -} - -static void -new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, - gpointer unused, - EmpathyNewChatroomDialog *dialog) -{ - gboolean listing; - - listing = empathy_tp_roomlist_is_listing (room_list); - - /* Update the throbber */ - if (listing) { - ephy_spinner_start (EPHY_SPINNER (dialog->throbber)); - } else { - ephy_spinner_stop (EPHY_SPINNER (dialog->throbber)); - } - - /* Update the refresh toggle button */ - g_signal_handlers_block_by_func (dialog->togglebutton_refresh, - new_chatroom_dialog_togglebutton_refresh_toggled_cb, - dialog); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->togglebutton_refresh), - listing); - g_signal_handlers_unblock_by_func (dialog->togglebutton_refresh, - new_chatroom_dialog_togglebutton_refresh_toggled_cb, - dialog); -} - -static void -new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog) -{ - GtkListStore *store; - - store = GTK_LIST_STORE (dialog->model); - gtk_list_store_clear (store); -} - -static void -new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - EmpathyNewChatroomDialog *dialog) -{ - gtk_widget_activate (dialog->button_join); -} - -static void -new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyNewChatroomDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - gchar *room = NULL; - gchar *server = NULL; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return; - } - - gtk_tree_model_get (model, &iter, COL_ROOM, &room, -1); - server = strstr (room, "@"); - if (server) { - *server = '\0'; - server++; - } - - gtk_entry_set_text (GTK_ENTRY (dialog->entry_server), server ? server : ""); - gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), room ? room : ""); - - g_free (room); -} - -static void -new_chatroom_dialog_join (EmpathyNewChatroomDialog *dialog) -{ - EmpathyAccountChooser *account_chooser; - McAccount *account; - const gchar *room; - const gchar *server = NULL; - gchar *room_name = NULL; - - room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - server = gtk_entry_get_text (GTK_ENTRY (dialog->entry_server)); - - account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); - account = empathy_account_chooser_get_account (account_chooser); - - if (!EMP_STR_EMPTY (server)) { - room_name = g_strconcat (room, "@", server, NULL); - } else { - room_name = g_strdup (room); - } - - DEBUG ("Requesting channel for '%s'", room_name); - empathy_dispatcher_join_muc (account, room_name, NULL, NULL); - - g_free (room_name); -} - -static void -new_chatroom_dialog_entry_changed_cb (GtkWidget *entry, - EmpathyNewChatroomDialog *dialog) -{ - if (entry == dialog->entry_room) { - const gchar *room; - - room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - gtk_widget_set_sensitive (dialog->button_join, !EMP_STR_EMPTY (room)); - /* FIXME: Select the room in the list */ - } -} - -static void -new_chatroom_dialog_browse_start (EmpathyNewChatroomDialog *dialog) -{ - new_chatroom_dialog_model_clear (dialog); - if (dialog->room_list) { - empathy_tp_roomlist_start (dialog->room_list); - } -} - -static void -new_chatroom_dialog_browse_stop (EmpathyNewChatroomDialog *dialog) -{ - if (dialog->room_list) { - empathy_tp_roomlist_stop (dialog->room_list); - } -} - -static void -new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog) -{ - new_chatroom_dialog_togglebutton_refresh_toggled_cb (dialog->togglebutton_refresh, - dialog); -} - -static void -new_chatroom_dialog_togglebutton_refresh_toggled_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog) -{ - gboolean toggled; - - toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - - if (toggled) { - new_chatroom_dialog_browse_start (dialog); - } else { - new_chatroom_dialog_browse_stop (dialog); - } -} - diff --git a/src/empathy-new-chatroom-dialog.glade b/src/empathy-new-chatroom-dialog.glade deleted file mode 100644 index 98984f7f7..000000000 --- a/src/empathy-new-chatroom-dialog.glade +++ /dev/null @@ -1,272 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkDialog" id="new_chatroom_dialog"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="title" translatable="yes">Join New</property> - <property name="role">join_new_chatroom</property> - <property name="resizable">False</property> - <property name="default_width">350</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox4"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkVBox" id="vbox_widgets"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="spacing">18</property> - <child> - <widget class="GtkTable" id="table_info"> - <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">3</property> - <property name="column_spacing">6</property> - <property name="row_spacing">6</property> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <widget class="GtkEntry" id="entry_room"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" 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">32</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">3</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkToggleButton" id="togglebutton_refresh"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Re_fresh</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkEntry" id="entry_server"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" 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> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_room"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Room:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_room</property> - </widget> - <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_server"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Server:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_server</property> - </widget> - <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_account"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Account:</property> - </widget> - <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkVBox" id="vbox_browse"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkHBox" id="hbox_status"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkHBox" id="hbox35"> - <property name="visible">True</property> - <property name="spacing">3</property> - <child> - <widget class="GtkImage" id="image_status"> - <property name="visible">True</property> - <property name="icon_size">2</property> - <property name="icon_name">gtk-find</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label_status"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Browse:</property> - <property name="wrap">True</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - <child> - <placeholder/> - </child> - </widget> - </child> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow2"> - <property name="height_request">150</property> - <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> - <child> - <widget class="GtkTreeView" id="treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">This list represents all chat rooms hosted on the server you have entered.</property> - <property name="headers_visible">False</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area4"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="button_cancel"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - <property name="response_id">-7</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="button_join"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="response_id">-5</property> - <child> - <widget class="GtkAlignment" id="alignment4"> - <property name="visible">True</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - <child> - <widget class="GtkHBox" id="hbox29"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkImage" id="image4"> - <property name="visible">True</property> - <property name="stock">gtk-execute</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label79"> - <property name="visible">True</property> - <property name="label" translatable="yes">Join</property> - <property name="use_underline">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-new-chatroom-dialog.h b/src/empathy-new-chatroom-dialog.h deleted file mode 100644 index ae8b2385e..000000000 --- a/src/empathy-new-chatroom-dialog.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2006-2007 Imendio AB - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Martyn Russell <martyn@imendio.com> - * Xavier Claessens <xclaesse@gmail.com> - */ - -#ifndef __EMPATHY_NEW_CHATROOMS_WINDOW_H__ -#define __EMPATHY_NEW_CHATROOMS_WINDOW_H__ - -G_BEGIN_DECLS - -void empathy_new_chatroom_dialog_show (GtkWindow *parent); - -G_END_DECLS - -#endif /* __EMPATHY_NEW_CHATROOMS_WINDOW_H__ */ diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c deleted file mode 100644 index 0ad8e9bdf..000000000 --- a/src/empathy-preferences.c +++ /dev/null @@ -1,1132 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2003-2007 Imendio AB - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Mikael Hallendal <micke@imendio.com> - * Richard Hult <richard@imendio.com> - * Martyn Russell <martyn@imendio.com> - */ - -#include <config.h> - -#include <string.h> - -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <glib/gi18n.h> - -#include <libempathy/empathy-utils.h> - -#include <libempathy-gtk/empathy-conf.h> -#include <libempathy-gtk/empathy-ui-utils.h> -#include <libempathy-gtk/empathy-theme-manager.h> -#include <libempathy-gtk/empathy-spell.h> -#include <libempathy-gtk/empathy-contact-list-store.h> -#include <libempathy-gtk/empathy-gtk-enum-types.h> - -#include "empathy-preferences.h" - -typedef struct { - GtkWidget *dialog; - - GtkWidget *notebook; - - GtkWidget *checkbutton_show_avatars; - GtkWidget *checkbutton_compact_contact_list; - GtkWidget *checkbutton_show_smileys; - GtkWidget *combobox_chat_theme; - GtkWidget *checkbutton_separate_chat_windows; - GtkWidget *checkbutton_autoconnect; - GtkWidget *radiobutton_contact_list_sort_by_name; - GtkWidget *radiobutton_contact_list_sort_by_state; - - GtkWidget *checkbutton_sounds_enabled; - GtkWidget *checkbutton_sounds_disabled_away; - GtkWidget *treeview_sounds; - - GtkWidget *checkbutton_notifications_enabled; - GtkWidget *checkbutton_notifications_disabled_away; - GtkWidget *checkbutton_notifications_focus; - - GtkWidget *treeview_spell_checker; - - GList *notify_ids; -} EmpathyPreferences; - -static void preferences_setup_widgets (EmpathyPreferences *preferences); -static void preferences_languages_setup (EmpathyPreferences *preferences); -static void preferences_languages_add (EmpathyPreferences *preferences); -static void preferences_languages_save (EmpathyPreferences *preferences); -static gboolean preferences_languages_save_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gchar **languages); -static void preferences_languages_load (EmpathyPreferences *preferences); -static gboolean preferences_languages_load_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gchar **languages); -static void preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell, - gchar *path_string, - EmpathyPreferences *preferences); -static void preferences_themes_setup (EmpathyPreferences *preferences); -static void preferences_widget_sync_bool (const gchar *key, - GtkWidget *widget); -static void preferences_widget_sync_string (const gchar *key, - GtkWidget *widget); -static void preferences_widget_sync_string_combo (const gchar *key, - GtkWidget *widget); -static void preferences_notify_string_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_notify_string_combo_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_notify_bool_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_notify_sensitivity_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_hookup_toggle_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_hookup_radio_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_hookup_string_combo (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_hookup_sensitivity (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_toggle_button_toggled_cb (GtkWidget *button, - gpointer user_data); -static void preferences_radio_button_toggled_cb (GtkWidget *button, - gpointer user_data); -static void preferences_string_combo_changed_cb (GtkWidget *button, - gpointer user_data); -static void preferences_destroy_cb (GtkWidget *widget, - EmpathyPreferences *preferences); -static void preferences_response_cb (GtkWidget *widget, - gint response, - EmpathyPreferences *preferences); - -enum { - COL_LANG_ENABLED, - COL_LANG_CODE, - COL_LANG_NAME, - COL_LANG_COUNT -}; - -enum { - COL_COMBO_VISIBLE_NAME, - COL_COMBO_NAME, - COL_COMBO_COUNT -}; - -enum { - COL_SOUND_ENABLED, - COL_SOUND_NAME, - COL_SOUND_KEY, - COL_SOUND_COUNT -}; - -typedef struct { - const char *name; - const char *key; -} SoundEventEntry; - -/* TODO: add phone related sounds also? */ -static SoundEventEntry sound_entries [] = { - { N_("Message received"), EMPATHY_PREFS_SOUNDS_INCOMING_MESSAGE }, - { N_("Message sent"), EMPATHY_PREFS_SOUNDS_OUTGOING_MESSAGE }, - { N_("New conversation"), EMPATHY_PREFS_SOUNDS_NEW_CONVERSATION }, - { N_("Contact goes online"), EMPATHY_PREFS_SOUNDS_CONTACT_LOGIN }, - { N_("Contact goes offline"), EMPATHY_PREFS_SOUNDS_CONTACT_LOGOUT }, - { N_("Account connected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGIN }, - { N_("Account disconnected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGOUT } -}; - -static void -preferences_add_id (EmpathyPreferences *preferences, guint id) -{ - preferences->notify_ids = g_list_prepend (preferences->notify_ids, - GUINT_TO_POINTER (id)); -} - -static void -preferences_compact_contact_list_changed_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - EmpathyPreferences *preferences = user_data; - gboolean value; - - if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) { - gtk_widget_set_sensitive (preferences->checkbutton_show_avatars, - !value); - } -} - -static void -preferences_setup_widgets (EmpathyPreferences *preferences) -{ - guint id; - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - preferences->checkbutton_notifications_enabled); - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_NOTIFICATIONS_DISABLED_AWAY, - preferences->checkbutton_notifications_disabled_away); - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_NOTIFICATIONS_FOCUS, - preferences->checkbutton_notifications_focus); - - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - preferences->checkbutton_notifications_disabled_away); - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - preferences->checkbutton_notifications_focus); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_SOUNDS_ENABLED, - preferences->checkbutton_sounds_enabled); - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_SOUNDS_DISABLED_AWAY, - preferences->checkbutton_sounds_disabled_away); - - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_SOUNDS_ENABLED, - preferences->checkbutton_sounds_disabled_away); - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_SOUNDS_ENABLED, - preferences->treeview_sounds); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, - preferences->checkbutton_separate_chat_windows); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_UI_SHOW_AVATARS, - preferences->checkbutton_show_avatars); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - preferences->checkbutton_compact_contact_list); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_CHAT_SHOW_SMILEYS, - preferences->checkbutton_show_smileys); - - preferences_hookup_string_combo (preferences, - EMPATHY_PREFS_CHAT_THEME, - preferences->combobox_chat_theme); - - preferences_hookup_radio_button (preferences, - EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, - preferences->radiobutton_contact_list_sort_by_name); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_AUTOCONNECT, - preferences->checkbutton_autoconnect); - - id = empathy_conf_notify_add (empathy_conf_get (), - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - preferences_compact_contact_list_changed_cb, - preferences); - if (id) { - preferences_add_id (preferences, id); - } - preferences_compact_contact_list_changed_cb (empathy_conf_get (), - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - preferences); -} - -static void -preferences_sound_cell_toggled_cb (GtkCellRendererToggle *toggle, - char *path_string, - EmpathyPreferences *preferences) -{ - GtkTreePath *path; - gboolean toggled, instore; - GtkTreeIter iter; - GtkTreeView *view; - GtkTreeModel *model; - char *key; - - view = GTK_TREE_VIEW (preferences->treeview_sounds); - model = gtk_tree_view_get_model (view); - - path = gtk_tree_path_new_from_string (path_string); - toggled = gtk_cell_renderer_toggle_get_active (toggle); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, COL_SOUND_KEY, &key, - COL_SOUND_ENABLED, &instore, -1); - - instore ^= 1; - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_SOUND_ENABLED, instore, -1); - - empathy_conf_set_bool (empathy_conf_get (), key, instore); - - gtk_tree_path_free (path); -} - -static void -preferences_sound_load (EmpathyPreferences *preferences) -{ - int i; - GtkTreeView *view; - GtkListStore *store; - GtkTreeIter iter; - gboolean set; - EmpathyConf *conf; - - view = GTK_TREE_VIEW (preferences->treeview_sounds); - store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); - conf = empathy_conf_get (); - - for (i = 0; i < G_N_ELEMENTS (sound_entries); i++) { - empathy_conf_get_bool (conf, sound_entries[i].key, &set); - - gtk_list_store_insert_with_values (store, &iter, i, - COL_SOUND_NAME, gettext (sound_entries[i].name), - COL_SOUND_KEY, sound_entries[i].key, - COL_SOUND_ENABLED, set, -1); - } -} - -static void -preferences_sound_setup (EmpathyPreferences *preferences) -{ - GtkTreeView *view; - GtkListStore *store; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - - view = GTK_TREE_VIEW (preferences->treeview_sounds); - - store = gtk_list_store_new (COL_SOUND_COUNT, - G_TYPE_BOOLEAN, /* enabled */ - G_TYPE_STRING, /* name */ - G_TYPE_STRING); /* key */ - - gtk_tree_view_set_model (view, GTK_TREE_MODEL (store)); - - renderer = gtk_cell_renderer_toggle_new (); - g_signal_connect (renderer, "toggled", - G_CALLBACK (preferences_sound_cell_toggled_cb), - preferences); - - column = gtk_tree_view_column_new (); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - gtk_tree_view_column_add_attribute (column, renderer, - "active", COL_SOUND_ENABLED); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, FALSE); - gtk_tree_view_column_add_attribute (column, renderer, - "text", COL_SOUND_NAME); - - gtk_tree_view_append_column (view, column); - - gtk_tree_view_column_set_resizable (column, FALSE); - gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); - - g_object_unref (store); -} - -static void -preferences_languages_setup (EmpathyPreferences *preferences) -{ - GtkTreeView *view; - GtkListStore *store; - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - guint col_offset; - - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); - - store = gtk_list_store_new (COL_LANG_COUNT, - G_TYPE_BOOLEAN, /* enabled */ - G_TYPE_STRING, /* code */ - G_TYPE_STRING); /* name */ - - gtk_tree_view_set_model (view, GTK_TREE_MODEL (store)); - - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - model = GTK_TREE_MODEL (store); - - renderer = gtk_cell_renderer_toggle_new (); - g_signal_connect (renderer, "toggled", - G_CALLBACK (preferences_languages_cell_toggled_cb), - preferences); - - column = gtk_tree_view_column_new_with_attributes (NULL, renderer, - "active", COL_LANG_ENABLED, - NULL); - - gtk_tree_view_append_column (view, column); - - renderer = gtk_cell_renderer_text_new (); - col_offset = gtk_tree_view_insert_column_with_attributes (view, - -1, _("Language"), - renderer, - "text", COL_LANG_NAME, - NULL); - - g_object_set_data (G_OBJECT (renderer), - "column", GINT_TO_POINTER (COL_LANG_NAME)); - - column = gtk_tree_view_get_column (view, col_offset - 1); - gtk_tree_view_column_set_sort_column_id (column, COL_LANG_NAME); - gtk_tree_view_column_set_resizable (column, FALSE); - gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); - - g_object_unref (store); -} - -static void -preferences_languages_add (EmpathyPreferences *preferences) -{ - GtkTreeView *view; - GtkListStore *store; - GList *codes, *l; - - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); - store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); - - codes = empathy_spell_get_language_codes (); - - empathy_conf_set_bool (empathy_conf_get(), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED, - codes != NULL); - if (!codes) { - gtk_widget_set_sensitive (preferences->treeview_spell_checker, FALSE); - } - - for (l = codes; l; l = l->next) { - GtkTreeIter iter; - const gchar *code; - const gchar *name; - - code = l->data; - name = empathy_spell_get_language_name (code); - if (!name) { - continue; - } - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - COL_LANG_CODE, code, - COL_LANG_NAME, name, - -1); - } - - empathy_spell_free_language_codes (codes); -} - -static void -preferences_languages_save (EmpathyPreferences *preferences) -{ - GtkTreeView *view; - GtkTreeModel *model; - - gchar *languages = NULL; - - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); - model = gtk_tree_view_get_model (view); - - gtk_tree_model_foreach (model, - (GtkTreeModelForeachFunc) preferences_languages_save_foreach, - &languages); - - /* if user selects no languages, we don't want spell check */ - empathy_conf_set_bool (empathy_conf_get (), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED, - languages != NULL); - - empathy_conf_set_string (empathy_conf_get (), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES, - languages ? languages : ""); - - g_free (languages); -} - -static gboolean -preferences_languages_save_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gchar **languages) -{ - gboolean enabled; - gchar *code; - - if (!languages) { - return TRUE; - } - - gtk_tree_model_get (model, iter, COL_LANG_ENABLED, &enabled, -1); - if (!enabled) { - return FALSE; - } - - gtk_tree_model_get (model, iter, COL_LANG_CODE, &code, -1); - if (!code) { - return FALSE; - } - - if (!(*languages)) { - *languages = g_strdup (code); - } else { - gchar *str = *languages; - *languages = g_strdup_printf ("%s,%s", str, code); - g_free (str); - } - - g_free (code); - - return FALSE; -} - -static void -preferences_languages_load (EmpathyPreferences *preferences) -{ - GtkTreeView *view; - GtkTreeModel *model; - gchar *value; - gchar **vlanguages; - - if (!empathy_conf_get_string (empathy_conf_get (), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES, - &value) || !value) { - return; - } - - vlanguages = g_strsplit (value, ",", -1); - g_free (value); - - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); - model = gtk_tree_view_get_model (view); - - gtk_tree_model_foreach (model, - (GtkTreeModelForeachFunc) preferences_languages_load_foreach, - vlanguages); - - g_strfreev (vlanguages); -} - -static gboolean -preferences_languages_load_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gchar **languages) -{ - gchar *code; - gchar *lang; - gint i; - gboolean found = FALSE; - - if (!languages) { - return TRUE; - } - - gtk_tree_model_get (model, iter, COL_LANG_CODE, &code, -1); - if (!code) { - return FALSE; - } - - for (i = 0, lang = languages[i]; lang; lang = languages[++i]) { - if (strcmp (lang, code) == 0) { - found = TRUE; - } - } - - gtk_list_store_set (GTK_LIST_STORE (model), iter, COL_LANG_ENABLED, found, -1); - return FALSE; -} - -static void -preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell, - gchar *path_string, - EmpathyPreferences *preferences) -{ - GtkTreeView *view; - GtkTreeModel *model; - GtkListStore *store; - GtkTreePath *path; - GtkTreeIter iter; - gboolean enabled; - - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); - model = gtk_tree_view_get_model (view); - store = GTK_LIST_STORE (model); - - path = gtk_tree_path_new_from_string (path_string); - - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_get (model, &iter, COL_LANG_ENABLED, &enabled, -1); - - enabled ^= 1; - - gtk_list_store_set (store, &iter, COL_LANG_ENABLED, enabled, -1); - gtk_tree_path_free (path); - - preferences_languages_save (preferences); -} - -static void -preferences_themes_setup (EmpathyPreferences *preferences) -{ - GtkComboBox *combo; - GtkListStore *model; - GtkTreeIter iter; - const gchar **themes; - gint i; - - combo = GTK_COMBO_BOX (preferences->combobox_chat_theme); - - model = gtk_list_store_new (COL_COMBO_COUNT, - G_TYPE_STRING, - G_TYPE_STRING); - - themes = empathy_theme_manager_get_themes (); - for (i = 0; themes[i]; i += 2) { - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - COL_COMBO_VISIBLE_NAME, _(themes[i + 1]), - COL_COMBO_NAME, themes[i], - -1); - } - - gtk_combo_box_set_model (combo, GTK_TREE_MODEL (model)); - g_object_unref (model); -} - -static void -preferences_widget_sync_bool (const gchar *key, GtkWidget *widget) -{ - gboolean value; - - if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value); - } -} - -static void -preferences_widget_sync_string (const gchar *key, GtkWidget *widget) -{ - gchar *value; - - if (empathy_conf_get_string (empathy_conf_get (), key, &value) && value) { - if (GTK_IS_ENTRY (widget)) { - gtk_entry_set_text (GTK_ENTRY (widget), value); - } else if (GTK_IS_RADIO_BUTTON (widget)) { - if (strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0) { - GType type; - GEnumClass *enum_class; - GEnumValue *enum_value; - GSList *list; - GtkWidget *toggle_widget; - - /* Get index from new string */ - type = empathy_contact_list_store_sort_get_type (); - enum_class = G_ENUM_CLASS (g_type_class_peek (type)); - enum_value = g_enum_get_value_by_nick (enum_class, 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); - } - } else { - g_warning ("Unhandled key:'%s' just had string change", key); - } - } - - g_free (value); - } -} - -static void -preferences_widget_sync_string_combo (const gchar *key, GtkWidget *widget) -{ - gchar *value; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean found; - - if (!empathy_conf_get_string (empathy_conf_get (), key, &value)) { - return; - } - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); - - found = FALSE; - if (value && gtk_tree_model_get_iter_first (model, &iter)) { - gchar *name; - - do { - gtk_tree_model_get (model, &iter, - COL_COMBO_NAME, &name, - -1); - - if (strcmp (name, value) == 0) { - found = TRUE; - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter); - break; - } else { - found = FALSE; - } - - g_free (name); - } while (gtk_tree_model_iter_next (model, &iter)); - } - - /* Fallback to the first one. */ - if (!found) { - if (gtk_tree_model_get_iter_first (model, &iter)) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter); - } - } - - g_free (value); -} - -static void -preferences_notify_string_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - preferences_widget_sync_string (key, user_data); -} - -static void -preferences_notify_string_combo_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - preferences_widget_sync_string_combo (key, user_data); -} - -static void -preferences_notify_bool_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - preferences_widget_sync_bool (key, user_data); -} - -static void -preferences_notify_sensitivity_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - gboolean value; - - if (empathy_conf_get_bool (conf, key, &value)) { - gtk_widget_set_sensitive (GTK_WIDGET (user_data), value); - } -} - -#if 0 -static void -preferences_widget_sync_int (const gchar *key, GtkWidget *widget) -{ - gint value; - - if (empathy_conf_get_int (empathy_conf_get (), key, &value)) { - if (GTK_IS_SPIN_BUTTON (widget)) { - gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value); - } - } -} - -static void -preferences_notify_int_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - preferences_widget_sync_int (key, user_data); -} - -static void -preferences_hookup_spin_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - guint id; - - preferences_widget_sync_int (key, widget); - - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); - - g_signal_connect (widget, - "value_changed", - G_CALLBACK (preferences_spin_button_value_changed_cb), - NULL); - - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_int_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } -} - -static void -preferences_hookup_entry (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - guint id; - - preferences_widget_sync_string (key, widget); - - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); - - g_signal_connect (widget, - "changed", - G_CALLBACK (preferences_entry_value_changed_cb), - NULL); - - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_string_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } -} - -static void -preferences_spin_button_value_changed_cb (GtkWidget *button, - gpointer user_data) -{ - const gchar *key; - - key = g_object_get_data (G_OBJECT (button), "key"); - - empathy_conf_set_int (empathy_conf_get (), - key, - gtk_spin_button_get_value (GTK_SPIN_BUTTON (button))); -} - -static void -preferences_entry_value_changed_cb (GtkWidget *entry, - gpointer user_data) -{ - const gchar *key; - - key = g_object_get_data (G_OBJECT (entry), "key"); - - empathy_conf_set_string (empathy_conf_get (), - key, - gtk_entry_get_text (GTK_ENTRY (entry))); -} -#endif - -static void -preferences_hookup_toggle_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - guint id; - - preferences_widget_sync_bool (key, widget); - - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); - - g_signal_connect (widget, - "toggled", - G_CALLBACK (preferences_toggle_button_toggled_cb), - NULL); - - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_bool_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } -} - -static void -preferences_hookup_radio_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - GSList *group, *l; - guint id; - - preferences_widget_sync_string (key, widget); - - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget)); - for (l = group; l; l = l->next) { - g_signal_connect (l->data, - "toggled", - G_CALLBACK (preferences_radio_button_toggled_cb), - NULL); - - g_object_set_data_full (G_OBJECT (l->data), "key", - g_strdup (key), g_free); - } - - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_string_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } -} - -static void -preferences_hookup_string_combo (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - guint id; - - preferences_widget_sync_string_combo (key, widget); - - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); - - g_signal_connect (widget, - "changed", - G_CALLBACK (preferences_string_combo_changed_cb), - NULL); - - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_string_combo_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } -} - -static void -preferences_hookup_sensitivity (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - gboolean value; - guint id; - - if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) { - gtk_widget_set_sensitive (widget, value); - } - - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_sensitivity_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } -} - -static void -preferences_toggle_button_toggled_cb (GtkWidget *button, - gpointer user_data) -{ - const gchar *key; - - key = g_object_get_data (G_OBJECT (button), "key"); - - empathy_conf_set_bool (empathy_conf_get (), - key, - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))); -} - -static void -preferences_radio_button_toggled_cb (GtkWidget *button, - gpointer user_data) -{ - const gchar *key; - const gchar *value = NULL; - - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { - return; - } - - key = g_object_get_data (G_OBJECT (button), "key"); - - if (key && strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0) { - GSList *group; - GType type; - GEnumClass *enum_class; - GEnumValue *enum_value; - - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)); - - /* Get string from index */ - type = empathy_contact_list_store_sort_get_type (); - enum_class = G_ENUM_CLASS (g_type_class_peek (type)); - 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_slist_index (group, button)); - return; - } - - value = enum_value->value_nick; - } - - empathy_conf_set_string (empathy_conf_get (), key, value); -} - -static void -preferences_string_combo_changed_cb (GtkWidget *combo, - gpointer user_data) -{ - const gchar *key; - GtkTreeModel *model; - GtkTreeIter iter; - gchar *name; - - key = g_object_get_data (G_OBJECT (combo), "key"); - - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) { - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); - - gtk_tree_model_get (model, &iter, - COL_COMBO_NAME, &name, - -1); - empathy_conf_set_string (empathy_conf_get (), key, name); - g_free (name); - } -} - -static void -preferences_response_cb (GtkWidget *widget, - gint response, - EmpathyPreferences *preferences) -{ - gtk_widget_destroy (widget); -} - -static void -preferences_destroy_cb (GtkWidget *widget, - EmpathyPreferences *preferences) -{ - GList *l; - - for (l = preferences->notify_ids; l; l = l->next) { - guint id; - - id = GPOINTER_TO_UINT (l->data); - empathy_conf_notify_remove (empathy_conf_get (), id); - } - - g_list_free (preferences->notify_ids); - g_free (preferences); -} - -GtkWidget * -empathy_preferences_show (GtkWindow *parent) -{ - static EmpathyPreferences *preferences; - GladeXML *glade; - gchar *filename; - - if (preferences) { - gtk_window_present (GTK_WINDOW (preferences->dialog)); - return preferences->dialog; - } - - preferences = g_new0 (EmpathyPreferences, 1); - - filename = empathy_file_lookup ("empathy-preferences.glade", "src"); - glade = empathy_glade_get_file (filename, - "preferences_dialog", - NULL, - "preferences_dialog", &preferences->dialog, - "notebook", &preferences->notebook, - "checkbutton_show_avatars", &preferences->checkbutton_show_avatars, - "checkbutton_compact_contact_list", &preferences->checkbutton_compact_contact_list, - "checkbutton_show_smileys", &preferences->checkbutton_show_smileys, - "combobox_chat_theme", &preferences->combobox_chat_theme, - "checkbutton_separate_chat_windows", &preferences->checkbutton_separate_chat_windows, - "checkbutton_autoconnect", &preferences->checkbutton_autoconnect, - "radiobutton_contact_list_sort_by_name", &preferences->radiobutton_contact_list_sort_by_name, - "radiobutton_contact_list_sort_by_state", &preferences->radiobutton_contact_list_sort_by_state, - "checkbutton_notifications_enabled", &preferences->checkbutton_notifications_enabled, - "checkbutton_notifications_disabled_away", &preferences->checkbutton_notifications_disabled_away, - "checkbutton_notifications_focus", &preferences->checkbutton_notifications_focus, - "checkbutton_sounds_enabled", &preferences->checkbutton_sounds_enabled, - "checkbutton_sounds_disabled_away", &preferences->checkbutton_sounds_disabled_away, - "treeview_sounds", &preferences->treeview_sounds, - "treeview_spell_checker", &preferences->treeview_spell_checker, - NULL); - g_free (filename); - - empathy_glade_connect (glade, - preferences, - "preferences_dialog", "destroy", preferences_destroy_cb, - "preferences_dialog", "response", preferences_response_cb, - NULL); - - g_object_unref (glade); - - g_object_add_weak_pointer (G_OBJECT (preferences->dialog), (gpointer) &preferences); - - preferences_themes_setup (preferences); - - preferences_setup_widgets (preferences); - - preferences_languages_setup (preferences); - preferences_languages_add (preferences); - preferences_languages_load (preferences); - - preferences_sound_setup (preferences); - preferences_sound_load (preferences); - - if (empathy_spell_supported ()) { - GtkWidget *page; - - page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (preferences->notebook), 2); - gtk_widget_show (page); - } - - if (parent) { - gtk_window_set_transient_for (GTK_WINDOW (preferences->dialog), - GTK_WINDOW (parent)); - } - - gtk_widget_show (preferences->dialog); - - return preferences->dialog; -} - diff --git a/src/empathy-preferences.glade b/src/empathy-preferences.glade deleted file mode 100644 index c7c5ace4b..000000000 --- a/src/empathy-preferences.glade +++ /dev/null @@ -1,652 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkDialog" id="preferences_dialog"> - <property name="border_width">5</property> - <property name="title" translatable="yes">Preferences</property> - <property name="role">preferences</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="icon_name">gtk-preferences</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox5"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child> - <widget class="GtkNotebook" id="notebook"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="border_width">5</property> - <child> - <widget class="GtkVBox" id="vbox197"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">18</property> - <child> - <widget class="GtkFrame" id="frame3"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment11"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkVBox" id="vbox199"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkCheckButton" id="checkbutton_compact_contact_list"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Show co_mpact contact list</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkCheckButton" id="checkbutton_show_avatars"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Avatars are user chosen images shown in the contact list</property> - <property name="label" translatable="yes">Show _avatars</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkCheckButton" id="checkbutton_show_smileys"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Show _smileys as images</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label611"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Appearance</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkFrame" id="frame4"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment12"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkVBox" id="vbox218"> - <property name="visible">True</property> - <child> - <widget class="GtkCheckButton" id="checkbutton_separate_chat_windows"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Open new chats in separate windows</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkCheckButton" id="checkbutton_autoconnect"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Automatically _connect on startup </property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label612"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Behavior</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkFrame" id="frame13"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment31"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkVBox" id="vbox217"> - <property name="visible">True</property> - <child> - <widget class="GtkRadioButton" id="radiobutton_contact_list_sort_by_name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Sort by _name</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkRadioButton" id="radiobutton_contact_list_sort_by_state"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Sort by s_tate</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton_contact_list_sort_by_name</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label644"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Contact List</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label602"> - <property name="visible">True</property> - <property name="label" translatable="yes">General</property> - </widget> - <packing> - <property name="type">tab</property> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="vbox2"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">6</property> - <child> - <widget class="GtkCheckButton" id="checkbutton_notifications_enabled"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Enable bubble notifications</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkVBox" id="vbox3"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkCheckButton" id="checkbutton_notifications_disabled_away"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Disable notifications when _away or busy</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - </child> - <child> - <widget class="GtkCheckButton" id="checkbutton_notifications_focus"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Enable notifications when the _chat is not focused</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Notifications</property> - </widget> - <packing> - <property name="type">tab</property> - <property name="position">4</property> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="outer_vbox"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">18</property> - <child> - <widget class="GtkVBox" id="vbox219"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkCheckButton" id="checkbutton_sounds_enabled"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Enable sound notifications</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkAlignment" id="alignment32"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkCheckButton" id="checkbutton_sounds_disabled_away"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Disable sounds when _away or busy</property> - <property name="use_underline">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="vbox221"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkLabel" id="label645"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><b>Play sound for events</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkAlignment" id="alignment33"> - <property name="visible">True</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow19"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTreeView" id="treeview_sounds"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="position">2</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label607"> - <property name="visible">True</property> - <property name="label" translatable="yes">Sounds</property> - </widget> - <packing> - <property name="type">tab</property> - <property name="position">2</property> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="vbox168"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">18</property> - <child> - <widget class="GtkFrame" id="frame7"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment15"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkVBox" id="vbox201"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkHBox" id="hbox153"> - <property name="visible">True</property> - <child> - <widget class="GtkHBox" id="hbox154"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow18"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <widget class="GtkTreeView" id="treeview_spell_checker"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">False</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkHBox" id="hbox155"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkImage" id="image422"> - <property name="visible">True</property> - <property name="yalign">0</property> - <property name="stock">gtk-dialog-info</property> - </widget> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label616"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes"><small>The list of languages reflects only the languages for which you have a dictionary installed.</small></property> - <property name="use_markup">True</property> - <property name="wrap">True</property> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label615"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Enable spell checking for languages:</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - </child> - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="position">3</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label567"> - <property name="visible">True</property> - <property name="label" translatable="yes">Spell Checking</property> - </widget> - <packing> - <property name="type">tab</property> - <property name="position">3</property> - <property name="tab_fill">False</property> - </packing> - </child> - <child> - <widget class="GtkVBox" id="vbox206"> - <property name="visible">True</property> - <property name="border_width">12</property> - <property name="spacing">18</property> - <child> - <widget class="GtkFrame" id="frame11"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <child> - <widget class="GtkAlignment" id="alignment19"> - <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">12</property> - <child> - <widget class="GtkVBox" id="vbox207"> - <property name="visible">True</property> - <property name="spacing">6</property> - <child> - <widget class="GtkHBox" id="hbox139"> - <property name="visible">True</property> - <property name="spacing">12</property> - <child> - <widget class="GtkLabel" id="label586"> - <property name="visible">True</property> - <property name="label" translatable="yes">Chat Th_eme:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">combobox_chat_theme</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - <child> - <widget class="GtkComboBox" id="combobox_chat_theme"> - <property name="visible">True</property> - <property name="items" translatable="yes"></property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label626"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Appearance</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="position">4</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label624"> - <property name="visible">True</property> - <property name="label" translatable="yes">Themes</property> - </widget> - <packing> - <property name="type">tab</property> - <property name="position">4</property> - <property name="tab_fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area5"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <widget class="GtkButton" id="button_close"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - <property name="response_id">-6</property> - </widget> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-preferences.h b/src/empathy-preferences.h deleted file mode 100644 index 07ae6b523..000000000 --- a/src/empathy-preferences.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2003-2007 Imendio AB - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Mikael Hallendal <micke@imendio.com> - * Richard Hult <richard@imendio.com> - * Martyn Russell <martyn@imendio.com> - */ - -#ifndef __EMPATHY_PREFERENCES_H__ -#define __EMPATHY_PREFERENCES_H__ - -#include <gtk/gtkwindow.h> - -G_BEGIN_DECLS - -GtkWidget * empathy_preferences_show (GtkWindow *parent); - -G_END_DECLS - -#endif /* __EMPATHY_PREFERENCES_H__ */ - - diff --git a/src/empathy-sidebar.c b/src/empathy-sidebar.c deleted file mode 100644 index a66abc757..000000000 --- a/src/empathy-sidebar.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (C) 2004 Red Hat, Inc. - * Copyright (C) 2007 The Free Software Foundation - * Copyright (C) 2008 Marco Barisione <marco@barisione.org> - * - * Based on evince code (shell/ev-sidebar.c) by: - * - Jonathan Blandford <jrb@alum.mit.edu> - * - * Base on eog code (src/eog-sidebar.c) by: - * - Lucas Rocha <lucasr@gnome.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> - -#include "empathy-sidebar.h" - -enum -{ - PROP_0, - PROP_CURRENT_PAGE -}; - -enum -{ - PAGE_COLUMN_TITLE, - PAGE_COLUMN_MENU_ITEM, - PAGE_COLUMN_MAIN_WIDGET, - PAGE_COLUMN_NOTEBOOK_INDEX, - PAGE_COLUMN_NUM_COLS -}; - -enum -{ - SIGNAL_PAGE_ADDED, - SIGNAL_PAGE_REMOVED, - SIGNAL_LAST -}; - -static gint signals[SIGNAL_LAST]; - -struct _EmpathySidebarPrivate -{ - GtkWidget *notebook; - GtkWidget *select_button; - GtkWidget *menu; - GtkWidget *hbox; - GtkWidget *label; - - GtkTreeModel *page_model; -}; - -G_DEFINE_TYPE (EmpathySidebar, empathy_sidebar, GTK_TYPE_VBOX) - -#define EMPATHY_SIDEBAR_GET_PRIVATE(object) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((object), EMPATHY_TYPE_SIDEBAR, EmpathySidebarPrivate)) - -static void -empathy_sidebar_destroy (GtkObject *object) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (object); - - if (sidebar->priv->menu) - { - gtk_menu_detach (GTK_MENU (sidebar->priv->menu)); - sidebar->priv->menu = NULL; - } - - if (sidebar->priv->page_model) - { - g_object_unref (sidebar->priv->page_model); - sidebar->priv->page_model = NULL; - } - - (* GTK_OBJECT_CLASS (empathy_sidebar_parent_class)->destroy) (object); -} - -static void -empathy_sidebar_select_page (EmpathySidebar *sidebar, - GtkTreeIter *iter) -{ - gchar *title; - gint index; - - gtk_tree_model_get (sidebar->priv->page_model, iter, - PAGE_COLUMN_TITLE, &title, - PAGE_COLUMN_NOTEBOOK_INDEX, &index, - -1); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar->priv->notebook), index); - gtk_label_set_text (GTK_LABEL (sidebar->priv->label), title); - - g_free (title); -} - -void -empathy_sidebar_set_page (EmpathySidebar *sidebar, - GtkWidget *main_widget) -{ - GtkTreeIter iter; - gboolean valid; - - valid = gtk_tree_model_get_iter_first (sidebar->priv->page_model, &iter); - - while (valid) - { - GtkWidget *widget; - - gtk_tree_model_get (sidebar->priv->page_model, &iter, - PAGE_COLUMN_MAIN_WIDGET, &widget, - -1); - - if (widget == main_widget) - { - empathy_sidebar_select_page (sidebar, &iter); - valid = FALSE; - } - else - { - valid = gtk_tree_model_iter_next (sidebar->priv->page_model, &iter); - } - - g_object_unref (widget); - } - - g_object_notify (G_OBJECT (sidebar), "current-page"); -} - -static GtkWidget * -empathy_sidebar_get_current_page (EmpathySidebar *sidebar) -{ - GtkNotebook *notebook = GTK_NOTEBOOK (sidebar->priv->notebook); - - return gtk_notebook_get_nth_page ( - notebook, gtk_notebook_get_current_page (notebook)); -} - -static void -empathy_sidebar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (object); - - switch (prop_id) - { - case PROP_CURRENT_PAGE: - empathy_sidebar_set_page (sidebar, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -empathy_sidebar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (object); - - switch (prop_id) - { - case PROP_CURRENT_PAGE: - g_value_set_object (value, - empathy_sidebar_get_current_page (sidebar)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -empathy_sidebar_class_init (EmpathySidebarClass *empathy_sidebar_class) -{ - GObjectClass *g_object_class; - GtkWidgetClass *widget_class; - GtkObjectClass *gtk_object_klass; - - g_object_class = G_OBJECT_CLASS (empathy_sidebar_class); - widget_class = GTK_WIDGET_CLASS (empathy_sidebar_class); - gtk_object_klass = GTK_OBJECT_CLASS (empathy_sidebar_class); - - g_type_class_add_private (g_object_class, sizeof (EmpathySidebarPrivate)); - - gtk_object_klass->destroy = empathy_sidebar_destroy; - g_object_class->get_property = empathy_sidebar_get_property; - g_object_class->set_property = empathy_sidebar_set_property; - - g_object_class_install_property (g_object_class, - PROP_CURRENT_PAGE, - g_param_spec_object ("current-page", - "Current page", - "The currently visible page", - GTK_TYPE_WIDGET, - G_PARAM_READWRITE)); - - signals[SIGNAL_PAGE_ADDED] = g_signal_new ("page-added", - EMPATHY_TYPE_SIDEBAR, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EmpathySidebarClass, page_added), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_WIDGET); - - signals[SIGNAL_PAGE_REMOVED] = g_signal_new ("page-removed", - EMPATHY_TYPE_SIDEBAR, G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EmpathySidebarClass, page_removed), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_WIDGET); -} - -static void -empathy_sidebar_menu_position_under (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - gpointer user_data) -{ - GtkWidget *widget; - - g_return_if_fail (GTK_IS_BUTTON (user_data)); - g_return_if_fail (GTK_WIDGET_NO_WINDOW (user_data)); - - widget = GTK_WIDGET (user_data); - - gdk_window_get_origin (widget->window, x, y); - - *x += widget->allocation.x; - *y += widget->allocation.y + widget->allocation.height; - - *push_in = FALSE; -} - -static gboolean -empathy_sidebar_select_button_press_cb (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (user_data); - - if (event->button == 1) - { - GtkRequisition requisition; - gint width; - - width = widget->allocation.width; - - gtk_widget_set_size_request (sidebar->priv->menu, -1, -1); - gtk_widget_size_request (sidebar->priv->menu, &requisition); - gtk_widget_set_size_request (sidebar->priv->menu, - MAX (width, requisition.width), -1); - - gtk_widget_grab_focus (widget); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); - - gtk_menu_popup (GTK_MENU (sidebar->priv->menu), - NULL, NULL, empathy_sidebar_menu_position_under, widget, - event->button, event->time); - - return TRUE; - } - - return FALSE; -} - -static gboolean -empathy_sidebar_select_button_key_press_cb (GtkWidget *widget, - GdkEventKey *event, - gpointer user_data) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (user_data); - - if (event->keyval == GDK_space || - event->keyval == GDK_KP_Space || - event->keyval == GDK_Return || - event->keyval == GDK_KP_Enter) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); - - gtk_menu_popup (GTK_MENU (sidebar->priv->menu), - NULL, NULL, empathy_sidebar_menu_position_under, widget, - 1, event->time); - - return TRUE; - } - - return FALSE; -} - -static void -empathy_sidebar_close_clicked_cb (GtkWidget *widget, - gpointer user_data) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (user_data); - - gtk_widget_hide (GTK_WIDGET (sidebar)); -} - -static void -empathy_sidebar_menu_deactivate_cb (GtkWidget *widget, - gpointer user_data) -{ - GtkWidget *menu_button; - - menu_button = GTK_WIDGET (user_data); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (menu_button), FALSE); -} - -static void -empathy_sidebar_menu_detach_cb (GtkWidget *widget, - GtkMenu *menu) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (widget); - - sidebar->priv->menu = NULL; -} - -static void -empathy_sidebar_menu_item_activate_cb (GtkWidget *widget, - gpointer user_data) -{ - EmpathySidebar *sidebar = EMPATHY_SIDEBAR (user_data); - GtkTreeIter iter; - GtkWidget *menu_item, *item; - gboolean valid; - - menu_item = gtk_menu_get_active (GTK_MENU (sidebar->priv->menu)); - valid = gtk_tree_model_get_iter_first (sidebar->priv->page_model, &iter); - - while (valid) - { - gtk_tree_model_get (sidebar->priv->page_model, &iter, - PAGE_COLUMN_MENU_ITEM, &item, - -1); - - if (item == menu_item) - { - empathy_sidebar_select_page (sidebar, &iter); - valid = FALSE; - } - else - { - valid = gtk_tree_model_iter_next (sidebar->priv->page_model, &iter); - } - - g_object_unref (item); - } - - g_object_notify (G_OBJECT (sidebar), "current-page"); -} - -static void -empathy_sidebar_init (EmpathySidebar *sidebar) -{ - GtkWidget *hbox; - GtkWidget *close_button; - GtkWidget *select_hbox; - GtkWidget *arrow; - GtkWidget *image; - - sidebar->priv = EMPATHY_SIDEBAR_GET_PRIVATE (sidebar); - - /* data model */ - sidebar->priv->page_model = (GtkTreeModel *) gtk_list_store_new ( - PAGE_COLUMN_NUM_COLS, - G_TYPE_STRING, - GTK_TYPE_WIDGET, - GTK_TYPE_WIDGET, - G_TYPE_INT); - - /* top option menu */ - hbox = gtk_hbox_new (FALSE, 0); - sidebar->priv->hbox = hbox; - gtk_box_pack_start (GTK_BOX (sidebar), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - sidebar->priv->select_button = gtk_toggle_button_new (); - gtk_button_set_relief (GTK_BUTTON (sidebar->priv->select_button), - GTK_RELIEF_NONE); - - g_signal_connect (sidebar->priv->select_button, "button_press_event", - G_CALLBACK (empathy_sidebar_select_button_press_cb), - sidebar); - - g_signal_connect (sidebar->priv->select_button, "key_press_event", - G_CALLBACK (empathy_sidebar_select_button_key_press_cb), - sidebar); - - select_hbox = gtk_hbox_new (FALSE, 0); - - sidebar->priv->label = gtk_label_new (""); - - gtk_box_pack_start (GTK_BOX (select_hbox), - sidebar->priv->label, - FALSE, FALSE, 0); - - gtk_widget_show (sidebar->priv->label); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_box_pack_end (GTK_BOX (select_hbox), arrow, FALSE, FALSE, 0); - gtk_widget_show (arrow); - - gtk_container_add (GTK_CONTAINER (sidebar->priv->select_button), select_hbox); - gtk_widget_show (select_hbox); - - gtk_box_pack_start (GTK_BOX (hbox), sidebar->priv->select_button, TRUE, TRUE, 0); - gtk_widget_show (sidebar->priv->select_button); - - close_button = gtk_button_new (); - - gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE); - - g_signal_connect (close_button, "clicked", - G_CALLBACK (empathy_sidebar_close_clicked_cb), - sidebar); - - image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, - GTK_ICON_SIZE_MENU); - gtk_container_add (GTK_CONTAINER (close_button), image); - gtk_widget_show (image); - - gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0); - gtk_widget_show (close_button); - - sidebar->priv->menu = gtk_menu_new (); - - g_signal_connect (sidebar->priv->menu, "deactivate", - G_CALLBACK (empathy_sidebar_menu_deactivate_cb), - sidebar->priv->select_button); - - gtk_menu_attach_to_widget (GTK_MENU (sidebar->priv->menu), - GTK_WIDGET (sidebar), - empathy_sidebar_menu_detach_cb); - - gtk_widget_show (sidebar->priv->menu); - - sidebar->priv->notebook = gtk_notebook_new (); - - gtk_notebook_set_show_border (GTK_NOTEBOOK (sidebar->priv->notebook), FALSE); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (sidebar->priv->notebook), FALSE); - - gtk_box_pack_start (GTK_BOX (sidebar), sidebar->priv->notebook, - TRUE, TRUE, 0); - - gtk_widget_show (sidebar->priv->notebook); -} - -GtkWidget * -empathy_sidebar_new (void) -{ - GtkWidget *sidebar; - - sidebar = g_object_new (EMPATHY_TYPE_SIDEBAR, NULL); - - return sidebar; -} - -void -empathy_sidebar_add_page (EmpathySidebar *sidebar, - const gchar *title, - GtkWidget *main_widget) -{ - GtkTreeIter iter; - GtkWidget *menu_item; - gchar *label_title; - gint index; - - g_return_if_fail (EMPATHY_IS_SIDEBAR (sidebar)); - g_return_if_fail (GTK_IS_WIDGET (main_widget)); - - index = gtk_notebook_append_page (GTK_NOTEBOOK (sidebar->priv->notebook), - main_widget, NULL); - - menu_item = gtk_image_menu_item_new_with_label (title); - - g_signal_connect (menu_item, "activate", - G_CALLBACK (empathy_sidebar_menu_item_activate_cb), - sidebar); - - gtk_widget_show (menu_item); - - gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->priv->menu), - menu_item); - - /* Insert and move to end */ - gtk_list_store_insert_with_values (GTK_LIST_STORE (sidebar->priv->page_model), - &iter, 0, - PAGE_COLUMN_TITLE, title, - PAGE_COLUMN_MENU_ITEM, menu_item, - PAGE_COLUMN_MAIN_WIDGET, main_widget, - PAGE_COLUMN_NOTEBOOK_INDEX, index, - -1); - - gtk_list_store_move_before (GTK_LIST_STORE(sidebar->priv->page_model), - &iter, - NULL); - - /* Set the first item added as active */ - gtk_tree_model_get_iter_first (sidebar->priv->page_model, &iter); - gtk_tree_model_get (sidebar->priv->page_model, - &iter, - PAGE_COLUMN_TITLE, &label_title, - PAGE_COLUMN_NOTEBOOK_INDEX, &index, - -1); - - gtk_menu_set_active (GTK_MENU (sidebar->priv->menu), index); - - gtk_label_set_text (GTK_LABEL (sidebar->priv->label), label_title); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar->priv->notebook), - index); - - g_free (label_title); - - g_signal_emit (G_OBJECT (sidebar), signals[SIGNAL_PAGE_ADDED], - 0, main_widget); -} - -void -empathy_sidebar_remove_page (EmpathySidebar *sidebar, - GtkWidget *main_widget) -{ - GtkTreeIter iter; - GtkWidget *widget, *menu_item; - gboolean valid; - gint index; - - g_return_if_fail (EMPATHY_IS_SIDEBAR (sidebar)); - g_return_if_fail (GTK_IS_WIDGET (main_widget)); - - valid = gtk_tree_model_get_iter_first (sidebar->priv->page_model, &iter); - - while (valid) - { - gtk_tree_model_get (sidebar->priv->page_model, &iter, - PAGE_COLUMN_NOTEBOOK_INDEX, &index, - PAGE_COLUMN_MENU_ITEM, &menu_item, - PAGE_COLUMN_MAIN_WIDGET, &widget, - -1); - - if (widget == main_widget) - break; - else - valid = gtk_tree_model_iter_next (sidebar->priv->page_model, &iter); - - g_object_unref (menu_item); - g_object_unref (widget); - } - - if (valid) - { - 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), - &iter); - - g_signal_emit (G_OBJECT (sidebar), - signals[SIGNAL_PAGE_REMOVED], 0, main_widget); - } -} - -gint -empathy_sidebar_get_n_pages (EmpathySidebar *sidebar) -{ - g_return_val_if_fail (EMPATHY_IS_SIDEBAR (sidebar), TRUE); - - return gtk_tree_model_iter_n_children ( - GTK_TREE_MODEL (sidebar->priv->page_model), NULL); -} - -gboolean -empathy_sidebar_is_empty (EmpathySidebar *sidebar) -{ - g_return_val_if_fail (EMPATHY_IS_SIDEBAR (sidebar), TRUE); - - return gtk_tree_model_iter_n_children ( - GTK_TREE_MODEL (sidebar->priv->page_model), NULL) == 0; -} diff --git a/src/empathy-sidebar.h b/src/empathy-sidebar.h deleted file mode 100644 index 6e88e789d..000000000 --- a/src/empathy-sidebar.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2004 Red Hat, Inc. - * Copyright (C) 2007 The Free Software Foundation - * Copyright (C) 2008 Marco Barisione <marco@barisione.org> - * - * Based on evince code (shell/ev-sidebar.h) by: - * - Jonathan Blandford <jrb@alum.mit.edu> - * - * Base on eog code (src/eog-sidebar.c) by: - * - Lucas Rocha <lucasr@gnome.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __EMPATHY_SIDEBAR_H__ -#define __EMPATHY_SIDEBAR_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -typedef struct _EmpathySidebar EmpathySidebar; -typedef struct _EmpathySidebarClass EmpathySidebarClass; -typedef struct _EmpathySidebarPrivate EmpathySidebarPrivate; - -#define EMPATHY_TYPE_SIDEBAR (empathy_sidebar_get_type()) -#define EMPATHY_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_SIDEBAR, EmpathySidebar)) -#define EMPATHY_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_SIDEBAR, EmpathySidebarClass)) -#define EMPATHY_IS_SIDEBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_SIDEBAR)) -#define EMPATHY_IS_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_SIDEBAR)) -#define EMPATHY_SIDEBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EMPATHY_TYPE_SIDEBAR, EmpathySidebarClass)) - -struct _EmpathySidebar -{ - GtkVBox base_instance; - - EmpathySidebarPrivate *priv; -}; - -struct _EmpathySidebarClass -{ - GtkVBoxClass base_class; - - void (* page_added) (EmpathySidebar *sidebar, - GtkWidget *main_widget); - - void (* page_removed) (EmpathySidebar *sidebar, - GtkWidget *main_widget); -}; - -GType empathy_sidebar_get_type (void); - -GtkWidget *empathy_sidebar_new (void); - -void empathy_sidebar_add_page (EmpathySidebar *sidebar, - const gchar *title, - GtkWidget *main_widget); - -void empathy_sidebar_remove_page (EmpathySidebar *sidebar, - GtkWidget *main_widget); - -void empathy_sidebar_set_page (EmpathySidebar *sidebar, - GtkWidget *main_widget); - -gint empathy_sidebar_get_n_pages (EmpathySidebar *sidebar); - -gboolean empathy_sidebar_is_empty (EmpathySidebar *sidebar); - -G_END_DECLS - -#endif /* __EMPATHY_SIDEBAR_H__ */ - - diff --git a/src/empathy-status-icon.c b/src/empathy-status-icon.c deleted file mode 100644 index 492c37a85..000000000 --- a/src/empathy-status-icon.c +++ /dev/null @@ -1,618 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2007-2008 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> - -#include <string.h> - -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <gdk/gdkkeysyms.h> - -#include <libnotify/notification.h> - -#include <libempathy/empathy-utils.h> -#include <libempathy/empathy-idle.h> -#include <libempathy/empathy-account-manager.h> - -#include <libempathy-gtk/empathy-presence-chooser.h> -#include <libempathy-gtk/empathy-conf.h> -#include <libempathy-gtk/empathy-ui-utils.h> -#include <libempathy-gtk/empathy-images.h> -#include <libempathy-gtk/empathy-new-message-dialog.h> - -#include "empathy-accounts-dialog.h" -#include "empathy-status-icon.h" -#include "empathy-preferences.h" -#include "empathy-event-manager.h" -#include "empathy-misc.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER -#include <libempathy/empathy-debug.h> - -/* Number of ms to wait when blinking */ -#define BLINK_TIMEOUT 500 - -#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyStatusIcon) -typedef struct { - GtkStatusIcon *icon; - EmpathyIdle *idle; - EmpathyAccountManager *account_manager; - gboolean showing_event_icon; - guint blink_timeout; - EmpathyEventManager *event_manager; - EmpathyEvent *event; - NotifyNotification *notification; - - GtkWindow *window; - GtkWidget *popup_menu; - GtkWidget *show_window_item; - GtkWidget *message_item; - GtkWidget *status_item; -} EmpathyStatusIconPriv; - -G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT); - -static gboolean -activate_event (EmpathyEvent *event) -{ - empathy_event_activate (event); - - return FALSE; -} - -static void -status_icon_notification_closed_cb (NotifyNotification *notification, - EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - EmpathyNotificationClosedReason reason = 0; - -#ifdef notify_notification_get_closed_reason - reason = notify_notification_get_closed_reason (notification); -#endif - if (priv->notification) { - g_object_unref (priv->notification); - priv->notification = NULL; - } - - if (!priv->event) { - return; - } - - /* the notification has been closed by the user, see the - * DesktopNotification spec. - */ - if (reason == EMPATHY_NOTIFICATION_CLOSED_DISMISSED) { - /* use an idle here, as this callback is called from a - * DBus signal handler inside libnotify, and we might call - * a *_run_* method when activating the event. - */ - g_idle_add ((GSourceFunc) activate_event, priv->event); - } else { - /* inhibit other updates for this event */ - empathy_event_inhibit_updates (priv->event); - } -} - -static void -notification_close_helper (EmpathyStatusIconPriv *priv) -{ - if (priv->notification) { - notify_notification_close (priv->notification, NULL); - g_object_unref (priv->notification); - priv->notification = NULL; - } -} - -static void -status_icon_update_notification (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - GdkPixbuf *pixbuf = NULL; - - if (!empathy_notification_is_enabled ()) { - /* always close the notification if this happens */ - notification_close_helper (priv); - return; - } - - if (priv->event) { - pixbuf = empathy_misc_get_pixbuf_for_notification (priv->event->contact, - priv->event->icon_name); - - if (priv->notification) { - notify_notification_update (priv->notification, - priv->event->header, priv->event->message, - NULL); - } else { - priv->notification = notify_notification_new_with_status_icon - (priv->event->header, priv->event->message, NULL, priv->icon); - notify_notification_set_timeout (priv->notification, - NOTIFY_EXPIRES_DEFAULT); - - g_signal_connect (priv->notification, "closed", - G_CALLBACK (status_icon_notification_closed_cb), icon); - - } - notify_notification_set_icon_from_pixbuf (priv->notification, - pixbuf); - notify_notification_show (priv->notification, NULL); - - g_object_unref (pixbuf); - } else { - notification_close_helper (priv); - } -} - -static void -status_icon_update_tooltip (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - gchar *tooltip = NULL; - - if (priv->event) { - if (priv->event->message != NULL) - tooltip = g_strdup_printf ("%s\n%s", - priv->event->header, - priv->event->message); - else - tooltip = g_strdup (priv->event->header); - } - - if (!tooltip) { - tooltip = g_strdup (empathy_idle_get_status (priv->idle)); - } - - /* FIXME: when we will depend on GTK+ 2.16.0, we should use - * gtk_status_icon_set_tooltip_markup () and make the header italic. - */ - gtk_status_icon_set_tooltip (priv->icon, tooltip); - - g_free (tooltip); -} - -static void -status_icon_update_icon (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - const gchar *icon_name; - - if (priv->event && priv->showing_event_icon) { - icon_name = priv->event->icon_name; - } else { - McPresence 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); -} - -static gboolean -status_icon_blink_timeout_cb (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - - priv->showing_event_icon = !priv->showing_event_icon; - status_icon_update_icon (icon); - - return TRUE; -} -static void -status_icon_event_added_cb (EmpathyEventManager *manager, - EmpathyEvent *event, - EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - - if (priv->event) { - return; - } - - DEBUG ("New event %p", event); - - priv->event = event; - priv->showing_event_icon = TRUE; - - status_icon_update_icon (icon); - status_icon_update_tooltip (icon); - status_icon_update_notification (icon); - - if (!priv->blink_timeout) { - priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT, - (GSourceFunc) status_icon_blink_timeout_cb, - icon); - } -} - -static void -status_icon_event_removed_cb (EmpathyEventManager *manager, - EmpathyEvent *event, - EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - - if (event != priv->event) { - return; - } - - priv->event = empathy_event_manager_get_top_event (priv->event_manager); - - status_icon_update_tooltip (icon); - status_icon_update_icon (icon); - - /* update notification anyway, as it's safe and we might have been - * changed presence in the meanwhile - */ - status_icon_update_notification (icon); - - if (!priv->event && priv->blink_timeout) { - g_source_remove (priv->blink_timeout); - priv->blink_timeout = 0; - } -} - -static void -status_icon_event_updated_cb (EmpathyEventManager *manager, - EmpathyEvent *event, - EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - - if (event != priv->event) { - return; - } - - if (empathy_notification_is_enabled ()) { - status_icon_update_notification (icon); - } - - status_icon_update_tooltip (icon); -} - -static void -status_icon_set_visibility (EmpathyStatusIcon *icon, - gboolean visible, - gboolean store) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - - if (store) { - empathy_conf_set_bool (empathy_conf_get (), - EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, !visible); - } - - if (!visible) { - empathy_window_iconify (priv->window, priv->icon); - } else { - GList *accounts; - - empathy_window_present (GTK_WINDOW (priv->window), TRUE); - - /* Show the accounts dialog if there is no enabled accounts */ - accounts = mc_accounts_list_by_enabled (TRUE); - if (accounts) { - mc_accounts_list_free (accounts); - } else { - DEBUG ("No enabled account, Showing account dialog"); - empathy_accounts_dialog_show (GTK_WINDOW (priv->window), NULL); - } - } -} - -static void -status_icon_notify_visibility_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - EmpathyStatusIcon *icon = user_data; - gboolean hidden = FALSE; - - if (empathy_conf_get_bool (conf, key, &hidden)) { - status_icon_set_visibility (icon, !hidden, FALSE); - } -} - -static void -status_icon_toggle_visibility (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - gboolean visible; - - visible = gtk_window_is_active (priv->window); - status_icon_set_visibility (icon, !visible, TRUE); -} - -static void -status_icon_idle_notify_cb (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - - status_icon_update_icon (icon); - status_icon_update_tooltip (icon); - - if (!empathy_notification_is_enabled ()) { - /* dismiss the outstanding notification if present */ - - if (priv->notification) { - notify_notification_close (priv->notification, NULL); - g_object_unref (priv->notification); - priv->notification = NULL; - } - } -} - -static gboolean -status_icon_delete_event_cb (GtkWidget *widget, - GdkEvent *event, - EmpathyStatusIcon *icon) -{ - status_icon_set_visibility (icon, FALSE, TRUE); - return TRUE; -} - -static gboolean -status_icon_key_press_event_cb (GtkWidget *window, - GdkEventKey *event, - EmpathyStatusIcon *icon) -{ - if (event->keyval == GDK_Escape) { - status_icon_set_visibility (icon, FALSE, TRUE); - } - return FALSE; -} - -static void -status_icon_activate_cb (GtkStatusIcon *status_icon, - EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - - DEBUG ("%s", priv->event ? "event" : "toggle"); - - if (priv->event) { - empathy_event_activate (priv->event); - } else { - status_icon_toggle_visibility (icon); - } -} - -static void -status_icon_show_hide_window_cb (GtkWidget *widget, - EmpathyStatusIcon *icon) -{ - gboolean visible; - - visible = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)); - status_icon_set_visibility (icon, visible, TRUE); -} - -static void -status_icon_new_message_cb (GtkWidget *widget, - EmpathyStatusIcon *icon) -{ - empathy_new_message_dialog_show (NULL); -} - -static void -status_icon_quit_cb (GtkWidget *window, - EmpathyStatusIcon *icon) -{ - gtk_main_quit (); -} - -static void -status_icon_popup_menu_cb (GtkStatusIcon *status_icon, - guint button, - guint activate_time, - EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - GtkWidget *submenu; - gboolean show; - - show = empathy_window_get_is_visible (GTK_WINDOW (priv->window)); - - g_signal_handlers_block_by_func (priv->show_window_item, - status_icon_show_hide_window_cb, - icon); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (priv->show_window_item), - show); - g_signal_handlers_unblock_by_func (priv->show_window_item, - status_icon_show_hide_window_cb, - icon); - - submenu = empathy_presence_chooser_create_menu (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (priv->status_item), - submenu); - - gtk_menu_popup (GTK_MENU (priv->popup_menu), - NULL, NULL, - gtk_status_icon_position_menu, - priv->icon, - button, - activate_time); -} - -static void -status_icon_create_menu (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - GladeXML *glade; - gchar *filename; - - filename = empathy_file_lookup ("empathy-status-icon.glade", "src"); - glade = empathy_glade_get_file (filename, - "tray_menu", - NULL, - "tray_menu", &priv->popup_menu, - "tray_show_list", &priv->show_window_item, - "tray_new_message", &priv->message_item, - "tray_status", &priv->status_item, - NULL); - g_free (filename); - - empathy_glade_connect (glade, - icon, - "tray_show_list", "toggled", status_icon_show_hide_window_cb, - "tray_new_message", "activate", status_icon_new_message_cb, - "tray_quit", "activate", status_icon_quit_cb, - NULL); - - g_object_unref (glade); -} - -static void -status_icon_connection_changed_cb (EmpathyAccountManager *manager, - McAccount *account, - TpConnectionStatusReason reason, - TpConnectionStatus current, - TpConnectionStatus previous, - EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (icon); - int connected_accounts; - - /* Check for a connected account */ - connected_accounts = empathy_account_manager_get_connected_accounts (manager); - - gtk_widget_set_sensitive (priv->message_item, connected_accounts > 0); -} - -static void -status_icon_finalize (GObject *object) -{ - EmpathyStatusIconPriv *priv = GET_PRIV (object); - - if (priv->blink_timeout) { - g_source_remove (priv->blink_timeout); - } - - g_signal_handlers_disconnect_by_func (priv->account_manager, - status_icon_connection_changed_cb, - object); - - if (priv->notification) { - notify_notification_close (priv->notification, NULL); - g_object_unref (priv->notification); - priv->notification = NULL; - } - - g_object_unref (priv->icon); - g_object_unref (priv->idle); - g_object_unref (priv->account_manager); - g_object_unref (priv->event_manager); -} - -static void -empathy_status_icon_class_init (EmpathyStatusIconClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = status_icon_finalize; - - g_type_class_add_private (object_class, sizeof (EmpathyStatusIconPriv)); -} - -static void -empathy_status_icon_init (EmpathyStatusIcon *icon) -{ - EmpathyStatusIconPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (icon, - EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIconPriv); - - icon->priv = priv; - priv->icon = gtk_status_icon_new (); - priv->account_manager = empathy_account_manager_dup_singleton (); - priv->idle = empathy_idle_dup_singleton (); - priv->event_manager = empathy_event_manager_dup_singleton (); - - g_signal_connect (priv->account_manager, - "account-connection-changed", - G_CALLBACK (status_icon_connection_changed_cb), icon); - - /* make icon listen and respond to MAIN_WINDOW_HIDDEN changes */ - empathy_conf_notify_add (empathy_conf_get (), - EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, - status_icon_notify_visibility_cb, - icon); - - status_icon_create_menu (icon); - status_icon_idle_notify_cb (icon); - - g_signal_connect_swapped (priv->idle, "notify", - G_CALLBACK (status_icon_idle_notify_cb), - icon); - g_signal_connect (priv->event_manager, "event-added", - G_CALLBACK (status_icon_event_added_cb), - icon); - g_signal_connect (priv->event_manager, "event-removed", - G_CALLBACK (status_icon_event_removed_cb), - icon); - g_signal_connect (priv->event_manager, "event-updated", - G_CALLBACK (status_icon_event_updated_cb), - icon); - g_signal_connect (priv->icon, "activate", - G_CALLBACK (status_icon_activate_cb), - icon); - g_signal_connect (priv->icon, "popup-menu", - G_CALLBACK (status_icon_popup_menu_cb), - icon); -} - -EmpathyStatusIcon * -empathy_status_icon_new (GtkWindow *window, gboolean hide_contact_list) -{ - EmpathyStatusIconPriv *priv; - EmpathyStatusIcon *icon; - gboolean should_hide; - - g_return_val_if_fail (GTK_IS_WINDOW (window), NULL); - - icon = g_object_new (EMPATHY_TYPE_STATUS_ICON, NULL); - priv = GET_PRIV (icon); - - priv->window = g_object_ref (window); - - g_signal_connect (priv->window, "key-press-event", - G_CALLBACK (status_icon_key_press_event_cb), - icon); - - g_signal_connect (priv->window, "delete-event", - G_CALLBACK (status_icon_delete_event_cb), - icon); - - if (!hide_contact_list) { - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN, - &should_hide); - } else { - should_hide = TRUE; - } - - if (gtk_window_is_active (priv->window) == should_hide) { - status_icon_set_visibility (icon, !should_hide, FALSE); - } - - return icon; -} - diff --git a/src/empathy-status-icon.glade b/src/empathy-status-icon.glade deleted file mode 100644 index ab0f09f84..000000000 --- a/src/empathy-status-icon.glade +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--*- mode: xml -*--> -<glade-interface> - <widget class="GtkMenu" id="tray_menu"> - <child> - <widget class="GtkCheckMenuItem" id="tray_show_list"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Show Contact List</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="avskiljare5"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="tray_new_message"> - <property name="visible">True</property> - <property name="label" translatable="yes">_New Conversation...</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image599"> - <property name="visible">True</property> - <property name="icon_size">1</property> - <property name="icon_name">im-message-new</property> - </widget> - </child> - </widget> - </child> - <child> - <widget class="GtkMenuItem" id="tray_status"> - <property name="visible">True</property> - <property name="label" translatable="yes">Status</property> - <property name="use_underline">True</property> - </widget> - </child> - <child> - <widget class="GtkSeparatorMenuItem" id="avskiljare6"> - <property name="visible">True</property> - </widget> - </child> - <child> - <widget class="GtkImageMenuItem" id="tray_quit"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Quit</property> - <property name="use_underline">True</property> - <child internal-child="image"> - <widget class="GtkImage" id="image600"> - <property name="visible">True</property> - <property name="stock">gtk-quit</property> - <property name="icon_size">1</property> - </widget> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/src/empathy-status-icon.h b/src/empathy-status-icon.h deleted file mode 100644 index ca21af833..000000000 --- a/src/empathy-status-icon.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2007-2008 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - */ - -#ifndef __EMPATHY_STATUS_ICON_H__ -#define __EMPATHY_STATUS_ICON_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -#define EMPATHY_TYPE_STATUS_ICON (empathy_status_icon_get_type ()) -#define EMPATHY_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIcon)) -#define EMPATHY_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIconClass)) -#define EMPATHY_IS_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_STATUS_ICON)) -#define EMPATHY_IS_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_STATUS_ICON)) -#define EMPATHY_STATUS_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIconClass)) - -typedef struct _EmpathyStatusIcon EmpathyStatusIcon; -typedef struct _EmpathyStatusIconClass EmpathyStatusIconClass; - -struct _EmpathyStatusIcon { - GObject parent; - gpointer priv; -}; - -struct _EmpathyStatusIconClass { - GObjectClass parent_class; -}; - -GType empathy_status_icon_get_type (void) G_GNUC_CONST; -EmpathyStatusIcon *empathy_status_icon_new (GtkWindow *window, - gboolean hide_contact_list); - -G_END_DECLS - -#endif /* __EMPATHY_STATUS_ICON_H__ */ diff --git a/src/empathy-tube-dispatch.c b/src/empathy-tube-dispatch.c deleted file mode 100644 index b1e7bce6d..000000000 --- a/src/empathy-tube-dispatch.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * empathy-tube-dispatch.c - Source for EmpathyTubeDispatch - * Copyright (C) 2008 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk> - * - * 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 <stdio.h> -#include <stdlib.h> - -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/util.h> -#include <telepathy-glib/proxy-subclass.h> - -#include <gtk/gtk.h> -#include <glib/gi18n.h> - - -#include <libempathy/empathy-tube-handler.h> -#include <extensions/extensions.h> - - -#include "empathy-tube-dispatch.h" -#include "empathy-tube-dispatch-enumtypes.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER -#include <libempathy/empathy-debug.h> - -G_DEFINE_TYPE(EmpathyTubeDispatch, empathy_tube_dispatch, G_TYPE_OBJECT) - -static void empathy_tube_dispatch_set_ability ( - EmpathyTubeDispatch *tube_dispatch, - EmpathyTubeDispatchAbility dispatchability); - -/* private structure */ -typedef struct _EmpathyTubeDispatchPriv EmpathyTubeDispatchPriv; - -/* properties */ -enum { - PROP_OPERATION = 1, - PROP_DISPATCHABILITY -}; - - -struct _EmpathyTubeDispatchPriv -{ - gboolean dispose_has_run; - EmpathyDispatchOperation *operation; - EmpathyTubeDispatchAbility dispatchability; - gchar *service; - gchar *bus_name; - gchar *object_path; - TpDBusDaemon *dbus; -}; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - EMPATHY_TYPE_TUBE_DISPATCH, EmpathyTubeDispatchPriv)) - -static void -empathy_tube_dispatch_init (EmpathyTubeDispatch *obj) -{ - EmpathyTubeDispatchPriv *priv = GET_PRIV (obj); - - priv->dispatchability = EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN; -} - -static void empathy_tube_dispatch_dispose (GObject *object); -static void empathy_tube_dispatch_finalize (GObject *object); - -static void -empathy_tube_dispatch_list_activatable_names_cb (TpDBusDaemon *proxy, - const gchar **names, const GError *error, gpointer user_data, - GObject *object) -{ - EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (self); - gchar **name; - - for (name = (gchar **) names; *name != NULL; name++) - { - if (!tp_strdiff (*name, priv->bus_name)) - { - DEBUG ("Found tube handler. Can dispatch it"); - empathy_tube_dispatch_set_ability (self, - EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE); - return; - } - } - - DEBUG ("Didn't find tube handler. Can't dispatch it"); - empathy_tube_dispatch_set_ability (self, - EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE); -} - -static void -empathy_tube_dispatch_name_has_owner_cb (TpDBusDaemon *proxy, - gboolean has_owner, const GError *error, gpointer user_data, - GObject *object) -{ - EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (self); - - if (error != NULL) - { - DEBUG ("NameHasOwner failed. Can't dispatch tube"); - empathy_tube_dispatch_set_ability (self, - EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE); - return; - } - - if (has_owner) - { - DEBUG ("Tube handler is running. Can dispatch it"); - empathy_tube_dispatch_set_ability (self, - EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE); - } - else - { - DEBUG ("Tube handler is not running. Calling ListActivatableNames"); - tp_cli_dbus_daemon_call_list_activatable_names (priv->dbus, -1, - empathy_tube_dispatch_list_activatable_names_cb, NULL, NULL, - G_OBJECT (self)); - } -} - -static void -empathy_tube_dispatch_constructed (GObject *object) -{ - EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (self); - TpChannel *channel; - GHashTable *properties; - const gchar *service; - const gchar *channel_type; - TpTubeType type; - - priv->dbus = tp_dbus_daemon_new (tp_get_bus()); - - channel = empathy_dispatch_operation_get_channel (priv->operation); - properties = tp_channel_borrow_immutable_properties (channel); - - channel_type = tp_asv_get_string (properties, - TP_IFACE_CHANNEL ".ChannelType"); - if (channel_type == NULL) - goto failed; - - if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE)) - { - type = TP_TUBE_TYPE_STREAM; - service = tp_asv_get_string (properties, - EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service"); - } - else if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE)) - { - type = TP_TUBE_TYPE_DBUS; - service = tp_asv_get_string (properties, - EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName"); - } - else - { - goto failed; - } - - - if (service == NULL) - goto failed; - - priv->bus_name = empathy_tube_handler_build_bus_name (type, service); - priv->object_path = empathy_tube_handler_build_object_path (type, service); - - priv->service = g_strdup (service); - - DEBUG ("Look for tube handler %s\n", priv->bus_name); - tp_cli_dbus_daemon_call_name_has_owner (priv->dbus, -1, priv->bus_name, - empathy_tube_dispatch_name_has_owner_cb, NULL, NULL, G_OBJECT (self)); - - return; - -failed: - empathy_tube_dispatch_set_ability (self, - EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE); -} - -static void -empathy_tube_dispatch_set_property (GObject *object, - guint property_id, const GValue *value, GParamSpec *pspec) -{ - EmpathyTubeDispatch *tube_dispatch = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch); - - switch (property_id) - { - case PROP_OPERATION: - priv->operation = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -empathy_tube_dispatch_get_property (GObject *object, - guint property_id, GValue *value, GParamSpec *pspec) -{ - EmpathyTubeDispatch *tube_dispatch = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch); - - switch (property_id) - { - case PROP_OPERATION: - g_value_set_object (value, priv->operation); - break; - case PROP_DISPATCHABILITY: - g_value_set_enum (value, priv->dispatchability); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -empathy_tube_dispatch_class_init ( - EmpathyTubeDispatchClass *empathy_tube_dispatch_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (empathy_tube_dispatch_class); - GParamSpec *param_spec; - - g_type_class_add_private (empathy_tube_dispatch_class, - sizeof (EmpathyTubeDispatchPriv)); - - object_class->set_property = empathy_tube_dispatch_set_property; - object_class->get_property = empathy_tube_dispatch_get_property; - - object_class->constructed = empathy_tube_dispatch_constructed; - object_class->dispose = empathy_tube_dispatch_dispose; - object_class->finalize = empathy_tube_dispatch_finalize; - - param_spec = g_param_spec_object ("operation", - "operation", "The telepathy connection", - EMPATHY_TYPE_DISPATCH_OPERATION, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_OPERATION, param_spec); - - param_spec = g_param_spec_enum ("dispatchability", - "dispatchability", - "Whether or not there is a handler to dispatch the operation to", - EMPATHY_TYPE_TUBE_DISPATCH_ABILITY, EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_DISPATCHABILITY, - param_spec); - -} - -void -empathy_tube_dispatch_dispose (GObject *object) -{ - EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (self); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - /* release any references held by the object here */ - if (priv->operation != NULL) - g_object_unref (priv->operation); - - priv->operation = NULL; - - if (priv->dbus != NULL) - g_object_unref (priv->dbus); - - priv->dbus = NULL; - - - if (G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->dispose) - G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->dispose (object); -} - -void -empathy_tube_dispatch_finalize (GObject *object) -{ - EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (self); - - g_free (priv->bus_name); - g_free (priv->object_path); - g_free (priv->service); - - /* free any data held directly by the object here */ - - G_OBJECT_CLASS (empathy_tube_dispatch_parent_class)->finalize (object); -} - -EmpathyTubeDispatch * -empathy_tube_dispatch_new (EmpathyDispatchOperation *operation) -{ - return EMPATHY_TUBE_DISPATCH (g_object_new (EMPATHY_TYPE_TUBE_DISPATCH, - "operation", operation, NULL)); -} - -EmpathyTubeDispatchAbility -empathy_tube_dispatch_is_dispatchable (EmpathyTubeDispatch *tube_dispatch) -{ - EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch); - - return priv->dispatchability; -} - -static void -empathy_tube_dispatch_set_ability (EmpathyTubeDispatch *tube_dispatch, - EmpathyTubeDispatchAbility dispatchability) -{ - EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch); - - if (priv->dispatchability == dispatchability) - return; - - priv->dispatchability = dispatchability; - g_object_notify (G_OBJECT (tube_dispatch), "dispatchability"); -} - -static void -empathy_tube_dispatch_show_error (EmpathyTubeDispatch *self, gchar *message) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, "%s", message); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_destroy (dialog); -} - -static void -empathy_tube_dispatch_handle_tube_cb (TpProxy *proxy, const GError *error, - gpointer user_data, GObject *object) -{ - EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object); - EmpathyTubeDispatchPriv *priv = GET_PRIV (self); - - if (error != NULL) - { - gchar *msg = g_strdup_printf ( - _("Unable to start application for service %s: %s"), - priv->service, error->message); - - empathy_tube_dispatch_show_error (self, msg); - g_free (msg); - } - - /* Remove the ref we were holding because of the dispatching */ - g_object_unref (object); -} - -static void -empathy_tube_do_dispatch (EmpathyTubeDispatch *self) -{ - EmpathyTubeDispatchPriv *priv = GET_PRIV (self); - TpChannel *channel; - TpProxy *connection; - TpProxy *thandler; - gchar *object_path; - guint handle_type; - guint handle; - - channel = empathy_dispatch_operation_get_channel (priv->operation); - - /* Create the proxy for the tube handler */ - thandler = g_object_new (TP_TYPE_PROXY, - "dbus-connection", tp_get_bus (), - "bus-name", priv->bus_name, - "object-path", priv->object_path, - NULL); - - tp_proxy_add_interface_by_id (thandler, EMP_IFACE_QUARK_TUBE_HANDLER); - - /* Give the tube to the handler */ - g_object_get (channel, - "connection", &connection, - "object-path", &object_path, - "handle_type", &handle_type, - "handle", &handle, - NULL); - - emp_cli_tube_handler_call_handle_tube (thandler, -1, - connection->bus_name, connection->object_path, - object_path, handle_type, handle, - empathy_tube_dispatch_handle_tube_cb, NULL, NULL, G_OBJECT (self)); - - g_object_unref (thandler); - g_object_unref (connection); - g_free (object_path); -} - -void -empathy_tube_dispatch_handle (EmpathyTubeDispatch *tube_dispatch) -{ - EmpathyTubeDispatchPriv *priv = GET_PRIV (tube_dispatch); - - /* Keep ourselves alive untill the dispatching is finished */ - g_object_ref (tube_dispatch); - - /* If we can't claim it, don't do anything */ - if (!empathy_dispatch_operation_claim (priv->operation)) - goto done; - - if (priv->dispatchability != EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE) - { - gchar *msg; - TpChannel *channel; - - channel = empathy_dispatch_operation_get_channel (priv->operation); - - msg = g_strdup_printf ( - _("An invitation was offered for service %s, but you don't have the " - "needed application to handle it"), priv->service); - - empathy_tube_dispatch_show_error (tube_dispatch, msg); - - g_free (msg); - - tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL); - - goto done; - } - else - { - empathy_tube_do_dispatch (tube_dispatch); - } - - return; -done: - g_object_unref (tube_dispatch); -} - diff --git a/src/empathy-tube-dispatch.h b/src/empathy-tube-dispatch.h deleted file mode 100644 index f1328bb68..000000000 --- a/src/empathy-tube-dispatch.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * empathy-tube-dispatch.h - Header for EmpathyTubeDispatch - * Copyright (C) 2008 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk> - * - * 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_TUBE_DISPATCH_H__ -#define __EMPATHY_TUBE_DISPATCH_H__ - -#include <glib-object.h> - -#include <libempathy/empathy-dispatch-operation.h> - -G_BEGIN_DECLS - -typedef enum { - EMPATHY_TUBE_DISPATCHABILITY_UNKNOWN, - EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE, - EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE, -} EmpathyTubeDispatchAbility; - -typedef struct _EmpathyTubeDispatch EmpathyTubeDispatch; -typedef struct _EmpathyTubeDispatchClass EmpathyTubeDispatchClass; - -struct _EmpathyTubeDispatchClass { - GObjectClass parent_class; -}; - -struct _EmpathyTubeDispatch { - GObject parent; -}; - -GType empathy_tube_dispatch_get_type(void); - -/* TYPE MACROS */ -#define EMPATHY_TYPE_TUBE_DISPATCH \ - (empathy_tube_dispatch_get_type()) -#define EMPATHY_TUBE_DISPATCH(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_TUBE_DISPATCH, \ - EmpathyTubeDispatch)) -#define EMPATHY_TUBE_DISPATCH_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_TUBE_DISPATCH, \ - EmpathyTubeDispatchClass)) -#define EMPATHY_IS_TUBE_DISPATCH(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_TUBE_DISPATCH)) -#define EMPATHY_IS_TUBE_DISPATCH_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_TUBE_DISPATCH)) -#define EMPATHY_TUBE_DISPATCH_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_TUBE_DISPATCH, \ - EmpathyTubeDispatchClass)) - -EmpathyTubeDispatch * empathy_tube_dispatch_new ( - EmpathyDispatchOperation *operation); - -EmpathyTubeDispatchAbility empathy_tube_dispatch_is_dispatchable ( - EmpathyTubeDispatch *tube_dispatch); -void empathy_tube_dispatch_handle (EmpathyTubeDispatch *tube_dispatch); - -G_END_DECLS - -#endif /* #ifndef __EMPATHY_TUBE_DISPATCH_H__*/ diff --git a/src/empathy.1 b/src/empathy.1 deleted file mode 100644 index bb191a0ac..000000000 --- a/src/empathy.1 +++ /dev/null @@ -1,24 +0,0 @@ -.TH EMPATHY "1" "October 2007" "Telepathy project" "User Commands" -.SH NAME -empathy \- GNOME instant messaging client using Telepathy -.SH SYNOPSIS -empathy -.SH DESCRIPTION -Empathy consists of a rich set of reusable instant messaging widgets, and a -GNOME client using those widgets. -It uses Telepathy and Nokia's Mission Control, and reuses Gossip's UI. -.PP -The main user interface consists of a contact list window and an icon in the -notification area. -.SH OPTIONS -There are no command-line options. -.SH ENVIRONMENT -.TP -\fBEMPATHY_LOGFILE\fR=\fIfilename\fR -If set, debug output will go to the given file rather than to stderr. -.TP -\fBEMPATHY_DEBUG\fR=\fItype\fR -May be set to "all" for full debug output, or various undocumented options -(which may change from release to release) to filter the output. -.SH SEE ALSO -\fIhttp://telepathy.freedesktop.org/\fR, \fIhttp://live.gnome.org/Empathy\fR diff --git a/src/empathy.c b/src/empathy.c deleted file mode 100644 index a2115a6cf..000000000 --- a/src/empathy.c +++ /dev/null @@ -1,585 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2007-2008 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 - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - */ - -#include <config.h> - -#include <stdlib.h> -#include <errno.h> -#include <string.h> - -#include <glib.h> -#include <glib/gi18n.h> -#include <gtk/gtk.h> -#include <gdk/gdkx.h> - -#include <libebook/e-book.h> -#include <libnotify/notify.h> - -#include <telepathy-glib/util.h> -#include <libmissioncontrol/mc-account.h> -#include <libmissioncontrol/mission-control.h> - -#include <libempathy/empathy-idle.h> -#include <libempathy/empathy-utils.h> -#include <libempathy/empathy-call-factory.h> -#include <libempathy/empathy-chatroom-manager.h> -#include <libempathy/empathy-dispatcher.h> -#include <libempathy/empathy-dispatch-operation.h> -#include <libempathy/empathy-log-manager.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 "empathy-accounts-dialog.h" -#include "empathy-main-window.h" -#include "empathy-status-icon.h" -#include "empathy-call-window.h" -#include "empathy-chat-window.h" -#include "empathy-ft-manager.h" -#include "bacon-message-connection.h" - -#include "extensions/extensions.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_OTHER -#include <libempathy/empathy-debug.h> - -#include <gst/gst.h> - -static BaconMessageConnection *connection = NULL; - -static void -dispatch_cb (EmpathyDispatcher *dispatcher, - EmpathyDispatchOperation *operation, - gpointer user_data) -{ - GQuark channel_type; - - channel_type = empathy_dispatch_operation_get_channel_type_id (operation); - - if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT) { - EmpathyTpChat *tp_chat; - EmpathyChat *chat = NULL; - const gchar *id; - - tp_chat = EMPATHY_TP_CHAT ( - empathy_dispatch_operation_get_channel_wrapper (operation)); - - id = empathy_tp_chat_get_id (tp_chat); - if (!id) { - EmpathyContact *contact; - - contact = empathy_tp_chat_get_remote_contact (tp_chat); - if (contact) { - id = empathy_contact_get_id (contact); - } - } - - if (id) { - McAccount *account; - - account = empathy_tp_chat_get_account (tp_chat); - chat = empathy_chat_window_find_chat (account, id); - } - - if (chat) { - empathy_chat_set_tp_chat (chat, tp_chat); - } else { - chat = empathy_chat_new (tp_chat); - } - - empathy_chat_window_present_chat (chat); - - empathy_dispatch_operation_claim (operation); - } else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) { - EmpathyCallFactory *factory; - - 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; - - 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); - } -} - -static void -service_ended_cb (MissionControl *mc, - gpointer user_data) -{ - DEBUG ("Mission Control stopped"); -} - -static void -operation_error_cb (MissionControl *mc, - guint operation_id, - guint error_code, - gpointer user_data) -{ - const gchar *message; - - switch (error_code) { - case MC_DISCONNECTED_ERROR: - message = "Disconnected"; - break; - case MC_INVALID_HANDLE_ERROR: - message = "Invalid handle"; - break; - case MC_NO_MATCHING_CONNECTION_ERROR: - message = "No matching connection"; - break; - case MC_INVALID_ACCOUNT_ERROR: - message = "Invalid account"; - break; - case MC_PRESENCE_FAILURE_ERROR: - message = "Presence failure"; - break; - case MC_NO_ACCOUNTS_ERROR: - message = "No accounts"; - break; - case MC_NETWORK_ERROR: - message = "Network error"; - break; - case MC_CONTACT_DOES_NOT_SUPPORT_VOICE_ERROR: - message = "Contact does not support voice"; - break; - case MC_LOWMEM_ERROR: - message = "Lowmem"; - break; - case MC_CHANNEL_REQUEST_GENERIC_ERROR: - message = "Channel request generic error"; - break; - case MC_CHANNEL_BANNED_ERROR: - message = "Channel banned"; - break; - case MC_CHANNEL_FULL_ERROR: - message = "Channel full"; - break; - case MC_CHANNEL_INVITE_ONLY_ERROR: - message = "Channel invite only"; - break; - default: - message = "Unknown error code"; - } - - DEBUG ("Error during operation %d: %s", operation_id, message); -} - -static void -use_nm_notify_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - EmpathyIdle *idle = user_data; - gboolean use_nm; - - if (empathy_conf_get_bool (conf, key, &use_nm)) { - empathy_idle_set_use_nm (idle, use_nm); - } -} - -static void -create_salut_account (void) -{ - McProfile *profile; - McProtocol *protocol; - gboolean salut_created = FALSE; - McAccount *account; - GList *accounts; - EBook *book; - EContact *contact; - gchar *nickname = NULL; - gchar *first_name = NULL; - gchar *last_name = NULL; - gchar *email = NULL; - gchar *jid = NULL; - GError *error = NULL; - - /* Check if we already created a salut account */ - empathy_conf_get_bool (empathy_conf_get(), - EMPATHY_PREFS_SALUT_ACCOUNT_CREATED, - &salut_created); - if (salut_created) { - return; - } - - DEBUG ("Try to add a salut account..."); - - /* Check if the salut CM is installed */ - profile = mc_profile_lookup ("salut"); - if (!profile) { - DEBUG ("No salut profile"); - return; - } - protocol = mc_profile_get_protocol (profile); - if (!protocol) { - DEBUG ("Salut not installed"); - g_object_unref (profile); - return; - } - g_object_unref (protocol); - - /* Get self EContact from EDS */ - if (!e_book_get_self (&contact, &book, &error)) { - DEBUG ("Failed to get self econtact: %s", - error ? error->message : "No error given"); - g_clear_error (&error); - g_object_unref (profile); - return; - } - - empathy_conf_set_bool (empathy_conf_get (), - EMPATHY_PREFS_SALUT_ACCOUNT_CREATED, - TRUE); - - /* Check if there is already a salut account */ - accounts = mc_accounts_list_by_profile (profile); - if (accounts) { - DEBUG ("There is already a salut account"); - mc_accounts_list_free (accounts); - g_object_unref (profile); - return; - } - - account = mc_account_create (profile); - mc_account_set_display_name (account, _("People nearby")); - - nickname = e_contact_get (contact, E_CONTACT_NICKNAME); - first_name = e_contact_get (contact, E_CONTACT_GIVEN_NAME); - last_name = e_contact_get (contact, E_CONTACT_FAMILY_NAME); - email = e_contact_get (contact, E_CONTACT_EMAIL_1); - jid = e_contact_get (contact, E_CONTACT_IM_JABBER_HOME_1); - - if (!tp_strdiff (nickname, "nickname")) { - g_free (nickname); - nickname = NULL; - } - - DEBUG ("Salut account created:\nnickname=%s\nfirst-name=%s\n" - "last-name=%s\nemail=%s\njid=%s\n", - nickname, first_name, last_name, email, jid); - - mc_account_set_param_string (account, "nickname", nickname ? nickname : ""); - mc_account_set_param_string (account, "first-name", first_name ? first_name : ""); - mc_account_set_param_string (account, "last-name", last_name ? last_name : ""); - mc_account_set_param_string (account, "email", email ? email : ""); - mc_account_set_param_string (account, "jid", jid ? jid : ""); - - g_free (nickname); - g_free (first_name); - g_free (last_name); - g_free (email); - g_free (jid); - g_object_unref (account); - g_object_unref (profile); - g_object_unref (contact); - g_object_unref (book); -} - -/* The code that handles single-instance and startup notification is - * copied from gedit. - * - * Copyright (C) 2005 - Paolo Maggi - */ -static void -on_bacon_message_received (const char *message, - gpointer data) -{ - GtkWidget *window = data; - guint32 startup_timestamp; - - g_return_if_fail (message != NULL); - - DEBUG ("Other instance launched, presenting the main window. message='%s'", - message); - - if (strcmp (message, "accounts") == 0) { - /* accounts dialog requested */ - empathy_accounts_dialog_show (GTK_WINDOW (window), NULL); - } else { - startup_timestamp = atoi (message); - - /* Set the proper interaction time on the window. - * Fall back to roundtripping to the X server when we - * don't have the timestamp, e.g. when launched from - * terminal. We also need to make sure that the window - * has been realized otherwise it will not work. lame. */ - if (startup_timestamp == 0) { - /* Work if launched from the terminal */ - DEBUG ("Using X server timestamp as a fallback"); - - if (!GTK_WIDGET_REALIZED (window)) { - gtk_widget_realize (GTK_WIDGET (window)); - } - - startup_timestamp = gdk_x11_get_server_time (window->window); - } - - gtk_window_present_with_time (GTK_WINDOW (window), startup_timestamp); - } -} - -static guint32 -get_startup_timestamp () -{ - const gchar *startup_id_env; - gchar *startup_id = NULL; - gchar *time_str; - gchar *end; - gulong retval = 0; - - /* we don't unset the env, since startup-notification - * may still need it */ - startup_id_env = g_getenv ("DESKTOP_STARTUP_ID"); - if (startup_id_env == NULL) { - goto out; - } - - startup_id = g_strdup (startup_id_env); - - time_str = g_strrstr (startup_id, "_TIME"); - if (time_str == NULL) { - goto out; - } - - errno = 0; - - /* Skip past the "_TIME" part */ - time_str += 5; - - retval = strtoul (time_str, &end, 0); - if (end == time_str || errno != 0) - retval = 0; - - out: - g_free (startup_id); - - return (retval > 0) ? retval : 0; -} - -static gboolean -show_version_cb (const char *option_name, - const char *value, - gpointer data, - GError **error) -{ - g_print ("%s\n", PACKAGE_STRING); - - exit (EXIT_SUCCESS); - - return FALSE; -} - -static void -new_call_handler_cb (EmpathyCallFactory *factory, EmpathyCallHandler *handler, - gboolean outgoing, gpointer user_data) -{ - EmpathyCallWindow *window; - - window = empathy_call_window_new (handler); - gtk_widget_show (GTK_WIDGET (window)); -} - -int -main (int argc, char *argv[]) -{ - guint32 startup_timestamp; - EmpathyStatusIcon *icon; - EmpathyDispatcher *dispatcher; - EmpathyLogManager *log_manager; - EmpathyChatroomManager *chatroom_manager; - EmpathyFTManager *ft_manager; - EmpathyCallFactory *call_factory; - GtkWidget *window; - MissionControl *mc; - EmpathyIdle *idle; - gboolean autoconnect = TRUE; - gboolean no_connect = FALSE; - gboolean hide_contact_list = FALSE; - gboolean accounts_dialog = FALSE; - GError *error = NULL; - GOptionEntry options[] = { - { "no-connect", 'n', - 0, G_OPTION_ARG_NONE, &no_connect, - N_("Don't connect on startup"), - NULL }, - { "hide-contact-list", 'h', - 0, G_OPTION_ARG_NONE, &hide_contact_list, - N_("Don't show the contact list on startup"), - NULL }, - { "accounts", 'a', - 0, G_OPTION_ARG_NONE, &accounts_dialog, - N_("Show the accounts dialog"), - NULL }, - { "version", 'v', - G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_cb, NULL, NULL }, - { NULL } - }; - - /* Init */ - g_thread_init (NULL); - empathy_init (); - - if (!gtk_init_with_args (&argc, &argv, - N_("- Empathy Instant Messenger"), - options, GETTEXT_PACKAGE, &error)) { - g_warning ("Error in empathy init: %s", error->message); - return EXIT_FAILURE; - } - - empathy_gtk_init (); - g_set_application_name (_(PACKAGE_NAME)); - g_setenv("PULSE_PROP_media.role", "phone", TRUE); - - gst_init (&argc, &argv); - - gtk_window_set_default_icon_name ("empathy"); - textdomain (GETTEXT_PACKAGE); - - /* Setting up the bacon connection */ - startup_timestamp = get_startup_timestamp (); - connection = bacon_message_connection_new ("empathy"); - if (connection != NULL) { - if (!bacon_message_connection_get_is_server (connection)) { - gchar *message; - - if (accounts_dialog) { - DEBUG ("Showing accounts dialog from existing Empathy instance"); - - message = g_strdup ("accounts"); - - } else { - - DEBUG ("Activating existing instance"); - - message = g_strdup_printf ("%" G_GUINT32_FORMAT, - startup_timestamp); - } - - bacon_message_connection_send (connection, message); - - /* We never popup a window, so tell startup-notification - * that we are done. */ - gdk_notify_startup_complete (); - - g_free (message); - bacon_message_connection_free (connection); - - return EXIT_SUCCESS; - } - } else { - g_warning ("Cannot create the 'empathy' bacon connection."); - } - - /* Setting up MC */ - mc = empathy_mission_control_dup_singleton (); - g_signal_connect (mc, "ServiceEnded", - G_CALLBACK (service_ended_cb), - NULL); - g_signal_connect (mc, "Error", - G_CALLBACK (operation_error_cb), - NULL); - - if (accounts_dialog) { - GtkWidget *dialog; - - dialog = empathy_accounts_dialog_show (NULL, NULL); - g_signal_connect (dialog, "destroy", - G_CALLBACK (gtk_main_quit), - NULL); - - gtk_main (); - return 0; - } - - /* Setting up Idle */ - idle = empathy_idle_dup_singleton (); - empathy_idle_set_auto_away (idle, TRUE); - use_nm_notify_cb (empathy_conf_get (), EMPATHY_PREFS_USE_NM, idle); - empathy_conf_notify_add (empathy_conf_get (), EMPATHY_PREFS_USE_NM, - use_nm_notify_cb, idle); - - /* Autoconnect */ - empathy_conf_get_bool (empathy_conf_get(), - EMPATHY_PREFS_AUTOCONNECT, - &autoconnect); - if (autoconnect && ! no_connect && - empathy_idle_get_state (idle) <= MC_PRESENCE_OFFLINE) { - empathy_idle_set_state (idle, MC_PRESENCE_AVAILABLE); - } - - create_salut_account (); - - /* Setting up UI */ - window = empathy_main_window_show (); - icon = empathy_status_icon_new (GTK_WINDOW (window), hide_contact_list); - - if (connection) { - /* We se the callback here because we need window */ - bacon_message_connection_set_callback (connection, - on_bacon_message_received, - window); - } - - /* Handle channels */ - dispatcher = empathy_dispatcher_dup_singleton (); - g_signal_connect (dispatcher, "dispatch", G_CALLBACK (dispatch_cb), NULL); - - /* Logging */ - log_manager = empathy_log_manager_dup_singleton (); - empathy_log_manager_observe (log_manager, dispatcher); - - 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); - - gtk_main (); - - empathy_idle_set_state (idle, MC_PRESENCE_OFFLINE); - - g_object_unref (mc); - g_object_unref (idle); - g_object_unref (icon); - g_object_unref (log_manager); - g_object_unref (dispatcher); - g_object_unref (chatroom_manager); - g_object_unref (ft_manager); - - notify_uninit (); - - return EXIT_SUCCESS; -} - diff --git a/src/ephy-spinner.c b/src/ephy-spinner.c deleted file mode 100644 index 43b9bc990..000000000 --- a/src/ephy-spinner.c +++ /dev/null @@ -1,977 +0,0 @@ -/* - * Copyright © 2000 Eazel, Inc. - * Copyright © 2002-2004 Marco Pesenti Gritti - * Copyright © 2004, 2006 Christian Persch - * - * Nautilus is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Nautilus is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * 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 $ - */ - -#include <config.h> - -#include "ephy-spinner.h" - -/* #include "ephy-debug.h" */ -#define LOG(msg, args...) -#define START_PROFILER(name) -#define STOP_PROFILER(name) - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gtk/gtkicontheme.h> -#include <gtk/gtkiconfactory.h> -#include <gtk/gtksettings.h> - -/* Spinner cache implementation */ - -#define EPHY_TYPE_SPINNER_CACHE (ephy_spinner_cache_get_type()) -#define EPHY_SPINNER_CACHE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_SPINNER_CACHE, EphySpinnerCache)) -#define EPHY_SPINNER_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EPHY_TYPE_SPINNER_CACHE, EphySpinnerCacheClass)) -#define EPHY_IS_SPINNER_CACHE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EPHY_TYPE_SPINNER_CACHE)) -#define EPHY_IS_SPINNER_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EPHY_TYPE_SPINNER_CACHE)) -#define EPHY_SPINNER_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_SPINNER_CACHE, EphySpinnerCacheClass)) - -typedef struct _EphySpinnerCache EphySpinnerCache; -typedef struct _EphySpinnerCacheClass EphySpinnerCacheClass; -typedef struct _EphySpinnerCachePrivate EphySpinnerCachePrivate; - -struct _EphySpinnerCacheClass -{ - GObjectClass parent_class; -}; - -struct _EphySpinnerCache -{ - GObject parent_object; - - /*< private >*/ - EphySpinnerCachePrivate *priv; -}; - -#define EPHY_SPINNER_CACHE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SPINNER_CACHE, EphySpinnerCachePrivate)) - -struct _EphySpinnerCachePrivate -{ - /* Hash table of GdkScreen -> EphySpinnerCacheData */ - GHashTable *hash; -}; - -typedef struct -{ - guint ref_count; - GtkIconSize size; - int width; - int height; - GdkPixbuf **animation_pixbufs; - guint n_animation_pixbufs; -} EphySpinnerImages; - -#define LAST_ICON_SIZE GTK_ICON_SIZE_DIALOG + 1 -#define SPINNER_ICON_NAME "process-working" -#define SPINNER_FALLBACK_ICON_NAME "gnome-spinner" -#define EPHY_SPINNER_IMAGES_INVALID ((EphySpinnerImages *) 0x1) - -typedef struct -{ - GdkScreen *screen; - GtkIconTheme *icon_theme; - EphySpinnerImages *images[LAST_ICON_SIZE]; -} EphySpinnerCacheData; - -static void ephy_spinner_cache_class_init (EphySpinnerCacheClass *klass); -static void ephy_spinner_cache_init (EphySpinnerCache *cache); - -static GObjectClass *ephy_spinner_cache_parent_class; - -static GType -ephy_spinner_cache_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - const GTypeInfo our_info = - { - sizeof (EphySpinnerCacheClass), - NULL, - NULL, - (GClassInitFunc) ephy_spinner_cache_class_init, - NULL, - NULL, - sizeof (EphySpinnerCache), - 0, - (GInstanceInitFunc) ephy_spinner_cache_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "EphySpinnerCache", - &our_info, 0); - } - - return type; -} - -static EphySpinnerImages * -ephy_spinner_images_ref (EphySpinnerImages *images) -{ - g_return_val_if_fail (images != NULL, NULL); - - images->ref_count++; - - return images; -} - -static void -ephy_spinner_images_unref (EphySpinnerImages *images) -{ - g_return_if_fail (images != NULL); - - images->ref_count--; - if (images->ref_count == 0) - { - guint i; - - LOG ("Freeing spinner images %p for size %d", images, images->size); - - for (i = 0; i < images->n_animation_pixbufs; ++i) - { - g_object_unref (images->animation_pixbufs[i]); - } - g_free (images->animation_pixbufs); - - g_free (images); - } -} - -static void -ephy_spinner_cache_data_unload (EphySpinnerCacheData *data) -{ - GtkIconSize size; - EphySpinnerImages *images; - - g_return_if_fail (data != NULL); - - LOG ("EphySpinnerDataCache unload for screen %p", data->screen); - - for (size = GTK_ICON_SIZE_INVALID; size < LAST_ICON_SIZE; ++size) - { - images = data->images[size]; - data->images[size] = NULL; - - if (images != NULL && images != EPHY_SPINNER_IMAGES_INVALID) - { - ephy_spinner_images_unref (images); - } - } -} - -static GdkPixbuf * -extract_frame (GdkPixbuf *grid_pixbuf, - int x, - int y, - int size) -{ - GdkPixbuf *pixbuf; - - if (x + size > gdk_pixbuf_get_width (grid_pixbuf) || - y + size > gdk_pixbuf_get_height (grid_pixbuf)) - { - return NULL; - } - - pixbuf = gdk_pixbuf_new_subpixbuf (grid_pixbuf, - x, y, - size, size); - g_return_val_if_fail (pixbuf != NULL, NULL); - - return pixbuf; -} - -static GdkPixbuf * -scale_to_size (GdkPixbuf *pixbuf, - int dw, - int dh) -{ - GdkPixbuf *result; - int pw, ph; - - g_return_val_if_fail (pixbuf != NULL, NULL); - - pw = gdk_pixbuf_get_width (pixbuf); - ph = gdk_pixbuf_get_height (pixbuf); - - if (pw != dw || ph != dh) - { - result = gdk_pixbuf_scale_simple (pixbuf, dw, dh, - GDK_INTERP_BILINEAR); - g_object_unref (pixbuf); - return result; - } - - return pixbuf; -} - -static EphySpinnerImages * -ephy_spinner_images_load (GdkScreen *screen, - GtkIconTheme *icon_theme, - GtkIconSize icon_size) -{ - EphySpinnerImages *images; - GdkPixbuf *icon_pixbuf, *pixbuf; - GtkIconInfo *icon_info = NULL; - int grid_width, grid_height, x, y, requested_size, size, isw, ish, n; - const char *icon; - GSList *list = NULL, *l; - - LOG ("EphySpinnerCacheData loading for screen %p at size %d", screen, icon_size); - - START_PROFILER ("loading spinner animation") - - if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen), - icon_size, &isw, &ish)) goto loser; - - requested_size = MAX (ish, isw); - - /* Load the animation. The 'rest icon' is the 0th frame */ - icon_info = gtk_icon_theme_lookup_icon (icon_theme, - SPINNER_ICON_NAME, - requested_size, 0); - if (icon_info == NULL) - { - g_warning ("Throbber animation not found"); - - /* If the icon naming spec compliant name wasn't found, try the old name */ - icon_info = gtk_icon_theme_lookup_icon (icon_theme, - SPINNER_FALLBACK_ICON_NAME, - requested_size, 0); - if (icon_info == NULL) - { - g_warning ("Throbber fallback animation not found either"); - goto loser; - } - } - g_assert (icon_info != NULL); - - size = gtk_icon_info_get_base_size (icon_info); - icon = gtk_icon_info_get_filename (icon_info); - if (icon == NULL) goto loser; - - icon_pixbuf = gdk_pixbuf_new_from_file (icon, NULL); - gtk_icon_info_free (icon_info); - icon_info = NULL; - - if (icon_pixbuf == NULL) - { - g_warning ("Could not load the spinner file"); - goto loser; - } - - grid_width = gdk_pixbuf_get_width (icon_pixbuf); - grid_height = gdk_pixbuf_get_height (icon_pixbuf); - - n = 0; - for (y = 0; y < grid_height; y += size) - { - for (x = 0; x < grid_width ; x += size) - { - pixbuf = extract_frame (icon_pixbuf, x, y, size); - - if (pixbuf) - { - list = g_slist_prepend (list, pixbuf); - ++n; - } - else - { - g_warning ("Cannot extract frame (%d, %d) from the grid\n", x, y); - } - } - } - - g_object_unref (icon_pixbuf); - - if (list == NULL) goto loser; - g_assert (n > 0); - - if (size > requested_size) - { - for (l = list; l != NULL; l = l->next) - { - l->data = scale_to_size (l->data, isw, ish); - } - } - - /* Now we've successfully got all the data */ - images = g_new (EphySpinnerImages, 1); - images->ref_count = 1; - - images->size = icon_size; - images->width = images->height = requested_size; - - images->n_animation_pixbufs = n; - images->animation_pixbufs = g_new (GdkPixbuf *, n); - - for (l = list; l != NULL; l = l->next) - { - g_assert (l->data != NULL); - images->animation_pixbufs[--n] = l->data; - } - g_assert (n == 0); - - g_slist_free (list); - - STOP_PROFILER ("loading spinner animation") - - return images; - -loser: - if (icon_info) - { - gtk_icon_info_free (icon_info); - } - g_slist_foreach (list, (GFunc) g_object_unref, NULL); - - STOP_PROFILER ("loading spinner animation") - - return NULL; -} - -static EphySpinnerCacheData * -ephy_spinner_cache_data_new (GdkScreen *screen) -{ - EphySpinnerCacheData *data; - - data = g_new0 (EphySpinnerCacheData, 1); - - data->screen = screen; - data->icon_theme = gtk_icon_theme_get_for_screen (screen); - g_signal_connect_swapped (data->icon_theme, "changed", - G_CALLBACK (ephy_spinner_cache_data_unload), - data); - - return data; -} - -static void -ephy_spinner_cache_data_free (EphySpinnerCacheData *data) -{ - g_return_if_fail (data != NULL); - g_return_if_fail (data->icon_theme != NULL); - - g_signal_handlers_disconnect_by_func - (data->icon_theme, - G_CALLBACK (ephy_spinner_cache_data_unload), data); - - ephy_spinner_cache_data_unload (data); - - g_free (data); -} - -static EphySpinnerImages * -ephy_spinner_cache_get_images (EphySpinnerCache *cache, - GdkScreen *screen, - GtkIconSize icon_size) -{ - EphySpinnerCachePrivate *priv = cache->priv; - EphySpinnerCacheData *data; - EphySpinnerImages *images; - - LOG ("Getting animation images for screen %p at size %d", screen, icon_size); - - g_return_val_if_fail (icon_size >= 0 && icon_size < LAST_ICON_SIZE, NULL); - - /* Backward compat: "invalid" meant "native" size which doesn't exist anymore */ - if (icon_size == GTK_ICON_SIZE_INVALID) - { - icon_size = GTK_ICON_SIZE_DIALOG; - } - - data = g_hash_table_lookup (priv->hash, screen); - if (data == NULL) - { - data = ephy_spinner_cache_data_new (screen); - /* FIXME: think about what happens when the screen's display is closed later on */ - g_hash_table_insert (priv->hash, screen, data); - } - - images = data->images[icon_size]; - if (images == EPHY_SPINNER_IMAGES_INVALID) - { - /* Load failed, but don't try endlessly again! */ - return NULL; - } - - if (images != NULL) - { - /* Return cached data */ - return ephy_spinner_images_ref (images); - } - - images = ephy_spinner_images_load (screen, data->icon_theme, icon_size); - - if (images == NULL) - { - /* Mark as failed-to-load */ - data->images[icon_size] = EPHY_SPINNER_IMAGES_INVALID; - - return NULL; - } - - data->images[icon_size] = images; - - return ephy_spinner_images_ref (images); -} - -static void -ephy_spinner_cache_init (EphySpinnerCache *cache) -{ - EphySpinnerCachePrivate *priv; - - priv = cache->priv = EPHY_SPINNER_CACHE_GET_PRIVATE (cache); - - LOG ("EphySpinnerCache initialising"); - - priv->hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, - (GDestroyNotify) ephy_spinner_cache_data_free); -} - -static void -ephy_spinner_cache_finalize (GObject *object) -{ - EphySpinnerCache *cache = EPHY_SPINNER_CACHE (object); - EphySpinnerCachePrivate *priv = cache->priv; - - g_hash_table_destroy (priv->hash); - - LOG ("EphySpinnerCache finalised"); - - G_OBJECT_CLASS (ephy_spinner_cache_parent_class)->finalize (object); -} - -static void -ephy_spinner_cache_class_init (EphySpinnerCacheClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - ephy_spinner_cache_parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ephy_spinner_cache_finalize; - - g_type_class_add_private (object_class, sizeof (EphySpinnerCachePrivate)); -} - -static EphySpinnerCache *spinner_cache = NULL; - -static EphySpinnerCache * -ephy_spinner_cache_ref (void) -{ - if (spinner_cache == NULL) - { - EphySpinnerCache **cache_ptr; - - spinner_cache = g_object_new (EPHY_TYPE_SPINNER_CACHE, NULL); - cache_ptr = &spinner_cache; - g_object_add_weak_pointer (G_OBJECT (spinner_cache), - (gpointer) cache_ptr); - - return spinner_cache; - } - - return g_object_ref (spinner_cache); -} - -/* Spinner implementation */ - -#define SPINNER_TIMEOUT 125 /* ms */ - -#define EPHY_SPINNER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SPINNER, EphySpinnerDetails)) - -struct _EphySpinnerDetails -{ - GtkIconTheme *icon_theme; - EphySpinnerCache *cache; - GtkIconSize size; - EphySpinnerImages *images; - guint current_image; - guint timeout; - guint timer_task; - guint spinning : 1; - guint need_load : 1; -}; - -static void ephy_spinner_class_init (EphySpinnerClass *class); -static void ephy_spinner_init (EphySpinner *spinner); - -static GObjectClass *parent_class; - -GType -ephy_spinner_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) - { - const GTypeInfo our_info = - { - sizeof (EphySpinnerClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ephy_spinner_class_init, - NULL, - NULL, /* class_data */ - sizeof (EphySpinner), - 0, /* n_preallocs */ - (GInstanceInitFunc) ephy_spinner_init - }; - - type = g_type_register_static (GTK_TYPE_WIDGET, - "EphySpinner", - &our_info, 0); - } - - return type; -} - -static gboolean -ephy_spinner_load_images (EphySpinner *spinner) -{ - EphySpinnerDetails *details = spinner->details; - - if (details->need_load) - { - START_PROFILER ("ephy_spinner_load_images") - - details->images = - ephy_spinner_cache_get_images - (details->cache, - gtk_widget_get_screen (GTK_WIDGET (spinner)), - details->size); - - STOP_PROFILER ("ephy_spinner_load_images") - - details->current_image = 0; /* 'rest' icon */ - details->need_load = FALSE; - } - - return details->images != NULL; -} - -static void -ephy_spinner_unload_images (EphySpinner *spinner) -{ - EphySpinnerDetails *details = spinner->details; - - if (details->images != NULL) - { - ephy_spinner_images_unref (details->images); - details->images = NULL; - } - - details->current_image = 0; - details->need_load = TRUE; -} - -static void -icon_theme_changed_cb (GtkIconTheme *icon_theme, - EphySpinner *spinner) -{ - ephy_spinner_unload_images (spinner); - gtk_widget_queue_resize (GTK_WIDGET (spinner)); -} - -static void -ephy_spinner_init (EphySpinner *spinner) -{ - EphySpinnerDetails *details; - - details = spinner->details = EPHY_SPINNER_GET_PRIVATE (spinner); - - GTK_WIDGET_SET_FLAGS (GTK_WIDGET (spinner), GTK_NO_WINDOW); - - details->cache = ephy_spinner_cache_ref (); - details->size = GTK_ICON_SIZE_DIALOG; - details->spinning = FALSE; - details->timeout = SPINNER_TIMEOUT; - details->need_load = TRUE; -} - -static int -ephy_spinner_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - EphySpinner *spinner = EPHY_SPINNER (widget); - EphySpinnerDetails *details = spinner->details; - EphySpinnerImages *images; - GdkPixbuf *pixbuf; - GdkGC *gc; - int x_offset, y_offset, width, height; - GdkRectangle pix_area, dest; - - if (!GTK_WIDGET_DRAWABLE (spinner)) - { - return FALSE; - } - - if (details->need_load && - !ephy_spinner_load_images (spinner)) - { - return FALSE; - } - - images = details->images; - if (images == NULL) - { - return FALSE; - } - - /* Otherwise |images| will be NULL anyway */ - g_assert (images->n_animation_pixbufs > 0); - - g_assert (details->current_image >= 0 && - details->current_image < images->n_animation_pixbufs); - - pixbuf = images->animation_pixbufs[details->current_image]; - - g_assert (pixbuf != NULL); - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - /* Compute the offsets for the image centered on our allocation */ - x_offset = (widget->allocation.width - width) / 2; - y_offset = (widget->allocation.height - height) / 2; - - pix_area.x = x_offset + widget->allocation.x; - pix_area.y = y_offset + widget->allocation.y; - pix_area.width = width; - pix_area.height = height; - - if (!gdk_rectangle_intersect (&event->area, &pix_area, &dest)) - { - return FALSE; - } - - gc = gdk_gc_new (widget->window); - gdk_draw_pixbuf (widget->window, gc, pixbuf, - dest.x - x_offset - widget->allocation.x, - dest.y - y_offset - widget->allocation.y, - dest.x, dest.y, - dest.width, dest.height, - GDK_RGB_DITHER_MAX, 0, 0); - g_object_unref (gc); - - return FALSE; -} - -static gboolean -bump_spinner_frame_cb (EphySpinner *spinner) -{ - EphySpinnerDetails *details = spinner->details; - - /* This can happen when we've unloaded the images on a theme - * change, but haven't been in the queued size request yet. - * Just skip this update. - */ - if (details->images == NULL) return TRUE; - - details->current_image++; - if (details->current_image >= details->images->n_animation_pixbufs) - { - /* the 0th frame is the 'rest' icon */ - details->current_image = MIN (1, details->images->n_animation_pixbufs); - } - - gtk_widget_queue_draw (GTK_WIDGET (spinner)); - - /* run again */ - return TRUE; -} - -/** - * ephy_spinner_start: - * @spinner: a #EphySpinner - * - * Start the spinner animation. - **/ -void -ephy_spinner_start (EphySpinner *spinner) -{ - EphySpinnerDetails *details = spinner->details; - - details->spinning = TRUE; - - if (GTK_WIDGET_MAPPED (GTK_WIDGET (spinner)) && - details->timer_task == 0 && - ephy_spinner_load_images (spinner)) - { - /* the 0th frame is the 'rest' icon */ - details->current_image = MIN (1, details->images->n_animation_pixbufs); - - details->timer_task = - g_timeout_add_full (G_PRIORITY_LOW, - details->timeout, - (GSourceFunc) bump_spinner_frame_cb, - spinner, - NULL); - } -} - -static void -ephy_spinner_remove_update_callback (EphySpinner *spinner) -{ - EphySpinnerDetails *details = spinner->details; - - if (details->timer_task != 0) - { - g_source_remove (details->timer_task); - details->timer_task = 0; - } -} - -/** - * ephy_spinner_stop: - * @spinner: a #EphySpinner - * - * Stop the spinner animation. - **/ -void -ephy_spinner_stop (EphySpinner *spinner) -{ - EphySpinnerDetails *details = spinner->details; - - details->spinning = FALSE; - details->current_image = 0; - - if (details->timer_task != 0) - { - ephy_spinner_remove_update_callback (spinner); - - if (GTK_WIDGET_MAPPED (GTK_WIDGET (spinner))) - { - gtk_widget_queue_draw (GTK_WIDGET (spinner)); - } - } -} - -/* - * ephy_spinner_set_size: - * @spinner: a #EphySpinner - * @size: the size of type %GtkIconSize - * - * Set the size of the spinner. - **/ -void -ephy_spinner_set_size (EphySpinner *spinner, - GtkIconSize size) -{ - if (size == GTK_ICON_SIZE_INVALID) - { - size = GTK_ICON_SIZE_DIALOG; - } - - if (size != spinner->details->size) - { - ephy_spinner_unload_images (spinner); - - spinner->details->size = size; - - gtk_widget_queue_resize (GTK_WIDGET (spinner)); - } -} - -#if 0 -/* - * ephy_spinner_set_timeout: - * @spinner: a #EphySpinner - * @timeout: time delay between updates to the spinner. - * - * Sets the timeout delay for spinner updates. - **/ -void -ephy_spinner_set_timeout (EphySpinner *spinner, - guint timeout) -{ - EphySpinnerDetails *details = spinner->details; - - if (timeout != details->timeout) - { - ephy_spinner_stop (spinner); - - details->timeout = timeout; - - if (details->spinning) - { - ephy_spinner_start (spinner); - } - } -} -#endif - -static void -ephy_spinner_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - EphySpinner *spinner = EPHY_SPINNER (widget); - EphySpinnerDetails *details = spinner->details; - - if ((details->need_load && - !ephy_spinner_load_images (spinner)) || - details->images == NULL) - { - requisition->width = requisition->height = 0; - gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget), - details->size, - &requisition->width, - &requisition->height); - return; - } - - requisition->width = details->images->width; - requisition->height = details->images->height; - - /* FIXME fix this hack */ - /* allocate some extra margin so we don't butt up against toolbar edges */ - if (details->size != GTK_ICON_SIZE_MENU) - { - requisition->width += 2; - requisition->height += 2; - } -} - -static void -ephy_spinner_map (GtkWidget *widget) -{ - EphySpinner *spinner = EPHY_SPINNER (widget); - EphySpinnerDetails *details = spinner->details; - - GTK_WIDGET_CLASS (parent_class)->map (widget); - - if (details->spinning) - { - ephy_spinner_start (spinner); - } -} - -static void -ephy_spinner_unmap (GtkWidget *widget) -{ - EphySpinner *spinner = EPHY_SPINNER (widget); - - ephy_spinner_remove_update_callback (spinner); - - GTK_WIDGET_CLASS (parent_class)->unmap (widget); -} - -static void -ephy_spinner_dispose (GObject *object) -{ - EphySpinner *spinner = EPHY_SPINNER (object); - - g_signal_handlers_disconnect_by_func - (spinner->details->icon_theme, - G_CALLBACK (icon_theme_changed_cb), spinner); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -ephy_spinner_finalize (GObject *object) -{ - EphySpinner *spinner = EPHY_SPINNER (object); - - ephy_spinner_remove_update_callback (spinner); - ephy_spinner_unload_images (spinner); - - g_object_unref (spinner->details->cache); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -ephy_spinner_screen_changed (GtkWidget *widget, - GdkScreen *old_screen) -{ - EphySpinner *spinner = EPHY_SPINNER (widget); - EphySpinnerDetails *details = spinner->details; - GdkScreen *screen; - - if (GTK_WIDGET_CLASS (parent_class)->screen_changed) - { - GTK_WIDGET_CLASS (parent_class)->screen_changed (widget, old_screen); - } - - screen = gtk_widget_get_screen (widget); - - /* FIXME: this seems to be happening when then spinner is destroyed!? */ - if (old_screen == screen) return; - - /* We'll get mapped again on the new screen, but not unmapped from - * the old screen, so remove timeout here. - */ - ephy_spinner_remove_update_callback (spinner); - - ephy_spinner_unload_images (spinner); - - if (old_screen != NULL) - { - g_signal_handlers_disconnect_by_func - (gtk_icon_theme_get_for_screen (old_screen), - G_CALLBACK (icon_theme_changed_cb), spinner); - } - - details->icon_theme = gtk_icon_theme_get_for_screen (screen); - g_signal_connect (details->icon_theme, "changed", - G_CALLBACK (icon_theme_changed_cb), spinner); -} - -static void -ephy_spinner_class_init (EphySpinnerClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); - - parent_class = g_type_class_peek_parent (class); - - object_class->dispose = ephy_spinner_dispose; - object_class->finalize = ephy_spinner_finalize; - - widget_class->expose_event = ephy_spinner_expose; - widget_class->size_request = ephy_spinner_size_request; - widget_class->map = ephy_spinner_map; - widget_class->unmap = ephy_spinner_unmap; - widget_class->screen_changed = ephy_spinner_screen_changed; - - g_type_class_add_private (object_class, sizeof (EphySpinnerDetails)); -} - -/* - * ephy_spinner_new: - * - * Create a new #EphySpinner. The spinner is a widget - * that gives the user feedback about network status with - * an animated image. - * - * Return Value: the spinner #GtkWidget - **/ -GtkWidget * -ephy_spinner_new (void) -{ - return GTK_WIDGET (g_object_new (EPHY_TYPE_SPINNER, NULL)); -} diff --git a/src/ephy-spinner.h b/src/ephy-spinner.h deleted file mode 100644 index 4435fe371..000000000 --- a/src/ephy-spinner.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* - * Copyright © 2000 Eazel, Inc. - * Copyright © 2004, 2006 Christian Persch - * - * Nautilus is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Nautilus is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Andy Hertzfeld <andy@eazel.com> - * - * $Id: ephy-spinner.h 2114 2006-12-25 12:15:00Z mr $ - */ - -#ifndef EPHY_SPINNER_H -#define EPHY_SPINNER_H - -#include <gtk/gtkwidget.h> -#include <gtk/gtkenums.h> - -G_BEGIN_DECLS - -#define EPHY_TYPE_SPINNER (ephy_spinner_get_type ()) -#define EPHY_SPINNER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_SPINNER, EphySpinner)) -#define EPHY_SPINNER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_SPINNER, EphySpinnerClass)) -#define EPHY_IS_SPINNER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_SPINNER)) -#define EPHY_IS_SPINNER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_SPINNER)) -#define EPHY_SPINNER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_SPINNER, EphySpinnerClass)) - -typedef struct _EphySpinner EphySpinner; -typedef struct _EphySpinnerClass EphySpinnerClass; -typedef struct _EphySpinnerDetails EphySpinnerDetails; - -struct _EphySpinner -{ - GtkWidget parent; - - /*< private >*/ - EphySpinnerDetails *details; -}; - -struct _EphySpinnerClass -{ - GtkWidgetClass parent_class; -}; - -GType ephy_spinner_get_type (void); - -GtkWidget *ephy_spinner_new (void); - -void ephy_spinner_start (EphySpinner *throbber); - -void ephy_spinner_stop (EphySpinner *throbber); - -void ephy_spinner_set_size (EphySpinner *spinner, - GtkIconSize size); - -G_END_DECLS - -#endif /* EPHY_SPINNER_H */ |