Logo Search packages:      
Sourcecode: telepathy-inspector version File versions  Download package

ti-wnd-connection.c

/*
 * Telapathy Inspector - A Telepathy client which exposes Telepathy interfaces.
 *                       Meant to inspect and/or test connection managers.
 * 
 * ti-wnd-connection.c:
 * Connection Window - UI to expose org.freedesktop.Telepathy.Connection functionality
 * 
 * Copyright (C) 2006, 2007 INdT - Instituto Nokia de Tecnologia
 * Author - Daniel d'Andrada T. de Carvalho <daniel.carvalho@indt.org.br>
 *
 * This program 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 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "ti-wnd-connection.h"
#include "ti-dlg-hold-handles.h"
#include "ti-dlg-get-handles.h"
#include "ti-dlg-request-channel.h"
#include "ti-wnd-channel.h"
#include "ti-page-aliasing.h"
#include "ti-page-capabilities.h"
#include "ti-page-presence.h"
#include "ti-page-properties.h"
#include "ti-properties.h"
#include "ti-constants.h"
#include "ti-config.h"
#include "ti-handle-mapper.h"
#include "ti-util.h"

#include <glade/glade.h>
#include <string.h>

G_DEFINE_TYPE (TIWndConnection, ti_wnd_connection, G_TYPE_OBJECT);

/* Function prototypes */
static gboolean on_delete_window (TIWndConnection* wnd_connection, GdkEvent  *event);
static void _ti_wnd_connection_setup_first_page (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_setup_acquired_handles_list (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_remove_interface_pages (TIWndConnection* wnd_connection);
static gchar* _get_status_string (guint status);
static void _ti_wnd_connection_build_interfaces_treeview (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_fill_interfaces_list (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_build_channels_treeview (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_connect (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_disconnect (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_on_conn_status_changed (TIWndConnection* wnd_connection, guint status, guint reason);
static void _ti_wnd_connection_on_new_channel (TIWndConnection* wnd_connection, TIChannel* channel, gboolean suppress_handler);
static void _ti_wnd_connection_refresh_channels_list (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_request_channel (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_request_handles (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_hold_handles (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_closed_channel_window (TIWndConnection* wnd_connection, TIWndChannel* wnd_channel);
static void _ti_wnd_connection_add_channel_to_list (TIWndConnection* wnd_connection,
                                                    const gchar* obj_path,
                                                    const gchar* type,
                                                    guint handle_type,
                                                    guint handle_number);
static gchar* _get_small_channel_type (const gchar* type);
static void _ti_wnd_connection_show_selected_channel (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_inspect_selected_handles (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_release_selected_handles (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_handles_selection_changed (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_get_selected_handles (TIWndConnection* wnd_connection,
                                                     GArray* contact_handles, GArray* room_handles, GArray* list_handles);
static void _ti_wnd_connection_create_interface_pages (TIWndConnection* wnd_connection);
static void _ti_wnd_connection_create_interface_page (TIWndConnection* wnd_connection, gchar* interface_name);
static void _ti_wnd_connection_on_connected (TIWndConnection* wnd_connection);

/**
 * Instance private data.
 */
00083 struct _TIWndConnectionPrivate {
    TIHandleMapper* handle_mapper;

    TIDlgHoldHandles* dlg_hold_handles;
    TIDlgGetHandles* dlg_get_handles;
    TIDlgRequestChannel* dlg_request_channel;

    GtkWindow* parent;

    GladeXML* glade_xml;

    GtkWidget* window;
    GtkNotebook* notebook;

    GtkListStore* interfaces_list;
    GtkListStore* channels_list;

    GtkTreeSelection* channel_selection;

    TIConnection* connection;

    GtkWidget* button_connect;
    GtkWidget* button_disconnect;

    GtkWidget* button_request_handles;

    GtkWidget* button_request_channel;
    GtkWidget* button_refresh_channels_list;

    GtkTreeSelection* acquired_handles_selection;
    GtkWidget* button_inspect_handles;
    GtkWidget* button_release_handles;
    GtkWidget* button_hold_handles;

    /* An array of TIWndChannel* containing all channel windows currently open. */
    GPtrArray* channel_wnds;

    TIPageAliasing* page_aliasing;
    TIPageCapabilities* page_capabilities;
    TIPagePresence* page_presence;
    TIPageProperties* page_properties;
};
typedef struct _TIWndConnectionPrivate TIWndConnectionPrivate;

#define TI_WND_CONNECTION_GET_PRIVATE(object)  (G_TYPE_INSTANCE_GET_PRIVATE ((object), TI_TYPE_WND_CONNECTION, TIWndConnectionPrivate))

/**
 * Drop all references to other objects.
 */
static void
ti_wnd_connection_dispose (GObject *object)
{
    TIWndConnection *wnd_connection = TI_WND_CONNECTION (object);
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    guint i;
    GObject* obj;

    TI_OBJ_UNREF (priv->handle_mapper);
    TI_OBJ_UNREF (priv->dlg_hold_handles);
    TI_OBJ_UNREF (priv->dlg_get_handles);
    TI_OBJ_UNREF (priv->dlg_request_channel);
    TI_OBJ_UNREF (priv->glade_xml);

    if (priv->connection != NULL)
    {
        g_signal_handlers_disconnect_by_func (priv->connection,
                                              G_CALLBACK (_ti_wnd_connection_on_conn_status_changed),
                                              wnd_connection);

        g_signal_handlers_disconnect_by_func (priv->connection,
                                              G_CALLBACK (_ti_wnd_connection_on_new_channel),
                                              wnd_connection);

        g_object_unref (priv->connection);
        priv->connection = NULL;
    }

    if (priv->channel_wnds != NULL)
    {
        for (i = 0; i < priv->channel_wnds->len; i++)
        {
            obj = G_OBJECT (g_ptr_array_index(priv->channel_wnds, i));
            g_object_unref (obj);
        }
        g_ptr_array_free (priv->channel_wnds, TRUE);
        priv->channel_wnds = NULL;
    }

    TI_OBJ_UNREF (priv->page_aliasing);
    TI_OBJ_UNREF (priv->page_capabilities);
    TI_OBJ_UNREF (priv->page_presence);
    TI_OBJ_UNREF (priv->page_properties);

    G_OBJECT_CLASS (ti_wnd_connection_parent_class)->dispose (object);
}

/**
 * Class initialization.
 */
static void
ti_wnd_connection_class_init (TIWndConnectionClass *ti_wnd_connection_class)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS (ti_wnd_connection_class);

    /* override base object methods */
    gobject_class->dispose = ti_wnd_connection_dispose;

    /* Add private */
    g_type_class_add_private (ti_wnd_connection_class, sizeof (TIWndConnectionPrivate));

    /* Signals */

    /* Emitted when the connection is closed. */
    ti_wnd_connection_class->close_signal_id = 
        g_signal_newv ("closed",
                       G_TYPE_FROM_CLASS (ti_wnd_connection_class),
                       G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
                       NULL /* class closure */,
                       NULL /* accumulator */,
                       NULL /* accu_data */,
                       g_cclosure_marshal_VOID__VOID,
                       G_TYPE_NONE /* return_type */,
                       0     /* n_params */,
                       NULL  /* param_types */);
}

/**
 * Instance initialization.
 */
static void
ti_wnd_connection_init (TIWndConnection *ti_wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (ti_wnd_connection);

    priv->handle_mapper = NULL;
    priv->dlg_get_handles = NULL;
    priv->dlg_request_channel = NULL;
    priv->glade_xml = NULL;
    priv->window = NULL;
    priv->connection = NULL;
    priv->notebook = NULL;
    priv->channel_wnds = g_ptr_array_new ();
    priv->page_aliasing = NULL;
    priv->page_capabilities = NULL;
    priv->page_presence = NULL;
    priv->page_properties = NULL;
}

/**
 * Returns a new instance.
 */
TIWndConnection*
ti_wnd_connection_new (GtkWindow* parent, const gchar* conn_man, const gchar* protocol, const gchar* account)
{
    gchar* service_name = NULL;
    gchar* obj_path = NULL;
    TIConnection* connection = NULL;
    TIWndConnection* wnd_connection = NULL;

    service_name = g_strdup_printf ("org.freedesktop.Telepathy.Connection.%s.%s.%s", conn_man, protocol, account);
    obj_path = g_strdup_printf ("/org/freedesktop/Telepathy/Connection/%s/%s/%s", conn_man, protocol, account);

    connection = ti_connection_new (service_name, obj_path);

    wnd_connection = ti_wnd_connection_new_with_conn (parent, connection);

    // Clean up
    g_free (service_name);
    g_free (obj_path);

    if (connection)
        g_object_unref (connection);

    return wnd_connection;
}

/**
 * Returns a new instance.
 */
TIWndConnection*
ti_wnd_connection_new_with_conn (GtkWindow* parent, TIConnection* connection) 
{
    TIWndConnection* wnd_connection = NULL;
    TIWndConnectionPrivate *priv = NULL;
    gchar* glade_file_path = NULL;

    g_assert (connection != NULL);
    g_assert (parent != NULL);

    wnd_connection = g_object_new (TI_TYPE_WND_CONNECTION, NULL);

    priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    priv->parent = parent;
    priv->handle_mapper = ti_handle_mapper_new (connection);
    priv->connection = connection;
    g_object_ref (connection);

    g_signal_connect_swapped (connection, "status-changed", G_CALLBACK (_ti_wnd_connection_on_conn_status_changed), wnd_connection);
    g_signal_connect_swapped (connection, "new-channel", G_CALLBACK (_ti_wnd_connection_on_new_channel), wnd_connection);

    glade_file_path = g_strdup_printf ("%s%s", TI_DATA_DIR_PREFIX, "wnd-connection.xml");
    priv->glade_xml = glade_xml_new (glade_file_path, NULL, NULL);
    if (priv->glade_xml == NULL)
    {
        g_critical ("Error loading glade file \"%s\".", glade_file_path);
        g_object_unref (wnd_connection);
        wnd_connection = NULL;
        goto CLEAN_UP;
    }

    priv->window = glade_xml_get_widget (priv->glade_xml, "window_connection");
    g_assert (GTK_IS_WINDOW (priv->window));

    priv->dlg_hold_handles = ti_dlg_hold_handles_new (GTK_WINDOW (priv->window));
    priv->dlg_get_handles = ti_dlg_get_handles_new (GTK_WINDOW (priv->window));
    priv->dlg_request_channel = ti_dlg_request_channel_new (GTK_WINDOW (priv->window), priv->handle_mapper);

    _ti_wnd_connection_setup_first_page (wnd_connection);
    _ti_wnd_connection_setup_acquired_handles_list (wnd_connection);

    g_signal_connect_swapped (priv->window, "delete-event", G_CALLBACK (on_delete_window), wnd_connection);

    gtk_window_set_transient_for (GTK_WINDOW (priv->window), GTK_WINDOW (priv->parent));

    // The Telepathy connection is considered as disconnected by default.
    // If it's already connected then we have to enable UI interaction, build interface pages, etc.
    if (ti_connection_get_status (connection) == TI_CONNECTION_STATUS_CONNECTED)
    {
        _ti_wnd_connection_on_connected (wnd_connection);
    }

    CLEAN_UP:
    g_free (glade_file_path);

    return wnd_connection;
}

/**
 * Setup First Page - Helper Function
 */
static void
_ti_wnd_connection_setup_first_page (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GtkWidget* first_page;
    guint status;
    GtkLabel* label;
    gchar* str;

    priv->notebook = GTK_NOTEBOOK (glade_xml_get_widget (priv->glade_xml, "notebook"));
    g_assert (GTK_IS_NOTEBOOK (priv->notebook));

    // Setup page label
    first_page = gtk_notebook_get_nth_page (priv->notebook, 0);
    gtk_notebook_set_tab_label_text (priv->notebook, first_page, "Connection");

    // Set status label
    status = ti_connection_get_status (priv->connection);
    label = GTK_LABEL (glade_xml_get_widget (priv->glade_xml, "label_status_value"));
    str = _get_status_string (status);
    gtk_label_set_text (label, str);
    g_free (str);

    // Set protocol label
    str = ti_connection_get_protocol (priv->connection);
    label = GTK_LABEL (glade_xml_get_widget (priv->glade_xml, "label_protocol_value"));
    gtk_label_set_text (label, str);
    g_free (str);

    // Interfaces List
    priv->interfaces_list = gtk_list_store_new (1, G_TYPE_STRING);
    _ti_wnd_connection_build_interfaces_treeview (wnd_connection);

    // Channels List
    priv->channels_list = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
    _ti_wnd_connection_build_channels_treeview (wnd_connection);

    // Connect button
    priv->button_connect = glade_xml_get_widget (priv->glade_xml, "button_connect");
    g_assert (GTK_IS_BUTTON (priv->button_connect));
    g_signal_connect_swapped (priv->button_connect, "clicked", G_CALLBACK (_ti_wnd_connection_connect), wnd_connection);

    // Disconnect button
    priv->button_disconnect = glade_xml_get_widget (priv->glade_xml, "button_disconnect");
    g_assert (GTK_IS_BUTTON (priv->button_disconnect));
    g_signal_connect_swapped (priv->button_disconnect, "clicked", G_CALLBACK (_ti_wnd_connection_disconnect), wnd_connection);

    // "refresh channels list" button
    priv->button_refresh_channels_list = glade_xml_get_widget (priv->glade_xml, "button_refresh_channels_list");
    g_assert (GTK_IS_BUTTON (priv->button_refresh_channels_list));
    g_signal_connect_swapped (priv->button_refresh_channels_list, "clicked", G_CALLBACK (_ti_wnd_connection_refresh_channels_list), wnd_connection);

    // "request channel" button
    priv->button_request_channel = glade_xml_get_widget (priv->glade_xml, "button_request_channel");
    g_assert (GTK_IS_BUTTON (priv->button_request_channel));
    g_signal_connect_swapped (priv->button_request_channel, "clicked", G_CALLBACK (_ti_wnd_connection_request_channel), wnd_connection);

    // "Request Handles" button
    priv->button_request_handles = glade_xml_get_widget (priv->glade_xml, "button_request_handles");
    g_assert (GTK_IS_BUTTON (priv->button_request_handles));
    g_signal_connect_swapped (GTK_BUTTON (priv->button_request_handles), "clicked", G_CALLBACK (_ti_wnd_connection_request_handles), wnd_connection);

    // "Hold Handles" button
    priv->button_hold_handles = glade_xml_get_widget (priv->glade_xml, "button_hold_handles");
    g_assert (GTK_IS_BUTTON (priv->button_hold_handles));
    g_signal_connect_swapped (GTK_BUTTON (priv->button_hold_handles), "clicked", G_CALLBACK (_ti_wnd_connection_hold_handles), wnd_connection);

    // "Release Handles" button
    priv->button_release_handles = glade_xml_get_widget (priv->glade_xml, "button_release_handles");
    g_assert (GTK_IS_BUTTON (priv->button_release_handles));
    g_signal_connect_swapped (GTK_BUTTON (priv->button_release_handles), "clicked", G_CALLBACK (_ti_wnd_connection_release_selected_handles), wnd_connection);

    // "Inspect Handles" button
    priv->button_inspect_handles = glade_xml_get_widget (priv->glade_xml, "button_inspect_handles");
    g_assert (GTK_IS_BUTTON (priv->button_inspect_handles));
    g_signal_connect_swapped (GTK_BUTTON (priv->button_inspect_handles), "clicked", G_CALLBACK (_ti_wnd_connection_inspect_selected_handles), wnd_connection);
}

/**
 * Setup Acquired Handles' List
 */
static void
_ti_wnd_connection_setup_acquired_handles_list (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GtkWidget* treeview_handles;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;


    treeview_handles = glade_xml_get_widget(priv->glade_xml, "treeview_handles");
    gtk_tree_view_set_model (GTK_TREE_VIEW(treeview_handles),
                             GTK_TREE_MODEL (ti_handle_mapper_get_handles_list_store (priv->handle_mapper)));

    renderer = gtk_cell_renderer_text_new ();

    /* Handle column */
    column = gtk_tree_view_column_new_with_attributes ("Handle",
                                                       renderer,
                                                       "text", TI_HANDLES_LIST_COLUMN_NUMBER,
                                                       NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_handles), column);

    /* Type column */
    column = gtk_tree_view_column_new_with_attributes ("Type",
                                                       renderer,
                                                       "text", TI_HANDLES_LIST_COLUMN_TYPE,
                                                       NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_handles), column);

    /* Name column */
    column = gtk_tree_view_column_new_with_attributes ("Name",
                                                       renderer,
                                                       "text", TI_HANDLES_LIST_COLUMN_NAME,
                                                       NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_handles), column);

    priv->acquired_handles_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_handles));
    gtk_tree_selection_set_mode (priv->acquired_handles_selection, GTK_SELECTION_MULTIPLE);

    g_signal_connect_swapped (priv->acquired_handles_selection, "changed",
                              G_CALLBACK (_ti_wnd_connection_handles_selection_changed),
                              wnd_connection);
}

/**
 * Build the GtkTreeView for the interfaces list.
 */
static void
_ti_wnd_connection_build_interfaces_treeview (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GtkWidget* treeview_interfaces;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;
    GtkTreeSelection* tree_selection;

    treeview_interfaces = glade_xml_get_widget(priv->glade_xml, "treeview_interfaces");
    gtk_tree_view_set_model (GTK_TREE_VIEW(treeview_interfaces), GTK_TREE_MODEL(priv->interfaces_list));

    renderer = gtk_cell_renderer_text_new ();
    column = gtk_tree_view_column_new_with_attributes ("Interface",
                                                       renderer,
                                                       "text", 0,
                                                       NULL);

    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_interfaces), column);

    tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_interfaces));
    gtk_tree_selection_set_mode (tree_selection, GTK_SELECTION_NONE);
}

/**
 * Fill Interfaces List
 */
static void
_ti_wnd_connection_fill_interfaces_list (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    char **str_list;
    char **str_list_ptr;
    GtkTreeIter iter;

    gtk_list_store_clear (priv->interfaces_list);

    str_list = ti_connection_get_interfaces (priv->connection);
    g_return_if_fail (str_list != NULL);

    /* Fill the list. */
    for (str_list_ptr = str_list; *str_list_ptr; str_list_ptr++)
    {
        gtk_list_store_append (priv->interfaces_list, &iter);
        gtk_list_store_set (priv->interfaces_list, &iter, 0, *str_list_ptr, -1);
    }

    g_strfreev (str_list);
}

/**
 * Build the GtkTreeView for the channels list.
 */
static void
_ti_wnd_connection_build_channels_treeview (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GtkWidget* treeview_channels;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;

    treeview_channels = glade_xml_get_widget(priv->glade_xml, "treeview_channels");
    g_signal_connect_swapped (treeview_channels, "row-activated", G_CALLBACK (_ti_wnd_connection_show_selected_channel), wnd_connection);
    gtk_tree_view_set_model (GTK_TREE_VIEW(treeview_channels), GTK_TREE_MODEL(priv->channels_list));

    renderer = gtk_cell_renderer_text_new ();
    
    /* Obj path column */
    column = gtk_tree_view_column_new_with_attributes ("Obj. Path",
                                                       renderer,
                                                       "text", 0,
                                                       NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_channels), column);

    /* Type column */
    column = gtk_tree_view_column_new_with_attributes ("Type",
                                                       renderer,
                                                       "text", 1,
                                                       NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_channels), column);

    /* Handle type column */
    column = gtk_tree_view_column_new_with_attributes ("H. Type",
                                                       renderer,
                                                       "text", 2,
                                                       NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_channels), column);

    /* Handle number column */
    column = gtk_tree_view_column_new_with_attributes ("H. Number",
                                                       renderer,
                                                       "text", 3,
                                                       NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_channels), column);

    priv->channel_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_channels));
    gtk_tree_selection_set_mode (priv->channel_selection, GTK_SELECTION_SINGLE);
}

