/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* turing_table_editor.c - a Turing machine simulator. * Copyright (C) 2001-2002 German Poo-Caaman~o * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "turing.h" #include "turing_table_editor.h" #include "gturing.h" /** * turing_table_editor_model_new * @tm: A Turing's states machine * * Description: Create a model of a Turing's states machine. * * Returns: A GtkTreeModel with the turing machine loaded. */ static GtkTreeModel * turing_table_editor_model_new (turing * tm) { GtkListStore *model; GtkTreeIter iter; turing_state *s; gchar text[3][2]; GdkPixbuf *left_pixbuf; GdkPixbuf *right_pixbuf; GdkPixbuf *pixbuf; model = gtk_list_store_new (NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT); left_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) leftarrow_xpm); right_pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) rightarrow_xpm); /* Fill the model with the machine's states */ for (s = tm->statehead; s; s = s->next) { text[0][0] = s->read; text[0][1] = 0; text[1][0] = s->write; text[1][1] = 0; text[2][0] = s->move; text[2][1] = 0; pixbuf = (s->move == 'l') ? left_pixbuf : right_pixbuf; gtk_list_store_append (model, &iter); gtk_list_store_set (model, &iter, COLUMN_STATE, s->no, COLUMN_READ, text[0], COLUMN_WRITE, text[1], COLUMN_MOVE, pixbuf, COLUMN_MOVE_DATA, text[2], COLUMN_NEW_STATE, s->new, COLUMN_COMMENTS, s->comments, COLUMN_EDITABLE, TRUE, COLUMN_INDEX, s->index, -1); } return GTK_TREE_MODEL (model); } /** * turing_table_editor_set_model * @treeview_editor: A GtkTreeView where is needed update its * model * @tm: The new Turing's states machines for treeview_editor. * * Description: Updates the Turing's states machine of a * turing_table_editor (GtkTreeView) * */ void turing_table_editor_set_model (GtkTreeView * treeview_editor, turing * tm) { GtkTreeModel *model; model = turing_table_editor_model_new (tm); gtk_tree_view_set_model (treeview_editor, model); } /** * turing_table_editor_new * @tree: A Widget where GtkTreeView with the columns needed * will be created. * * Description: Create a GtkScrolledWindow with an empty * GtkTreeView, ready for use it with states of Turing's * machine. */ GtkWidget * turing_table_editor_new (GtkTreeView ** tree, turing *tm) { GtkWidget *scrolled_window; scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN); (*tree) = turing_table_editor_treeview_new (tm); gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (*tree)); return scrolled_window; } /** * turing_table_editor_treeview_new * * Description: Create a GtkTreeView with an empty model. * */ GtkTreeView * turing_table_editor_treeview_new (turing *tm) { GtkTreeView *treeview; GtkTreeModel *model; /* create an empty model */ model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT)); treeview = GTK_TREE_VIEW (gtk_tree_view_new_with_model (model)); gtk_tree_view_set_rules_hint (treeview, TRUE); gtk_tree_selection_set_mode (gtk_tree_view_get_selection (treeview), GTK_SELECTION_SINGLE); turing_table_editor_add_columns (treeview, tm); g_object_unref (G_OBJECT (model)); return treeview; } static void cell_edited (GtkCellRendererText * cell, gchar * path_string, gchar * new_text, gpointer data) { GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (data)); GtkTreePath *path = gtk_tree_path_new_from_string (path_string); GtkTreeIter iter; turing_state ts; /* turing *tm;*/ gint *column; gint cstate, cnew_state, cindex; gchar *cread, *cwrite, *cmove, *ccomments; column = g_object_get_data (G_OBJECT (cell), "column"); /*tm = g_object_get_data (G_OBJECT (cell), "turing_machine");*/ gtk_tree_model_get_iter (model, &iter, path); switch ((gint) column) { case COLUMN_STATE: case COLUMN_NEW_STATE: { gint old_text; gtk_tree_model_get (model, &iter, column, &old_text, -1); gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, atoi (new_text), -1); /* if (atoi (new_text) == old_text) { g_print ("%d y %d son iguales\n", atoi (new_text), old_text); }*/ break; } default: /* Change strings is easy */ { gint i; gchar *old_text; gtk_tree_model_get (model, &iter, column, &old_text, -1); i = gtk_tree_path_get_indices (path)[0]; gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, new_text, -1); /*if (g_utf8_collate (old_text, new_text) == 0) { g_print ("%s y %s son iguales\n", old_text, new_text); }*/ g_free (old_text); break; } } gtk_tree_model_get (model, &iter, COLUMN_STATE, &cstate, COLUMN_READ, &cread, COLUMN_WRITE, &cwrite, COLUMN_MOVE_DATA, &cmove, COLUMN_NEW_STATE, &cnew_state, COLUMN_COMMENTS, &ccomments, COLUMN_INDEX, &cindex, -1); g_print ("%d: %d, %c, %c, %c, %d, %s\n", cindex, cstate, cread[0], cwrite[0], cmove[0], cnew_state, ccomments); ts.index = cindex; ts.no = cstate; ts.read = cread[0]; ts.write = cwrite[0]; ts.move = cmove[0]; ts.new = cnew_state; strncpy (ts.comments, ccomments, strlen (ccomments)+1); turing_set_state (tm, ts); g_free (cread); g_free (cwrite); g_free (ccomments); gtk_tree_path_free (path); } /** * turing_table_editor_add_columns * @treeeview: A GtkTreeView where the columns sill be * created (emptys columns) * * Description: Fill the treeview with empty columns * */ static void turing_table_editor_add_columns (GtkTreeView * treeview, turing * tm) { GtkCellRenderer *renderer; GtkTreeViewColumn *column; gchar *text[] = { N_("State"), N_("Read"), N_("Write"), N_("Move"), N_("New State"), N_("Comments") }; gint i; /* Add each column with title */ for (i = COLUMN_STATE; i < NUM_COLUMNS - 3; i++) { switch (i) { case COLUMN_MOVE: renderer = gtk_cell_renderer_pixbuf_new (); column = gtk_tree_view_column_new_with_attributes (text [i], renderer, "pixbuf", i, NULL); break; /*} else {*/ case COLUMN_STATE: renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (text [i], renderer, "text", i, NULL); break; default: renderer = gtk_cell_renderer_text_new (); g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (cell_edited), treeview); g_object_set_data (G_OBJECT (renderer), "column", (gint *) i); g_object_set_data (G_OBJECT (renderer), "turing_machine", tm); column = gtk_tree_view_column_new_with_attributes (text [i], renderer, "text", i, "editable", COLUMN_EDITABLE, NULL); break; } gtk_tree_view_append_column (treeview, column); } /* column = gtk_tree_view_get_column (treeview, 0); */ /* gtk_tree_view_column_set_sort_column_id (column, COLUMN_STATE); */ }