|
Packit |
d394d9 |
/* Copyright (C) 2002 Bjoern Beutel. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Description. =============================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Read in and display Malaga Variables. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Includes. ================================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
#include <stdio.h>
|
|
Packit |
d394d9 |
#include <stdlib.h>
|
|
Packit |
d394d9 |
#include <stdarg.h>
|
|
Packit |
d394d9 |
#include <setjmp.h>
|
|
Packit |
d394d9 |
#include <string.h>
|
|
Packit |
d394d9 |
#include <gtk/gtk.h>
|
|
Packit |
d394d9 |
#include "basic.h"
|
|
Packit |
d394d9 |
#include "scanner.h"
|
|
Packit |
d394d9 |
#include "input.h"
|
|
Packit |
d394d9 |
#include "canvas.h"
|
|
Packit |
d394d9 |
#include "tree.h"
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Constants. ===============================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
enum {FIRST_STATE, NEXT_STATE, PREV_STATE, LAST_STATE};
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
enum {PATH_BEGIN, PATH_END, FROM_ROOT}; /* Items of the tree's pop-up menu. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Types. ===================================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
typedef enum {INTER_NODE, BREAK_NODE, FINAL_NODE, UNFINAL_NODE,
|
|
Packit |
d394d9 |
PRUNED_NODE} tree_node_type_t;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
typedef enum {ELEMENT_NODE, ELEMENT_LINK, ELEMENT_RULE} element_t;
|
|
Packit |
d394d9 |
/* Elements of a node that may be hit by the mouse pointer. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
typedef struct tree_node
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
struct tree_node *parent; /* Parent of this tree node. */
|
|
Packit |
d394d9 |
struct tree_node *sibling; /* Next sibling of this tree node. */
|
|
Packit |
d394d9 |
struct tree_node *child; /* First successor of this tree node. */
|
|
Packit |
d394d9 |
int_t state_index; /* State index of this tree node. */
|
|
Packit |
d394d9 |
tree_node_type_t type; /* Type of this node. */
|
|
Packit |
d394d9 |
string_t rule_name; /* Name of rule that created this node. */
|
|
Packit |
d394d9 |
string_t link_surf;
|
|
Packit |
d394d9 |
string_t link_feat;
|
|
Packit |
d394d9 |
string_t result_surf;
|
|
Packit |
d394d9 |
string_t result_feat;
|
|
Packit |
d394d9 |
string_t rule_set;
|
|
Packit |
d394d9 |
bool_t result_path;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* The following items are used to display the tree node. */
|
|
Packit |
d394d9 |
bool_t in_path; /* TRUE iff this node is in displayed path. */
|
|
Packit |
d394d9 |
int_t x, y; /* Node position. */
|
|
Packit |
d394d9 |
pos_string_t *pos_rule_name; /* Positioned rule name. */
|
|
Packit |
d394d9 |
pos_string_t *pos_link_surf; /* Positioned link surface. */
|
|
Packit |
d394d9 |
pos_string_t *pos_state_index; /* Positioned state index. */
|
|
Packit |
d394d9 |
} tree_node_t;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
typedef struct
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
list_node_t *next; /* Next path node in this list. */
|
|
Packit |
d394d9 |
pos_string_t *state_index;
|
|
Packit |
d394d9 |
pos_string_t *link_surf;
|
|
Packit |
d394d9 |
pos_value_t *link_feat;
|
|
Packit |
d394d9 |
pos_string_t *rule_name;
|
|
Packit |
d394d9 |
pos_string_t *result_surf;
|
|
Packit |
d394d9 |
pos_value_t *result_feat;
|
|
Packit |
d394d9 |
pos_string_t *rule_set;
|
|
Packit |
d394d9 |
} path_node_t;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Global variables. ========================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
rectangle_t tree_geometry, path_geometry;
|
|
Packit |
d394d9 |
string_t tree_font_family, path_font_family;
|
|
Packit |
d394d9 |
int_t tree_font_size, path_font_size;
|
|
Packit |
d394d9 |
tree_mode_t tree_mode;
|
|
Packit |
d394d9 |
bool_t show_state_indexes;
|
|
Packit |
d394d9 |
bool_t inline_path;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Variables. ===============================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Information in Tree window. */
|
|
Packit |
d394d9 |
static pos_string_t *result_surf;
|
|
Packit |
d394d9 |
static tree_node_t *tree_nodes;
|
|
Packit |
d394d9 |
static tree_node_t **states; /* Dynamic array of nodes representing states. */
|
|
Packit |
d394d9 |
static int_t state_count; /* Size of the array STATES. */
|
|
Packit |
d394d9 |
static int_t tree_width, tree_height; /* Width and height of tree canvas. */
|
|
Packit |
d394d9 |
static canvas_t *tree_canvas;
|
|
Packit |
d394d9 |
static tree_node_t *popup_menu_node;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static bool_t tree_show_state_indexes;
|
|
Packit |
d394d9 |
/* Controls whether state indexes are shown in tree. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Information in Path window. */
|
|
Packit |
d394d9 |
static list_t path_nodes;
|
|
Packit |
d394d9 |
static canvas_t *path_canvas;
|
|
Packit |
d394d9 |
static pos_string_t *plus;
|
|
Packit |
d394d9 |
static pos_string_t *comma;
|
|
Packit |
d394d9 |
static tree_node_t *path_begin, *path_end;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static bool_t path_show_state_indexes;
|
|
Packit |
d394d9 |
/* Controls whether state indexes are shown in path. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Forward declarations. ====================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void goto_state( canvas_t *canvas, guint action );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Functions. ===============================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static string_t
|
|
Packit |
d394d9 |
parse_optional_value( string_t *input )
|
|
Packit |
d394d9 |
/* Parse "{}" or "{VALUE}" in *INPUT and return NULL or VALUE, resp.
|
|
Packit |
d394d9 |
* Update *INPUT. The result must bee freed after use. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
string_t s, value;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (**input != '{')
|
|
Packit |
d394d9 |
complain( "Missing \"{\"." );
|
|
Packit |
d394d9 |
for (s = *input + 1; *s != '}'; s++)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (*s == EOS)
|
|
Packit |
d394d9 |
complain( "Missing \"}\"." );
|
|
Packit |
d394d9 |
if (*s == '\"')
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
for (s++; *s != '\"'; s++)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (*s == EOS)
|
|
Packit |
d394d9 |
complain( "Missing '\"'." );
|
|
Packit |
d394d9 |
if (s[0] == '\\' && s[1] == '\"')
|
|
Packit |
d394d9 |
s++;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (s > *input + 1)
|
|
Packit |
d394d9 |
value = new_string( *input + 1, s );
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
value = NULL;
|
|
Packit |
d394d9 |
*input = s + 1;
|
|
Packit |
d394d9 |
parse_whitespace( input );
|
|
Packit |
d394d9 |
return value;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
configure_path( canvas_t *canvas, int_t *width_p, int_t *height_p )
|
|
Packit |
d394d9 |
/* Do the layout of the path CANVAS.
|
|
Packit |
d394d9 |
* Return the canvas' total size in *WIDTH_P and *HEIGHT_P. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t path_width, path_height, x, x_dist;
|
|
Packit |
d394d9 |
path_node_t *node;
|
|
Packit |
d394d9 |
bool_t is_first;
|
|
Packit |
d394d9 |
int_t space_width = get_space_width( canvas );
|
|
Packit |
d394d9 |
int_t font_height = get_font_height( canvas );
|
|
Packit |
d394d9 |
int_t font_ascent = get_font_ascent( canvas );
|
|
Packit |
d394d9 |
int_t border_width = get_border_width( canvas );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
config_pos_string( plus, canvas );
|
|
Packit |
d394d9 |
config_pos_string( comma, canvas );
|
|
Packit |
d394d9 |
x_dist = space_width + comma->width;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
path_width = path_height = border_width;
|
|
Packit |
d394d9 |
is_first = TRUE;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
FOREACH( node, path_nodes )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (node->link_feat != NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (is_first)
|
|
Packit |
d394d9 |
is_first = FALSE;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
path_height += font_height;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
config_pos_string( node->link_surf, canvas );
|
|
Packit |
d394d9 |
node->link_surf->x = border_width + plus->width + space_width;
|
|
Packit |
d394d9 |
path_width = MAX( path_width,
|
|
Packit |
d394d9 |
node->link_surf->x + node->link_surf->width );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
config_pos_value( node->link_feat, canvas );
|
|
Packit |
d394d9 |
node->link_feat->x = node->link_surf->x;
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->link_surf->y = (path_height
|
|
Packit |
d394d9 |
+ node->link_feat->ascent - font_ascent);
|
|
Packit |
d394d9 |
node->link_feat->x += node->link_surf->width + x_dist;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->link_surf->y = path_height;
|
|
Packit |
d394d9 |
path_height += font_height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
node->link_feat->y = path_height;
|
|
Packit |
d394d9 |
path_width = MAX( path_width,
|
|
Packit |
d394d9 |
node->link_feat->x + node->link_feat->width );
|
|
Packit |
d394d9 |
path_height += node->link_feat->height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (node->result_feat != NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (is_first)
|
|
Packit |
d394d9 |
is_first = FALSE;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
path_height += font_height;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
x = border_width;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Configure rule name. */
|
|
Packit |
d394d9 |
if (node != (path_node_t *) path_nodes.first)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
config_pos_string( node->rule_name, canvas );
|
|
Packit |
d394d9 |
node->rule_name->x = x;
|
|
Packit |
d394d9 |
x += node->rule_name->width + 2 * space_width;
|
|
Packit |
d394d9 |
if (! inline_path)
|
|
Packit |
d394d9 |
node->rule_name->y = path_height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Configure state index. */
|
|
Packit |
d394d9 |
if (path_show_state_indexes)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
config_pos_string( node->state_index, canvas );
|
|
Packit |
d394d9 |
node->state_index->x = x;
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
x += node->state_index->width + x_dist;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->state_index->y = path_height;
|
|
Packit |
d394d9 |
path_width = MAX( path_width, x + node->state_index->width );
|
|
Packit |
d394d9 |
path_height += font_height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Configure result surface. */
|
|
Packit |
d394d9 |
config_pos_string( node->result_surf, canvas );
|
|
Packit |
d394d9 |
node->result_surf->x = x;
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
x += node->result_surf->width + x_dist;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->result_surf->y = path_height;
|
|
Packit |
d394d9 |
path_width = MAX( path_width, x + node->result_surf->width );
|
|
Packit |
d394d9 |
path_height += font_height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Configure result feature structure. */
|
|
Packit |
d394d9 |
config_pos_value( node->result_feat, canvas );
|
|
Packit |
d394d9 |
node->result_feat->x = x;
|
|
Packit |
d394d9 |
node->result_feat->y = path_height;
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
x += node->result_feat->width + x_dist;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
path_width = MAX( path_width, x + node->result_feat->width );
|
|
Packit |
d394d9 |
path_height += node->result_feat->height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Configure rule set. */
|
|
Packit |
d394d9 |
config_pos_string( node->rule_set, canvas );
|
|
Packit |
d394d9 |
node->rule_set->x = x;
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->rule_name->y
|
|
Packit |
d394d9 |
= node->state_index->y
|
|
Packit |
d394d9 |
= node->result_surf->y
|
|
Packit |
d394d9 |
= node->rule_set->y
|
|
Packit |
d394d9 |
= path_height + node->result_feat->ascent - font_ascent;
|
|
Packit |
d394d9 |
path_height += node->result_feat->height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->rule_set->y = path_height;
|
|
Packit |
d394d9 |
path_height += font_height;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
path_width = MAX( path_width, x + node->rule_set->width );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
*width_p = path_width + border_width;
|
|
Packit |
d394d9 |
*height_p = path_height + border_width;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
expose_path( canvas_t *canvas, rectangle_t *area )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
path_node_t *node;
|
|
Packit |
d394d9 |
int_t x1, x2, y;
|
|
Packit |
d394d9 |
int_t space_width = get_space_width( canvas );
|
|
Packit |
d394d9 |
int_t font_height = get_font_height( canvas );
|
|
Packit |
d394d9 |
int_t border_width = get_border_width( canvas );
|
|
Packit |
d394d9 |
int_t line_width = get_line_width( canvas );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
set_color( BLACK );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
FOREACH( node, path_nodes )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (node->link_feat != NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
plus->x = border_width;
|
|
Packit |
d394d9 |
plus->y = node->link_surf->y;
|
|
Packit |
d394d9 |
draw_pos_string( plus, canvas );
|
|
Packit |
d394d9 |
draw_pos_string( node->link_surf, canvas );
|
|
Packit |
d394d9 |
draw_pos_value( node->link_feat, canvas );
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
comma->x = node->link_surf->x + node->link_surf->width;
|
|
Packit |
d394d9 |
comma->y = node->link_surf->y;
|
|
Packit |
d394d9 |
draw_pos_string( comma, canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (node->result_feat != NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (node != (path_node_t *) path_nodes.first)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
x1 = node->rule_name->x;
|
|
Packit |
d394d9 |
x2 = x1 + node->rule_name->width + space_width;
|
|
Packit |
d394d9 |
y = node->rule_name->y + font_height + line_width;
|
|
Packit |
d394d9 |
draw_pos_string( node->rule_name, canvas );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Draw arrow. */
|
|
Packit |
d394d9 |
draw_lines( 2, x1, y, x2, y );
|
|
Packit |
d394d9 |
draw_lines( 3,
|
|
Packit |
d394d9 |
x2 - space_width, y - space_width / 2,
|
|
Packit |
d394d9 |
x2, y,
|
|
Packit |
d394d9 |
x2 - space_width, y + space_width / 2 );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (path_show_state_indexes)
|
|
Packit |
d394d9 |
draw_pos_string( node->state_index, canvas );
|
|
Packit |
d394d9 |
draw_pos_string( node->result_surf, canvas );
|
|
Packit |
d394d9 |
draw_pos_value( node->result_feat, canvas );
|
|
Packit |
d394d9 |
draw_pos_string( node->rule_set, canvas );
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
comma->x = node->result_surf->x + node->result_surf->width;
|
|
Packit |
d394d9 |
comma->y = node->result_surf->y;
|
|
Packit |
d394d9 |
draw_pos_string( comma, canvas );
|
|
Packit |
d394d9 |
comma->x = node->result_feat->x + node->result_feat->width;
|
|
Packit |
d394d9 |
draw_pos_string( comma, canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
unmark_tree_nodes( tree_node_t *node )
|
|
Packit |
d394d9 |
/* Mark NODE and all its children and siblings *not* to be part of the path. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
for (; node != NULL; node = node->sibling)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->in_path = FALSE;
|
|
Packit |
d394d9 |
unmark_tree_nodes( node->child );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
free_path( void )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
path_node_t *path_node;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Clear old path nodes. */
|
|
Packit |
d394d9 |
FOREACH_FREE( path_node, path_nodes )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
free_pos_string( &path_node->state_index );
|
|
Packit |
d394d9 |
free_pos_value( &path_node->link_feat );
|
|
Packit |
d394d9 |
free_pos_value( &path_node->result_feat );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
unmark_tree_nodes( tree_nodes );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
close_path( canvas_t *canvas )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
free_path();
|
|
Packit |
d394d9 |
path_begin = path_end = NULL;
|
|
Packit |
d394d9 |
redraw_canvas( tree_canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
set_inline_path( canvas_t *canvas, guint action, GtkWidget *item )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
inline_path = GTK_CHECK_MENU_ITEM( item )->active;
|
|
Packit |
d394d9 |
configure_canvas( canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
path_index_option( canvas_t *canvas, guint action, GtkWidget *item )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
path_show_state_indexes = GTK_CHECK_MENU_ITEM( item )->active;
|
|
Packit |
d394d9 |
configure_canvas( canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static GtkItemFactoryEntry path_items[] =
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
{ "/Style/Inline", NULL, set_inline_path, 0, "<ToggleItem>" },
|
|
Packit |
d394d9 |
{ "/Path", NULL, NULL, 0, "<Branch>" },
|
|
Packit |
d394d9 |
{ "/Path/Show State Indexes", NULL, path_index_option, 0, "<ToggleItem>" },
|
|
Packit |
d394d9 |
{ "/End States", NULL, NULL, 0, "<Branch>" },
|
|
Packit |
d394d9 |
{ "/End States/Show First End State", "<Control>F", goto_state, FIRST_STATE,
|
|
Packit |
d394d9 |
NULL },
|
|
Packit |
d394d9 |
{ "/End States/Show Previous End State", "<Control>P", goto_state, PREV_STATE,
|
|
Packit |
d394d9 |
NULL },
|
|
Packit |
d394d9 |
{ "/End States/Show Next End State", "<Control>N", goto_state, NEXT_STATE,
|
|
Packit |
d394d9 |
NULL },
|
|
Packit |
d394d9 |
{ "/End States/Show Last End State", "<Control>L", goto_state, LAST_STATE,
|
|
Packit |
d394d9 |
NULL }
|
|
Packit |
d394d9 |
};
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
display_path( void )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_node_t *tree_node;
|
|
Packit |
d394d9 |
path_node_t *path_node;
|
|
Packit |
d394d9 |
string_t state_index, string;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
free_path();
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Create the path nodes. We go backwards from the path end to the path
|
|
Packit |
d394d9 |
* beginning, since this direction is easier to traverse. */
|
|
Packit |
d394d9 |
for (tree_node = path_end; ; tree_node = tree_node->parent)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_node->in_path = TRUE;
|
|
Packit |
d394d9 |
path_node = new_node( &path_nodes, sizeof( path_node_t ), LIST_START );
|
|
Packit |
d394d9 |
if (path_begin != NULL && tree_node->result_feat != NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
/* Create a new state in the path. */
|
|
Packit |
d394d9 |
state_index = int_to_string( tree_node->state_index );
|
|
Packit |
d394d9 |
string = concat_strings( "State ", state_index, ":", NULL );
|
|
Packit |
d394d9 |
path_node->state_index = new_pos_string( string );
|
|
Packit |
d394d9 |
free_mem( &string );
|
|
Packit |
d394d9 |
free_mem( &state_index );
|
|
Packit |
d394d9 |
path_node->rule_name = new_pos_string( tree_node->rule_name );
|
|
Packit |
d394d9 |
path_node->result_surf = new_pos_string( tree_node->result_surf );
|
|
Packit |
d394d9 |
set_scanner_input( tree_node->result_feat );
|
|
Packit |
d394d9 |
path_node->result_feat = parse_pos_value();
|
|
Packit |
d394d9 |
parse_token( EOF );
|
|
Packit |
d394d9 |
set_scanner_input( NULL );
|
|
Packit |
d394d9 |
path_node->rule_set = new_pos_string( tree_node->rule_set );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (tree_node == path_begin)
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
if (tree_node->link_feat != NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
/* Create a new link in the path. */
|
|
Packit |
d394d9 |
path_node->link_surf = new_pos_string( tree_node->link_surf );
|
|
Packit |
d394d9 |
set_scanner_input( tree_node->link_feat );
|
|
Packit |
d394d9 |
path_node->link_feat = parse_pos_value();
|
|
Packit |
d394d9 |
parse_token( EOF );
|
|
Packit |
d394d9 |
set_scanner_input( NULL );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (path_begin == NULL)
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (path_canvas == NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
path_canvas = create_canvas(
|
|
Packit |
d394d9 |
"Malaga Path", "path.eps", &path_geometry, configure_path, expose_path,
|
|
Packit |
d394d9 |
close_path, NULL, TRUE, path_items, ARRAY_LENGTH( path_items ) );
|
|
Packit |
d394d9 |
path_show_state_indexes = show_state_indexes;
|
|
Packit |
d394d9 |
if (path_show_state_indexes)
|
|
Packit |
d394d9 |
activate_menu_item( path_canvas, "/Path/Show State Indexes" );
|
|
Packit |
d394d9 |
if (inline_path)
|
|
Packit |
d394d9 |
activate_menu_item( path_canvas, "/Style/Inline" );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
configure_canvas( path_canvas );
|
|
Packit |
d394d9 |
show_canvas( path_canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
redraw_canvas( tree_canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
configure_node( canvas_t *canvas, tree_node_t *node, int_t x, int_t y )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t w, node_width;
|
|
Packit |
d394d9 |
tree_node_t *subnode;
|
|
Packit |
d394d9 |
bool_t is_first;
|
|
Packit |
d394d9 |
int_t font_height = get_font_height( canvas );
|
|
Packit |
d394d9 |
int_t space_width = get_space_width( canvas );
|
|
Packit |
d394d9 |
int_t line_width = get_line_width( canvas );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (tree_show_state_indexes && node->state_index != -1)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
config_pos_string( node->pos_state_index, canvas );
|
|
Packit |
d394d9 |
node_width = MAX( node->pos_state_index->width + space_width,
|
|
Packit |
d394d9 |
font_height );
|
|
Packit |
d394d9 |
node->pos_state_index->x
|
|
Packit |
d394d9 |
= x + (node_width - node->pos_state_index->width) / 2;
|
|
Packit |
d394d9 |
node->pos_state_index->y = tree_height - font_height * 3 / 2 + 1;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
node_width = font_height;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
node->x = x + node_width / 2;
|
|
Packit |
d394d9 |
node->y = y;
|
|
Packit |
d394d9 |
x += node_width;
|
|
Packit |
d394d9 |
tree_width = MAX( tree_width, x );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
is_first = TRUE;
|
|
Packit |
d394d9 |
for (subnode = node->child; subnode != NULL; subnode = subnode->sibling)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (tree_mode == NO_DEAD_ENDS && subnode->type == BREAK_NODE)
|
|
Packit |
d394d9 |
continue;
|
|
Packit |
d394d9 |
if (tree_mode == RESULT_PATHS && ! subnode->result_path)
|
|
Packit |
d394d9 |
continue;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (is_first)
|
|
Packit |
d394d9 |
is_first = FALSE;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
tree_height += (5 * font_height) / 2;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
config_pos_string( subnode->pos_link_surf, canvas );
|
|
Packit |
d394d9 |
config_pos_string( subnode->pos_rule_name, canvas );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
w = MAX( subnode->pos_link_surf->width, subnode->pos_rule_name->width );
|
|
Packit |
d394d9 |
w = MAX( w, space_width );
|
|
Packit |
d394d9 |
subnode->pos_link_surf->x = x + (w - subnode->pos_link_surf->width) / 2;
|
|
Packit |
d394d9 |
subnode->pos_link_surf->y = tree_height - font_height - line_width;
|
|
Packit |
d394d9 |
subnode->pos_rule_name->x = x + (w - subnode->pos_rule_name->width) / 2;
|
|
Packit |
d394d9 |
subnode->pos_rule_name->y = tree_height + line_width;
|
|
Packit |
d394d9 |
configure_node( canvas, subnode, x + w, tree_height );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
configure_tree( canvas_t *canvas, int_t *width_p, int_t *height_p )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t font_height = get_font_height( canvas );
|
|
Packit |
d394d9 |
int_t border_width = get_border_width( canvas );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
tree_width = tree_height = border_width;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Configure result surface. */
|
|
Packit |
d394d9 |
config_pos_string( result_surf, canvas );
|
|
Packit |
d394d9 |
result_surf->x = border_width;
|
|
Packit |
d394d9 |
result_surf->y = border_width;
|
|
Packit |
d394d9 |
tree_width = MAX( tree_width, border_width + result_surf->width );
|
|
Packit |
d394d9 |
tree_height += font_height;
|
|
Packit |
d394d9 |
if (tree_mode != RESULT_PATHS || tree_nodes->result_path)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
/* Configure tree. */
|
|
Packit |
d394d9 |
tree_height += 2 * font_height;
|
|
Packit |
d394d9 |
configure_node( canvas, tree_nodes, border_width, tree_height );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Return width and height. */
|
|
Packit |
d394d9 |
*width_p = tree_width + border_width;
|
|
Packit |
d394d9 |
*height_p = tree_height + font_height + border_width;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
expose_node( canvas_t *canvas, tree_node_t *node, int_t font_height )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_node_t *subnode;
|
|
Packit |
d394d9 |
const int_t x = node->x;
|
|
Packit |
d394d9 |
const int_t y = node->y;
|
|
Packit |
d394d9 |
const int_t radius1 = font_height / 2;
|
|
Packit |
d394d9 |
const int_t radius2 = (radius1 * 3) / 5;
|
|
Packit |
d394d9 |
int_t middle = y;
|
|
Packit |
d394d9 |
int_t bottom = y;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Draw all subnodes. */
|
|
Packit |
d394d9 |
for (subnode = node->child; subnode != NULL; subnode = subnode->sibling)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (tree_mode == NO_DEAD_ENDS && subnode->type == BREAK_NODE)
|
|
Packit |
d394d9 |
continue;
|
|
Packit |
d394d9 |
if (tree_mode == RESULT_PATHS && ! subnode->result_path)
|
|
Packit |
d394d9 |
continue;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Draw horizontal line. */
|
|
Packit |
d394d9 |
bottom = subnode->y;
|
|
Packit |
d394d9 |
if (node->in_path && subnode->in_path)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
middle = subnode->y;
|
|
Packit |
d394d9 |
set_color( RED );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
set_color( BLACK );
|
|
Packit |
d394d9 |
draw_lines( 2, x, subnode->y, subnode->x, subnode->y );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (path_begin == NULL && subnode->in_path)
|
|
Packit |
d394d9 |
set_color( RED );
|
|
Packit |
d394d9 |
draw_pos_string( subnode->pos_link_surf, canvas );
|
|
Packit |
d394d9 |
set_color( BLACK );
|
|
Packit |
d394d9 |
draw_pos_string( subnode->pos_rule_name, canvas );
|
|
Packit |
d394d9 |
expose_node( canvas, subnode, font_height );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Draw vertical line. */
|
|
Packit |
d394d9 |
set_color( BLACK );
|
|
Packit |
d394d9 |
draw_lines( 2, x, middle, x, bottom );
|
|
Packit |
d394d9 |
if (middle != y)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
set_color( RED );
|
|
Packit |
d394d9 |
draw_lines( 2, x, y, x, middle );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Draw the node itself. */
|
|
Packit |
d394d9 |
if (node->type == BREAK_NODE)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
set_color( (node->in_path && path_begin != NULL ? RED : BLACK) );
|
|
Packit |
d394d9 |
draw_rectangle( x - radius1 , y - radius1, 2 * radius1, 2 * radius1 );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
set_color( WHITE );
|
|
Packit |
d394d9 |
draw_circle( TRUE, x, y, radius1 );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
set_color( (node->in_path && path_begin != NULL ? RED : BLACK) );
|
|
Packit |
d394d9 |
draw_circle( FALSE, x, y, radius1 );
|
|
Packit |
d394d9 |
if (node->type == FINAL_NODE || node->type == UNFINAL_NODE)
|
|
Packit |
d394d9 |
draw_circle( FALSE, x, y, radius2 );
|
|
Packit |
d394d9 |
if (node->type == PRUNED_NODE || node->type == UNFINAL_NODE)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
draw_lines( 2, x - radius1, y - radius1, x + radius1, y + radius1 );
|
|
Packit |
d394d9 |
draw_lines( 2, x + radius1, y - radius1, x - radius1, y + radius1 );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Draw the state index. */
|
|
Packit |
d394d9 |
if (tree_show_state_indexes && node->state_index != -1)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
set_color( BLUE );
|
|
Packit |
d394d9 |
draw_pos_string( node->pos_state_index, canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
expose_tree( canvas_t *canvas, rectangle_t *area )
|
|
Packit |
d394d9 |
/* Expose AREA on tree CANVAS. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t font_height = get_font_height( canvas );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (result_surf != NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
set_color( BLACK );
|
|
Packit |
d394d9 |
draw_pos_string( result_surf, canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (tree_nodes == NULL)
|
|
Packit |
d394d9 |
return;
|
|
Packit |
d394d9 |
if (tree_mode != RESULT_PATHS || tree_nodes->result_path)
|
|
Packit |
d394d9 |
expose_node( canvas, tree_nodes, font_height );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static bool_t
|
|
Packit |
d394d9 |
in_circle( int_t x, int_t y, int_t circle_x, int_t circle_y, int_t radius )
|
|
Packit |
d394d9 |
/* Return TRUE if position (X,Y) lies in disc with center (CIRCLE_X, CIRCLE_Y)
|
|
Packit |
d394d9 |
* and RADIUS. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t diff_x = x - circle_x;
|
|
Packit |
d394d9 |
int_t diff_y = y - circle_y;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Taking DIFF_X or DIFF_Y to the 2nd power may result in an overflow,
|
|
Packit |
d394d9 |
* so we will check first whether DIFF_X and DIFF_Y are small enough. */
|
|
Packit |
d394d9 |
return (ABS( diff_x ) < radius && ABS( diff_y ) < radius
|
|
Packit |
d394d9 |
&& diff_x * diff_x + diff_y * diff_y <= radius * radius);
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static bool_t
|
|
Packit |
d394d9 |
in_pos_string( int_t x, int_t y, pos_string_t *pos_string, int_t height )
|
|
Packit |
d394d9 |
/* Return TRUE if position (X,Y) lies in bounding box of POS_STRING, using font
|
|
Packit |
d394d9 |
* height HEIGHT. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
return (x >= pos_string->x
|
|
Packit |
d394d9 |
&& x < pos_string->x + pos_string->width
|
|
Packit |
d394d9 |
&& y >= pos_string->y
|
|
Packit |
d394d9 |
&& y < pos_string->y + height);
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static bool_t
|
|
Packit |
d394d9 |
in_rectangle( int_t x, int_t y,
|
|
Packit |
d394d9 |
int_t rect_x, int_t rect_y, int_t width, int_t height )
|
|
Packit |
d394d9 |
/* Return TRUE if position (X,Y) lies in rectangle with upper left corner
|
|
Packit |
d394d9 |
* (RECT_X, RECT_Y), width WIDTH and height HEIGHT. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
return (x >= rect_x
|
|
Packit |
d394d9 |
&& x <= rect_x + width
|
|
Packit |
d394d9 |
&& y >= rect_y
|
|
Packit |
d394d9 |
&& y <= rect_y + height);
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
set_tree( canvas_t *canvas, guint mode )
|
|
Packit |
d394d9 |
/* Set the tree's display mode to MODE. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_mode = mode;
|
|
Packit |
d394d9 |
if (path_end != NULL
|
|
Packit |
d394d9 |
&& ((tree_mode == NO_DEAD_ENDS && path_end->type == BREAK_NODE)
|
|
Packit |
d394d9 |
|| (tree_mode == RESULT_PATHS && ! path_end->result_path)))
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
hide_canvas( path_canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
configure_canvas( tree_canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
goto_state( canvas_t *canvas, guint action )
|
|
Packit |
d394d9 |
/* Display a certain state, according to ACTION, in the path window. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t i = 0;
|
|
Packit |
d394d9 |
bool_t inverse = FALSE; /* TRUE if we search in inverse direction. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (action == FIRST_STATE || action == LAST_STATE
|
|
Packit |
d394d9 |
|| (path_begin != NULL && path_begin->type == FINAL_NODE))
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
switch (action)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
case FIRST_STATE:
|
|
Packit |
d394d9 |
i = 0;
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
case PREV_STATE:
|
|
Packit |
d394d9 |
i = path_begin->state_index - 1;
|
|
Packit |
d394d9 |
inverse = TRUE;
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
case NEXT_STATE:
|
|
Packit |
d394d9 |
i = path_begin->state_index + 1;
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
case LAST_STATE:
|
|
Packit |
d394d9 |
i = state_count - 1;
|
|
Packit |
d394d9 |
inverse = TRUE;
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
while (i >= 0 && i < state_count)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (states[i] != NULL && states[i]->type == FINAL_NODE)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
path_begin = path_end = states[i];
|
|
Packit |
d394d9 |
make_visible( tree_canvas, path_begin->x, path_begin->y );
|
|
Packit |
d394d9 |
display_path();
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (inverse)
|
|
Packit |
d394d9 |
i--;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
i++;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static tree_node_t *
|
|
Packit |
d394d9 |
tree_node_at_position( tree_node_t *node, int_t x, int_t y, int_t font_height,
|
|
Packit |
d394d9 |
element_t *element_p)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_node_t *subnode;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (node == NULL)
|
|
Packit |
d394d9 |
return NULL;
|
|
Packit |
d394d9 |
for (; node != NULL; node = node->sibling)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (tree_mode == NO_DEAD_ENDS && node->type == BREAK_NODE)
|
|
Packit |
d394d9 |
continue;
|
|
Packit |
d394d9 |
if (tree_mode == RESULT_PATHS && ! node->result_path)
|
|
Packit |
d394d9 |
continue;
|
|
Packit |
d394d9 |
if ((node->type == BREAK_NODE
|
|
Packit |
d394d9 |
&& in_rectangle( x, y,
|
|
Packit |
d394d9 |
node->x - font_height / 2, node->y - font_height / 2,
|
|
Packit |
d394d9 |
font_height, font_height ))
|
|
Packit |
d394d9 |
|| (node->type != BREAK_NODE
|
|
Packit |
d394d9 |
&& in_circle( x, y, node->x, node->y, font_height / 2 ) ))
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
*element_p = ELEMENT_NODE;
|
|
Packit |
d394d9 |
return node;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (in_pos_string( x, y, node->pos_link_surf, font_height ))
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
*element_p = ELEMENT_LINK;
|
|
Packit |
d394d9 |
return node;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (in_pos_string( x, y, node->pos_rule_name, font_height ))
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
*element_p = ELEMENT_RULE;
|
|
Packit |
d394d9 |
return node;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
subnode = tree_node_at_position( node->child, x, y, font_height,
|
|
Packit |
d394d9 |
element_p );
|
|
Packit |
d394d9 |
if (subnode != NULL)
|
|
Packit |
d394d9 |
return subnode;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
return NULL;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
display_node( canvas_t *canvas, guint action )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_node_t *node;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (action == PATH_BEGIN)
|
|
Packit |
d394d9 |
path_begin = popup_menu_node;
|
|
Packit |
d394d9 |
else if (action == FROM_ROOT)
|
|
Packit |
d394d9 |
path_begin = tree_nodes;
|
|
Packit |
d394d9 |
if (action == PATH_END || action == FROM_ROOT)
|
|
Packit |
d394d9 |
path_end = popup_menu_node;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Check whether there is a part from PATH_BEGIN to PATH_END. */
|
|
Packit |
d394d9 |
node = path_end;
|
|
Packit |
d394d9 |
while (node != NULL && node != path_begin)
|
|
Packit |
d394d9 |
node = node->parent;
|
|
Packit |
d394d9 |
if (node == NULL)
|
|
Packit |
d394d9 |
path_begin = path_end = popup_menu_node;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
display_path();
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static bool_t
|
|
Packit |
d394d9 |
mouse_event( canvas_t *canvas, int_t x, int_t y, int_t button )
|
|
Packit |
d394d9 |
/* Called if mouse has moved to position (X,Y). */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_node_t *node;
|
|
Packit |
d394d9 |
element_t element;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
node = tree_node_at_position( tree_nodes, x, y, get_font_height( canvas ),
|
|
Packit |
d394d9 |
&element );
|
|
Packit |
d394d9 |
if (node == NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
set_cursor( canvas, FALSE );
|
|
Packit |
d394d9 |
return FALSE;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* No button pressed: we should just update the cursor. */
|
|
Packit |
d394d9 |
if (button == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
set_cursor( canvas, TRUE );
|
|
Packit |
d394d9 |
return TRUE;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
switch (element)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
case ELEMENT_NODE:
|
|
Packit |
d394d9 |
if (button == 1)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
path_begin = path_end = node;
|
|
Packit |
d394d9 |
display_path();
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else if (button == 3)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
popup_menu_node = node;
|
|
Packit |
d394d9 |
popup_menu( canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
case ELEMENT_LINK:
|
|
Packit |
d394d9 |
path_begin = NULL;
|
|
Packit |
d394d9 |
path_end = node;
|
|
Packit |
d394d9 |
display_path();
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
case ELEMENT_RULE:
|
|
Packit |
d394d9 |
path_begin = node->parent;
|
|
Packit |
d394d9 |
path_end = node;
|
|
Packit |
d394d9 |
display_path();
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
return TRUE;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
tree_index_option( canvas_t *canvas, guint action, GtkWidget *item )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_show_state_indexes = GTK_CHECK_MENU_ITEM( item )->active;
|
|
Packit |
d394d9 |
configure_canvas( canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static GtkItemFactoryEntry tree_items[] =
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
{ "/Tree", NULL, NULL, 0, "<Branch>" },
|
|
Packit |
d394d9 |
{ "/Tree/Full Tree", NULL, set_tree, FULL_TREE, "<RadioItem>" },
|
|
Packit |
d394d9 |
{ "/Tree/No Dead Ends", NULL, set_tree, NO_DEAD_ENDS, "/Tree/Full Tree" },
|
|
Packit |
d394d9 |
{ "/Tree/Complete Paths", NULL, set_tree, RESULT_PATHS, "/Tree/Full Tree" },
|
|
Packit |
d394d9 |
{ "/Tree/sep1", NULL, NULL, 0, "<Separator>" },
|
|
Packit |
d394d9 |
{ "/Tree/Show State Indexes", NULL, tree_index_option, 0, "<ToggleItem>" },
|
|
Packit |
d394d9 |
{ "/End States", NULL, NULL, 0, "<Branch>" },
|
|
Packit |
d394d9 |
{ "/End States/Show First End State", "<Control>F", goto_state, FIRST_STATE,
|
|
Packit |
d394d9 |
NULL },
|
|
Packit |
d394d9 |
{ "/End States/Show Previous End State", "<Control>P", goto_state, PREV_STATE,
|
|
Packit |
d394d9 |
NULL },
|
|
Packit |
d394d9 |
{ "/End States/Show Next End State", "<Control>N", goto_state, NEXT_STATE,
|
|
Packit |
d394d9 |
NULL },
|
|
Packit |
d394d9 |
{ "/End States/Show Last End State", "<Control>L", goto_state, LAST_STATE,
|
|
Packit |
d394d9 |
NULL }
|
|
Packit |
d394d9 |
};
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static GtkItemFactoryEntry popup_items[] =
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
{ "/Set Path Begin", NULL, display_node, PATH_BEGIN, "<Item>" },
|
|
Packit |
d394d9 |
{ "/Set Path End", NULL, display_node, PATH_END, "<Item>" },
|
|
Packit |
d394d9 |
{ "/Show Path From Root", NULL, display_node, FROM_ROOT, "<Item>" }
|
|
Packit |
d394d9 |
};
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
free_tree_nodes( tree_node_t *node )
|
|
Packit |
d394d9 |
/* Free *NODE_P and all its siblings and children. Set *NODE_P to NULL. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_node_t *next;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
for (; node != NULL; node = next)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
/* Remove node from state index. */
|
|
Packit |
d394d9 |
if (node->state_index != -1)
|
|
Packit |
d394d9 |
states[ node->state_index ] = NULL;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
free_tree_nodes( node->child );
|
|
Packit |
d394d9 |
free_mem( &node->rule_name );
|
|
Packit |
d394d9 |
free_mem( &node->link_surf );
|
|
Packit |
d394d9 |
free_mem( &node->link_feat );
|
|
Packit |
d394d9 |
free_mem( &node->result_surf );
|
|
Packit |
d394d9 |
free_mem( &node->result_feat );
|
|
Packit |
d394d9 |
free_mem( &node->rule_set );
|
|
Packit |
d394d9 |
free_pos_string( &node->pos_link_surf );
|
|
Packit |
d394d9 |
free_pos_string( &node->pos_rule_name );
|
|
Packit |
d394d9 |
free_pos_string( &node->pos_state_index );
|
|
Packit |
d394d9 |
next = node->sibling;
|
|
Packit |
d394d9 |
free( node );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
free_tree( void )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
/* Clear old variables. */
|
|
Packit |
d394d9 |
free_pos_string( &result_surf );
|
|
Packit |
d394d9 |
free_pos_string( &plus );
|
|
Packit |
d394d9 |
free_pos_string( &comma );
|
|
Packit |
d394d9 |
free_tree_nodes( tree_nodes );
|
|
Packit |
d394d9 |
tree_nodes = NULL;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
close_tree( canvas_t *canvas )
|
|
Packit |
d394d9 |
/* Called by "canvas.c" when CANVAS gets hidden. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (path_canvas != NULL)
|
|
Packit |
d394d9 |
hide_canvas( path_canvas );
|
|
Packit |
d394d9 |
free_tree();
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
void
|
|
Packit |
d394d9 |
read_tree( void )
|
|
Packit |
d394d9 |
/* Read new tree from STDIN. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
string_t line; /* A line of input from STDIN. */
|
|
Packit |
d394d9 |
string_t line_p; /* Part of LINE which is yet to parse. */
|
|
Packit |
d394d9 |
string_t type; /* Node type. */
|
|
Packit |
d394d9 |
string_t state_index;
|
|
Packit |
d394d9 |
tree_node_t *node;
|
|
Packit |
d394d9 |
int_t parent_state_index, i;
|
|
Packit |
d394d9 |
tree_node_t **node_p;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (path_canvas != NULL)
|
|
Packit |
d394d9 |
hide_canvas( path_canvas );
|
|
Packit |
d394d9 |
free_tree();
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Allocate new nodes array. */
|
|
Packit |
d394d9 |
if (state_count == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
state_count = 100;
|
|
Packit |
d394d9 |
states = new_vector( sizeof( tree_node_t * ), state_count );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Read new input surface. */
|
|
Packit |
d394d9 |
line = read_line( stdin );
|
|
Packit |
d394d9 |
result_surf = new_pos_string( line );
|
|
Packit |
d394d9 |
free_mem( &line );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Read new tree. */
|
|
Packit |
d394d9 |
while (TRUE)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
line = read_line( stdin );
|
|
Packit |
d394d9 |
if (line == NULL)
|
|
Packit |
d394d9 |
complain( "Premature EOF." );
|
|
Packit |
d394d9 |
if (strcmp_no_case( line, "end" ) == 0)
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
node = new_mem( sizeof( tree_node_t ) );
|
|
Packit |
d394d9 |
line_p = line;
|
|
Packit |
d394d9 |
node->state_index = parse_int( &line_p );
|
|
Packit |
d394d9 |
type = parse_word( &line_p );
|
|
Packit |
d394d9 |
if (strcmp_no_case( type, "inter" ) == 0)
|
|
Packit |
d394d9 |
node->type = INTER_NODE;
|
|
Packit |
d394d9 |
else if (strcmp_no_case( type, "break" ) == 0)
|
|
Packit |
d394d9 |
node->type = BREAK_NODE;
|
|
Packit |
d394d9 |
else if (strcmp_no_case( type, "final" ) == 0)
|
|
Packit |
d394d9 |
node->type = FINAL_NODE;
|
|
Packit |
d394d9 |
else if (strcmp_no_case( type, "unfinal" ) == 0)
|
|
Packit |
d394d9 |
node->type = UNFINAL_NODE;
|
|
Packit |
d394d9 |
else if (strcmp_no_case( type, "pruned" ) == 0)
|
|
Packit |
d394d9 |
node->type = PRUNED_NODE;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
complain( "Unknown node type \"%s\".", type );
|
|
Packit |
d394d9 |
free_mem( &type );
|
|
Packit |
d394d9 |
parent_state_index = parse_int( &line_p );
|
|
Packit |
d394d9 |
node->rule_name = parse_word( &line_p );
|
|
Packit |
d394d9 |
node->link_surf = parse_optional_value( &line_p );
|
|
Packit |
d394d9 |
node->link_feat = parse_optional_value( &line_p );
|
|
Packit |
d394d9 |
node->result_surf = parse_optional_value( &line_p );
|
|
Packit |
d394d9 |
node->result_feat = parse_optional_value( &line_p );
|
|
Packit |
d394d9 |
node->rule_set = parse_word( &line_p );
|
|
Packit |
d394d9 |
parse_end( &line_p );
|
|
Packit |
d394d9 |
free_mem( &line );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
node->pos_link_surf = new_pos_string( node->link_surf );
|
|
Packit |
d394d9 |
node->pos_rule_name = new_pos_string( node->rule_name );
|
|
Packit |
d394d9 |
if (node->state_index != -1)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
state_index = int_to_string( node->state_index );
|
|
Packit |
d394d9 |
node->pos_state_index = new_pos_string( state_index );
|
|
Packit |
d394d9 |
free_mem( &state_index );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Find parent node. */
|
|
Packit |
d394d9 |
if (parent_state_index == -1)
|
|
Packit |
d394d9 |
tree_nodes = node; /* This is the root node. */
|
|
Packit |
d394d9 |
else if (parent_state_index < 0 || parent_state_index >= state_count
|
|
Packit |
d394d9 |
|| states[ parent_state_index ] == NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
complain( "Display data corrupted." );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
node->parent = states[ parent_state_index ];
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Add NODE to be a child of NODE->PARENT. */
|
|
Packit |
d394d9 |
node_p = &node->parent->child;
|
|
Packit |
d394d9 |
while (*node_p != NULL)
|
|
Packit |
d394d9 |
node_p = &(*node_p)->sibling;
|
|
Packit |
d394d9 |
*node_p = node;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Add node to the STATES array. */
|
|
Packit |
d394d9 |
if (node->state_index >= state_count)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
renew_vector( &states, sizeof( tree_node_t * ), 2 * node->state_index );
|
|
Packit |
d394d9 |
for (i = state_count; i < 2 * node->state_index; i++)
|
|
Packit |
d394d9 |
states[i] = NULL;
|
|
Packit |
d394d9 |
state_count = 2 * node->state_index;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (node->state_index != -1)
|
|
Packit |
d394d9 |
states[ node->state_index ] = node;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* If this is a final node, mark it and all its predecessors. */
|
|
Packit |
d394d9 |
if (node->type == FINAL_NODE)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
for (; node != NULL; node = node->parent)
|
|
Packit |
d394d9 |
node->result_path = TRUE;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
free_mem( &line );
|
|
Packit |
d394d9 |
if (tree_nodes == NULL)
|
|
Packit |
d394d9 |
complain( "Missing root node in tree." );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
plus = new_pos_string( "+" );
|
|
Packit |
d394d9 |
comma = new_pos_string( "," );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (tree_canvas == NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
tree_canvas = create_canvas(
|
|
Packit |
d394d9 |
"Malaga Tree", "tree.eps", &tree_geometry, configure_tree, expose_tree,
|
|
Packit |
d394d9 |
close_tree, mouse_event, FALSE, tree_items, ARRAY_LENGTH( tree_items ) );
|
|
Packit |
d394d9 |
set_popup_menu( tree_canvas, popup_items, ARRAY_LENGTH( popup_items ) );
|
|
Packit |
d394d9 |
tree_show_state_indexes = show_state_indexes;
|
|
Packit |
d394d9 |
if (tree_show_state_indexes )
|
|
Packit |
d394d9 |
activate_menu_item( tree_canvas, "/Tree/Show State Indexes" );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
configure_canvas( tree_canvas );
|
|
Packit |
d394d9 |
show_canvas( tree_canvas );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* End of file. =============================================================*/
|