/**
 * Get Status String - Helper Function
 */
static gchar*
_get_status_string (guint status)
{
    switch (status)
    {
        case TI_CONNECTION_STATUS_CONNECTED:
            return g_strdup_printf ("%u - CONNECTION_STATUS_CONNECTED", status);

        case TI_CONNECTION_STATUS_CONNECTING:
            return g_strdup_printf ("%u - CONNECTION_STATUS_CONNECTING", status);

        case TI_CONNECTION_STATUS_DISCONNECTED:
            return g_strdup_printf ("%u - CONNECTION_STATUS_DISCONNECTED", status);

        default:
            return g_strdup_printf ("%u - Invalid/unknown status code", status);
    }
}

/**
 * Show
 */
void
ti_wnd_connection_show (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);

    gtk_widget_show_all (priv->window);
}

/**
 * On Delete Window
 * Called when the top window receives a "delete-event" signal.
 */
static gboolean
on_delete_window (TIWndConnection* wnd_connection, GdkEvent  *event)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);

    gtk_widget_hide_all (priv->window);

    g_signal_emit (wnd_connection, TI_WND_CONNECTION_GET_CLASS(wnd_connection)->close_signal_id, 0, NULL);

    return TRUE;
}

/**
 * Connect
 */
static void
_ti_wnd_connection_connect (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);

    if (!ti_connection_connect (priv->connection))
    {
        return;
    }

    gtk_widget_set_sensitive (priv->button_connect, FALSE);
    gtk_widget_set_sensitive (priv->button_disconnect, FALSE);

    gtk_widget_set_sensitive (priv->button_request_handles, FALSE);
    gtk_widget_set_sensitive (priv->button_request_channel, FALSE);
    gtk_widget_set_sensitive (priv->button_refresh_channels_list, FALSE);
}

