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

ti-dlg-set-aliases.c

/*
 * Telapathy Inspector - A Telepathy client which exposes Telepathy interfaces.
 *                       Meant to inspect and/or test connection managers.
 * 
 * ti-dlg-set-aliases.c:
 * Dialog for [...].Telepathy.Connection.SetAliases() method.
 * 
 * Copyright (C) 2006 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-dlg-set-aliases.h"
#include "ti-util.h"
#include "ti-config.h"
#include "ti-preferences.h"
#include "ti-constants.h"

#include <glade/glade.h>

G_DEFINE_TYPE (TIDlgSetAliases, ti_dlg_set_aliases, G_TYPE_OBJECT);

enum {
    TI_ALIASES_COLUMN_HANDLE = 0,
    TI_ALIASES_COLUMN_NAME,
    TI_ALIASES_COLUMN_ALIAS,
    TI_ALIASES_N_COLUMNS
};

/**
 * Instance private data.
 */
00046 struct _TIDlgSetAliasesPrivate {
    TIPreferences* preferences;
    TIHandleMapper* handle_mapper;

    GtkWindow* parent;

    GladeXML* glade_xml;

    GtkWidget* dialog;

    GtkBox* main_box;

    GtkEntry* entry_alias;
    GtkTreeView* aliases_treeview;
    GtkTreeSelection* aliases_selection;

    GtkWidget* contacts_scrolledwnd;
    GtkTreeView* contacts_treeview;
    GtkTreeSelection* contacts_selection;

    GtkWidget* handle_box;
    GtkEntry* handle_entry;

    GtkListStore* aliases_list;
};
typedef struct _TIDlgSetAliasesPrivate TIDlgSetAliasesPrivate;

#define TI_DLG_SET_ALIASES_GET_PRIVATE(object)  (G_TYPE_INSTANCE_GET_PRIVATE ((object), TI_TYPE_DLG_SET_ALIASES, TIDlgSetAliasesPrivate))

/* Function prototypes */
static void _button_ok_clicked (GtkButton *button, gpointer user_data);
static void _button_cancel_clicked (GtkButton *button, gpointer user_data);
static void _ti_dlg_set_aliases_build_aliases_treeview (TIDlgSetAliases* self);
static void _ti_dlg_set_aliases_build_contacts_treeview (TIDlgSetAliases* self);
static void _ti_dlg_set_aliases_setup (TIDlgSetAliases* self);
static GHashTable* _ti_dlg_set_aliases_get_aliases_hash_table (TIDlgSetAliases* self);
static void _ti_dlg_set_aliases_add (TIDlgSetAliases* self);
static void _ti_dlg_set_aliases_handle_display_mode_changed (TIDlgSetAliases* self, guint handle_display_mode);
static void _ti_dlg_set_aliases_change_aliases_treeview_display_mode (TIDlgSetAliases* self, guint handle_display_mode);

/**
 * Drop all references to other objects.
 */
