3 * $XConsortium: obj.c /main/4 1996/10/02 16:11:56 drk $
5 * @(#)obj.c 3.46 11 Feb 1994 cde_app_builder/src/libABobj
7 * RESTRICTED CONFIDENTIAL INFORMATION:
9 * The information in this document is subject to special restrictions in a
10 * confidential disclosure agreement between HP, IBM, Sun, USL, SCO and
11 * Univel. Do not distribute this document outside HP, IBM, Sun, USL, SCO,
12 * or Univel without Sun's specific written approval. This document and all
13 * copies and derivative works thereof must be returned or destroyed at Sun's
16 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
22 * ABObj.c - manipulations of one gobj structure
30 #include <sys/param.h>
32 #include "objP.h" /* include first! */
33 #include <ab_private/trav.h>
34 #include <ab_private/util.h>
35 #include "obj_names_listP.h"
36 #include "obj_notifyP.h"
39 objP_or_tree_update_clients_with_data(
44 UpdateDataFreeFunc free_func
48 * Gets the item for this object with index which_item
51 obj_get_item(ABObj obj, int which_item)
55 int item_num = -1; /* must be -1 */
57 for (trav_open(&trav, obj, AB_TRAV_ITEMS_FOR_OBJ);
58 (item = trav_next(&trav)) != NULL;)
61 if (item_num == which_item)
71 * Return the Help Item for a given menubar
74 obj_get_menubar_help_item(
79 ABObj help_item = NULL;
82 if (!obj_is_menubar(obj))
85 for (trav_open(&trav, obj, AB_TRAV_ITEMS_FOR_OBJ);
86 (item = trav_next(&trav)) != NULL;)
88 if (obj_is_help_item(item) == TRUE)
100 * Returns the number of this object, as a child of it's parent.
103 obj_get_child_num(ABObj obj)
108 if (obj->parent == NULL)
113 for (child = obj->parent->first_child;
114 child != NULL; child = child->next_sibling)
129 obj_get_container_child(ABObj obj)
132 for (child = obj->first_child; child != NULL;
133 child = child->next_sibling)
135 if (obj_is_container(child))
145 * Returns the item number of this object, with reference to it's parent
148 obj_get_item_num(ABObj obj)
152 for (item = obj->parent->first_child;
153 item != NULL; item = item->next_sibling)
155 if (!obj_is_item(item))
170 obj_get_menu(ABObj obj)
173 for (child = obj->first_child; child != NULL; child = child->next_sibling)
175 if (obj_is_menu(child))
185 obj_get_pane_child(ABObj obj)
188 for (child = obj->first_child; child != NULL;
189 child = child->next_sibling)
191 if (obj_is_pane(child))
201 obj_has_menu(ABObj obj)
203 if (!util_strempty(obj_get_menu_name(obj)))
211 * Moves the children only if *all* the children can be moved.
214 obj_move_children(ABObj to, ABObj from)
217 int iRC = 0;/* return code */
221 * Get permission for all children
223 for (child = from->first_child;
224 child != NULL; child = child->next_sibling)
226 if ((iRC = objP_notify_send_allow_reparent(child, to)) < 0)
233 while ((child = from->first_child) != NULL)
237 * Don't send reparent to NULL
240 objP_notify_push_mode();
241 objP_notify_clear_mode(OBJEV_MODE_SEND_NOTIFY_EVS);
243 obj_append_child(to, child);
244 objP_notify_pop_mode();
246 objP_notify_send_reparent(child, from);
254 * maxlen < 1 means no max.
257 obj_ensure_unique_name(ABObj obj, ABObj root, int maxlen)
261 BOOL name_changed = FALSE;
268 ABObj other_obj = NULL;
272 if (obj->name == NULL)
280 strncpy(obj_name, istr_string(obj->name), maxlen);
284 if (obj_is_module(obj))
286 trav_type = AB_TRAV_MODULES;
290 trav_type = AB_TRAV_UI;
292 while ((!unique) && (!error))
295 for (trav_open(&trav, root, trav_type);
296 (other_obj = trav_next(&trav)) != NULL;)
298 if ((other_obj != obj)
299 && (other_obj->name != NULL)
300 && (strncmp(istr_string(other_obj->name), obj_name, maxlen)
305 sprintf(mod_name, "%d", ++modifier);
306 if ((strlen(mod_name) + 1) > (unsigned) maxlen)
311 oldlen = istr_len(obj->name);
312 modlen = strlen(mod_name);
313 newlen = oldlen + modlen;
317 oldlen = newlen - modlen;
319 strncpy(obj_name, istr_string(obj->name),
321 obj_name[oldlen] = 0;
322 strcat(obj_name, mod_name);
327 if (name_changed && (!error))
329 /* printf("CHANGED %s -> %s\n", obj->name, obj_name); */
332 * REMIND: CHANGE ALL BY-NAME REFS TO THIS OBJECT!
334 obj_set_name(obj, obj_name);
337 return error ? -1 : 0;
342 * Munges name, as necessary to get uniqueness
345 obj_set_unique_name_istr(ABObj obj, ISTRING name)
347 int rc = 0; /* return code */
348 ISTRING newName = obj_alloc_unique_name_istr(obj, name, -1);
349 rc = obj_set_name_istr(obj, newName);
350 istr_destroy(newName);
356 obj_set_unique_name(ABObj obj, STRING strName)
358 int return_value = 0;
359 ISTRING name = istr_create(strName);
361 return_value = obj_set_unique_name_istr(obj, name);
369 obj_alloc_unique_name(
375 ABObj parent = obj->parent;
376 if ( (parent == NULL)
377 || (obj_find_by_name(parent, name) == obj) )
381 return obj_alloc_unique_name_for_child(parent, name, maxNameLen);
386 obj_alloc_unique_name_istr(
392 ABObj parent = obj->parent;
393 if ( (parent == NULL)
394 || (obj_find_by_name(parent, istr_string(name)) == obj) )
396 return istr_dup(name);
398 return obj_alloc_unique_name_istr_for_child(parent, name, maxNameLen);
410 ABObj parent = obj->parent;
411 if ( (parent == NULL)
412 || (obj_find_by_name(parent, name) == obj) )
416 return obj_get_unique_name_for_child(parent, name, maxNameLen-1, nameOutBuf);
421 * maxlen < 1 means no max.
424 obj_alloc_unique_name_for_child(
431 STRING unique_name = NULL;
438 #if defined (USL) || defined(__uxp__)
440 * The USL specific changes were added ifdef due to time constraints
441 * They should be removed in the next release
443 maxlen = util_min(8191,maxlen); /* don't overrun buf */
445 maxlen = util_min(8192,maxlen); /* don't overrun buf */
449 * Alloc space and copy-in the unique name
451 unique_name = strdup(
452 obj_get_unique_name_for_child(obj, name, maxlen-1, nameBuf));
459 obj_alloc_unique_name_istr_for_child(
466 ISTRING unique_name = NULL;
473 #if defined (USL) || defined(__uxp__)
474 maxlen = util_min(8191,maxlen);
476 maxlen = util_min(8192,maxlen);
478 unique_name = istr_create(
479 obj_get_unique_name_for_child(obj, istr_string(name), maxlen-1, nameBuf));
486 obj_get_unique_name_for_child(
493 STRING returnName = NULL;
494 int nameOutBufSize = maxlen+1;
495 StringList namesList = NULL;
500 int objNumberStart = 0;
503 namesList = objP_get_names_scope_for_children(obj);
504 if (namesList == NULL)
510 unique = !strlist_str_exists(namesList, name);
518 * Determine trailing number
520 util_strncpy(nameOutBuf, name, nameOutBufSize);
521 nameLen = strlen(nameOutBuf);
522 for (i = nameLen-1; i >= 0; --i)
524 if (!isdigit(nameOutBuf[i]))
529 objNumberStart = i + 1;
530 objNumber = atoi(&(nameOutBuf[objNumberStart]));
533 * Search for a unique name by incrementing trailing #
539 if (++objNumber == 1)
541 /* skip 1 - name w/no # is implied 1 */
544 sprintf(&(nameOutBuf[objNumberStart]), "%d", objNumber);
545 unique = !strlist_str_exists(namesList, nameOutBuf);
550 returnName = nameOutBuf;
559 * Don't run this on a project!!! It's a severe dog, and can take many
560 * seconds to complete.
562 * Run it on each module (root = an module) instead.
565 obj_tree_ensure_unique_names(ABObj root, int maxnamelen)
570 for (trav_open(&trav, root, AB_TRAV_UI);
571 (obj = trav_next(&trav)) != NULL;)
573 obj_ensure_unique_name(obj, root, maxnamelen);
581 * Calls obj_tree_ensure_unique_names on each module in the given tree.
584 obj_tree_ensure_unique_names_in_modules(ABObj root, int maxnamelen)
589 for (trav_open(&trav, root, AB_TRAV_MODULES);
590 (module = trav_next(&trav)) != NULL;)
592 obj_tree_ensure_unique_names(module, maxnamelen);
599 * Gives an object a name by munging it's parent's name with it's own label.
600 * Used for item children, which aren't given names directly.
602 * actual_parent overrides the parent of the object. If actual_parent is NULL,
603 * the "normal" parent of the object is used.
606 obj_set_name_from_label(ABObj obj, STRING parent_name_in)
608 STRING parent_name = NULL;
609 STRING item_label = NULL;
610 STRING new_name = NULL;
613 (parent_name_in == NULL ?
614 (obj->parent == NULL ?
617 istr_string(obj->parent->name)
622 if (parent_name == NULL)
627 if (istr_len(obj->label) > 0)
629 item_label = istr_string(obj->label);
636 obj_set_unique_name(obj,
637 ab_ident_from_name_and_label(parent_name, item_label));
643 obj_set_name_from_parent(ABObj obj, STRING suffix)
646 STRING new_name = NULL;
648 parent_name = (obj->parent == NULL ?
651 istr_string(obj->parent->name)
654 if (parent_name == NULL)
659 obj_set_unique_name(obj,
660 ab_ident_from_name_and_label(parent_name,
668 * Gets a name for an object. Object may be NULL, or have a NULL name
670 * Copies name into passed-in buffer name, guarantees 0 termination. returns
674 obj_get_safe_name(ABObj obj, STRING name, int name_size)
683 strncpy(name, "(nil ABObj)", name_size);
685 else if (obj_get_name(obj) == NULL)
688 sprintf(buf, "(ABObj:0x%08lx)", obj);
689 strncpy(name, buf, name_size);
693 strncpy(name, obj_get_name(obj), name_size);
696 name[name_size - 1] = 0;
701 /*************************************************************************
703 ** UPDATE_CLIENTS METHODS **
705 *************************************************************************/
708 obj_update_clients(ABObj obj)
710 return objP_notify_send_update(obj, FALSE);
715 obj_tree_update_clients(ABObj tree)
718 return objP_notify_send_update(tree, TRUE);
723 obj_update_clients_with_data(
727 UpdateDataFreeFunc free_func)
729 return objP_or_tree_update_clients_with_data(
730 obj, FALSE, update_code, update_data, free_func);
735 obj_tree_update_clients_with_data(ABObj obj,
738 UpdateDataFreeFunc free_func)
740 return objP_or_tree_update_clients_with_data(
741 obj, TRUE, update_code, update_data, free_func);
746 objP_or_tree_update_clients_with_data(
751 UpdateDataFreeFunc free_func
757 * event notification will only free the data if the notify events are
758 * batched. It's pretty smart about it, so we're going to go to batch
759 * mode and let it handle it.
761 objP_notify_push_mode();
762 objP_notify_set_mode(OBJEV_MODE_BATCH_NOTIFY_EVS);
764 iReturn = objP_notify_send_update_with_data(
765 obj, update_subtree, update_code, update_data, free_func);
767 objP_notify_pop_mode();