/**
 * Disconnect
 */
static void
_ti_wnd_connection_disconnect (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);

    if (!ti_connection_disconnect (priv->connection))
    {
        return;
    }

    gtk_widget_set_sensitive (priv->button_connect, FALSE);
    gtk_widget_set_sensitive (priv->button_disconnect, FALSE);

    gtk_widget_set_sensitive (priv->button_request_handles, FALSE);
    gtk_widget_set_sensitive (priv->button_request_channel, FALSE);
    gtk_widget_set_sensitive (priv->button_refresh_channels_list, FALSE);
}

/**
 * On Connected
 */
static void
_ti_wnd_connection_on_connected (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);

    gtk_widget_set_sensitive (priv->button_connect, FALSE);
    gtk_widget_set_sensitive (priv->button_disconnect, TRUE);
    gtk_widget_set_sensitive (priv->button_request_handles, TRUE);
    gtk_widget_set_sensitive (priv->button_request_channel, TRUE);
    gtk_widget_set_sensitive (priv->button_refresh_channels_list, TRUE);
    gtk_widget_set_sensitive (priv->button_hold_handles, TRUE);

    _ti_wnd_connection_fill_interfaces_list (wnd_connection);
    _ti_wnd_connection_create_interface_pages (wnd_connection);

    _ti_wnd_connection_refresh_channels_list (wnd_connection);
}