static void
ti_dlg_set_aliases_dispose (GObject *object)
{
    TIDlgSetAliases* self = TI_DLG_SET_ALIASES (object);
    TIDlgSetAliasesPrivate *priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);

    if (priv->preferences != NULL)
    {
        g_signal_handlers_disconnect_by_func (priv->preferences,
                                              G_CALLBACK (_ti_dlg_set_aliases_handle_display_mode_changed),
                                              self);

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

    if (priv->handle_mapper != NULL)
    {
        g_object_unref (priv->handle_mapper);
        priv->handle_mapper = NULL;
    }

    if (priv->glade_xml != NULL)
    {
        g_object_unref (priv->glade_xml);
        priv->glade_xml = NULL;
    }

    if (priv->contacts_scrolledwnd != NULL)
    {
        g_object_unref (priv->contacts_scrolledwnd);
        priv->contacts_scrolledwnd = NULL;
    }

    if (priv->handle_box != NULL)
    {
        g_object_unref (priv->handle_box);
        priv->handle_box = NULL;
    }

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

/**
 * Class initialization.
 */
static void
ti_dlg_set_aliases_class_init (TIDlgSetAliasesClass *ti_dlg_set_aliases_class)
{
      GObjectClass *gobject_class = G_OBJECT_CLASS (ti_dlg_set_aliases_class);

      /* override base object methods */ 
      gobject_class->dispose = ti_dlg_set_aliases_dispose;
            
      /* Add private */
      g_type_class_add_private (ti_dlg_set_aliases_class, sizeof (TIDlgSetAliasesPrivate));
}

/**
 * Instance initialization.
 */
static void
ti_dlg_set_aliases_init (TIDlgSetAliases *ti_dlg_set_aliases)
{
    TIDlgSetAliasesPrivate *priv = TI_DLG_SET_ALIASES_GET_PRIVATE (ti_dlg_set_aliases);

    priv->preferences = ti_preferences_new ();
    priv->handle_mapper = NULL;
    priv->aliases_list = NULL;
    priv->contacts_scrolledwnd = NULL;
    priv->handle_box = NULL;
}

/**
 * Returns a new instance.
 */
TIDlgSetAliases*
ti_dlg_set_aliases_new (GtkWindow* parent, TIHandleMapper* handle_mapper) 
{
    TIDlgSetAliases* dialog = NULL;
    gchar* glade_file_path = NULL;
    TIDlgSetAliasesPrivate* priv = NULL;

      dialog = g_object_new (TI_TYPE_DLG_SET_ALIASES, NULL);
    priv = TI_DLG_SET_ALIASES_GET_PRIVATE (dialog);

    priv->parent = parent;
    priv->handle_mapper = handle_mapper;
    g_object_ref (handle_mapper);

    glade_file_path = g_strdup_printf ("%s%s", TI_DATA_DIR_PREFIX, "dlg-set-aliases.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 (dialog);
        dialog = NULL;
        goto CLEAN_UP;
    }

    _ti_dlg_set_aliases_setup (dialog);

    CLEAN_UP:
    g_free (glade_file_path);

    return dialog;
}

/**
 * Setup
 */
static void
_ti_dlg_set_aliases_setup (TIDlgSetAliases* self)
{
    TIDlgSetAliasesPrivate *priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);
    GtkWidget* widget;

    g_signal_connect_swapped (priv->preferences, "handle-display-mode-changed",
                              G_CALLBACK (_ti_dlg_set_aliases_handle_display_mode_changed), self);

    // The dialog itself
    priv->dialog = glade_xml_get_widget (priv->glade_xml, "dialog_set_aliases");
    g_assert (GTK_IS_DIALOG (priv->dialog));
    gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (priv->parent));
    gtk_window_set_position (GTK_WINDOW (priv->dialog), GTK_WIN_POS_CENTER_ON_PARENT);

    // Main box
    priv->main_box = GTK_BOX (glade_xml_get_widget (priv->glade_xml, "box_main"));
    g_assert (GTK_IS_BOX (priv->main_box));

    // Alias Entry
    priv->entry_alias = GTK_ENTRY (glade_xml_get_widget (priv->glade_xml, "entry_alias"));
    g_assert (GTK_IS_ENTRY (priv->entry_alias));

    // Add Button
    widget = glade_xml_get_widget (priv->glade_xml, "button_add");
    g_signal_connect_swapped (widget, "clicked", G_CALLBACK (_ti_dlg_set_aliases_add), self);

    // Contacts Scrolled Window
    priv->contacts_scrolledwnd = glade_xml_get_widget (priv->glade_xml, "scrolledwindow_contacts");
    g_assert (GTK_IS_SCROLLED_WINDOW (priv->contacts_scrolledwnd));
    g_object_ref (priv->contacts_scrolledwnd);

    _ti_dlg_set_aliases_build_contacts_treeview (self);

    // OK and Cancel buttons
    glade_xml_signal_connect_data (priv->glade_xml, "button_ok_clicked", G_CALLBACK(_button_ok_clicked), priv->dialog);
    glade_xml_signal_connect_data (priv->glade_xml, "button_cancel_clicked", G_CALLBACK(_button_cancel_clicked), priv->dialog);

    // Aliases list
    priv->aliases_list = gtk_list_store_new (TI_ALIASES_N_COLUMNS,
                                             G_TYPE_UINT,    // handle
                                             G_TYPE_STRING,  // name
                                             G_TYPE_STRING); // alias
    _ti_dlg_set_aliases_build_aliases_treeview (self);

    // Box Entry Handle
    priv->handle_box = glade_xml_get_widget (priv->glade_xml, "handle_box");
    g_assert (GTK_IS_BOX (priv->handle_box));
    g_object_ref (priv->handle_box);

    // Entry Handle
    priv->handle_entry = GTK_ENTRY (glade_xml_get_widget (priv->glade_xml, "handle_entry"));
    g_assert (GTK_IS_ENTRY (priv->handle_entry));

    // Set to current mode
    _ti_dlg_set_aliases_handle_display_mode_changed (self, ti_preferences_get_handle_display_mode (priv->preferences));
}

/**
 * Run
 */
gboolean
ti_dlg_set_aliases_run (TIDlgSetAliases* self, GHashTable** aliases)
{
    TIDlgSetAliasesPrivate *priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);
    gint result;

    g_assert (aliases != NULL);

    gtk_list_store_clear (priv->aliases_list);

    gtk_widget_show_all (priv->dialog);
    result = gtk_dialog_run (GTK_DIALOG (priv->dialog));
    gtk_widget_hide_all (priv->dialog);

    *aliases = _ti_dlg_set_aliases_get_aliases_hash_table (self);

    return result == GTK_RESPONSE_OK;
}

