/* OpenIDA - Outil d'analyse de fichiers binaires
 * strings.c - panneau d'affichage des chaînes de caractères
 *
 * Copyright (C) 2006-2007 Cyrille Bagard
 *
 *  This file is part of OpenIDA.
 *
 *  OpenIDA 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  OpenIDA is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include "strings.h"


#include "../format/format.h"



/* Colonnes de la liste des symboles */
typedef enum _StringsColumn
{
    STC_ADDRESS,                            /* Adresse mémoire du symbole  */
    STC_STRING,                             /* Désignation humaine         */

    STC_COUNT                               /* Nombre de colonnes          */

} StringsColumn;


#define _(str) str


/******************************************************************************
*                                                                             *
*  Paramètres  : ref = adresse de l'espace de référencements.                 *
*                                                                             *
*  Description : Construit le panneau d'affichage des symboles.               *
*                                                                             *
*  Retour      : Adresse du panneau mis en place.                             *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

GtkWidget *build_strings_panel(GObject *ref)
{
    GtkWidget *result;                      /* Panneau à retourner         */
    GtkTreeStore *store;                    /* Modèle de gestion           */
    GtkWidget *treeview;                    /* Affichage de la liste       */
    GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
    GtkTreeViewColumn *column;              /* Colonne de la liste         */
    GtkTreeSelection *select;               /* Sélection dans la liste     */

    result = gtk_scrolled_window_new(NULL, NULL);
    gtk_widget_show(result);

    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(result), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(result), GTK_SHADOW_IN);

    store = gtk_tree_store_new(STC_COUNT, G_TYPE_STRING, G_TYPE_STRING);
    g_object_set_data(G_OBJECT(result), "store", store);

    treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
    gtk_widget_show(treeview);
    gtk_container_add(GTK_CONTAINER(result), treeview);

    g_object_unref(G_OBJECT(store));

    column = gtk_tree_view_column_new();
    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
    gtk_tree_view_set_expander_column(GTK_TREE_VIEW(treeview), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("Address"), renderer, "text", STC_ADDRESS, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(_("String"), renderer, "text", STC_STRING, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);


    /*
    select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
    gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
    g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(change_symbols_selection), ref);
    */



    return result;

}



/******************************************************************************
*                                                                             *
*  Paramètres  : panel  = panneau à mettre à jour.                            *
*                format = données sur l'exécutable à représenter.             *
*                                                                             *
*  Description : Affiche la liste des symboles présents dans un exécutable.   *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

void handle_new_exe_on_strings_panel(GtkWidget *panel, const GExeFormat *format)
{
    GtkTreeStore *store;                    /* Modèle de gestion           */
    size_t count;                           /* Nombre des chaînes          */
    GBinSymbol **symbols;                   /* Liste des chaînes trouvées  */
    size_t i;                               /* Boucle de parcours          */
    char address[11];                       /* Conversion de l'adresse     */
    GtkTreeIter iter;                       /* Point d'insertion           */

    store = g_object_get_data(G_OBJECT(panel), "store");

    symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &count);

    for (i = 0; i < count; i++)
    {
        if (g_binary_symbol_get_target_type(symbols[i]) != STP_STRING) continue;

        /* FIXME : adresses autres que 32 bits */
        snprintf(address, 11, "0x%08llx", g_binary_symbol_get_address(symbols[i]));

        gtk_tree_store_append(store, &iter, NULL);
        gtk_tree_store_set(store, &iter,
                           STC_ADDRESS, address,
                           STC_STRING, g_binary_symbol_to_string(symbols[i]),
                           -1);

    }

}