diff options
author | Xavier Claessens <xclaesse@gmail.com> | 2010-08-04 14:33:51 +0200 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2010-08-10 12:07:53 +0200 |
commit | 2c2dfdcc5449dedcd8529e3d9d42ddd417cc42bb (patch) | |
tree | 6c5e1a55c12ca1946eb9a5c37aa19c902ad928e8 | |
parent | 758a2df6236d4851c3f03ea4071ec704e3d82302 (diff) |
Add initial vinagre plugin
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | configure.ac | 28 | ||||
-rw-r--r-- | po/POTFILES.in | 4 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/vinagre/Makefile.am | 37 | ||||
-rw-r--r-- | src/vinagre/connection.c | 223 | ||||
-rw-r--r-- | src/vinagre/connection.h | 65 | ||||
-rw-r--r-- | src/vinagre/plugin.c | 244 | ||||
-rw-r--r-- | src/vinagre/plugin.h | 58 | ||||
-rw-r--r-- | src/vinagre/ssh-contact.vinagre-plugin.desktop.in | 11 | ||||
-rw-r--r-- | src/vinagre/tab.c | 274 | ||||
-rw-r--r-- | src/vinagre/tab.h | 56 | ||||
-rw-r--r-- | src/vinagre/tree-view.c | 328 | ||||
-rw-r--r-- | src/vinagre/tree-view.h | 61 |
14 files changed, 1397 insertions, 0 deletions
@@ -39,6 +39,7 @@ m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 +po/.intltool-merge-cache po/POTFILES po/ssh-contact.pot po/stamp-it @@ -46,3 +47,6 @@ po/stamp-it src/ssh-contact src/ssh-contact-service src/org.freedesktop.Telepathy.Client.SSHContact.service + +src/vinagre/ssh-contact.vinagre-plugin + diff --git a/configure.ac b/configure.ac index 0b20aec..081e94b 100644 --- a/configure.ac +++ b/configure.ac @@ -81,9 +81,37 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Gettext package name]) AM_GLIB_GNU_GETTEXT # ----------------------------------------------------------- +# Vinagre plugin +# ----------------------------------------------------------- +AC_ARG_ENABLE(vinagre, + AS_HELP_STRING([--enable-vinagre=@<:@no/yes/auto@:>@], + [build with vinagre plugin]), , + enable_vinagre=auto) + +if test "x$enable_vinagre" != "xno"; then + PKG_CHECK_MODULES(VINAGRE, + [ + vinagre-1.0 + vte + ], have_vinagre="yes", have_vinagre="no") + + if test "x$have_vinagre" = "xyes"; then + AC_DEFINE(HAVE_VINAGRE, 1, [Define if you have libvinagre]) + fi +else + have_vinagre=no +fi + +if test "x$enable_vinagre" = "xyes" -a "x$have_vinagre" != "xyes"; then + AC_MSG_ERROR([Could not find vinagre dependencies.]) +fi +AM_CONDITIONAL(HAVE_VINAGRE, test "x$have_vinagre" = "xyes") + +# ----------------------------------------------------------- AC_OUTPUT([ Makefile po/Makefile.in src/Makefile +src/vinagre/Makefile ]) diff --git a/po/POTFILES.in b/po/POTFILES.in index 1cbe438..a3f3fb2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,3 +1,7 @@ # List of source files containing translatable strings. # Please keep this file sorted alphabetically. +src/vinagre/plugin.c +src/vinagre/ssh-contact.vinagre-plugin.desktop.in +src/vinagre/tab.c + diff --git a/src/Makefile.am b/src/Makefile.am index b3194b0..3492352 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,7 @@ +if HAVE_VINAGRE +SUBDIRS = vinagre +endif + AM_CPPFLAGS = \ $(ERROR_CFLAGS) \ $(SSH_CONTACT_CFLAGS) \ diff --git a/src/vinagre/Makefile.am b/src/vinagre/Makefile.am new file mode 100644 index 0000000..5845572 --- /dev/null +++ b/src/vinagre/Makefile.am @@ -0,0 +1,37 @@ +# ssh plugin +plugindir = $(libdir)/vinagre-1/plugins + +AM_CPPFLAGS = \ + $(ERROR_CFLAGS) \ + $(SSH_CONTACT_CFLAGS) \ + $(VINAGRE_CFLAGS) \ + $(NULL) + +plugin_LTLIBRARIES = libssh-contact.la + +libssh_contact_la_LIBADD = \ + $(SSH_CONTACT_LIBS) \ + $(VINAGRE_LIBS) \ + $(NULL) + +libssh_contact_la_SOURCES = \ + plugin.h plugin.c \ + connection.h connection.c \ + tab.h tab.c \ + tree-view.h tree-view.c \ + ../client-helpers.h ../client-helpers.c \ + ../common.h ../common.c \ + $(NULL) + +plugin_in_files = ssh-contact.vinagre-plugin.desktop.in + +ssh-contact.vinagre-plugin: ssh-contact.vinagre-plugin.desktop.in + $(AM_V_GEN) $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c \ + $(top_builddir)/po/.intltool-merge-cache + +plugin_DATA = $(plugin_in_files:.vinagre-plugin.desktop.in=.vinagre-plugin) + +EXTRA_DIST = $(plugin_in_files) +CLEANFILES = $(plugin_DATA) +DISTCLEANFILES = $(plugin_DATA) + diff --git a/src/vinagre/connection.c b/src/vinagre/connection.c new file mode 100644 index 0000000..05b950c --- /dev/null +++ b/src/vinagre/connection.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2009 Jonh Wendell <wendell@bani.com.br> + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include <glib/gi18n.h> + +#include <vinagre/vinagre-utils.h> +#include <vinagre/vinagre-cache-prefs.h> + +#include <telepathy-glib/telepathy-glib.h> + +#include "connection.h" +#include "tree-view.h" + +struct _SshContactConnectionPrivate +{ + gchar *account_path; + gchar *contact_id; +}; + +G_DEFINE_TYPE (SshContactConnection, ssh_contact_connection, + VINAGRE_TYPE_CONNECTION); + +static void +impl_fill_writer (VinagreConnection *conn, xmlTextWriter *writer) +{ + SshContactConnection *self = SSH_CONTACT_CONNECTION (conn); + + xmlTextWriterWriteElement (writer, (const xmlChar *) "account", + (const xmlChar *) (self->priv->account_path ? self->priv->account_path : "")); + xmlTextWriterWriteElement (writer, (const xmlChar *) "contact", + (const xmlChar *) (self->priv->contact_id ? self->priv->contact_id : "")); + + VINAGRE_CONNECTION_CLASS (ssh_contact_connection_parent_class)->impl_fill_writer (conn, writer); +} + +static void +impl_parse_item (VinagreConnection *conn, xmlNode *root) +{ + SshContactConnection *self = SSH_CONTACT_CONNECTION (conn); + xmlNode *curr; + xmlChar *s_value; + + for (curr = root->children; curr; curr = curr->next) + { + s_value = xmlNodeGetContent (curr); + + if (!xmlStrcmp(curr->name, (const xmlChar *)"account")) + ssh_contact_connection_set_account_path (self, (gchar *) s_value); + else if (!xmlStrcmp(curr->name, (const xmlChar *)"contact")) + ssh_contact_connection_set_contact_id (self, (gchar *) s_value); + + xmlFree (s_value); + } + + VINAGRE_CONNECTION_CLASS (ssh_contact_connection_parent_class)->impl_parse_item (conn, root); +} + +static void +impl_parse_options_widget (VinagreConnection *conn, + GtkWidget *widget) +{ + GtkWidget *entry; + const gchar *username; + + entry = g_object_get_data (G_OBJECT (widget), "username_entry"); + if (entry == NULL) + { + g_warning ("Wrong widget passed to impl_parse_options_widget()"); + return; + } + + username = gtk_entry_get_text (GTK_ENTRY (entry)); + vinagre_cache_prefs_set_string ("ssh-contact-connection", "username", + username); + vinagre_connection_set_username (conn, username); + + VINAGRE_CONNECTION_CLASS (ssh_contact_connection_parent_class)->impl_parse_options_widget (conn, widget); +} + +static void +impl_parse_host_widget (VinagreConnection *conn, + GtkWidget *widget) +{ + SshContactConnection *self = SSH_CONTACT_CONNECTION (conn); + SshContactTreeView *view; + TpAccount *account; + TpContact *contact; + + /* widget is a GtkScrolledWindow containing an SshContactTreeView */ + view = SSH_CONTACT_TREE_VIEW (gtk_bin_get_child (GTK_BIN (widget))); + + account = ssh_contact_tree_view_get_selected_account (view); + ssh_contact_connection_set_account_path (self, + tp_proxy_get_object_path (account)); + + contact = ssh_contact_tree_view_get_selected_contact (view); + ssh_contact_connection_set_contact_id (self, + tp_contact_get_identifier (contact)); + + VINAGRE_CONNECTION_CLASS (ssh_contact_connection_parent_class)->impl_parse_host_widget (conn, widget); +} + +static gchar * +impl_get_string_rep (VinagreConnection *conn, + gboolean has_protocol) +{ + SshContactConnection *self = SSH_CONTACT_CONNECTION (conn); + GString *uri; + + if (has_protocol) + { + uri = g_string_new (vinagre_connection_get_protocol (conn)); + g_string_append (uri, "://"); + } + else + { + uri = g_string_new (NULL); + } + + g_string_append (uri, self->priv->account_path); + g_string_append_c (uri, '/'); + g_string_append (uri, self->priv->contact_id); + + return g_string_free (uri, FALSE); +} + +static void +finalize (GObject *object) +{ + SshContactConnection *self = SSH_CONTACT_CONNECTION (object); + + g_free (self->priv->contact_id); + g_free (self->priv->account_path); + + G_OBJECT_CLASS (ssh_contact_connection_parent_class)->finalize (object); +} + +static void +ssh_contact_connection_init (SshContactConnection *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SSH_CONTACT_TYPE_CONNECTION, + SshContactConnectionPrivate); +} + +static void +ssh_contact_connection_class_init (SshContactConnectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + VinagreConnectionClass* vinagre_class = VINAGRE_CONNECTION_CLASS (klass); + + object_class->finalize = finalize; + + vinagre_class->impl_fill_writer = impl_fill_writer; + vinagre_class->impl_parse_item = impl_parse_item; + vinagre_class->impl_parse_options_widget = impl_parse_options_widget; + vinagre_class->impl_parse_host_widget = impl_parse_host_widget; + vinagre_class->impl_get_string_rep = impl_get_string_rep; + + g_type_class_add_private (klass, sizeof (SshContactConnectionPrivate)); +} + +VinagreConnection * +ssh_contact_connection_new (void) +{ + return g_object_new (SSH_CONTACT_TYPE_CONNECTION, + "protocol", "ssh-contact", + NULL); +} + +const gchar * +ssh_contact_connection_get_account_path (SshContactConnection *self) +{ + g_return_val_if_fail (SSH_CONTACT_IS_CONNECTION (self), NULL); + + return self->priv->account_path; +} + +void +ssh_contact_connection_set_account_path (SshContactConnection *self, + const gchar *account_path) +{ + g_return_if_fail (SSH_CONTACT_IS_CONNECTION (self)); + + g_free (self->priv->account_path); + self->priv->account_path = g_strdup (account_path); +} + +const gchar * +ssh_contact_connection_get_contact_id (SshContactConnection *self) +{ + g_return_val_if_fail (SSH_CONTACT_IS_CONNECTION (self), NULL); + + return self->priv->contact_id; +} + +void +ssh_contact_connection_set_contact_id (SshContactConnection *self, + const gchar *contact_id) +{ + g_return_if_fail (SSH_CONTACT_IS_CONNECTION (self)); + + g_free (self->priv->contact_id); + self->priv->contact_id = g_strdup (contact_id); +} + +/* vim: set ts=8: */ diff --git a/src/vinagre/connection.h b/src/vinagre/connection.h new file mode 100644 index 0000000..7a56947 --- /dev/null +++ b/src/vinagre/connection.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009 Jonh Wendell <wendell@bani.com.br> + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __SSH_CONTACT_CONNECTION_H__ +#define __SSH_CONTACT_CONNECTION_H__ + +#include <vinagre/vinagre-connection.h> + +G_BEGIN_DECLS + +#define SSH_CONTACT_TYPE_CONNECTION (ssh_contact_connection_get_type ()) +#define SSH_CONTACT_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SSH_CONTACT_TYPE_CONNECTION, SshContactConnection)) +#define SSH_CONTACT_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SSH_CONTACT_TYPE_CONNECTION, SshContactConnectionClass)) +#define SSH_CONTACT_IS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SSH_CONTACT_TYPE_CONNECTION)) +#define SSH_CONTACT_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SSH_CONTACT_TYPE_CONNECTION)) +#define SSH_CONTACT_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SSH_CONTACT_TYPE_CONNECTION, SshContactConnectionClass)) + +typedef struct _SshContactConnectionPrivate SshContactConnectionPrivate; + +typedef struct +{ + VinagreConnection parent_instance; + SshContactConnectionPrivate *priv; +} SshContactConnection; + +typedef struct +{ + VinagreConnectionClass parent_class; +} SshContactConnectionClass; + +GType ssh_contact_connection_get_type (void) G_GNUC_CONST; + +VinagreConnection *ssh_contact_connection_new (void); + +const gchar *ssh_contact_connection_get_account_path (SshContactConnection *self); + +void ssh_contact_connection_set_account_path (SshContactConnection *self, + const gchar *account_path); + +const gchar *ssh_contact_connection_get_contact_id (SshContactConnection *self); + +void ssh_contact_connection_set_contact_id (SshContactConnection *self, + const gchar *contact_id); + +G_END_DECLS + +#endif /* __SSH_CONTACT_CONNECTION_H__ */ +/* vim: set ts=8: */ diff --git a/src/vinagre/plugin.c b/src/vinagre/plugin.c new file mode 100644 index 0000000..33be5c9 --- /dev/null +++ b/src/vinagre/plugin.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2009 Jonh Wendell <wendell@bani.com.br> + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include <glib/gi18n-lib.h> +#include <gmodule.h> + +#include <vinagre/vinagre-debug.h> +#include <vinagre/vinagre-cache-prefs.h> + +#include "plugin.h" +#include "connection.h" +#include "tab.h" +#include "tree-view.h" + +VINAGRE_PLUGIN_REGISTER_TYPE (SshContactPlugin, ssh_contact_plugin) + +static void +impl_activate (VinagrePlugin *plugin, + VinagreWindow *window) +{ + vinagre_debug_message (DEBUG_PLUGINS, "SshContactPlugin Activate"); +} + +static void +impl_deactivate (VinagrePlugin *plugin, + VinagreWindow *window) +{ + vinagre_debug_message (DEBUG_PLUGINS, "SshContactPlugin Deactivate"); +} + +static void +impl_update_ui (VinagrePlugin *plugin, + VinagreWindow *window) +{ + vinagre_debug_message (DEBUG_PLUGINS, "SshContactPlugin Update UI"); +} + +static const gchar * +impl_get_protocol (VinagrePlugin *plugin) +{ + return "ssh-contact"; +} + +static gchar ** +impl_get_public_description (VinagrePlugin *plugin) +{ + gchar **result = g_new (gchar *, 3); + + result[0] = g_strdup (_("SSH-Contact")); + /* Translators: This is a description of the SSH protocol. It appears at + * Connect dialog. */ + result[1] = g_strdup (_("Access Unix/Linux terminals using a Telepathy Tube")); + result[2] = NULL; + + return result; +} + +static const gchar * +impl_get_mdns_service (VinagrePlugin *plugin) +{ + return NULL; +} + +static VinagreConnection * +impl_new_connection (VinagrePlugin *plugin) +{ + return ssh_contact_connection_new (); +} + +static VinagreConnection * +impl_new_connection_from_string (VinagrePlugin *plugin, + const gchar *uri, + gchar **error_msg, + gboolean use_bookmarks) +{ + VinagreConnection *conn = NULL; + const gchar *p1 = uri; + const gchar *p2; + gchar *account_path; + gchar *contact_id; + + /* FIXME: Search in bookmarks */ + + /* URI is in the form "ssh-contact://<account path>/<contact id>". */ + + /* Skip the scheme part */ + if (!g_str_has_prefix (p1, vinagre_plugin_get_protocol (plugin))) + goto OUT; + p1 += strlen (vinagre_plugin_get_protocol (plugin)); + if (!g_str_has_prefix (p1, "://")) + goto OUT; + p1 += strlen ("://"); + + /* Search delimiter between account path and contact id */ + p2 = g_strrstr (p1, "/"); + if (p2 == NULL) + goto OUT; + + account_path = g_strndup (p1, p2 - p1); + contact_id = g_strdup (p2 + 1); + + conn = ssh_contact_connection_new (); + ssh_contact_connection_set_account_path (SSH_CONTACT_CONNECTION (conn), + account_path); + ssh_contact_connection_set_contact_id (SSH_CONTACT_CONNECTION (conn), + contact_id); + + g_free (account_path); + g_free (contact_id); + +OUT: + + if (conn == NULL) + *error_msg = g_strdup ("URI format not recognized"); + + return conn; +} + +static GtkWidget * +impl_new_tab (VinagrePlugin *plugin, + VinagreConnection *conn, + VinagreWindow *window) +{ + return ssh_contact_tab_new (conn, window); +} + +static gint +impl_get_default_port (VinagrePlugin *plugin) +{ + return 0; +} + +static GtkWidget * +impl_get_connect_widget (VinagrePlugin *plugin, + VinagreConnection *conn) +{ + GtkWidget *box, *label, *u_box, *u_entry; + gchar *str; + + box = gtk_vbox_new (FALSE, 0); + + str = g_strdup_printf ("<b>%s</b>", _("SSH Options")); + label = gtk_label_new (str); + g_free (str); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_misc_set_padding (GTK_MISC (label), 0, 6); + gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); + + u_box = gtk_hbox_new (FALSE, 4); + label = gtk_label_new (" "); + gtk_box_pack_start (GTK_BOX (u_box), label, FALSE, FALSE, 0); + + label = gtk_label_new_with_mnemonic (_("_Username:")); + gtk_box_pack_start (GTK_BOX (u_box), label, FALSE, FALSE, 0); + + u_entry = gtk_entry_new (); + /* Translators: This is the tooltip for the username field in a SSH + * connection */ + gtk_widget_set_tooltip_text (u_entry, + _("Optional. If blank, your username will be used.")); + g_object_set_data (G_OBJECT (box), "username_entry", u_entry); + gtk_box_pack_start (GTK_BOX (u_box), u_entry, TRUE, TRUE, 5); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), u_entry); + str = g_strdup (VINAGRE_IS_CONNECTION (conn) ? + vinagre_connection_get_username (conn) : + vinagre_cache_prefs_get_string ("ssh-contact-connection", "username", "")); + gtk_entry_set_text (GTK_ENTRY (u_entry), str); + gtk_entry_set_activates_default (GTK_ENTRY (u_entry), TRUE); + g_free (str); + + gtk_box_pack_start (GTK_BOX (box), u_box, TRUE, TRUE, 0); + + return box; +} + +static GtkWidget * +impl_get_connect_host_widget (VinagrePlugin *plugin, + VinagreConnection *conn) +{ + GtkWidget *sw; + GtkWidget *view; + + view = ssh_contact_tree_view_new (); + gtk_widget_show (view); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (sw), view); + gtk_widget_set_size_request (GTK_WIDGET (sw), -1, 150); + + return sw; +} + +static void +impl_parse_mdns_dialog (VinagrePlugin *plugin, + GtkWidget *connect_widget, + GtkWidget *dialog) +{ +} + +static void +ssh_contact_plugin_init (SshContactPlugin *self) +{ +} + +static void +ssh_contact_plugin_class_init (SshContactPluginClass *klass) +{ + VinagrePluginClass *plugin_class = VINAGRE_PLUGIN_CLASS (klass); + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + plugin_class->update_ui = impl_update_ui; + plugin_class->get_protocol = impl_get_protocol; + plugin_class->get_public_description = impl_get_public_description; + plugin_class->new_connection = impl_new_connection; + plugin_class->new_connection_from_string = impl_new_connection_from_string; + plugin_class->get_mdns_service = impl_get_mdns_service; + plugin_class->new_tab = impl_new_tab; + plugin_class->get_default_port = impl_get_default_port; + plugin_class->get_connect_widget = impl_get_connect_widget; + plugin_class->get_connect_host_widget = impl_get_connect_host_widget; + plugin_class->parse_mdns_dialog = impl_parse_mdns_dialog; +} +/* vim: set ts=8: */ diff --git a/src/vinagre/plugin.h b/src/vinagre/plugin.h new file mode 100644 index 0000000..50e10b9 --- /dev/null +++ b/src/vinagre/plugin.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Jonh Wendell <wendell@bani.com.br> + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __SSH_CONTACT_PLUGIN_H__ +#define __SSH_CONTACT_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <vinagre/vinagre-plugin.h> + +G_BEGIN_DECLS + +#define SSH_CONTACT_TYPE_PLUGIN (ssh_contact_plugin_get_type ()) +#define SSH_CONTACT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SSH_CONTACT_TYPE_PLUGIN, SshContactPlugin)) +#define SSH_CONTACT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SSH_CONTACT_TYPE_PLUGIN, SshContactPluginClass)) +#define SSH_CONTACT_IS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SSH_CONTACT_TYPE_PLUGIN)) +#define SSH_CONTACT_IS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SSH_CONTACT_TYPE_PLUGIN)) +#define SSH_CONTACT_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SSH_CONTACT_TYPE_PLUGIN, SshContactPluginClass)) + +typedef struct _SshContactPluginPrivate SshContactPluginPrivate; + +typedef struct +{ + VinagrePlugin parent_instance; + SshContactPluginPrivate *priv; +} SshContactPlugin; + +typedef struct +{ + VinagrePluginClass parent_class; +} SshContactPluginClass; + +GType ssh_contact_plugin_get_type (void) G_GNUC_CONST; + +/* All the plugins must implement this function */ +G_MODULE_EXPORT GType register_vinagre_plugin (GTypeModule *module); + +G_END_DECLS + +#endif /* __SSH_CONTACT_PLUGIN_H__ */ +/* vim: set ts=8: */ diff --git a/src/vinagre/ssh-contact.vinagre-plugin.desktop.in b/src/vinagre/ssh-contact.vinagre-plugin.desktop.in new file mode 100644 index 0000000..db50f0f --- /dev/null +++ b/src/vinagre/ssh-contact.vinagre-plugin.desktop.in @@ -0,0 +1,11 @@ +[Vinagre Plugin] +Module=ssh-contact +IAge=1 +_Name=SSH-Contact +_Description=SSH-Contact support +Authors=Xavier Claessens +Copyright=Copyright © 2010 Collabora Ltd. +Website=http://telepathy.freedesktop.org/wiki/SSH-Contact +Version=1.0 +Engine=1 +Icon=utilities-terminal diff --git a/src/vinagre/tab.c b/src/vinagre/tab.c new file mode 100644 index 0000000..ef4e559 --- /dev/null +++ b/src/vinagre/tab.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2009 Jonh Wendell <wendell@bani.com.br> + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include <glib/gi18n.h> +#include <vte/vte.h> +#include <gdk/gdkkeysyms.h> + +#include <vinagre/vinagre-utils.h> +#include <vinagre/vinagre-prefs.h> + +#include "tab.h" +#include "connection.h" +#include "../client-helpers.h" +#include "../common.h" + +struct _SshContactTabPrivate +{ + GtkWidget *vte; + GSocketConnection *tube_connection; + GSocketConnection *ssh_connection; +}; + +G_DEFINE_TYPE (SshContactTab, ssh_contact_tab, VINAGRE_TYPE_TAB) + +static void +ssh_disconnected_cb (VteTerminal *ssh, + SshContactTab *self) +{ + g_signal_emit_by_name (self, "tab-disconnected"); +} + +static void +get_connection_info (SshContactTab *self, + const gchar **account_path, + const gchar **contact_id, + const gchar **username) +{ + VinagreConnection *conn; + + conn = vinagre_tab_get_conn (VINAGRE_TAB (self)); + if (account_path != NULL) + *account_path = ssh_contact_connection_get_account_path (SSH_CONTACT_CONNECTION (conn)); + if (contact_id != NULL) + *contact_id = ssh_contact_connection_get_contact_id (SSH_CONTACT_CONNECTION (conn)); + if (username != NULL) + *username = vinagre_connection_get_username (conn); +} + +static gchar * +impl_get_tooltip (VinagreTab *tab) +{ + SshContactTab *self = SSH_CONTACT_TAB (tab); + const gchar *account_path; + const gchar *contact_id; + + get_connection_info (self, &account_path, &contact_id, NULL); + + return g_markup_printf_escaped ( + "<b>%s</b> %s\n" + "<b>%s</b> %s", + _("Account:"), account_path + strlen (TP_ACCOUNT_OBJECT_PATH_BASE), + _("Contact:"), contact_id); +} + +static GdkPixbuf * +impl_get_screenshot (VinagreTab *tab) +{ + SshContactTab *self = SSH_CONTACT_TAB (tab); + GdkPixbuf *pixbuf; + GdkPixmap *pixmap; + + pixmap = gtk_widget_get_snapshot (self->priv->vte, NULL); + pixbuf = gdk_pixbuf_get_from_drawable (NULL, GDK_DRAWABLE (pixmap), + gdk_colormap_get_system (), 0, 0, 0, 0, -1, -1); + + g_object_unref (pixmap); + + return pixbuf; +} + +static void +throw_error (SshContactTab *self, + const GError *error) +{ + g_debug ("ERROR: %s", error->message); + g_signal_emit_by_name (self, "tab-auth-failed", error->message); +} + +static void +splice_cb (GIOStream *stream1, + GIOStream *stream2, + const GError *error, + gpointer user_data) +{ + SshContactTab *self = user_data; + + if (error != NULL) + throw_error (self, error); + else + g_signal_emit_by_name (self, "tab-disconnected"); +} + +static void +maybe_start_splice (SshContactTab *self) +{ + if (self->priv->tube_connection != NULL && self->priv->ssh_connection != NULL) + { + g_signal_emit_by_name (self, "tab-connected"); + + /* Splice tube and ssh connections */ + _g_io_stream_splice (G_IO_STREAM (self->priv->tube_connection), + G_IO_STREAM (self->priv->ssh_connection), splice_cb, self); + } +} + +static void +ssh_socket_connected_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + SshContactTab *self = user_data; + GSocketListener *listener = G_SOCKET_LISTENER (source_object); + GError *error = NULL; + + self->priv->ssh_connection = g_socket_listener_accept_finish (listener, res, + NULL, &error); + if (error != NULL) + { + throw_error (self, error); + g_clear_error (&error); + return; + } + + maybe_start_splice (self); +} + +static void +create_tube_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + SshContactTab *self = user_data; + GError *error = NULL; + + self->priv->tube_connection = _client_create_tube_finish (res, &error); + if (error != NULL) + { + throw_error (self, error); + g_clear_error (&error); + return; + } + + maybe_start_splice (self); +} + +static gboolean +start_tube (gpointer user_data) +{ + SshContactTab *self = user_data; + const gchar *username; + const gchar *account_path; + const gchar *contact_id; + GSocketListener *listener; + GSocket *socket; + GError *error = NULL; + GStrv args = NULL; + + g_signal_emit_by_name (self, "tab-initialized"); + + get_connection_info (self, &account_path, &contact_id, &username); + + listener = g_socket_listener_new (); + socket = _client_create_local_socket (&error); + if (socket == NULL) + goto OUT; + if (!g_socket_listen (socket, &error)) + goto OUT; + if (!g_socket_listener_add_socket (listener, socket, NULL, &error)) + goto OUT; + + g_socket_listener_accept_async (listener, NULL, + ssh_socket_connected_cb, self); + + args = _client_create_exec_args (socket, contact_id, username); + vte_terminal_fork_command (VTE_TERMINAL (self->priv->vte), "ssh", args, + NULL, NULL, FALSE, FALSE, FALSE); + + _client_create_tube_async (account_path, contact_id, create_tube_cb, self); + +OUT: + + if (error != NULL) + throw_error (self, error); + + g_clear_error (&error); + tp_clear_object (&listener); + tp_clear_object (&socket); + g_strfreev (args); + + return FALSE; +} + +static void +constructed (GObject *object) +{ + SshContactTab *self = SSH_CONTACT_TAB (object); + + g_idle_add (start_tube, self); + + vinagre_tab_add_recent_used (VINAGRE_TAB (self)); + vinagre_tab_set_state (VINAGRE_TAB (self), VINAGRE_TAB_STATE_CONNECTED); + + gtk_widget_show (GTK_WIDGET (self)); + + if (G_OBJECT_CLASS (ssh_contact_tab_parent_class)->constructed) + G_OBJECT_CLASS (ssh_contact_tab_parent_class)->constructed (object); +} + +static void +ssh_contact_tab_class_init (SshContactTabClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + VinagreTabClass* tab_class = VINAGRE_TAB_CLASS (klass); + + object_class->constructed = constructed; + + tab_class->impl_get_tooltip = impl_get_tooltip; + tab_class->impl_get_screenshot = impl_get_screenshot; + + g_type_class_add_private (klass, sizeof (SshContactTabPrivate)); + +} + +static void +ssh_contact_tab_init (SshContactTab *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SSH_CONTACT_TYPE_TAB, + SshContactTabPrivate); + + /* Create the ssh widget */ + self->priv->vte = vte_terminal_new (); + vinagre_tab_add_view (VINAGRE_TAB (self), self->priv->vte); + gtk_widget_show (self->priv->vte); + + g_signal_connect (self->priv->vte, "child-exited", + G_CALLBACK (ssh_disconnected_cb), self); +} + +GtkWidget * +ssh_contact_tab_new (VinagreConnection *conn, + VinagreWindow *window) +{ + return g_object_new (SSH_CONTACT_TYPE_TAB, "conn", conn, "window", window, + NULL); +} + +/* vim: set ts=8: */ diff --git a/src/vinagre/tab.h b/src/vinagre/tab.h new file mode 100644 index 0000000..8dd889a --- /dev/null +++ b/src/vinagre/tab.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 Jonh Wendell <wendell@bani.com.br> + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __SSH_CONTACT_TAB_H__ +#define __SSH_CONTACT_TAB_H__ + +#include <vinagre/vinagre-tab.h> + +G_BEGIN_DECLS + +#define SSH_CONTACT_TYPE_TAB (ssh_contact_tab_get_type()) +#define SSH_CONTACT_TAB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SSH_CONTACT_TYPE_TAB, SshContactTab)) +#define SSH_CONTACT_TAB_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SSH_CONTACT_TYPE_TAB, SshContactTab const)) +#define SSH_CONTACT_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SSH_CONTACT_TYPE_TAB, SshContactTabClass)) +#define SSH_CONTACT_IS_TAB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SSH_CONTACT_TYPE_TAB)) +#define SSH_CONTACT_IS_TAB_CLASS(klass)...(G_TYPE_CHECK_CLASS_TYPE ((klass), SSH_CONTACT_TYPE_TAB)) +#define SSH_CONTACT_TAB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SSH_CONTACT_TYPE_TAB, SshContactTabClass)) + +typedef struct _SshContactTabPrivate SshContactTabPrivate; + +typedef struct +{ + VinagreTab tab; + SshContactTabPrivate *priv; +} SshContactTab; + +typedef struct +{ + VinagreTabClass parent_class; +} SshContactTabClass; + +GType ssh_contact_tab_get_type (void) G_GNUC_CONST; + +GtkWidget *ssh_contact_tab_new (VinagreConnection *conn, VinagreWindow *window); + +G_END_DECLS + +#endif /* __VINAGRE_SSH_TAB_H__ */ +/* vim: set ts=8: */ diff --git a/src/vinagre/tree-view.c b/src/vinagre/tree-view.c new file mode 100644 index 0000000..6ddc91c --- /dev/null +++ b/src/vinagre/tree-view.c @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ +#include <gtk/gtk.h> + +#include <telepathy-glib/telepathy-glib.h> + +#include "tree-view.h" +#include "../client-helpers.h" + +enum +{ + COL_ACCOUNT, + COL_CONTACT, + COL_TEXT, + N_COL +}; + +struct _SshContactTreeViewPrivate +{ + GtkListStore *store; + TpAccountManager *account_manager; +}; + +G_DEFINE_TYPE (SshContactTreeView, ssh_contact_tree_view, + GTK_TYPE_TREE_VIEW); + +static TpAccount * +find_account_for_contact (SshContactTreeView *self, + TpContact *contact) +{ + TpAccount *account = NULL; + TpConnection *connection; + GList *list; + + connection = tp_contact_get_connection (contact); + list = tp_account_manager_get_valid_accounts (self->priv->account_manager); + while (list) + { + if (tp_account_get_connection (list->data) == connection) + { + account = list->data; + break; + } + + list = g_list_delete_link (list, list); + } + g_list_free (list); + + return account; +} + +static void +got_contacts_cb (TpConnection *connection, + guint n_contacts, + TpContact * const *contacts, + guint n_failed, + const TpHandle *failed, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + SshContactTreeView *self = user_data; + guint i; + + if (error != NULL) + { + g_debug ("%s", error->message); + return; + } + + for (i = 0; i < n_contacts; i++) + { + TpAccount *account; + + if (!_capabilities_has_stream_tube (tp_contact_get_capabilities (contacts[i]))) + continue; + + account = find_account_for_contact (self, contacts[i]); + gtk_list_store_insert_with_values (self->priv->store, NULL, -1, + COL_ACCOUNT, account, + COL_CONTACT, contacts[i], + COL_TEXT, tp_contact_get_alias (contacts[i]), + -1); + } +} + +static void +stored_channel_prepare_cb (GObject *object, + GAsyncResult *res, + gpointer self) +{ + TpChannel *channel = TP_CHANNEL (object); + TpConnection *connection; + TpContactFeature features[] = { TP_CONTACT_FEATURE_ALIAS, + TP_CONTACT_FEATURE_CAPABILITIES }; + const TpIntSet *set; + GArray *handles; + GError *error = NULL; + + if (!tp_proxy_prepare_finish (channel, res, &error)) + { + g_debug ("%s", error->message); + g_clear_error (&error); + return; + } + + connection = tp_channel_borrow_connection (channel); + set = tp_channel_group_get_members (channel); + handles = tp_intset_to_array (set); + + tp_connection_get_contacts_by_handle (connection, handles->len, + (TpHandle *) handles->data, G_N_ELEMENTS (features), features, + got_contacts_cb, self, NULL, NULL); + + g_array_unref (handles); +} + +static void +ensure_stored_channel_cb (TpConnection *connection, + gboolean yours, + const gchar *channel_path, + GHashTable *properties, + const GError *error, + gpointer self, + GObject *weak_object) +{ + TpChannel *channel; + GQuark features[] = { TP_CHANNEL_FEATURE_GROUP, 0 }; + GError *err = NULL; + + if (error != NULL) + { + g_debug ("%s", error->message); + return; + } + + channel = tp_channel_new_from_properties (connection, channel_path, + properties, &err); + if (channel == NULL) + { + g_debug ("%s", err->message); + g_clear_error (&err); + return; + } + + tp_proxy_prepare_async (TP_PROXY (channel), features, + stored_channel_prepare_cb, self); + + g_object_unref (channel); +} + +static void +connection_prepare_cb (GObject *object, + GAsyncResult *res, + gpointer self) +{ + TpConnection *connection = TP_CONNECTION (object); + GError *error = NULL; + GHashTable *request; + + if (!tp_proxy_prepare_finish (TP_PROXY (connection), res, &error)) + { + g_debug ("%s", error->message); + g_clear_error (&error); + return; + } + + if (!_capabilities_has_stream_tube (tp_connection_get_capabilities (connection))) + return; + + request = tp_asv_new ( + TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, + TP_IFACE_CHANNEL_TYPE_CONTACT_LIST, + TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, + TP_HANDLE_TYPE_LIST, + TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, + "stored", + NULL); + + tp_cli_connection_interface_requests_call_ensure_channel (connection, -1, + request, ensure_stored_channel_cb, self, NULL, NULL); + + g_hash_table_unref (request); +} + +static void +account_manager_prepare_cb (GObject *object, + GAsyncResult *res, + gpointer self) +{ + TpAccountManager *manager = TP_ACCOUNT_MANAGER (object); + GList *accounts, *l; + GError *error = NULL; + + if (!tp_proxy_prepare_finish (TP_PROXY (manager), res, &error)) + { + g_debug ("%s", error->message); + g_clear_error (&error); + return; + } + + accounts = tp_account_manager_get_valid_accounts (manager); + for (l = accounts; l != NULL; l = l->next) + { + GQuark features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 }; + TpAccount *account = l->data; + TpConnection *connection; + + connection = tp_account_get_connection (account); + if (connection != NULL) + tp_proxy_prepare_async (TP_PROXY (connection), features, + connection_prepare_cb, self); + } + g_list_free (accounts); +} + +static void +dispose (GObject *object) +{ + SshContactTreeView *self = SSH_CONTACT_TREE_VIEW (object); + + tp_clear_object (&self->priv->store); + tp_clear_object (&self->priv->account_manager); + + G_OBJECT_CLASS (ssh_contact_tree_view_parent_class)->dispose (object); +} + +static void +ssh_contact_tree_view_init (SshContactTreeView *self) +{ + GtkTreeView *view = GTK_TREE_VIEW (self); + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SSH_CONTACT_TYPE_TREE_VIEW, + SshContactTreeViewPrivate); + + self->priv->store = gtk_list_store_new (N_COL, + G_TYPE_OBJECT, /* ACCOUNT */ + G_TYPE_OBJECT, /* CONTACT */ + G_TYPE_STRING); /* TEXT */ + + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Contacts", + renderer, "text", COL_TEXT, NULL); + + gtk_tree_view_append_column (view, column); + gtk_tree_view_set_headers_visible (view, FALSE); + gtk_tree_view_set_model (view, GTK_TREE_MODEL (self->priv->store)); + + self->priv->account_manager = tp_account_manager_dup (); + tp_proxy_prepare_async (TP_PROXY (self->priv->account_manager), NULL, + account_manager_prepare_cb, self); +} + +static void +ssh_contact_tree_view_class_init (SshContactTreeViewClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = dispose; + + g_type_class_add_private (klass, sizeof (SshContactTreeViewPrivate)); +} + +GtkWidget * +ssh_contact_tree_view_new (void) +{ + return g_object_new (SSH_CONTACT_TYPE_TREE_VIEW, NULL); +} + +TpAccount * +ssh_contact_tree_view_get_selected_account (SshContactTreeView *self) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + TpAccount *account = NULL; + + g_return_val_if_fail (SSH_CONTACT_IS_TREE_VIEW (self), NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self)); + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return NULL; + + gtk_tree_model_get (model, &iter, COL_ACCOUNT, &account, -1); + g_object_unref (account); + + return account; +} + +TpContact * +ssh_contact_tree_view_get_selected_contact (SshContactTreeView *self) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + TpContact *contact; + + g_return_val_if_fail (SSH_CONTACT_IS_TREE_VIEW (self), NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self)); + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return NULL; + + gtk_tree_model_get (model, &iter, COL_CONTACT, &contact, -1); + g_object_unref (contact); + + return contact; +} + +/* vim: set ts=8: */ diff --git a/src/vinagre/tree-view.h b/src/vinagre/tree-view.h new file mode 100644 index 0000000..bd93d26 --- /dev/null +++ b/src/vinagre/tree-view.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef __SSH_CONTACT_TREE_VIEW_H__ +#define __SSH_CONTACT_TREE_VIEW_H__ + +#include <gtk/gtk.h> + +#include <telepathy-glib/telepathy-glib.h> + +G_BEGIN_DECLS + +#define SSH_CONTACT_TYPE_TREE_VIEW (ssh_contact_tree_view_get_type ()) +#define SSH_CONTACT_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SSH_CONTACT_TYPE_TREE_VIEW, SshContactTreeView)) +#define SSH_CONTACT_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SSH_CONTACT_TYPE_TREE_VIEW, SshContactTreeViewClass)) +#define SSH_CONTACT_IS_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SSH_CONTACT_TYPE_TREE_VIEW)) +#define SSH_CONTACT_IS_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SSH_CONTACT_TYPE_TREE_VIEW)) +#define SSH_CONTACT_TREE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SSH_CONTACT_TYPE_TREE_VIEW, SshContactTreeViewClass)) + +typedef struct _SshContactTreeViewPrivate SshContactTreeViewPrivate; + +typedef struct +{ + GtkTreeView parent_instance; + SshContactTreeViewPrivate *priv; +} SshContactTreeView; + +typedef struct +{ + GtkTreeViewClass parent_class; +} SshContactTreeViewClass; + +GType ssh_contact_tree_view_get_type (void) G_GNUC_CONST; + +GtkWidget *ssh_contact_tree_view_new (void); + +TpAccount *ssh_contact_tree_view_get_selected_account (SshContactTreeView *self); + +TpContact *ssh_contact_tree_view_get_selected_contact (SshContactTreeView *self); + + +G_END_DECLS + +#endif /* __SSH_CONTACT_TREE_VIEW_H__ */ +/* vim: set ts=8: */ |