/**
 * On Connection Status Changed
 */
static void
_ti_wnd_connection_on_conn_status_changed (TIWndConnection* wnd_connection, guint status, guint reason)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GtkLabel* label;
    gchar* str;

    label = GTK_LABEL (glade_xml_get_widget (priv->glade_xml, "label_status_value"));
    str = _get_status_string (status);
    gtk_label_set_text (label, str);
    g_free (str);

    if (status == TI_CONNECTION_STATUS_CONNECTED)
    {
        _ti_wnd_connection_on_connected (wnd_connection);
    }
    else if (status == TI_CONNECTION_STATUS_DISCONNECTED)
    {
        gtk_widget_set_sensitive (priv->button_connect, TRUE);
        gtk_widget_set_sensitive (priv->button_disconnect, FALSE);
        gtk_widget_set_sensitive (priv->button_request_handles, FALSE);
        gtk_widget_set_sensitive (priv->button_request_channel, FALSE);
        gtk_widget_set_sensitive (priv->button_refresh_channels_list, FALSE);
        gtk_widget_set_sensitive (priv->button_hold_handles, FALSE);

        gtk_list_store_clear (priv->interfaces_list);
        _ti_wnd_connection_remove_interface_pages (wnd_connection);

        gtk_list_store_clear (priv->channels_list);
    }
    else
    {
        /* Connecting or disconnecting */
        gtk_widget_set_sensitive (priv->button_connect, FALSE);
        gtk_widget_set_sensitive (priv->button_disconnect, FALSE);
        gtk_widget_set_sensitive (priv->button_request_handles, FALSE);
        gtk_widget_set_sensitive (priv->button_request_channel, FALSE);
        gtk_widget_set_sensitive (priv->button_refresh_channels_list, FALSE);
        gtk_widget_set_sensitive (priv->button_hold_handles, FALSE);
    }

    switch(reason)
    {
        case TI_CONNECTION_STATUS_REASON_NONE_SPECIFIED:
            g_debug ("There is no reason set for this state change.");
            break;
        case TI_CONNECTION_STATUS_REASON_REQUESTED:
            g_debug ("The change is in response to a user request");
            break;
        case TI_CONNECTION_STATUS_REASON_NETWORK_ERROR:
            g_debug ("There was an error sending or receiving on the network socket.");
            break;
        case TI_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED:
            g_debug ("The username or password was invalid.");
            break;
        case TI_CONNECTION_STATUS_REASON_ENCRYPTION_ERROR:
            g_debug ("There was an error negotiating SSL on this connection, or encryption was unavailable and require-encryption was set when the connection was created.");
            break;
        case TI_CONNECTION_STATUS_REASON_NAME_IN_USE:
            g_debug ("Someone is already connected to the server using the name you are trying to connect with.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_NOT_PROVIDED:
            g_debug ("The server did not provide a SSL certificate.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_UNTRUSTED:
            g_debug ("The server's SSL certificate could not be trusted.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_EXPIRED:
            g_debug ("The server's SSL certificate has expired.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_NOT_ACTIVATED:
            g_debug ("The server's SSL certificate is not yet valid.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_HOSTNAME_MISMATCH:
            g_debug ("The server's SSL certificate did not match its hostname.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_FINGERPRINT_MISMATCH:
            g_debug ("The server's SSL certificate does not have the expected fingerprint.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_SELF_SIGNED:
            g_debug ("The server's SSL certificate is self-signed.");
            break;
        case TI_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR:
            g_debug ("There was some other error validating the server's SSL certificate.");
            break;
        default:
            g_debug("Unkown connection status reason");
    }
}

/**
 * On New Channel
 */
static void
_ti_wnd_connection_on_new_channel (TIWndConnection* wnd_connection, TIChannel* channel, gboolean suppress_handler)
{
    TIWndConnectionPrivate* priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    TIWndChannel* channel_window = NULL;
    GError* error = NULL;
    gchar* channel_type = NULL;

    channel_type = ti_channel_get_channel_type (channel, &error);
    if (error != NULL)
    {
        // TODO: Display a message or something.
        goto CLEAN_UP;
    }

    // We don't popup channel windows for suppressed and/or ContactList channels.
    if (!suppress_handler && strcmp (channel_type, "org.freedesktop.Telepathy.Channel.Type.ContactList") != 0)
    {
        channel_window = ti_wnd_channel_new (GTK_WINDOW (priv->window), channel, priv->handle_mapper);
        if (channel_window != NULL)
        {
            g_ptr_array_add (priv->channel_wnds, channel_window);
            g_signal_connect_swapped (channel_window, "close-wnd", G_CALLBACK (_ti_wnd_connection_closed_channel_window), wnd_connection);
            ti_wnd_channel_show (channel_window);
        }
    }

    _ti_wnd_connection_refresh_channels_list (wnd_connection);

    CLEAN_UP:

    if (error != NULL)
        g_error_free (error);

    if (channel_type != NULL)
        g_free (channel_type);
}

/**
 * Refresh Channels List
 */
static void
_ti_wnd_connection_refresh_channels_list (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GPtrArray* channels;
    GValueArray* channel;
    guint i;
    GError* error;

    // Channel fields
    const gchar* obj_path;
    const gchar* type;
    guint handle_type;
    guint handle_number;

    gtk_list_store_clear (priv->channels_list);

    channels = ti_connection_list_channels (priv->connection, &error);
    if (error != NULL)
    {
        // TODO: Display error or something.
        g_error_free (error);
        return;
    }

    for (i = 0; i < channels->len; i++)
    {
        channel = g_ptr_array_index (channels, i);

        obj_path      = (const gchar*)g_value_get_boxed (&(channel->values[0]));
        type          = g_value_get_string (&(channel->values[1]));
        handle_type   = g_value_get_uint   (&(channel->values[2]));
        handle_number = g_value_get_uint   (&(channel->values[3])); 

        _ti_wnd_connection_add_channel_to_list (wnd_connection, obj_path, type, handle_type, handle_number);

        g_value_array_free (channel);
    }

    g_ptr_array_free (channels, TRUE);
}

/**
 * Get Small Channel Type
 */
static gchar*
_get_small_channel_type (const gchar* type)
{
    if (g_str_equal (type, "org.freedesktop.Telepathy.Channel.Type.ContactList"))
    {
        return g_strdup ("ContactList");
    }
    else if (g_str_equal (type, "org.freedesktop.Telepathy.Channel.Type.ContactSearch"))
    {
        return g_strdup ("ContactSearch");
    }
    else if (g_str_equal (type, "org.freedesktop.Telepathy.Channel.Type.RoomList"))
    {
        return g_strdup ("RoomList");
    }
    else if (g_str_equal (type, "org.freedesktop.Telepathy.Channel.Type.Text"))
    {
        return g_strdup ("Text");
    }
    else
    {
        return g_strdup ("UNKNOWN");
    }
}

/**
 * Add Channel to List
 */
static void
_ti_wnd_connection_add_channel_to_list (TIWndConnection* wnd_connection,
                                        const gchar* obj_path,
                                        const gchar* type,
                                        guint handle_type,
                                        guint handle_number)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GtkTreeIter iter;
    gchar* small_chan_type;
    gchar* htype_str;
    gchar* hnumber_str;

    small_chan_type = _get_small_channel_type (type);
    htype_str = g_strdup_printf ("%u", handle_type);
    hnumber_str = g_strdup_printf ("%u", handle_number);

    gtk_list_store_append (priv->channels_list, &iter);
    gtk_list_store_set (priv->channels_list, &iter,
                        0, obj_path,
                        1, small_chan_type,
                        2, htype_str,
                        3, hnumber_str,
                        -1);

    g_free (small_chan_type);
    g_free (htype_str);
    g_free (hnumber_str);
}

/**
 * Request Channel
 */
static void
_ti_wnd_connection_request_channel (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    gboolean ok;
    gchar* type = NULL;
    guint handle_type;
    guint handle;
    gboolean suppress_handler;
    GError* error = NULL;
    TIChannel* channel;
    TIWndChannel* channel_window;

    ok = ti_dlg_request_channel_run (priv->dlg_request_channel, &type, &handle_type, &handle, &suppress_handler);
    if (!ok)
    {
        goto CLEAN_UP;
    }

    channel = ti_connection_request_channel (priv->connection, type, handle_type, handle, suppress_handler, &error);
    if (error != NULL || channel == NULL)
    {
        // TODO: Handle error (e.g.: display message)
        goto CLEAN_UP;
    }

    channel_window = ti_wnd_channel_new (GTK_WINDOW (priv->window), channel, priv->handle_mapper);
    if (channel_window != NULL)
    {
        g_ptr_array_add (priv->channel_wnds, channel_window);
        g_signal_connect_swapped (channel_window, "close-wnd", G_CALLBACK (_ti_wnd_connection_closed_channel_window), wnd_connection);
        ti_wnd_channel_show (channel_window);
    }
    g_object_unref (channel);

    CLEAN_UP:
    g_free (type);

    if (error != NULL)
    {
        g_error_free (error);
    }
}

/**
 * Request Handles
 */
static void
_ti_wnd_connection_request_handles (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    guint type;
    gchar** names = NULL;
    gboolean ok;
    GArray* handles = NULL;
    GError* error = NULL;
    guint i;
    guint handle;

    ok = ti_dlg_get_handles_run (priv->dlg_get_handles, "Request Handles", &type, &names);
    if (!ok)
    {
        goto CLEAN_UP;
    }

    handles = ti_connection_request_handles (priv->connection, type, names, &error);
    if (error != NULL)
    {
        // TODO: Display error.
        goto CLEAN_UP;
    }

    for (i = 0; i < handles->len; i++)
    {
        handle = g_array_index (handles, guint, i);
        ti_handle_mapper_set_handle_name (priv->handle_mapper, type, handle, names[i]);
    }

    CLEAN_UP:

    if (names != NULL)
    {
        g_strfreev (names);
    }

    if (handles != NULL)
    {
        g_array_free (handles, TRUE);
    }

    if (error != NULL)
    {
        g_error_free (error);
    }
}

/**
 * Hold Handles
 */
static void
_ti_wnd_connection_hold_handles (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    gboolean ok;
    GArray* handles = NULL;
    guint handle_type;
    GError* error = NULL;
    guint i;
    guint handle_number;

    ok = ti_dlg_hold_handles_run (priv->dlg_hold_handles, &handle_type, &handles);
    if (!ok)
    {
        goto CLEAN_UP;
    }

    ti_connection_hold_handles (priv->connection, handle_type, handles, &error);
    if (error != NULL)
    {
        // TODO: Display error.
        goto CLEAN_UP;
    }

    for (i = 0; i < handles->len; i++)
    {
        handle_number = g_array_index (handles, guint, i);

        ti_handle_mapper_set_handle (priv->handle_mapper, handle_type, handle_number);
    }

    CLEAN_UP:

    if (handles != NULL)
    {
        g_array_free (handles, TRUE);
    }

    if (error != NULL)
    {
        g_error_free (error);
    }
}

/**
 * Close Channel Window
 */
static void
_ti_wnd_connection_closed_channel_window (TIWndConnection* wnd_connection, TIWndChannel* wnd_channel)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    gboolean ok;

    ok = g_ptr_array_remove (priv->channel_wnds, wnd_channel);
    g_assert (ok);

    g_object_unref (wnd_channel);

    _ti_wnd_connection_refresh_channels_list (wnd_connection);
}

/**
 * Show Selected Channel
 * Opens a window for the selected channel.
 */
static void
_ti_wnd_connection_show_selected_channel (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    gboolean ok;
    GtkTreeModel* model = NULL;
    GtkTreeIter iter;
    gchar* obj_path = NULL;
    TIChannel* channel = NULL;
    const gchar* service_name = NULL;
    TIWndChannel* channel_window = NULL;

    ok = gtk_tree_selection_get_selected (priv->channel_selection, &model, &iter);
    g_assert (ok);

    gtk_tree_model_get (model, &iter,
                        0, &obj_path,
                        -1);

    service_name = ti_connection_get_service_name (priv->connection);
    channel = ti_channel_new (service_name, obj_path);
    if (channel == NULL)
        goto CLEAN_UP;

    channel_window = ti_wnd_channel_new (GTK_WINDOW (priv->window), channel, priv->handle_mapper);
    if (channel_window == NULL)
        goto CLEAN_UP;

    g_ptr_array_add (priv->channel_wnds, channel_window);
    g_signal_connect_swapped (channel_window, "close-wnd", G_CALLBACK (_ti_wnd_connection_closed_channel_window), wnd_connection);
    ti_wnd_channel_show (channel_window);

    CLEAN_UP:
    if (channel != NULL)
        g_object_unref (channel);
    g_free (obj_path);
}

/**
 * Inspect Selected Handles
 */
static void
_ti_wnd_connection_inspect_selected_handles (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GError* error = NULL;
    GArray* contact_handles = NULL;
    GArray* room_handles = NULL;
    GArray* list_handles = NULL;
    gchar** handle_names = NULL;
    guint i;
    guint handle_number;

    contact_handles = g_array_new (FALSE, FALSE, sizeof (guint));
    room_handles = g_array_new (FALSE, FALSE, sizeof (guint));
    list_handles = g_array_new (FALSE, FALSE, sizeof (guint));

    _ti_wnd_connection_get_selected_handles (wnd_connection, contact_handles, room_handles, list_handles);

    if (contact_handles->len > 0)
    {
        handle_names = ti_connection_inspect_handles (priv->connection, TI_CONNECTION_HANDLE_TYPE_CONTACT, contact_handles, &error);
        if (error != NULL)
        {
            // TODO: Display a message or something.
            goto CLEAN_UP;
        }

        for (i = 0; i < contact_handles->len; i++)
        {
            handle_number = g_array_index (contact_handles, guint, i);
            ti_handle_mapper_set_contact_handle_name (priv->handle_mapper, handle_number, handle_names[i]);
        }

        g_strfreev (handle_names);
    }

    if (room_handles->len > 0)
    {
        handle_names = ti_connection_inspect_handles (priv->connection, TI_CONNECTION_HANDLE_TYPE_ROOM, room_handles, &error);
        if (error != NULL)
        {
            // TODO: Display a message or something.
            goto CLEAN_UP;
        }

        for (i = 0; i < room_handles->len; i++)
        {
            handle_number = g_array_index (room_handles, guint, i);
            ti_handle_mapper_set_room_handle_name (priv->handle_mapper, handle_number, handle_names[i]);
        }

        g_strfreev (handle_names);
    }

    if (list_handles->len > 0)
    {
        handle_names = ti_connection_inspect_handles (priv->connection, TI_CONNECTION_HANDLE_TYPE_LIST, list_handles, &error);
        if (error != NULL)
        {
            // TODO: Display a message or something.
            goto CLEAN_UP;
        }

        for (i = 0; i < list_handles->len; i++)
        {
            handle_number = g_array_index (list_handles, guint, i);
            ti_handle_mapper_set_list_handle_name (priv->handle_mapper, handle_number, handle_names[i]);
        }

        g_strfreev (handle_names);
    }

    CLEAN_UP:

    if (error != NULL)
        g_error_free (error);

    g_array_free (contact_handles, TRUE);
    g_array_free (room_handles, TRUE);
    g_array_free (list_handles, TRUE);
}

/**
 * Release Selected Handles
 */
static void
_ti_wnd_connection_release_selected_handles (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GError* error = NULL;
    GArray* contact_handles = NULL;
    GArray* room_handles = NULL;
    GArray* list_handles = NULL;

    contact_handles = g_array_new (FALSE, FALSE, sizeof (guint));
    room_handles = g_array_new (FALSE, FALSE, sizeof (guint));
    list_handles = g_array_new (FALSE, FALSE, sizeof (guint));

    _ti_wnd_connection_get_selected_handles (wnd_connection, contact_handles, room_handles, list_handles);

    ti_handle_mapper_invalidate_contact_handles (priv->handle_mapper, contact_handles);
    ti_handle_mapper_invalidate_list_handles (priv->handle_mapper, list_handles);

    if (contact_handles->len > 0)
    {
        ti_connection_release_handles (priv->connection, TI_CONNECTION_HANDLE_TYPE_CONTACT, contact_handles, &error);
        if (error != NULL)
        {
            // TODO: Display a message or something.
            goto CLEAN_UP;
        }
    }

    if (room_handles->len > 0)
    {
        ti_connection_release_handles (priv->connection, TI_CONNECTION_HANDLE_TYPE_ROOM, room_handles, &error);
        if (error != NULL)
        {
            // TODO: Display a message or something.
            goto CLEAN_UP;
        }
    }

    if (list_handles->len > 0)
    {
        ti_connection_release_handles (priv->connection, TI_CONNECTION_HANDLE_TYPE_LIST, list_handles, &error);
        if (error != NULL)
        {
            // TODO: Display a message or something.
            goto CLEAN_UP;
        }
    }

    ti_remove_selected_elements (priv->acquired_handles_selection);

    CLEAN_UP:

    if (error != NULL)
        g_error_free (error);

    g_array_free (contact_handles, TRUE);
    g_array_free (room_handles, TRUE);
    g_array_free (list_handles, TRUE);
}

/**
 * Handles Selection Changed
 */
static void
_ti_wnd_connection_handles_selection_changed (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    gint selection_count;

    selection_count = gtk_tree_selection_count_selected_rows (priv->acquired_handles_selection);

    gtk_widget_set_sensitive (priv->button_release_handles, selection_count > 0);
    gtk_widget_set_sensitive (priv->button_inspect_handles, selection_count > 0);
}

/**
 * Helper function for _ti_wnd_connection_get_selected_handles()
 */
static void
_ti_free_gtk_tree_path (gpointer data, gpointer user_data)
{
    gtk_tree_path_free ((GtkTreePath*)data);
}

/**
 * Get Selected Handles
 */
static void
_ti_wnd_connection_get_selected_handles (TIWndConnection* wnd_connection,
                                         GArray* contact_handles, GArray* room_handles, GArray* list_handles)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    GList* rows = NULL;
    GList* curr_row = NULL;
    GtkTreeIter iter;
    GtkTreePath* path = NULL;
    guint handle_number;
    guint handle_type;
    GtkTreeModel* tree_model = NULL;
    
    rows = gtk_tree_selection_get_selected_rows (priv->acquired_handles_selection, &tree_model);

    for (curr_row = rows; curr_row != NULL; curr_row = curr_row->next)
    {
        path = (GtkTreePath*) curr_row->data;

        gtk_tree_model_get_iter (tree_model, &iter, path);

        gtk_tree_model_get (tree_model, &iter,
                            TI_HANDLES_LIST_COLUMN_NUMBER, &handle_number,
                            TI_HANDLES_LIST_COLUMN_TYPE, &handle_type,
                            -1);

        if (handle_type == TI_CONNECTION_HANDLE_TYPE_CONTACT)
        {
            g_array_append_val (contact_handles, handle_number);
        }
        else if (handle_type == TI_CONNECTION_HANDLE_TYPE_ROOM)
        {
            g_array_append_val (room_handles, handle_number);
        }
        else if (handle_type == TI_CONNECTION_HANDLE_TYPE_LIST)
        {
            g_array_append_val (list_handles, handle_number);
        }
        else
        {
            g_assert_not_reached ();
        }
    }

    // Clean up
    if (rows != NULL)
    {
        g_list_foreach (rows, _ti_free_gtk_tree_path, NULL);
        g_list_free (rows);
    }
}

/**
 * Remove Interface Pages
 */
static void
_ti_wnd_connection_remove_interface_pages (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);

    if (priv->page_aliasing != NULL)
    {
        ti_page_detach_from_notebook (TI_PAGE (priv->page_aliasing));
    }

    if (priv->page_capabilities != NULL)
    {
        ti_page_detach_from_notebook (TI_PAGE (priv->page_capabilities));
    }

    if (priv->page_presence != NULL)
    {
        ti_page_detach_from_notebook (TI_PAGE (priv->page_presence));
    }

    if (priv->page_properties != NULL)
    {
        ti_page_detach_from_notebook (TI_PAGE (priv->page_properties));
    }
}

/**
 * Create Interface Pages
 * Creates a notebook page for every interface (org.freedesktop.Telepathy.Connection.Interface.*)
 * implemented by this connection.
 */
static void
_ti_wnd_connection_create_interface_pages (TIWndConnection* wnd_connection)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    gchar** interfaces;
    guint i;

    interfaces = ti_connection_get_interfaces (priv->connection);
    g_return_if_fail (interfaces != NULL);

    for (i = 0; interfaces[i] != NULL; i++)
    {
        _ti_wnd_connection_create_interface_page (wnd_connection, interfaces[i]);
    }

    g_strfreev (interfaces);
}

/**
 * Create Interface Page
 */
static void
_ti_wnd_connection_create_interface_page (TIWndConnection* wnd_connection, gchar* interface_name)
{
    TIWndConnectionPrivate *priv = TI_WND_CONNECTION_GET_PRIVATE (wnd_connection);
    TIProperties* properties = NULL;

    if (g_str_equal (interface_name, "org.freedesktop.Telepathy.Connection.Interface.Presence"))
    {
        if (priv->page_presence == NULL)
        {
            priv->page_presence = ti_page_presence_new (GTK_WINDOW (priv->window), priv->notebook, priv->connection, priv->handle_mapper);
        }
        else
        {
            ti_page_attach_to_notebook (TI_PAGE (priv->page_presence), priv->notebook);
        }
    }
    else if (g_str_equal (interface_name, "org.freedesktop.Telepathy.Connection.Interface.Aliasing"))
    {
        if (priv->page_aliasing == NULL)
        {
            priv->page_aliasing = ti_page_aliasing_new (GTK_WINDOW (priv->window), priv->notebook, priv->connection, priv->handle_mapper);
        }
        else
        {
            ti_page_attach_to_notebook (TI_PAGE (priv->page_aliasing), priv->notebook);
        }
    }
    else if (g_str_equal (interface_name, "org.freedesktop.Telepathy.Connection.Interface.Capabilities"))
    {
        if (priv->page_capabilities == NULL)
        {
            priv->page_capabilities = ti_page_capabilities_new (GTK_WINDOW (priv->window), priv->notebook, priv->connection, priv->handle_mapper);
        }
        else
        {
            ti_page_attach_to_notebook (TI_PAGE (priv->page_capabilities), priv->notebook);
        }
    }
    else if (g_str_equal (interface_name, "org.freedesktop.Telepathy.Properties"))
    {
        if (priv->page_properties == NULL)
        {
            properties = ti_properties_new (ti_connection_get_service_name (priv->connection),
                                            ti_connection_get_object_path (priv->connection));

            priv->page_properties = ti_page_properties_new (priv->notebook, properties);
        }
        else
        {
            ti_page_attach_to_notebook (TI_PAGE (priv->page_properties), priv->notebook);
        }
    }
    else
    {
        // TODO: Add more interface pages if that's the case.
        g_warning ("Unrecognized interface: \"%s\"", interface_name);
    }

    // Clean up
    TI_OBJ_UNREF (properties);
}

Generated by  Doxygen 1.6.0   Back to index