/* * wtree.c * * Copyright 2010 Alexander Petukhov * * 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 Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ /* * Watch tree view. */ #include #include "wtree.h" #include "watch_model.h" #include "vtree.h" #include "dconfig.h" #include "breakpoint.h" #include "debug_module.h" /* drag types */ enum { TARGET_STRING, }; static GtkTargetEntry targetentries[] = { { (gchar*)"STRING", 0, TARGET_STRING } }; /* reference to an empty row */ static GtkTreeRowReference *empty_row = NULL; /* tree view widget */ static GtkWidget *tree = NULL; static GtkTreeModel *model = NULL; static GtkTreeStore *store = NULL; /* * add empty row */ static void add_empty_row(void) { GtkTreeIter empty; GtkTreePath *path; if (empty_row) gtk_tree_row_reference_free(empty_row); gtk_tree_store_prepend (store, &empty, NULL); gtk_tree_store_set (store, &empty, W_NAME, "", W_VALUE, "", W_TYPE, "", W_LAST_VISIBLE, "", W_INTERNAL, "", W_EXPRESSION, "", W_STUB, 0, W_CHANGED, 0, W_VT, VT_NONE, -1); /* save reference */ path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &empty); empty_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(store), path); gtk_tree_path_free(path); } /* * name column renderer */ static void on_render_name(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { /* sets editable to true only for root items */ GtkTreePath *path = gtk_tree_model_get_path(tree_model, iter); g_object_set (cell, "editable", gtk_tree_path_get_depth(path) <= 1, NULL); gtk_tree_path_free(path); } /* * get iterator to an empty row */ void wtree_empty_row(GtkTreeIter *iter) { GtkTreePath *path = gtk_tree_row_reference_get_path(empty_row); gtk_tree_model_get_iter(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)), iter, path); gtk_tree_path_free(path); } /* * get an empty row path */ GtkTreePath* wtree_empty_path(void) { return gtk_tree_row_reference_get_path(empty_row); } /* * iterating function to collect all watches */ static gboolean watches_foreach_collect(GtkTreeModel *_model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { if (gtk_tree_path_compare(path, wtree_empty_path()) && 1 == gtk_tree_path_get_depth(path)) { gchar *watch; GList **watches = (GList**)data; gtk_tree_model_get ( _model, iter, W_NAME, &watch, -1); *watches = g_list_append(*watches, watch); } return FALSE; } /* * init watches tree view */ GtkWidget* wtree_init(watch_expanded_callback expanded, new_watch_dragged dragged, watch_key_pressed keypressed, watch_expression_changed changed, watch_button_pressed buttonpressed) { GtkTreeSelection *selection; tree = vtree_create(on_render_name, changed); model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree)); store = GTK_TREE_STORE(model); gtk_tree_view_enable_model_drag_dest( GTK_TREE_VIEW(tree), targetentries, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); g_signal_connect(G_OBJECT(tree), "row-expanded", G_CALLBACK (expanded), NULL); g_signal_connect(G_OBJECT(tree), "drag_data_received", G_CALLBACK(dragged), NULL); g_signal_connect(G_OBJECT(tree), "key-press-event", G_CALLBACK (keypressed), NULL); g_signal_connect(G_OBJECT(tree), "button-press-event", G_CALLBACK (buttonpressed) , NULL); /* add empty row */ add_empty_row(); /* set multiple selection */ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); return tree; } /* * get watches list */ GList *wtree_get_watches(void) { GList *watches = NULL; gtk_tree_model_foreach(gtk_tree_view_get_model(GTK_TREE_VIEW(tree)), watches_foreach_collect, &watches); return watches; } /* * remove all watches from the tree view */ void wtree_remove_all(void) { gtk_tree_store_clear(store); add_empty_row(); } /* * add new watche to the tree view */ void wtree_add_watch(gchar *watch) { GtkTreeIter newvar, empty; wtree_empty_row(&empty); gtk_tree_store_insert_before(store, &newvar, NULL, &empty); variable_set_name_only(store, &newvar, watch); }