/**
 * Called when OK button is clicked.
 */
static void
_button_ok_clicked (GtkButton *button, gpointer user_data)
{
    GtkDialog* dialog = GTK_DIALOG (user_data);
    gtk_dialog_response (dialog, GTK_RESPONSE_OK);
}

/**
 * Called when "Cancel" button is clicked.
 */
static void
_button_cancel_clicked (GtkButton *button, gpointer user_data)
{
    GtkDialog* dialog = GTK_DIALOG (user_data);
    gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL);
}

/**
 * Build Aliases Treeview
 */
static void
_ti_dlg_set_aliases_build_aliases_treeview (TIDlgSetAliases* self)
{
    TIDlgSetAliasesPrivate *priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);
    GtkCellRenderer* renderer;
    GtkTreeViewColumn* column;

    priv->aliases_treeview = GTK_TREE_VIEW (glade_xml_get_widget (priv->glade_xml, "treeview_aliases"));
    g_assert (priv->aliases_treeview != NULL);

    gtk_tree_view_set_model (priv->aliases_treeview, GTK_TREE_MODEL (priv->aliases_list));

    renderer = gtk_cell_renderer_text_new ();

    if (ti_preferences_get_handle_display_mode (priv->preferences) ==
        TI_PREFERENCES_HANDLE_DISPLAY_HANDLE)
    {
        /* Handle column */
        column = gtk_tree_view_column_new_with_attributes ("Handle",
                                                           renderer,
                                                           "text", TI_ALIASES_COLUMN_HANDLE,
                                                           NULL);
        gtk_tree_view_append_column (priv->aliases_treeview, column);
    }
    else
    {
        /* Name column */
        column = gtk_tree_view_column_new_with_attributes ("Name",
                                                           renderer,
                                                           "text", TI_ALIASES_COLUMN_NAME,
                                                           NULL);
        gtk_tree_view_append_column (priv->aliases_treeview, column);
    }

    /* Alias column */
    column = gtk_tree_view_column_new_with_attributes ("Alias",
                                                       renderer,
                                                       "text", TI_ALIASES_COLUMN_ALIAS,
                                                       NULL);
    gtk_tree_view_append_column (priv->aliases_treeview, column);

    priv->aliases_selection = gtk_tree_view_get_selection (priv->aliases_treeview);

    gtk_tree_selection_set_mode (priv->aliases_selection, GTK_SELECTION_MULTIPLE);
}

/**
 * Build Contacts Treeview
 */
static void
_ti_dlg_set_aliases_build_contacts_treeview (TIDlgSetAliases* self)
{
    TIDlgSetAliasesPrivate *priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);
    GtkCellRenderer* renderer;
    GtkTreeViewColumn* column;

    priv->contacts_treeview = GTK_TREE_VIEW (glade_xml_get_widget (priv->glade_xml, "treeview_contacts"));
    g_assert (GTK_IS_TREE_VIEW (priv->contacts_treeview));

    gtk_tree_view_set_model (priv->contacts_treeview, GTK_TREE_MODEL (ti_handle_mapper_get_contact_handle_list_store (priv->handle_mapper)));

    renderer = gtk_cell_renderer_text_new ();

    /* Name column */
    column = gtk_tree_view_column_new_with_attributes ("Name",
                                                        renderer,
                                                        "text", TI_HANDLES_LIST_COLUMN_NAME,
                                                        NULL);
    gtk_tree_view_append_column (priv->contacts_treeview, column);
    
    priv->contacts_selection = gtk_tree_view_get_selection (priv->contacts_treeview);

    gtk_tree_selection_set_mode (priv->contacts_selection, GTK_SELECTION_SINGLE);
}

/**
 * Get Aliases Hash Table
 */
static GHashTable*
_ti_dlg_set_aliases_get_aliases_hash_table (TIDlgSetAliases* self)
{
    TIDlgSetAliasesPrivate *priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);
    GtkTreeIter iter;
    gboolean ok;
    GHashTable* hash_table;
    guint handle;
    gchar* alias;

    // GUINT_TO_POINTER.... direct hashes and equals.... This is efficient but ugly. It would be much cleaner if we used
    // guint* instead (along with g_int_hash, g_int_equal and g_free)

    hash_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_free);

    ok = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->aliases_list), &iter);
    while (ok)
    {
        gtk_tree_model_get (GTK_TREE_MODEL (priv->aliases_list), &iter,
                                            TI_ALIASES_COLUMN_HANDLE, &handle,
                                            TI_ALIASES_COLUMN_ALIAS, &alias,
                                            -1);

        g_hash_table_insert (hash_table, GUINT_TO_POINTER (handle), alias);

        ok = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->aliases_list), &iter);
    }

    return hash_table;
}

