home *** CD-ROM | disk | FTP | other *** search
- /*
- * $XConsortium: wtree.c,v 1.13 91/07/09 12:08:53 rws Exp $
- *
- * Copyright 1989 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #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"
-
- extern ScreenData global_screen_data;
- extern void SetMessage();
-
- static Boolean IsActiveNode();
- static void AddChild(), FillNode();
- static void AddNode();
- static void AddNodeToActiveList(), RemoveNodeFromActiveList();
-
- extern void PrepareToLayoutTree(), LayoutTree();
-
- extern void _TreeSelectNode(), _TreeActivateNode(), _TreeRelabelNode();
- static WNode ** CopyActiveNodes();
-
- void TreeToggle();
-
- /* Function Name: BuildVisualTree
- * Description: Creates the Tree and shows it.
- * Arguments: tree_parent - parent of the tree widget.
- * event - the event that caused this action.
- * Returns: none.
- */
-
- /* ARGSUSED */
- void
- BuildVisualTree(tree_parent, event)
- Widget tree_parent;
- Event * event;
- {
- WNode * top;
- TreeInfo *CreateTree();
- void AddTreeNode();
- 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,
- "There is no widget tree to display.");
- return;
- }
-
- AddTreeNode(global_tree_info->tree_widget, top);
-
- if (XtIsRealized(tree_parent)) /* hack around problems in Xt. */
- XtRealizeWidget(global_tree_info->tree_widget);
-
- XtManageChild(global_tree_info->tree_widget);
-
- sprintf(msg, "Widget Tree for client %s(%s).", top->name, top->class);
- SetMessage(global_screen_data.info_label, msg);
- }
-
- /* Function Name: AddTreeNode
- * Description: Adds all nodes below this to the Tree widget.
- * Arguments: parent - parent of the tree widget.
- * top - the top node of the tree.
- * Returns: the tree widget.
- *
- * NOTE: This is a recursive function.
- */
-
- 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, "Loop in tree: node %s's parent (%s) has %s.\n",
- 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, (caddr_t) top) != 0) {
- sprintf( msg, "XSaveContext failed on widget %s.", 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]);
- }
-
- /* Function Name: TreeToggle
- * Description: Called whenever a tree node is toggled.
- * Arguments: w - the tree widget.
- * node_ptr - pointer to this node's information.
- * state_ptr - state of the toggle.
- * Returns: none.
- */
-
- /* ARGSUSED */
- void
- TreeToggle(w, node_ptr, state_ptr)
- Widget w;
- caddr_t node_ptr, state_ptr;
- {
- Boolean state = (Boolean) state_ptr;
- WNode * node = (WNode *) node_ptr;
-
- if (state)
- AddNodeToActiveList(node);
- else
- RemoveNodeFromActiveList(node);
- }
-
- /* Function Name: AddNodeToActiveList
- * Description: Adds this node to the list of active toggles.
- * Arguments: node - node to add.
- * Returns: none.
- */
-
- static void
- AddNodeToActiveList(node)
- WNode * node;
- {
- TreeInfo * info = node->tree_info;
-
- if (IsActiveNode(node)) /* node already active. */
- 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;
- }
-
- /* Function Name: RemoveNodeFromActiveList
- * Description: Removes a node from the active list.
- * Arguments: node - node to remove.
- * Returns: none.
- */
-
- static void
- RemoveNodeFromActiveList(node)
- WNode * node;
- {
- TreeInfo * info = node->tree_info;
- Boolean found_node = FALSE;
- int i;
-
- if (!IsActiveNode(node)) /* This node is not active. */
- 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--;
- }
-
- /* Function Name: IsActiveNode
- * Description: returns TRUE is this node is on the active list.
- * Arguments: node - node to check.
- * Returns: see above.
- */
-
- 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);
- }
-
- /* Function Name: CreateTree
- * Description: Creates a widget tree give a list of names and classes.
- * Arguments: event - the information from the client.
- * Returns: The tree_info about this new tree.
- */
-
- 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);
- }
-
- /* Function Name: PrintNodes
- * Description: Prints all nodes.
- * Arguments: top - the top node.
- * Returns: none.
- */
-
- 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]);
- }
-
- /* Function Name: _TreeRelabel
- * Description: Modifies the selected elements of the tree
- * Arguments: tree_info - the tree we are working on.
- * type - type of selection to perform
- * Returns: none.
- */
-
- void
- _TreeRelabel(tree_info, type)
- TreeInfo * tree_info;
- LabelTypes type;
- {
- WNode * top;
-
- if (tree_info == NULL) {
- SetMessage(global_screen_data.info_label,
- "No widget Tree is avaliable.");
- return;
- }
-
- top = tree_info->top_node;
-
- PrepareToLayoutTree(tree_info->tree_widget);
- _TreeRelabelNode(top, type, TRUE);
- LayoutTree(tree_info->tree_widget);
- }
-
- /* Function Name: _TreeSelect
- * Description: Activates relatives of the active nodes, as specified
- * by type, or Selects all nodes as specified by type.
- * Arguments: tree_info - information about the tree to work on.
- * type - type of activate to invode.
- * Returns: none.
- */
-
- void
- _TreeSelect(tree_info, type)
- TreeInfo * tree_info;
- SelectTypes type;
- {
- WNode ** active_nodes;
- Cardinal num_active_nodes;
- int i;
-
- if (tree_info == NULL) {
- SetMessage(global_screen_data.info_label,
- "No widget Tree is avaliable.");
- return;
- }
-
- switch(type) {
- case SelectNone:
- case SelectAll:
- case SelectInvert:
- _TreeSelectNode(tree_info->top_node, type, TRUE);
- return;
- default:
- break; /* otherwise continue. */
- }
-
- if (tree_info->num_nodes == 0) {
- SetMessage(global_screen_data.info_label,
- "There are no active nodes.");
- 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);
- }
-
- /* Function Name: _TreeSelectNode
- * Description: Modifies the state of a node and all its decendants.
- * Arguments: node - node to operate on.
- * type - type of selection to perform.
- * recurse - whether to continue on down the tree.
- * Returns: none.
- */
-
- void
- _TreeSelectNode(node, type, recurse)
- 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,
- "Internal Error: Unknown select type.");
- return;
- }
-
- XtSetArg(args[0], XtNstate, state);
- XtSetValues(node->widget, args, ONE);
- TreeToggle(node->widget, (XtPointer) node, (XtPointer) state);
-
- if (!recurse)
- return;
-
- for (i = 0; i < node->num_children; i++)
- _TreeSelectNode(node->children[i], type, recurse);
- }
-
- /* Function Name: _TreeRelabelNodes
- * Description: Modifies the node and all its decendants label.
- * Arguments: node - node to operate on.
- * type - type of selection to perform.
- * recurse - whether to continue on down the tree.
- * Returns: none.
- */
-
- void
- _TreeRelabelNode(node, type, recurse)
- 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,
- "Internal Error: Unknown label type.");
- return;
- }
-
- XtSetValues(node->widget, args, ONE);
-
- if (!recurse)
- return;
-
- for (i = 0; i < node->num_children; i++)
- _TreeRelabelNode(node->children[i], type, recurse);
- }
-
- /* Function Name: _TreeActivateNode
- * Description: Activates relatives of the node specfied, as specified
- * by type.
- * Arguments: node - node to opererate on.
- * type - type of activate to invode.
- * Returns: none.
- */
-
- 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,
- "Internal Error: Unknown activate type.");
- }
-
- /************************************************************
- *
- * Non - Exported Functions.
- *
- ************************************************************/
-
- WNode * FindNode();
-
- /* Function Name: AddNode
- * Description: adds a node to the widget tree.
- * Arguments: top_node - a pointer to the current top node.
- * info - the info from the client about the widget tree.
- * tree_info - global information on this tree.
- * Returns: none.
- */
-
- 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);
- }
-
- /* Function Name: FillNode
- * Description: Fills in everything but the node id in the node.
- * Arguments: info - the info from the client.
- * node - node to fill.
- * tree_info - global information on this tree.
- * Returns: none
- */
-
- static void
- FillNode(info, node, tree_info)
- WidgetTreeInfo * info;
- WNode * node;
- TreeInfo * tree_info;
- {
- node->class = info->class;
- info->class = NULL; /* keeps it from deallocating. */
- node->name = info->name;
- info->name = NULL;
- node->window = info->window;
- node->tree_info = tree_info;
- }
-
- /* Function Name: AddChild
- * Description: Adds a child to an existing node.
- * Arguments: parent - parent node.
- * child - child node to add.
- * Returns: none.
- */
-
- 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;
- }
-
- /************************************************************
- *
- * Functions that operate of the current tree.
- *
- ************************************************************/
-
- /* Function Name: CopyActiveNodes
- * Description: returns a copy of the currently selected nodes.
- * Arguments: tree_info - the tree info struct.
- * Returns: a copy of the selected nodes.
- */
-
- 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);
- }
-
- /* Function Name: SetAndCenterTreeNode
- * Description: Deactivates all nodes, activates the one specified, and
- * and moves the tree to be centered on the current node.
- * Arguments: node - node to use.
- * Returns: none.
- */
-
- 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); /* Unselect all nodes */
- _TreeSelectNode(node, SelectAll, FALSE); /* Select this node */
-
- /*
- * Get porthole dimensions.
- */
-
- 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);
-
- /*
- * Get node widget dimensions.
- */
-
- 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);
-
- /*
- * reset the node x and y location to be the new x and y location of
- * the tree relative to the porthole.
- */
-
- 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);
- }
-
- /* Function Name: PerformTreeToFileDump
- * Description: Dumps the contents of the current widget tree to
- * the file specified.
- * Arguments: node - node to dump.
- * num_tabs - number of spaces to indent.
- * fp - pointer to the file to write to.
- * Returns: none.
- */
-
- 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);
- }
-
-