Logo Search packages:      
Sourcecode: jmp version File versions  Download package

methodlist_menu.c

#include <methodlist_menu.h>
#include <gtk/gtk.h>
#include <method.h>
#include <cls.h>
#include <filtermenu.h>
#include <heap_dump.h>
#include <ui.h>
#include <mvector.h>
#include <method_info.h>
#include <mvector.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <jmp-config.h>
#include <gtkutils.h>
#include <method_window.h>
#include <code_usage_dump.h>

static method* m;

void mlist_row_changed (GtkTreeSelection *selection, gpointer data) {
    GtkTreeIter iter;
    GtkTreeModel *model;
    
    if (gtk_tree_selection_get_selected (selection, &model, &iter)) 
      gtk_tree_model_get (model, &iter, MMETHOD_COLUMN, &m, -1);
    else 
      m = NULL;
}

/** request to show all live objects allocated by a method. */
static void mmenu_show_alloced (GtkObject *method_list) {
    if (m != NULL)
      run_show_objects_alloced_by_method (m);
}

enum {
    JCLASS = 0,
    METHODNAME,
    NUM_COLUMNS
};

static mvector* get_called_method (method* m) {
    return m->called_methods;
}

static mvector* get_callee_method (method* m) {
    return m->callee_methods;
}

typedef mvector*(get_mvector)(method* m);

static void add_methods (GtkTreeStore* model, GtkTreeIter* parent, 
                   mvector* mv, size_t level, get_mvector* gv){
    GtkTreeIter iter;
    size_t i;
    if (level >= 10)
      return;
    for (i = 0; i < mvector_load (mv); i++) {
      method* mm = mvector_get (mv, i);
      mvector* mmv;
      gtk_tree_store_append (model, &iter, parent);
      gtk_tree_store_set (model, &iter, 
                      JCLASS, mm->owner->name,
                      METHODNAME, mm->jmpname,
                      -1);
      mmv = gv (mm);
      if (mvector_load (mmv))
          add_methods (model, &iter, mmv, level + 1, gv);
    }
}

/** build a tree for call graphs... 
 */
static GtkTreeStore*
create_model (method* m, get_mvector* gv) {
    GtkTreeStore *model;
    GtkTreeIter iter;
    mvector *mv = gv (m);
    
    /* create tree store */
    model = gtk_tree_store_new (NUM_COLUMNS,
                        G_TYPE_STRING,
                        G_TYPE_STRING);
    gtk_tree_store_append (model, &iter, NULL);
    gtk_tree_store_set (model, &iter, 
                  JCLASS, m->owner->name,
                  METHODNAME, m->jmpname,
                  -1);
    add_methods (model, &iter, mv, 0, gv);
    return model;
}

static void add_columns (GtkTreeView *treeview) {
    gint col_offset;
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;

    renderer = gtk_cell_renderer_text_new ();
    g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);

    col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                                -1, _("Class"),
                                                renderer, "text",
                                                JCLASS,
                                                NULL);
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1);
    gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);

    col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                                -1, _("Method"),
                                                renderer, "text",
                                                METHODNAME,
                                                NULL);
    column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), col_offset - 1);
    gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);

}

/** Create a window with a call graph for the currently selected method. */
static void mmenu_show_call_list (GtkObject *method_list, get_mvector* gv) {
    GtkWidget *win;
    GtkWidget *scrolledwindow;
    GtkWidget *tree;
    GtkTreeStore *model;
    win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (win), _("Call graph"));
    scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
    gtk_container_add (GTK_CONTAINER (win), scrolledwindow);
    model = create_model (m, gv);
    tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree), TRUE);
    add_columns (GTK_TREE_VIEW (tree));
    gtk_container_add (GTK_CONTAINER (scrolledwindow), tree);
    gtk_widget_set_usize (win, 500, 200);
    gtk_widget_show_all (win);
}

/** Create a window with a call graph for the currently selected method. */
static void mmenu_show_called (GtkObject *method_list) {
    mmenu_show_call_list (method_list, get_called_method);
}

/** Create a window with a call graph for the currently selected method. */
static void mmenu_show_callee (GtkObject *method_list) {
    mmenu_show_call_list (method_list, get_callee_method);    
}

static void mmenu_show_method_info (GtkObject *method_list) {
    if (m != NULL)
      show_method_info (m);
}

static void mmenu_code_usage_dump (GtkObject *method_list) {
    write_code_usage_dump ();
}

static GtkWidget* build_mmenu (GtkWidget* method_list) {
    GtkWidget* menuitem;
    GtkWidget* mmenu;
    GtkWidget* filters;
    
    mmenu = gtk_menu_new ();
    add_menu_item (mmenu, _("show alloc'ed instances"), (GCallback)mmenu_show_alloced);
    add_menu_separator (mmenu);    
    add_menu_item (mmenu, _("show called methods (down)"), (GCallback)mmenu_show_called);
    add_menu_item (mmenu, _("show callee methods (up)"), (GCallback)mmenu_show_callee);
    add_menu_item (mmenu, _("show method info"), (GCallback)mmenu_show_method_info);
    add_menu_separator (mmenu);
    add_menu_item (mmenu, _("write code usage dump"), (GCallback)mmenu_code_usage_dump);
    add_menu_separator (mmenu);
    /* add filters... */
    filters = build_filter_menu (method_get_owner (m));
    menuitem = gtk_menu_item_new_with_label (_("Filter"));
    gtk_menu_append (GTK_MENU (mmenu), menuitem);
    gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), filters);
    gtk_widget_show_all (mmenu);
    return mmenu;
}

gint mlist_button_handler (GtkWidget *widget,
                     GdkEventButton  *event,
                     gpointer   callback_data) {
    if (event->button == 3 && m != NULL) {
      GtkWidget* mmenu = build_mmenu (widget);
      gtk_menu_popup (GTK_MENU (mmenu), NULL, NULL, NULL, NULL,
                        event->button, event->time);  
      return TRUE;
    }
    return FALSE;
}

/* Emacs Local Variables: */
/* Emacs mode:C */
/* Emacs c-indentation-style:"gnu" */
/* Emacs c-hanging-braces-alist:((brace-list-open)(brace-entry-open)(defun-open after)(substatement-open after)(block-close . c-snug-do-while)(extern-lang-open after)) */
/* Emacs c-cleanup-list:(brace-else-brace brace-elseif-brace space-before-funcall) */
/* Emacs c-basic-offset:4 */
/* Emacs End: */

Generated by  Doxygen 1.6.0   Back to index