/**
 * Add
 */
static void
_ti_dlg_set_aliases_add (TIDlgSetAliases* self)
{
    TIDlgSetAliasesPrivate* priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);
    GtkTreeModel* tree_model;
    GtkTreeIter iter;
    gboolean ok;
    guint handle;
    gchar* name;
    const gchar* alias;
    guint handle_display_mode = ti_preferences_get_handle_display_mode (priv->preferences);
    int result;

    // Get selected contact
    if (handle_display_mode == TI_PREFERENCES_HANDLE_DISPLAY_HANDLE)
    {
        result = sscanf (gtk_entry_get_text (priv->handle_entry), "%u", &handle);
        if (result != 1)
            return;

        name = ti_handle_mapper_get_contact_handle_name (priv->handle_mapper, handle);
        if (name == NULL)
            name = g_strdup_printf ("%u", handle);
    }
    else
    {
        ok = gtk_tree_selection_get_selected (priv->contacts_selection, &tree_model, &iter);
        if (!ok)
            return;

        gtk_tree_model_get (tree_model, &iter,
                            TI_HANDLES_LIST_COLUMN_NUMBER, &handle,
                            TI_HANDLES_LIST_COLUMN_NAME, &name,
                            -1);
    }

    // Get entered alias
    alias = gtk_entry_get_text (priv->entry_alias);

    // Add a new row to aliases list
    gtk_list_store_append (priv->aliases_list, &iter);
    gtk_list_store_set (priv->aliases_list, &iter,
                        TI_ALIASES_COLUMN_HANDLE, handle,
                        TI_ALIASES_COLUMN_NAME, name,
                        TI_ALIASES_COLUMN_ALIAS, alias,
                        -1);

    // Clean up
    g_free (name);
}

/**
 * Handle Display Mode Changed
 */
static void
_ti_dlg_set_aliases_handle_display_mode_changed (TIDlgSetAliases* self, guint handle_display_mode)
{
    TIDlgSetAliasesPrivate* priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);

    // Remove the existing UI
    gtk_container_remove (GTK_CONTAINER (priv->main_box), GTK_WIDGET (priv->contacts_scrolledwnd));
    gtk_container_remove (GTK_CONTAINER (priv->main_box), priv->handle_box);

    // Add one according to the global preferences
    if (handle_display_mode == TI_PREFERENCES_HANDLE_DISPLAY_HANDLE)
    {
        gtk_box_pack_start (priv->main_box, priv->handle_box, FALSE, TRUE, 0);
        gtk_box_reorder_child (priv->main_box, priv->handle_box, 0);
    }
    else
    {
        gtk_box_pack_start (priv->main_box, GTK_WIDGET (priv->contacts_scrolledwnd), TRUE, TRUE, 0);
        gtk_box_reorder_child (priv->main_box, GTK_WIDGET (priv->contacts_scrolledwnd), 0);
    }

    _ti_dlg_set_aliases_change_aliases_treeview_display_mode (self, handle_display_mode);
}

/**
 * Change Aliases Treeview Display Mode
 */
static void
_ti_dlg_set_aliases_change_aliases_treeview_display_mode (TIDlgSetAliases* self, guint handle_display_mode)
{
    TIDlgSetAliasesPrivate* priv = TI_DLG_SET_ALIASES_GET_PRIVATE (self);
    GtkTreeViewColumn* contact_handle_column;
    GtkCellRenderer* renderer;
    GList* renderers_list = NULL;

    contact_handle_column = gtk_tree_view_get_column (priv->aliases_treeview, 0); // It's the first column.

    renderers_list = gtk_tree_view_column_get_cell_renderers (contact_handle_column);
    g_assert (g_list_length (renderers_list) == 1);

    renderer = GTK_CELL_RENDERER (renderers_list->data);

    if (handle_display_mode == TI_PREFERENCES_HANDLE_DISPLAY_HANDLE)
    {
        gtk_tree_view_column_set_title (contact_handle_column, "Handle");

        gtk_tree_view_column_set_attributes (contact_handle_column, renderer,
                                             "text", TI_ALIASES_COLUMN_HANDLE,
                                             NULL);
    }
    else // TI_PREFERENCES_HANDLE_DISPLAY_NAME
    {
        gtk_tree_view_column_set_title (contact_handle_column, "Name");

        gtk_tree_view_column_set_attributes (contact_handle_column, renderer,
                                             "text", TI_ALIASES_COLUMN_NAME,
                                             NULL);
    }

    // Clean up
    g_list_free (renderers_list);
}

Generated by  Doxygen 1.6.0   Back to index