#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/Xutil.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/Toggle.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Tree.h>
#include "editresP.h"
static void AddNodeToActiveList ( WNode * node );
static void RemoveNodeFromActiveList ( WNode * node );
static Boolean IsActiveNode ( WNode * node );
static void AddNode ( WNode ** top_node, WidgetTreeInfo * info,
TreeInfo * tree_info );
static void FillNode ( WidgetTreeInfo * info, WNode * node,
TreeInfo * tree_info );
static void AddChild ( WNode * parent, WNode * child );
static WNode ** CopyActiveNodes ( TreeInfo * tree_info );
void
BuildVisualTree(tree_parent, event)
Widget tree_parent;
Event * event;
{
WNode * top;
char msg[BUFSIZ];
if (global_tree_info != NULL) {
XtDestroyWidget(global_tree_info->tree_widget);
XtFree((char *)global_tree_info->active_nodes);
XtFree((char *)global_tree_info);
}
global_tree_info = CreateTree(event);
top = global_tree_info->top_node;
global_tree_info->tree_widget = XtCreateWidget("tree", treeWidgetClass,
tree_parent, NULL, ZERO);
if (top == NULL) {
SetMessage(global_screen_data.info_label,
res_labels[27]);
return;
}
AddTreeNode(global_tree_info->tree_widget, top);
if (XtIsRealized(tree_parent))
XtRealizeWidget(global_tree_info->tree_widget);
XtManageChild(global_tree_info->tree_widget);
sprintf(msg, res_labels[11], top->name, top->class);
SetMessage(global_screen_data.info_label, msg);
}
void
AddTreeNode(tree, top)
Widget tree;
WNode * top;
{
int i;
Arg args[1];
Cardinal num_args = 0;
char msg[BUFSIZ];
if (top->parent != NULL) {
if (top->parent->widget == NULL) {
sprintf( msg, res_labels[28],
top->name, top->parent->name, "not been created yet");
SetMessage(global_screen_data.info_label, msg);
}
XtSetArg(args[num_args], XtNtreeParent, top->parent->widget);
num_args++;
}
top->widget = XtCreateManagedWidget(top->name, toggleWidgetClass, tree,
args, num_args);
if (XSaveContext(XtDisplay(top->widget), (Window) top->widget,
NODE_INFO, (XPointer) top) != 0) {
sprintf( msg, res_labels[29], top->name);
SetMessage(global_screen_data.info_label, msg);
}
XtAddCallback(top->widget, XtNcallback, TreeToggle, (XtPointer) top);
for (i = 0; i < top->num_children; i++)
AddTreeNode(tree, top->children[i]);
}
void
TreeToggle(w, node_ptr, state_ptr)
Widget w;
XtPointer node_ptr, state_ptr;
{
Boolean state = (Boolean)(long) state_ptr;
WNode * node = (WNode *) node_ptr;
if (state)
AddNodeToActiveList(node);
else
RemoveNodeFromActiveList(node);
}
static void
AddNodeToActiveList(node)
WNode * node;
{
TreeInfo * info = node->tree_info;
if (IsActiveNode(node))
return;
if (info->num_nodes >= info->alloc_nodes) {
info->alloc_nodes += NUM_INC;
info->active_nodes =(WNode **)XtRealloc((XtPointer) info->active_nodes,
sizeof(WNode *) *
info->alloc_nodes);
}
info->active_nodes[info->num_nodes++] = node;
}
static void
RemoveNodeFromActiveList(node)
WNode * node;
{
TreeInfo * info = node->tree_info;
Boolean found_node = FALSE;
int i;
if (!IsActiveNode(node))
return;
for (i = 0; i < info->num_nodes; i++) {
if (found_node)
info->active_nodes[i - 1] = info->active_nodes[i];
else if (info->active_nodes[i] == node)
found_node = TRUE;
}
info->num_nodes--;
}
static Boolean
IsActiveNode(node)
WNode * node;
{
TreeInfo * info = node->tree_info;
int i;
for (i = 0; i < info->num_nodes; i++)
if (info->active_nodes[i] == node)
return(TRUE);
return(FALSE);
}
TreeInfo *
CreateTree(event)
Event * event;
{
SendWidgetTreeEvent * send_event = (SendWidgetTreeEvent *) event;
int i;
TreeInfo * tree_info;
tree_info = (TreeInfo *) XtMalloc( (Cardinal) sizeof(TreeInfo));
tree_info->tree_widget = NULL;
tree_info->top_node = NULL;
tree_info->active_nodes = NULL;
tree_info->num_nodes = tree_info->alloc_nodes = 0;
tree_info->flash_widgets = NULL;
tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
for ( i = 0; i < (int)send_event->num_entries; i++)
AddNode(&(tree_info->top_node), (send_event->info + i), tree_info);
return(tree_info);
}
void
PrintNodes(top)
WNode * top;
{
int i;
if (top->parent == NULL)
printf("Top of Tree, Name: %10s, ID: %10ld, Class: %10s\n",
top->name, top->id, top->class);
else
printf("Parent %10s, Name: %10s, ID: %10ld, Class: %10s\n",
top->parent->name, top->name, top->id, top->class);
for (i = 0; i < top->num_children; i++)
PrintNodes(top->children[i]);
}
void
_TreeRelabel(tree_info, type)
TreeInfo * tree_info;
LabelTypes type;
{
WNode * top;
if (tree_info == NULL) {
SetMessage(global_screen_data.info_label,
res_labels[17]);
return;
}
top = tree_info->top_node;
PrepareToLayoutTree(tree_info->tree_widget);
_TreeRelabelNode(top, type, TRUE);
LayoutTree(tree_info->tree_widget);
}
void
_TreeSelect(TreeInfo *tree_info, SelectTypes type)
{
WNode ** active_nodes;
Cardinal num_active_nodes;
int i;
if (tree_info == NULL) {
SetMessage(global_screen_data.info_label,
res_labels[17]);
return;
}
switch(type) {
case SelectNone:
case SelectAll:
case SelectInvert:
_TreeSelectNode(tree_info->top_node, type, TRUE);
return;
default:
break;
}
if (tree_info->num_nodes == 0) {
SetMessage(global_screen_data.info_label,
res_labels[18]);
return;
}
active_nodes = CopyActiveNodes(tree_info);
num_active_nodes = tree_info->num_nodes;
for (i = 0; i < num_active_nodes; i++)
_TreeActivateNode(active_nodes[i], type);
XtFree((XtPointer) active_nodes);
}
void
_TreeSelectNode(WNode *node, SelectTypes type, Boolean recurse)
{
int i;
Arg args[1];
Boolean state;
switch(type) {
case SelectAll:
state = TRUE;
break;
case SelectNone:
state = FALSE;
break;
case SelectInvert:
XtSetArg(args[0], XtNstate, &state);
XtGetValues(node->widget, args, ONE);
state = !state;
break;
default:
SetMessage(global_screen_data.info_label,
res_labels[16]);
return;
}
XtSetArg(args[0], XtNstate, state);
XtSetValues(node->widget, args, ONE);
TreeToggle(node->widget, (XtPointer) node, (XtPointer)(long) state);
if (!recurse)
return;
for (i = 0; i < node->num_children; i++)
_TreeSelectNode(node->children[i], type, recurse);
}
void
_TreeRelabelNode(WNode *node, LabelTypes type, Boolean recurse)
{
int i;
Arg args[1];
char buf[30];
char *label;
switch(type) {
case ClassLabel:
XtSetArg(args[0], XtNlabel, node->class);
break;
case NameLabel:
XtSetArg(args[0], XtNlabel, node->name);
break;
case IDLabel:
sprintf(buf, "id: 0x%lx", node->id);
XtSetArg(args[0], XtNlabel, buf);
break;
case WindowLabel:
if (node->window == EDITRES_IS_UNREALIZED)
strcpy(buf, "unrealized widget");
else if (node->window == EDITRES_IS_OBJECT)
strcpy(buf, "non windowed object");
else
sprintf(buf, "win: 0x%lx", node->window);
XtSetArg(args[0], XtNlabel, buf);
break;
case ToggleLabel:
XtSetArg(args[0], XtNlabel, &label);
XtGetValues(node->widget, args, ONE);
if (label && !strcmp(label, node->name))
XtSetArg(args[0], XtNlabel, node->class);
else
XtSetArg(args[0], XtNlabel, node->name);
break;
default:
SetMessage(global_screen_data.info_label,
res_labels[32]);
return;
}
XtSetValues(node->widget, args, ONE);
if (!recurse)
return;
for (i = 0; i < node->num_children; i++)
_TreeRelabelNode(node->children[i], type, recurse);
}
void
_TreeActivateNode(node, type)
WNode * node;
SelectTypes type;
{
Arg args[1];
int i;
XtSetArg(args[0], XtNstate, TRUE);
if ((type == SelectParent) || (type == SelectAncestors)) {
node = node->parent;
if (node == NULL)
return;
XtSetValues(node->widget, args, ONE);
AddNodeToActiveList(node);
if (type == SelectAncestors)
_TreeActivateNode(node, type);
}
else if ((type == SelectChildren) || (type == SelectDescendants))
for (i = 0; i < node->num_children; i++) {
AddNodeToActiveList(node->children[i]);
XtSetValues(node->children[i]->widget, args, ONE);
if (type == SelectDescendants)
_TreeActivateNode(node->children[i], type);
}
else
SetMessage(global_screen_data.info_label,
res_labels[33]);
}
static void
AddNode(top_node, info, tree_info)
WNode ** top_node;
WidgetTreeInfo * info;
TreeInfo * tree_info;
{
WNode *node, *parent;
Boolean early_break = FALSE;
Cardinal number = info->widgets.num_widgets;
if ( (node = FindNode(*top_node, info->widgets.ids, number)) == NULL) {
node = (WNode *) XtCalloc(sizeof(WNode), ONE);
node->id = info->widgets.ids[number - 1];
FillNode(info, node, tree_info);
for ( number--; number > 0; number--, node = parent) {
parent = FindNode(*top_node, info->widgets.ids, number);
if (parent == NULL) {
parent = (WNode *) XtCalloc(sizeof(WNode), ONE);
parent->id = info->widgets.ids[number - 1];
}
else
early_break = TRUE;
AddChild(parent, node);
if (early_break)
break;
}
if (!early_break) {
if (node->parent == NULL)
*top_node = node;
else
*top_node = node->parent;
}
}
else
FillNode(info, node, tree_info);
}
static void
FillNode(info, node, tree_info)
WidgetTreeInfo * info;
WNode * node;
TreeInfo * tree_info;
{
node->class = info->class;
info->class = NULL;
node->name = info->name;
info->name = NULL;
node->window = info->window;
node->tree_info = tree_info;
}
static void
AddChild(parent, child)
WNode * parent, * child;
{
if (parent->num_children >= parent->alloc_children) {
parent->alloc_children += NUM_INC;
parent->children = (WNode **) XtRealloc((char *)parent->children,
sizeof(WNode *) * parent->alloc_children);
}
parent->children[parent->num_children] = child;
(parent->num_children)++;
child->parent = parent;
}
static WNode **
CopyActiveNodes(tree_info)
TreeInfo * tree_info;
{
WNode ** list;
int i;
if ( (tree_info == NULL) || (tree_info->num_nodes == 0))
return(NULL);
list = (WNode **) XtMalloc(sizeof(WNode *) * tree_info->num_nodes);
for (i = 0; i < tree_info->num_nodes; i++)
list[i] = tree_info->active_nodes[i];
return(list);
}
void
SetAndCenterTreeNode(node)
WNode * node;
{
Arg args[5];
Cardinal num_args;
Position node_x, node_y;
Dimension port_width, port_height;
Dimension node_width, node_height, node_bw;
_TreeSelect(node->tree_info, SelectNone);
_TreeSelectNode(node, SelectAll, FALSE);
num_args = 0;
XtSetArg(args[num_args], XtNwidth, &port_width); num_args++;
XtSetArg(args[num_args], XtNheight, &port_height); num_args++;
XtGetValues(XtParent(node->tree_info->tree_widget), args, num_args);
num_args = 0;
XtSetArg(args[num_args], XtNwidth, &node_width); num_args++;
XtSetArg(args[num_args], XtNheight, &node_height); num_args++;
XtSetArg(args[num_args], XtNborderWidth, &node_bw); num_args++;
XtSetArg(args[num_args], XtNx, &node_x); num_args++;
XtSetArg(args[num_args], XtNy, &node_y); num_args++;
XtGetValues(node->widget, args, num_args);
node_x = port_width/2 - (node_x + node_width/2 + node_bw);
node_y = port_height/2 - (node_y + node_height/2 + node_bw);
num_args = 0;
XtSetArg(args[num_args], XtNx, node_x); num_args++;
XtSetArg(args[num_args], XtNy, node_y); num_args++;
XtSetValues(node->tree_info->tree_widget, args, num_args);
}
void
PerformTreeToFileDump(node, num_tabs, fp)
WNode * node;
int num_tabs;
FILE * fp;
{
int i;
for (i = 0; i < num_tabs; i++)
fprintf(fp, "\t");
fprintf(fp, "%s %s\n", node->class, node->name);
num_tabs++;
for (i = 0; i < node->num_children; i++)
PerformTreeToFileDump(node->children[i], num_tabs, fp);
}